Skip to content

Commit

Permalink
Merge branch 'weekly/11' of https://github.com/kakao-tech-campus-2nd-…
Browse files Browse the repository at this point in the history
…step3/Team28_BE into week11-haegyeong
  • Loading branch information
HaegyeongKim01 committed Nov 14, 2024
2 parents 710788b + 32fa518 commit bca75db
Show file tree
Hide file tree
Showing 31 changed files with 1,147 additions and 54 deletions.
28 changes: 18 additions & 10 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
name: Build and Deploy to EC2

# 워크플로우가 언제 실행될 것인지 조건 명시
# 워크플로우가 언제 실행될 것인지 조건 설정
on:
# push:
# branches: [ "weekly/11"]
pull_request:
branches: [ "Master" ]
types: [closed]
push:
branches: [ "weekly/11"]

# AWS 관련 값 변수로 설정
env:
Expand All @@ -31,21 +28,32 @@ jobs:
java-version: '21'
distribution: 'temurin'

# 공개되면 안되는 정보를 담은 .properties 파일을 생성
# 개별 환경 변수를 사용하여 application-secret.properties 파일 생성
- name: make application-secret.properties
run: |
mkdir -p ./src/main/resources
cd ./src/main/resources
touch ./application-secret.properties
echo "${{ secrets.APPLICATION_SECRET }}" > ./application-secret.properties
echo "kakao.javascript.key=${{ secrets.KAKAO_JAVASCRIPT_KEY }}" >> ./application-secret.properties
echo "GITHUB_CLIENT_ID=${{ secrets.GH_CLIENT_ID }}" >> ./application-secret.properties
echo "GITHUB_CLIENT_SECRET=${{ secrets.GH_CLIENT_SECRET }}" >> ./application-secret.properties
echo "GITHUB_REDIRECT_URI=${{ secrets.GH_REDIRECT_URI }}" >> ./application-secret.properties
echo "DB_USERNAME=${{ secrets.DB_USERNAME }}" >> ./application-secret.properties
echo "DB_PASSWORD=${{ secrets.DB_PASSWORD }}" >> ./application-secret.properties
- name: Check environment variables
run: |
echo "AWS_REGION: ${{ env.AWS_REGION }}"
echo "AWS_S3_BUCKET: ${{ env.AWS_S3_BUCKET }}"
echo "AWS_CODE_DEPLOY_APPLICATION: ${{ env.AWS_CODE_DEPLOY_APPLICATION }}"
echo "AWS_CODE_DEPLOY_GROUP: ${{ env.AWS_CODE_DEPLOY_GROUP }}"
echo "DATABASE_URL: ${{ secrets.DATABASE_URL }}"
# 권한 부여
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
shell: bash

- name: Build and Test
run: ./gradlew build test
run: ./gradlew build test --info

# 빌드 파일을 zip 형식으로 압축
- name: Make zip file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
"/walletList",
"/qrcodes/**",
"/notice",
"/notice/**"
"/notice/**",
"/qna",
"/qna/**"
).permitAll();
// 그 외의 모든 요청은 인증 필요
auth.anyRequest().authenticated();
Expand Down
49 changes: 35 additions & 14 deletions src/main/java/com/devcard/devcard/card/service/GroupService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,31 @@
import com.devcard.devcard.card.entity.Group;
import com.devcard.devcard.card.repository.CardRepository;
import com.devcard.devcard.card.repository.GroupRepository;
import com.devcard.devcard.chat.dto.CreateRoomRequest;
import com.devcard.devcard.chat.service.ChatRoomService;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.server.ResponseStatusException;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class GroupService {

private final GroupRepository groupRepository;
private final CardRepository cardRepository;
private final ChatRoomService chatRoomService;

public GroupService(GroupRepository groupRepository, CardRepository cardRepository) {
public GroupService(
GroupRepository groupRepository,
CardRepository cardRepository,
ChatRoomService chatRoomService
) {
this.groupRepository = groupRepository;
this.cardRepository = cardRepository;
this.chatRoomService = chatRoomService;
}

@Transactional
Expand All @@ -37,33 +45,46 @@ public List<GroupResponseDto> getGroupsByMember(Member member) {
List<Group> groups = groupRepository.findByMember(member);

return groups.stream()
.map(group -> new GroupResponseDto(group.getId(), group.getName(), group.getCount()))
.collect(Collectors.toList());
.map(group -> new GroupResponseDto(group.getId(), group.getName(), group.getCount()))
.collect(Collectors.toList());
}

@Transactional
public void addCardToGroup(Long groupId, Long cardId, Member member) {
Group group = groupRepository.findByIdAndMember(groupId, member)
.orElseThrow(() -> new IllegalArgumentException("해당 그룹이 존재하지 않거나 접근 권한이 없습니다."));
.orElseThrow(() -> new IllegalArgumentException("해당 그룹이 존재하지 않거나 접근 권한이 없습니다."));

Card card = cardRepository.findById(cardId)
.orElseThrow(() -> new IllegalArgumentException("해당 ID의 명함이 존재하지 않습니다."));
.orElseThrow(() -> new IllegalArgumentException("해당 ID의 명함이 존재하지 않습니다."));

if (group.getCards().contains(card)) {
throw new IllegalArgumentException("이미 해당 그룹에 추가되어 있는 명함입니다.");
}

// 채팅방 생성
CreateRoomRequest createRoomRequest = new CreateRoomRequest(Arrays.asList(
member.getId(),
card.getMember().getId()
));
chatRoomService.createChatRoom(createRoomRequest);

group.addCard(card);
groupRepository.save(group);
}

@Transactional
public void deleteCardFromGroup(Long groupId, Long cardId, Member member) {
Group group = groupRepository.findByIdAndMember(groupId, member)
.orElseThrow(() -> new IllegalArgumentException("해당 그룹이 존재하지 않거나 접근 권한이 없습니다."));
.orElseThrow(() -> new IllegalArgumentException("해당 그룹이 존재하지 않거나 접근 권한이 없습니다."));

Card card = cardRepository.findById(cardId)
.orElseThrow(() -> new IllegalArgumentException("해당 ID의 명함이 존재하지 않습니다."));
.orElseThrow(() -> new IllegalArgumentException("해당 ID의 명함이 존재하지 않습니다."));

// 채팅방 제거
chatRoomService.deleteChatRoomByParticipants(Arrays.asList(
member.getId(),
card.getMember().getId()
));

group.removeCard(card); // 그룹에서 명함을 제거
groupRepository.save(group); // 변경사항 저장
Expand All @@ -72,9 +93,9 @@ public void deleteCardFromGroup(Long groupId, Long cardId, Member member) {
@Transactional
public void updateGroupName(Long groupId, String newName, Member member) {
Group group = groupRepository.findByIdAndMember(groupId, member)
.orElseThrow(() -> new ResponseStatusException(
HttpStatus.BAD_REQUEST, "해당 그룹이 존재하지 않거나 접근 권한이 없습니다."
));
.orElseThrow(() -> new ResponseStatusException(
HttpStatus.BAD_REQUEST, "해당 그룹이 존재하지 않거나 접근 권한이 없습니다."
));

group.setName(newName);
groupRepository.save(group);
Expand All @@ -83,7 +104,7 @@ public void updateGroupName(Long groupId, String newName, Member member) {
@Transactional
public void deleteGroup(Long groupId, Member member) {
Group group = groupRepository.findByIdAndMember(groupId, member)
.orElseThrow(() -> new IllegalArgumentException("해당 그룹이 존재하지 않거나 접근 권한이 없습니다."));
.orElseThrow(() -> new IllegalArgumentException("해당 그룹이 존재하지 않거나 접근 권한이 없습니다."));

groupRepository.delete(group); // 그룹 삭제
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ public class CreateRoomRequest {

private List<Long> participantsId;

public List<Long> getParticipantsId() {
return participantsId;
public <T> CreateRoomRequest(List<T> list) {
}

public void setParticipantsId(List<Long> participantsId) {
this.participantsId = participantsId;
public List<Long> getParticipantsId() {
return participantsId;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.devcard.devcard.chat.repository;

import com.devcard.devcard.chat.model.ChatRoom;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
Expand All @@ -10,4 +12,6 @@ public interface ChatRoomRepository extends JpaRepository<ChatRoom, Long> {

@Query("SELECT cr FROM ChatRoom cr JOIN cr.participants p WHERE p.id = :userId")
List<ChatRoom> findByParticipantId(@Param("userId") String userId);

Optional<ChatRoom> findByParticipants_IdIn(Collection<Long> participantsId);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.devcard.devcard.chat.service;

import static com.devcard.devcard.chat.util.Constants.CHAT_ROOM_NOT_FOUND;
import static com.devcard.devcard.chat.util.Constants.CHAT_ROOM_NOT_FOUND_BY_PARTICIPANTS;

import com.devcard.devcard.auth.entity.Member;
import com.devcard.devcard.chat.dto.ChatMessageResponse;
Expand All @@ -15,6 +16,7 @@
import com.devcard.devcard.chat.repository.ChatRoomRepository;
import com.devcard.devcard.chat.repository.ChatUserRepository;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -122,7 +124,7 @@ public ChatRoomResponse getChatRoomById(String chatId) {
}

/**
* 채팅방 삭제
* chatId를 이용해 채팅방 삭제
* @param chatId 채팅방 ID
*/
public void deleteChatRoom(String chatId) {
Expand All @@ -139,6 +141,23 @@ public void deleteChatRoom(String chatId) {
chatRoomRepository.deleteById(chatRoomId);
}

/**
* 참여자 ID를 이용해 채팅방 삭제
* @param participantsId 채팅방에 참여하는 모든 유저의 ID List
*/
public void deleteChatRoomByParticipants(List<Long> participantsId) {
// 참여자 ID 목록으로 채팅방 조회
ChatRoom chatRoom = chatRoomRepository.findByParticipants_IdIn(participantsId)
.orElseThrow(() -> new ChatRoomNotFoundException(
CHAT_ROOM_NOT_FOUND_BY_PARTICIPANTS + participantsId.toString()));

// 관련된 메시지 삭제
chatRepository.deleteByChatRoomId(chatRoom.getId());

// 채팅방 삭제
chatRoomRepository.delete(chatRoom);
}

/**
* 특정 채팅방이 존재하는지 확인
* @param chatId 채팅방 ID
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ public Long extractUserIdFromSession(WebSocketSession session) {
* @return 해당 파라미터 값 (존재하지 않으면 null 반환)
*/
private Long extractParamFromUri(String uri, String paramName) {
// e.g. `ws://localhost:8080/ws?chatId=1&userId=1` 입력의 경우,
// e.g. `ws://3.34.144.148:8080/ws?chatId=1&userId=1` 입력의 경우,
try {
// "?"로 나누어 쿼리 파라미터 부분만 가져옴 (e.g. `chatId=1&userId=1`)
String[] parts = uri.split("\\?");
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/devcard/devcard/chat/util/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public class Constants {

// 채팅방 상수
public static final String CHAT_ROOM_NOT_FOUND = "채팅방을 다음의 id로 찾을 수 없습니다. id: ";
public static final String CHAT_ROOM_NOT_FOUND_BY_PARTICIPANTS = "해당 참여자 ID 목록으로 채팅방을 찾을 수 없습니다. 참여자 ID 목록: ";
public static final String USER_NOT_IN_CHAT_ROOM = "사용자가 해당 채팅방의 참여자가 아닙니다.";
public static final String EMPTY_MESSAGE = "메시지가 비어 있습니다.";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package com.devcard.devcard.mypage.controller.page;

import com.devcard.devcard.auth.entity.Member;
import com.devcard.devcard.auth.repository.MemberRepository;
import com.devcard.devcard.mypage.service.NoticeService;
import com.devcard.devcard.mypage.service.QnAService;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -9,9 +14,14 @@
@Controller
public class MyPageController {
private final NoticeService noticeService;
private final QnAService qnAService;
private final MemberRepository memberRepository;

public MyPageController(NoticeService noticeService) {
public MyPageController(NoticeService noticeService, QnAService qnAService,
MemberRepository memberRepository) {
this.noticeService = noticeService;
this.qnAService = qnAService;
this.memberRepository = memberRepository;
}

@GetMapping("/mypage/notice")
Expand All @@ -25,4 +35,34 @@ public String getNotice(@PathVariable(name = "id") Long id, Model model) {
model.addAttribute("notice", noticeService.getNotice(id));
return "notice-detail";
}

@GetMapping("/mypage/qna")
public String getQnAList(Model model) {
model.addAttribute("qnaList", qnAService.getQnAList());
return "qna-list";
}

@GetMapping("/mypage/qna/{id}")
public String getQnA(@PathVariable(name = "id") Long id, Model model) {
model.addAttribute("qna", qnAService.getQnA(id));
return "qna-detail";
}

@GetMapping("/mypage/qna/create")
public String getQnACreate(Model model, Authentication authentication) {
OAuth2User oAuth2User = (OAuth2User) authentication.getPrincipal();
String githubId = String.valueOf(oAuth2User.getAttributes().get("id"));

// GitHub ID로 사용자를 찾아서 등록 여부 확인
Member member = memberRepository.findByGithubId(githubId);

model.addAttribute("member", member);
return "qna-create-new";
}

@GetMapping("/mypage/qna/create/{id}")
public String getQnAUpdate(@PathVariable(name = "id") Long id, Model model) {
model.addAttribute("qna", qnAService.getQnA(id));
return "qna-create-update";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.devcard.devcard.mypage.controller.rest;

import com.devcard.devcard.mypage.dto.NoticeRequest;
import com.devcard.devcard.mypage.dto.NoticeResponse;
import com.devcard.devcard.mypage.dto.NoticeUpdateRequest;
import com.devcard.devcard.mypage.dto.QnAListResponse;
import com.devcard.devcard.mypage.dto.QnARequest;
import com.devcard.devcard.mypage.dto.QnAResponse;
import com.devcard.devcard.mypage.dto.QnAUpdateRequest;
import com.devcard.devcard.mypage.service.QnAService;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/qna")
public class QnAController {

private final QnAService qnAService;

public QnAController(QnAService qnAService) {
this.qnAService = qnAService;
}

@GetMapping
public ResponseEntity<List<QnAListResponse>> getAllQnA(){
return ResponseEntity.status(201).body(qnAService.getQnAList());
}

@GetMapping("/{id}")
public ResponseEntity<QnAResponse> getQnA(@PathVariable("id") Long id){
return ResponseEntity.ok(qnAService.getQnA(id));
}

@PostMapping("")
public ResponseEntity<QnAResponse> addQnA(@RequestBody QnARequest qnARequest){
return ResponseEntity.ok(qnAService.addQnA(qnARequest));
}

@PutMapping("")
public ResponseEntity<QnAResponse> updateQnA(@RequestBody QnAUpdateRequest qnAUpdateRequest){
return ResponseEntity.ok(qnAService.updateQnA(qnAUpdateRequest));
}

@DeleteMapping("/{id}")
public ResponseEntity<QnAResponse> deleteQnA(@PathVariable("id") Long id){
return ResponseEntity.ok(qnAService.deleteQnA(id));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.devcard.devcard.mypage.dto;

public record QnAAnswerDTO(Long id, String answer) {

}
Loading

0 comments on commit bca75db

Please sign in to comment.