Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

채팅방 생성/삭제 로직 추가, CI/CD 적용 #97

Merged
merged 4 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
# push:
# branches: [ "weekly/11"]
pull_request:
branches: [ "Master" ]
# branches: [ "Master" ]
types: [closed]

# AWS 관련 값 변수로 설정
Expand All @@ -18,6 +18,7 @@ env:
jobs:
deploy:
runs-on: ubuntu-latest
if: github.repository == 'kakao-tech-campus-2nd-step3/Team28_BE' && github.event.pull_request.merged == true
permissions:
contents: read
packages: write
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
4 changes: 2 additions & 2 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ spring.jpa.show-sql=true
#spring.datasource.url=jdbc:h2:mem:test;MODE=MYSQL;DB_CLOSE_DELAY=-1
#spring.datasource.username=sa
#spring.datasource.password=
spring.datasource.url=jdbc:mysql://localhost:3306/devcard_db?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&characterEncoding=UTF-8
spring.datasource.url=jdbc:mysql://3.34.144.148:3306/devcard_db?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&characterEncoding=UTF-8
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
Expand All @@ -37,7 +37,7 @@ logging.level.org.springframework.security=DEBUG


# QR Code Service
qr.domain.uri=http://localhost:8080/
qr.domain.uri=http://3.34.144.148:8080/
qr.code.directory=src/main/resources/static/qrcodes/

# Kakao Service
Expand Down
8 changes: 4 additions & 4 deletions src/main/resources/static/js/card/card-share.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ document.getElementById('kakao-share-btn').addEventListener('click', function ()
description: '회사: [[${card.company}]], 직책: [[${card.position}]]',
imageUrl: 'https://developers.kakao.com/assets/img/about/logos/kakaolink/kakaolink_btn_medium.png',
link: {
mobileWebUrl: 'http://localhost:8080/cards/' + cardId + '/view',
webUrl: 'http://localhost:8080/cards/' + cardId + '/view'
mobileWebUrl: 'http://3.34.144.148:8080/cards/' + cardId + '/view',
webUrl: 'http://3.34.144.148:8080/cards/' + cardId + '/view'
}
},
buttons: [
{
title: '명함 보기',
link: {
mobileWebUrl: 'http://localhost:8080/cards/' + cardId + '/view',
webUrl: 'http://localhost:8080/cards/' + cardId + '/view'
mobileWebUrl: 'http://3.34.144.148:8080/cards/' + cardId + '/view',
webUrl: 'http://3.34.144.148:8080/cards/' + cardId + '/view'
}
}
],
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/static/js/chat.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ $(document).ready(function () {
fetchChatRoom(chatId);

// 임시로 로컬 서버 설정
const socket = new WebSocket(`ws://localhost:8080/ws?chatId=${chatId}&userId=${memberId}`);
const socket = new WebSocket(`ws://3.34.144.148:8080/ws?chatId=${chatId}&userId=${memberId}`);

// 웹소켓 연결
socket.addEventListener("open", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ void testExtractMessage_EmptyJsonObject() {
@DisplayName("유효한 chatId 추출 성공")
void testExtractChatIdFromSession_ValidChatId() {
// 유효한 URI 설정
when(session.getUri()).thenReturn(URI.create("ws://localhost:8080/ws?chatId=1&userId=1"));
when(session.getUri()).thenReturn(URI.create("ws://3.34.144.148:8080/ws?chatId=1&userId=1"));

// chatId가 1로 반환되는지 확인
Long chatId = chatService.extractChatIdFromSession(session);
Expand All @@ -381,7 +381,7 @@ void testExtractChatIdFromSession_ValidChatId() {
@DisplayName("쿼리 파라미터 없음 - chatId")
void testExtractChatIdFromSession_NoChatId() {
// chatId가 없는 URI 설정
when(session.getUri()).thenReturn(URI.create("ws://localhost:8080/ws"));
when(session.getUri()).thenReturn(URI.create("ws://3.34.144.148:8080/ws"));

// chatId가 없으므로 IllegalArgumentException 발생
Exception exception = assertThrows(
Expand All @@ -395,7 +395,7 @@ void testExtractChatIdFromSession_NoChatId() {
@DisplayName("chatId 숫자 형식 오류")
void testExtractChatIdFromSession_InvalidChatIdFormat() {
// chatId가 잘못된 형식인 URI 설정
when(session.getUri()).thenReturn(URI.create("ws://localhost:8080/ws?chatId=abc&userId=1"));
when(session.getUri()).thenReturn(URI.create("ws://3.34.144.148:8080/ws?chatId=abc&userId=1"));

// chatId가 숫자 형식이 아니므로 IllegalArgumentException 발생
Exception exception = assertThrows(
Expand All @@ -409,7 +409,7 @@ void testExtractChatIdFromSession_InvalidChatIdFormat() {
@DisplayName("유효한 userId 추출 성공")
void testExtractUserIdFromSession_ValidUserId() {
// 유효한 URI 설정
when(session.getUri()).thenReturn(URI.create("ws://localhost:8080/ws?chatId=1&userId=1"));
when(session.getUri()).thenReturn(URI.create("ws://3.34.144.148:8080/ws?chatId=1&userId=1"));

// userId가 1로 반환되는지 확인
Long userId = chatService.extractUserIdFromSession(session);
Expand All @@ -420,7 +420,7 @@ void testExtractUserIdFromSession_ValidUserId() {
@DisplayName("쿼리 파라미터 없음 - userId")
void testExtractUserIdFromSession_NoUserId() {
// userId가 없는 URI 설정
when(session.getUri()).thenReturn(URI.create("ws://localhost:8080/ws"));
when(session.getUri()).thenReturn(URI.create("ws://3.34.144.148:8080/ws"));

// userId가 없으므로 IllegalArgumentException 발생
Exception exception = assertThrows(
Expand All @@ -434,7 +434,7 @@ void testExtractUserIdFromSession_NoUserId() {
@DisplayName("userId 숫자 형식 오류")
void testExtractUserIdFromSession_InvalidUserIdFormat() {
// userId가 잘못된 형식인 URI 설정
when(session.getUri()).thenReturn(URI.create("ws://localhost:8080/ws?chatId=1&userId=abc"));
when(session.getUri()).thenReturn(URI.create("ws://3.34.144.148:8080/ws?chatId=1&userId=abc"));

// userId가 숫자 형식이 아니므로 IllegalArgumentException 발생
Exception exception = assertThrows(
Expand Down
Loading