From 509a10771ee0acbf7a4a27a39512718374315f8b Mon Sep 17 00:00:00 2001 From: coen park Date: Thu, 13 Mar 2025 00:06:06 +0900 Subject: [PATCH 01/17] =?UTF-8?q?feat:=20servlet=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=82=AC=EC=9D=B4=EC=A6=88=20=EC=A0=9C=ED=95=9C=2010MB?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ef46c2a..3ce7910 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,3 +1,7 @@ spring: profiles: - active: local \ No newline at end of file + active: local + servlet: + multipart: + max-file-size: 10MB + max-request-size: 10MB From 8b58377f5304f4cde54ae768bcba52e0c7e4a6fa Mon Sep 17 00:00:00 2001 From: coen park Date: Thu, 13 Mar 2025 00:12:46 +0900 Subject: [PATCH 02/17] =?UTF-8?q?feat:=20=EC=9D=91=EB=8B=B5=EA=B0=92?= =?UTF-8?q?=EC=97=90=EC=84=9C=20totalCount=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/adapter/in/web/response/ReviewInfoResponses.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/codeit/side/user/adapter/in/web/response/ReviewInfoResponses.java b/src/main/java/com/codeit/side/user/adapter/in/web/response/ReviewInfoResponses.java index da8c364..1313779 100644 --- a/src/main/java/com/codeit/side/user/adapter/in/web/response/ReviewInfoResponses.java +++ b/src/main/java/com/codeit/side/user/adapter/in/web/response/ReviewInfoResponses.java @@ -4,11 +4,11 @@ import java.util.List; -public record ReviewInfoResponses(List reviews, Integer totalCount) { +public record ReviewInfoResponses(List reviews) { public static ReviewInfoResponses from(ReviewInfos reviewInfos) { List reviewInfoResponses = reviewInfos.stream() .map(ReviewInfoResponse::from) .toList(); - return new ReviewInfoResponses(reviewInfoResponses, reviewInfos.getTotalCount()); + return new ReviewInfoResponses(reviewInfoResponses); } } From 3738480cdfec6adab9a5716ea3ad1cf0a7e80a63 Mon Sep 17 00:00:00 2001 From: coen park Date: Thu, 13 Mar 2025 07:30:53 +0900 Subject: [PATCH 03/17] =?UTF-8?q?feat:=20=EC=9D=91=EB=8B=B5=EA=B0=92=20?= =?UTF-8?q?=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../side/user/adapter/in/web/response/ReviewInfoResponse.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/codeit/side/user/adapter/in/web/response/ReviewInfoResponse.java b/src/main/java/com/codeit/side/user/adapter/in/web/response/ReviewInfoResponse.java index 52adfd4..9d4b677 100644 --- a/src/main/java/com/codeit/side/user/adapter/in/web/response/ReviewInfoResponse.java +++ b/src/main/java/com/codeit/side/user/adapter/in/web/response/ReviewInfoResponse.java @@ -1,5 +1,6 @@ package com.codeit.side.user.adapter.in.web.response; +import com.codeit.side.lightening.domain.Category; import com.codeit.side.lightening.domain.Lightening; import com.codeit.side.lightening.domain.Review; import com.codeit.side.user.domain.ReviewInfo; @@ -13,6 +14,7 @@ public record ReviewInfoResponse( Integer rating, LocalDateTime createdAt, Long lighteningId, + Category category, String title, String city, String town, @@ -33,6 +35,7 @@ public static ReviewInfoResponse from(ReviewInfo reviewInfo) { review.getScore(), review.getCreatedAt(), lightening.getId(), + lightening.getCategory(), lightening.getTitle(), lightening.getCity(), lightening.getTown(), From fa65e051783ecc3dbf690bf9bcf26d419ef1e85b Mon Sep 17 00:00:00 2001 From: coen park Date: Thu, 13 Mar 2025 07:31:18 +0900 Subject: [PATCH 04/17] =?UTF-8?q?feat:=20=EC=B1=84=ED=8C=85=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=9C=A0=EC=A0=80=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../in/web/response/ChatMessageResponse.java | 22 +++++++++------- .../port/in/ChatMessageUseCase.java | 2 +- .../service/ChatMessageService.java | 26 ++++++++++++++----- .../codeit/side/chat/domain/ChatMessages.java | 6 ++--- .../side/chat/domain/UserChatMessage.java | 17 ++++++++++++ .../adapter/in/web/LighteningController.java | 4 +-- .../response/CreateLighteningResponse.java | 8 +++--- .../port/in/LighteningUseCase.java | 3 ++- .../service/LighteningService.java | 6 ++--- .../lightening/domain/LighteningChatRoom.java | 17 ++++++++++++ 10 files changed, 83 insertions(+), 28 deletions(-) create mode 100644 src/main/java/com/codeit/side/chat/domain/UserChatMessage.java create mode 100644 src/main/java/com/codeit/side/lightening/domain/LighteningChatRoom.java diff --git a/src/main/java/com/codeit/side/chat/adapter/in/web/response/ChatMessageResponse.java b/src/main/java/com/codeit/side/chat/adapter/in/web/response/ChatMessageResponse.java index effce54..9b455ee 100644 --- a/src/main/java/com/codeit/side/chat/adapter/in/web/response/ChatMessageResponse.java +++ b/src/main/java/com/codeit/side/chat/adapter/in/web/response/ChatMessageResponse.java @@ -1,6 +1,7 @@ package com.codeit.side.chat.adapter.in.web.response; -import com.codeit.side.chat.domain.ChatMessage; +import com.codeit.side.chat.domain.UserChatMessage; +import com.codeit.side.user.domain.User; import java.time.LocalDateTime; @@ -10,16 +11,19 @@ public record ChatMessageResponse( Long userId, String userNickname, String content, - LocalDateTime createdAt + LocalDateTime createdAt, + String userImage ) { - public static ChatMessageResponse from(ChatMessage chatMessage) { + public static ChatMessageResponse from(UserChatMessage chatMessage) { + User user = chatMessage.getUser(); return new ChatMessageResponse( - chatMessage.getId(), - chatMessage.getRoomId(), - chatMessage.getUserId(), - chatMessage.getUserNickname(), - chatMessage.getContent(), - chatMessage.getCreatedAt() + chatMessage.getChatMessage().getId(), + chatMessage.getChatMessage().getRoomId(), + chatMessage.getChatMessage().getUserId(), + chatMessage.getChatMessage().getUserNickname(), + chatMessage.getChatMessage().getContent(), + chatMessage.getChatMessage().getCreatedAt(), + user.isHasImage() ? "https://codeit-doit.s3.ap-northeast-2.amazonaws.com/user/%s/image.jpg".formatted(user.getId()) : "" ); } } diff --git a/src/main/java/com/codeit/side/chat/application/port/in/ChatMessageUseCase.java b/src/main/java/com/codeit/side/chat/application/port/in/ChatMessageUseCase.java index 33bfb0c..1c96feb 100644 --- a/src/main/java/com/codeit/side/chat/application/port/in/ChatMessageUseCase.java +++ b/src/main/java/com/codeit/side/chat/application/port/in/ChatMessageUseCase.java @@ -10,7 +10,7 @@ public interface ChatMessageUseCase { void save(ChatMessage chatMessage); - void createChatRoom(String email, Long lighteningId, String chatRoomName); + ChatRoom createChatRoom(String email, Long lighteningId, String chatRoomName); List findAllChatRooms(String email); diff --git a/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java b/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java index 2051a6e..b106aac 100644 --- a/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java +++ b/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java @@ -4,10 +4,7 @@ import com.codeit.side.chat.application.port.out.ChatMemberRepository; import com.codeit.side.chat.application.port.out.ChatMessageRepository; import com.codeit.side.chat.application.port.out.ChatRoomRepository; -import com.codeit.side.chat.domain.ChatMessage; -import com.codeit.side.chat.domain.ChatMessages; -import com.codeit.side.chat.domain.ChatRoom; -import com.codeit.side.chat.domain.ChatRoomInfo; +import com.codeit.side.chat.domain.*; import com.codeit.side.chat.domain.command.ChatRoomCommand; import com.codeit.side.common.adapter.exception.IllegalRequestException; import com.codeit.side.user.application.port.out.UserQueryRepository; @@ -19,6 +16,8 @@ import java.util.List; import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; @Primary @Service @@ -38,12 +37,13 @@ public void save(ChatMessage chatMessage) { @Override @Transactional - public void createChatRoom(String email, Long lighteningId, String chatRoomName) { + public ChatRoom createChatRoom(String email, Long lighteningId, String chatRoomName) { User host = userQueryRepository.getByEmail(email) .toDomain(); ChatRoomCommand userChatRoomCommand = ChatRoomCommand.of(chatRoomName, lighteningId, host.getId()); ChatRoom chatRoom = chatRoomRepository.save(userChatRoomCommand); chatMemberRepository.save(chatRoom.getId(), userChatRoomCommand); + return chatRoom; } @Override @@ -77,7 +77,21 @@ public ChatMessages findAllMessagesByRoomId(Long roomId, String email, Long offs List messages = chatMessages.stream() .limit(size) .toList(); - return ChatMessages.of(messages, isLast); + List userIds = extractUserIds(chatMessages); + Map idToUser = userQueryRepository.findAllByIds(userIds) + .stream() + .collect(Collectors.toMap(User::getId, Function.identity())); + List userChatMessages = messages.stream() + .map(message -> UserChatMessage.of(message, idToUser.get(message.getUserId()))) + .toList(); + return ChatMessages.of(userChatMessages, isLast); + } + + private List extractUserIds(List chatMessages) { + return chatMessages.stream() + .map(ChatMessage::getUserId) + .distinct() + .toList(); } @Override diff --git a/src/main/java/com/codeit/side/chat/domain/ChatMessages.java b/src/main/java/com/codeit/side/chat/domain/ChatMessages.java index 4dfc613..1a5bd17 100644 --- a/src/main/java/com/codeit/side/chat/domain/ChatMessages.java +++ b/src/main/java/com/codeit/side/chat/domain/ChatMessages.java @@ -10,14 +10,14 @@ @Getter @RequiredArgsConstructor(access = AccessLevel.PRIVATE) public class ChatMessages { - private final List messages; + private final List messages; private final boolean isLast; - public static ChatMessages of(List messages, boolean isLast) { + public static ChatMessages of(List messages, boolean isLast) { return new ChatMessages(messages, isLast); } - public Stream stream() { + public Stream stream() { return messages.stream(); } } diff --git a/src/main/java/com/codeit/side/chat/domain/UserChatMessage.java b/src/main/java/com/codeit/side/chat/domain/UserChatMessage.java new file mode 100644 index 0000000..ca84311 --- /dev/null +++ b/src/main/java/com/codeit/side/chat/domain/UserChatMessage.java @@ -0,0 +1,17 @@ +package com.codeit.side.chat.domain; + +import com.codeit.side.user.domain.User; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public class UserChatMessage { + private final ChatMessage chatMessage; + private final User user; + + public static UserChatMessage of(ChatMessage chatMessage, User user) { + return new UserChatMessage(chatMessage, user); + } +} diff --git a/src/main/java/com/codeit/side/lightening/adapter/in/web/LighteningController.java b/src/main/java/com/codeit/side/lightening/adapter/in/web/LighteningController.java index c958415..d31ca61 100644 --- a/src/main/java/com/codeit/side/lightening/adapter/in/web/LighteningController.java +++ b/src/main/java/com/codeit/side/lightening/adapter/in/web/LighteningController.java @@ -31,8 +31,8 @@ public ResponseEntity create( ) { String email = getEmail(true); Lightening lighteningModel = lighteningRequest.toModel(hasImage(image)); - Lightening savedLightening = lighteningUseCase.save(email, lighteningModel, image); - return ResponseEntity.ok(CreateLighteningResponse.from(savedLightening.getId())); + LighteningChatRoom lighteningChatRoom = lighteningUseCase.save(email, lighteningModel, image); + return ResponseEntity.ok(CreateLighteningResponse.from(lighteningChatRoom)); } @PostMapping("/{id}/like") diff --git a/src/main/java/com/codeit/side/lightening/adapter/in/web/response/CreateLighteningResponse.java b/src/main/java/com/codeit/side/lightening/adapter/in/web/response/CreateLighteningResponse.java index 3831f7a..99f9eb8 100644 --- a/src/main/java/com/codeit/side/lightening/adapter/in/web/response/CreateLighteningResponse.java +++ b/src/main/java/com/codeit/side/lightening/adapter/in/web/response/CreateLighteningResponse.java @@ -1,7 +1,9 @@ package com.codeit.side.lightening.adapter.in.web.response; -public record CreateLighteningResponse(long id) { - public static CreateLighteningResponse from(long id) { - return new CreateLighteningResponse(id); +import com.codeit.side.lightening.domain.LighteningChatRoom; + +public record CreateLighteningResponse(long id, long chatRoomId) { + public static CreateLighteningResponse from(LighteningChatRoom lighteningChatRoom) { + return new CreateLighteningResponse(lighteningChatRoom.getLightening().getId(), lighteningChatRoom.getChatRoom().getId()); } } diff --git a/src/main/java/com/codeit/side/lightening/application/port/in/LighteningUseCase.java b/src/main/java/com/codeit/side/lightening/application/port/in/LighteningUseCase.java index 7581d58..36907a9 100644 --- a/src/main/java/com/codeit/side/lightening/application/port/in/LighteningUseCase.java +++ b/src/main/java/com/codeit/side/lightening/application/port/in/LighteningUseCase.java @@ -1,6 +1,7 @@ package com.codeit.side.lightening.application.port.in; import com.codeit.side.lightening.domain.Lightening; +import com.codeit.side.lightening.domain.LighteningChatRoom; import com.codeit.side.lightening.domain.LighteningCondition; import com.codeit.side.lightening.domain.LighteningInfo; import org.springframework.web.multipart.MultipartFile; @@ -8,7 +9,7 @@ import java.util.List; public interface LighteningUseCase { - Lightening save(String email, Lightening lightening, MultipartFile image); + LighteningChatRoom save(String email, Lightening lightening, MultipartFile image); void like(String email, Long id); diff --git a/src/main/java/com/codeit/side/lightening/application/service/LighteningService.java b/src/main/java/com/codeit/side/lightening/application/service/LighteningService.java index 2962f09..b88b750 100644 --- a/src/main/java/com/codeit/side/lightening/application/service/LighteningService.java +++ b/src/main/java/com/codeit/side/lightening/application/service/LighteningService.java @@ -32,13 +32,13 @@ public class LighteningService implements LighteningUseCase { @Override @Transactional - public Lightening save(String email, Lightening lightening, MultipartFile image) { + public LighteningChatRoom save(String email, Lightening lightening, MultipartFile image) { fileUploader.validateImage(image); Lightening savedLightening = lighteningCommandRepository.save(email, lightening); lighteningCommandRepository.join(email, savedLightening.getId()); - chatMessageUseCase.createChatRoom(email, savedLightening.getId(), savedLightening.getTitle()); + ChatRoom chatRoom = chatMessageUseCase.createChatRoom(email, savedLightening.getId(), savedLightening.getTitle()); fileUploader.uploadImageToS3(image, "lightening/" + savedLightening.getId(), "image.jpg", "jpg"); - return savedLightening; + return LighteningChatRoom.of(savedLightening, chatRoom); } @Override diff --git a/src/main/java/com/codeit/side/lightening/domain/LighteningChatRoom.java b/src/main/java/com/codeit/side/lightening/domain/LighteningChatRoom.java new file mode 100644 index 0000000..b919755 --- /dev/null +++ b/src/main/java/com/codeit/side/lightening/domain/LighteningChatRoom.java @@ -0,0 +1,17 @@ +package com.codeit.side.lightening.domain; + +import com.codeit.side.chat.domain.ChatRoom; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public class LighteningChatRoom { + private final Lightening lightening; + private final ChatRoom chatRoom; + + public static LighteningChatRoom of(Lightening lightening, ChatRoom chatRoom){ + return new LighteningChatRoom(lightening, chatRoom); + } +} From 8fc6fe26ebdb67f894384e1d644e3601a0bf6aaf Mon Sep 17 00:00:00 2001 From: coen park Date: Fri, 14 Mar 2025 00:02:31 +0900 Subject: [PATCH 05/17] =?UTF-8?q?feat:=20=EB=B2=88=EA=B0=9C=20=EC=97=AC?= =?UTF-8?q?=EB=9F=AC=EA=B0=9C=20=EC=A2=8B=EC=95=84=EC=9A=94=20API=20?= =?UTF-8?q?=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/in/web/LighteningController.java | 9 ++++++++ .../web/request/LighteningLikesRequest.java | 10 +++++++++ .../LighteningCommandRepositoryImpl.java | 17 +++++++++++++++ .../entity/LighteningLikeEntity.java | 4 ++++ .../port/in/LighteningUseCase.java | 3 +++ .../port/out/LighteningCommandRepository.java | 4 ++++ .../service/LighteningService.java | 21 +++++++++++++++++++ .../mock/FakeLighteningCommandRepository.java | 6 ++++++ 8 files changed, 74 insertions(+) create mode 100644 src/main/java/com/codeit/side/lightening/adapter/in/web/request/LighteningLikesRequest.java diff --git a/src/main/java/com/codeit/side/lightening/adapter/in/web/LighteningController.java b/src/main/java/com/codeit/side/lightening/adapter/in/web/LighteningController.java index d31ca61..99a84cf 100644 --- a/src/main/java/com/codeit/side/lightening/adapter/in/web/LighteningController.java +++ b/src/main/java/com/codeit/side/lightening/adapter/in/web/LighteningController.java @@ -1,6 +1,7 @@ package com.codeit.side.lightening.adapter.in.web; import com.codeit.side.common.adapter.exception.AuthenticationFailedException; +import com.codeit.side.lightening.adapter.in.web.request.LighteningLikesRequest; import com.codeit.side.lightening.adapter.in.web.request.LighteningRequest; import com.codeit.side.lightening.adapter.in.web.request.LighteningUpdateRequest; import com.codeit.side.lightening.adapter.in.web.response.CreateLighteningResponse; @@ -43,6 +44,14 @@ public ResponseEntity like(@PathVariable Long id) { .build(); } + @PostMapping("/like") + public ResponseEntity likesAll(@RequestBody @Valid LighteningLikesRequest request) { + String email = getEmail(true); + lighteningUseCase.likesAll(email, request.lighteningIds()); + return ResponseEntity.ok() + .build(); + } + @PostMapping("/{id}/join") public ResponseEntity join(@PathVariable Long id) { String email = getEmail(true); diff --git a/src/main/java/com/codeit/side/lightening/adapter/in/web/request/LighteningLikesRequest.java b/src/main/java/com/codeit/side/lightening/adapter/in/web/request/LighteningLikesRequest.java new file mode 100644 index 0000000..c5fb793 --- /dev/null +++ b/src/main/java/com/codeit/side/lightening/adapter/in/web/request/LighteningLikesRequest.java @@ -0,0 +1,10 @@ +package com.codeit.side.lightening.adapter.in.web.request; + +import jakarta.validation.constraints.NotNull; + +import java.util.Set; + +public record LighteningLikesRequest( + @NotNull(message = "lighteningIds는 필수입니다.") Set lighteningIds +) { +} diff --git a/src/main/java/com/codeit/side/lightening/adapter/out/persistence/LighteningCommandRepositoryImpl.java b/src/main/java/com/codeit/side/lightening/adapter/out/persistence/LighteningCommandRepositoryImpl.java index 4078551..c48e0ea 100644 --- a/src/main/java/com/codeit/side/lightening/adapter/out/persistence/LighteningCommandRepositoryImpl.java +++ b/src/main/java/com/codeit/side/lightening/adapter/out/persistence/LighteningCommandRepositoryImpl.java @@ -12,6 +12,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; +import java.util.Set; + @Repository @RequiredArgsConstructor public class LighteningCommandRepositoryImpl implements LighteningCommandRepository { @@ -62,4 +64,19 @@ public void delete(Long id) { lighteningJpaEntityRepository.findById(id) .ifPresent(LighteningEntity::delete); } + + @Override + public void likesAll(String email, Set lighteningIds) { + lighteningIds.forEach(lighteningId -> { + likeLightening(email, lighteningId); + }); + } + + private void likeLightening(String email, Long lighteningId) { + lighteningLikeJpaEntityRepository.findByLighteningIdAndEmail(lighteningId, email) + .ifPresentOrElse( + LighteningLikeEntity::like, + () -> lighteningLikeJpaEntityRepository.save(LighteningLikeEntity.of(lighteningId, email)) + ); + } } diff --git a/src/main/java/com/codeit/side/lightening/adapter/out/persistence/entity/LighteningLikeEntity.java b/src/main/java/com/codeit/side/lightening/adapter/out/persistence/entity/LighteningLikeEntity.java index cedf5f0..c3f45d1 100644 --- a/src/main/java/com/codeit/side/lightening/adapter/out/persistence/entity/LighteningLikeEntity.java +++ b/src/main/java/com/codeit/side/lightening/adapter/out/persistence/entity/LighteningLikeEntity.java @@ -40,6 +40,10 @@ public void update() { isDeleted = !isDeleted; } + public void like() { + isDeleted = false; + } + public LighteningLike toDomain() { return LighteningLike.of(lighteningId, email); } diff --git a/src/main/java/com/codeit/side/lightening/application/port/in/LighteningUseCase.java b/src/main/java/com/codeit/side/lightening/application/port/in/LighteningUseCase.java index 36907a9..1bf1d1e 100644 --- a/src/main/java/com/codeit/side/lightening/application/port/in/LighteningUseCase.java +++ b/src/main/java/com/codeit/side/lightening/application/port/in/LighteningUseCase.java @@ -7,6 +7,7 @@ import org.springframework.web.multipart.MultipartFile; import java.util.List; +import java.util.Set; public interface LighteningUseCase { LighteningChatRoom save(String email, Lightening lightening, MultipartFile image); @@ -24,4 +25,6 @@ public interface LighteningUseCase { void update(String email, Long id, String description); void delete(String email, Long id); + + void likesAll(String email, Set lighteningIds); } diff --git a/src/main/java/com/codeit/side/lightening/application/port/out/LighteningCommandRepository.java b/src/main/java/com/codeit/side/lightening/application/port/out/LighteningCommandRepository.java index cd6fc86..ce3ce65 100644 --- a/src/main/java/com/codeit/side/lightening/application/port/out/LighteningCommandRepository.java +++ b/src/main/java/com/codeit/side/lightening/application/port/out/LighteningCommandRepository.java @@ -2,6 +2,8 @@ import com.codeit.side.lightening.domain.Lightening; +import java.util.Set; + public interface LighteningCommandRepository { Lightening save(String email, Lightening lightening); @@ -14,4 +16,6 @@ public interface LighteningCommandRepository { void update(Long id, String description); void delete(Long id); + + void likesAll(String email, Set lighteningIds); } diff --git a/src/main/java/com/codeit/side/lightening/application/service/LighteningService.java b/src/main/java/com/codeit/side/lightening/application/service/LighteningService.java index b88b750..30aebad 100644 --- a/src/main/java/com/codeit/side/lightening/application/service/LighteningService.java +++ b/src/main/java/com/codeit/side/lightening/application/service/LighteningService.java @@ -16,8 +16,10 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -107,6 +109,25 @@ public void delete(String email, Long id) { lighteningCommandRepository.delete(id); } + @Override + @Transactional + public void likesAll(String email, Set lighteningIds) { + List lightenings = lighteningReadRepository.findAllBy(new ArrayList<>(lighteningIds)); + if (lightenings.size() != lighteningIds.size()) { + List extractIds = extractNotExistingLighteningIds(lightenings, new ArrayList<>(lighteningIds)); + throw new IllegalRequestException("존재하지 않는 번개가 포함되어 있습니다. lighteningIds: %s".formatted(extractIds)); + } + lighteningCommandRepository.likesAll(email, lighteningIds); + } + + private List extractNotExistingLighteningIds(List lightenings, List lighteningIds) { + Set target = lightenings.stream() + .map(Lightening::getId) + .collect(Collectors.toSet()); + lighteningIds.removeAll(target); + return lighteningIds; + } + private List createLighteningInfos(List lightenings, List lighteningMembers, List chatRooms, List lighteningLikes) { Map> idToLighteningMembers = lighteningMembers.stream() .collect(Collectors.groupingBy(LighteningMember::getLighteningId)); diff --git a/src/test/java/com/codeit/side/mock/FakeLighteningCommandRepository.java b/src/test/java/com/codeit/side/mock/FakeLighteningCommandRepository.java index 8922278..689c841 100644 --- a/src/test/java/com/codeit/side/mock/FakeLighteningCommandRepository.java +++ b/src/test/java/com/codeit/side/mock/FakeLighteningCommandRepository.java @@ -5,6 +5,7 @@ import com.codeit.side.lightening.domain.LighteningFixture; import java.util.List; +import java.util.Set; public class FakeLighteningCommandRepository implements LighteningCommandRepository { private final List lightenings; @@ -45,4 +46,9 @@ public void update(Long id, String description) { public void delete(Long id) { } + + @Override + public void likesAll(String email, Set lighteningIds) { + + } } From dbea6f7093faf4435c3c710371ccd2fd753bfbc9 Mon Sep 17 00:00:00 2001 From: coen park Date: Sat, 15 Mar 2025 23:34:16 +0900 Subject: [PATCH 06/17] =?UTF-8?q?feat:=20=EB=B2=88=EA=B0=9C=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94=20API=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../in/websocket/ChatWebsocketController.java | 7 ++++-- .../side/common/config/SecurityConfig.java | 3 ++- .../side/common/config/WebSocketConfig.java | 24 ++++++++++++++++++- .../LighteningCommandRepositoryImpl.java | 23 ++++++++++-------- .../entity/LighteningLikeEntity.java | 7 +++++- 5 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/codeit/side/chat/adapter/in/websocket/ChatWebsocketController.java b/src/main/java/com/codeit/side/chat/adapter/in/websocket/ChatWebsocketController.java index 3c96679..e453d72 100644 --- a/src/main/java/com/codeit/side/chat/adapter/in/websocket/ChatWebsocketController.java +++ b/src/main/java/com/codeit/side/chat/adapter/in/websocket/ChatWebsocketController.java @@ -41,9 +41,12 @@ public void sendMessage( ChatType.CHAT, chatMessageReceived.getContent() ); - String destination = "/topic/room/%s".formatted(id); - messagingTemplate.convertAndSend(destination, ChatMessageSend.of(chatMessage, "")); + String destination = "/topic/room/" + id; + System.out.println("destination = " + destination); + + String userImage = user.isHasImage() ? "https://codeit-doit.s3.ap-northeast-2.amazonaws.com/user/%s/image.jpg".formatted(user.getId()) : ""; + messagingTemplate.convertAndSend(destination, ChatMessageSend.of(chatMessage, userImage)); chatMessageUseCase.save(chatMessage); } } diff --git a/src/main/java/com/codeit/side/common/config/SecurityConfig.java b/src/main/java/com/codeit/side/common/config/SecurityConfig.java index 9c43bcf..63dd2aa 100644 --- a/src/main/java/com/codeit/side/common/config/SecurityConfig.java +++ b/src/main/java/com/codeit/side/common/config/SecurityConfig.java @@ -38,7 +38,8 @@ public class SecurityConfig { "/api/v1/login", "/api/v1/join", "/api/v1/**", - "/api/v1/ws/**" + "/api/v1/ws/**", + "/api/v1/ws", }; private final JwtAuthenticationFilter jwtAuthenticationFilter; diff --git a/src/main/java/com/codeit/side/common/config/WebSocketConfig.java b/src/main/java/com/codeit/side/common/config/WebSocketConfig.java index 2a524af..fd5304e 100644 --- a/src/main/java/com/codeit/side/common/config/WebSocketConfig.java +++ b/src/main/java/com/codeit/side/common/config/WebSocketConfig.java @@ -3,9 +3,13 @@ import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; +import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration; +import org.springframework.web.socket.handler.WebSocketHandlerDecorator; +import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory; @Configuration @EnableWebSocketMessageBroker @@ -31,7 +35,25 @@ public void registerStompEndpoints(StompEndpointRegistry registry) { * */ @Override //메시지 라우팅 public void configureMessageBroker(MessageBrokerRegistry registry) { - registry.enableSimpleBroker("/topic", "/queue"); + registry.enableSimpleBroker("/topic"); registry.setApplicationDestinationPrefixes("/app"); } + + @Override + public void configureWebSocketTransport(WebSocketTransportRegistration registration) { + registration.setMessageSizeLimit(128 * 1024); + registration.setSendBufferSizeLimit(512 * 1024); + registration.setSendTimeLimit(20 * 1000); + registration.setDecoratorFactories(webSocketHandlerDecoratorFactory()); + } + + private WebSocketHandlerDecoratorFactory webSocketHandlerDecoratorFactory() { + return handler -> new WebSocketHandlerDecorator(handler) { + @Override + public void afterConnectionEstablished(WebSocketSession session) throws Exception { + System.out.println("WebSocket connection established: " + session.getId()); + super.afterConnectionEstablished(session); + } + }; + } } diff --git a/src/main/java/com/codeit/side/lightening/adapter/out/persistence/LighteningCommandRepositoryImpl.java b/src/main/java/com/codeit/side/lightening/adapter/out/persistence/LighteningCommandRepositoryImpl.java index c48e0ea..987059c 100644 --- a/src/main/java/com/codeit/side/lightening/adapter/out/persistence/LighteningCommandRepositoryImpl.java +++ b/src/main/java/com/codeit/side/lightening/adapter/out/persistence/LighteningCommandRepositoryImpl.java @@ -12,6 +12,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; +import java.util.Optional; import java.util.Set; @Repository @@ -31,11 +32,12 @@ public Lightening save(String email, Lightening lightening) { @Override public void like(String email, Long lighteningId) { - lighteningLikeJpaEntityRepository.findByLighteningIdAndEmail(lighteningId, email) - .ifPresentOrElse( - LighteningLikeEntity::update, - () -> lighteningLikeJpaEntityRepository.save(LighteningLikeEntity.of(lighteningId, email)) - ); + Optional lighteningLikeEntity = lighteningLikeJpaEntityRepository.findByLighteningIdAndEmail(lighteningId, email); + if (lighteningLikeEntity.isPresent()) { + lighteningLikeEntity.get().update(); + return; + } + lighteningLikeJpaEntityRepository.save(LighteningLikeEntity.of(lighteningId, email)); } @Override @@ -73,10 +75,11 @@ public void likesAll(String email, Set lighteningIds) { } private void likeLightening(String email, Long lighteningId) { - lighteningLikeJpaEntityRepository.findByLighteningIdAndEmail(lighteningId, email) - .ifPresentOrElse( - LighteningLikeEntity::like, - () -> lighteningLikeJpaEntityRepository.save(LighteningLikeEntity.of(lighteningId, email)) - ); + Optional lighteningLikeEntity = lighteningLikeJpaEntityRepository.findByLighteningIdAndEmail(lighteningId, email); + if (lighteningLikeEntity.isPresent()) { + lighteningLikeEntity.get().like(); + return; + } + lighteningLikeJpaEntityRepository.save(LighteningLikeEntity.of(lighteningId, email)); } } diff --git a/src/main/java/com/codeit/side/lightening/adapter/out/persistence/entity/LighteningLikeEntity.java b/src/main/java/com/codeit/side/lightening/adapter/out/persistence/entity/LighteningLikeEntity.java index c3f45d1..f101fc4 100644 --- a/src/main/java/com/codeit/side/lightening/adapter/out/persistence/entity/LighteningLikeEntity.java +++ b/src/main/java/com/codeit/side/lightening/adapter/out/persistence/entity/LighteningLikeEntity.java @@ -9,7 +9,12 @@ import lombok.NoArgsConstructor; @Entity -@Table(name = "lightening_likes") +@Table( + name = "lightening_likes", + uniqueConstraints = { + @UniqueConstraint(columnNames = {"lightening_id", "email"}) + } +) @Builder(access = AccessLevel.PACKAGE) @AllArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PROTECTED) From b6e0ed01319341312fb5f81c62a5550bd5250854 Mon Sep 17 00:00:00 2001 From: coen park Date: Sun, 16 Mar 2025 00:37:23 +0900 Subject: [PATCH 07/17] =?UTF-8?q?feat:=20=EB=B2=88=EA=B0=9C=20=EC=B1=84?= =?UTF-8?q?=ED=8C=85=20=EC=9D=BD=EC=9D=8C=20=EC=97=AC=EB=B6=80=20API=20?= =?UTF-8?q?=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../in/websocket/ChatWebsocketController.java | 2 +- .../persistence/ChatMemberRepositoryImpl.java | 5 ++++ .../ChatMessageReadRepositoryImpl.java | 12 ++++++++ .../out/persistence/ChatRepositoryImpl.java | 5 ++-- .../entity/ChatMessageReadEntity.java | 30 +++++++++++++++++++ .../port/out/ChatMemberRepository.java | 3 ++ .../port/out/ChatMessageReadRepository.java | 7 +++++ .../port/out/ChatMessageRepository.java | 2 +- .../service/ChatMessageService.java | 8 ++++- 9 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMessageReadRepositoryImpl.java create mode 100644 src/main/java/com/codeit/side/chat/adapter/out/persistence/entity/ChatMessageReadEntity.java create mode 100644 src/main/java/com/codeit/side/chat/application/port/out/ChatMessageReadRepository.java diff --git a/src/main/java/com/codeit/side/chat/adapter/in/websocket/ChatWebsocketController.java b/src/main/java/com/codeit/side/chat/adapter/in/websocket/ChatWebsocketController.java index e453d72..2f00d3e 100644 --- a/src/main/java/com/codeit/side/chat/adapter/in/websocket/ChatWebsocketController.java +++ b/src/main/java/com/codeit/side/chat/adapter/in/websocket/ChatWebsocketController.java @@ -46,7 +46,7 @@ public void sendMessage( System.out.println("destination = " + destination); String userImage = user.isHasImage() ? "https://codeit-doit.s3.ap-northeast-2.amazonaws.com/user/%s/image.jpg".formatted(user.getId()) : ""; - messagingTemplate.convertAndSend(destination, ChatMessageSend.of(chatMessage, userImage)); chatMessageUseCase.save(chatMessage); + messagingTemplate.convertAndSend(destination, ChatMessageSend.of(chatMessage, userImage)); } } diff --git a/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMemberRepositoryImpl.java b/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMemberRepositoryImpl.java index ea9369e..c4276a2 100644 --- a/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMemberRepositoryImpl.java +++ b/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMemberRepositoryImpl.java @@ -41,4 +41,9 @@ public boolean existsByChatRoomIdAndUserId(Long id, Long userId) { public void join(Long id, Long userId) { chatMemberJpaRepository.save(ChatMemberEntity.of(id, userId)); } + + @Override + public List findAllMemberById(Long roomId) { + return chatMemberJpaRepository.findAllByChatRoomId(roomId); + } } diff --git a/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMessageReadRepositoryImpl.java b/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMessageReadRepositoryImpl.java new file mode 100644 index 0000000..95652a0 --- /dev/null +++ b/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMessageReadRepositoryImpl.java @@ -0,0 +1,12 @@ +package com.codeit.side.chat.adapter.out.persistence; + +import com.codeit.side.chat.application.port.out.ChatMessageReadRepository; + +import java.util.List; + +public class ChatMessageReadRepositoryImpl implements ChatMessageReadRepository { + @Override + public void save(Long roomId, List userIds) { + + } +} diff --git a/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatRepositoryImpl.java b/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatRepositoryImpl.java index e8ef62d..9af4fe8 100644 --- a/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatRepositoryImpl.java +++ b/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatRepositoryImpl.java @@ -22,8 +22,9 @@ public class ChatRepositoryImpl implements ChatMessageRepository { @Override @Transactional - public void save(ChatMessage chatMessage) { - chatMessageJpaRepository.save(ChatMessageEntity.from(chatMessage)); + public ChatMessage save(ChatMessage chatMessage) { + return chatMessageJpaRepository.save(ChatMessageEntity.from(chatMessage)) + .toDomain(); } @Override diff --git a/src/main/java/com/codeit/side/chat/adapter/out/persistence/entity/ChatMessageReadEntity.java b/src/main/java/com/codeit/side/chat/adapter/out/persistence/entity/ChatMessageReadEntity.java new file mode 100644 index 0000000..5f7b19a --- /dev/null +++ b/src/main/java/com/codeit/side/chat/adapter/out/persistence/entity/ChatMessageReadEntity.java @@ -0,0 +1,30 @@ +package com.codeit.side.chat.adapter.out.persistence.entity; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Table( + name = "chat_message_read", + indexes = @Index(name = "idx_chat_room", columnList = "chatRoomId") +) +public class ChatMessageReadEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private Long chatRoomId; + + private Long userId; + + private Boolean isRead; + + public static ChatMessageReadEntity of(Long chatRoomId, Long userId) { + return new ChatMessageReadEntity(null, chatRoomId, userId, false); + } +} diff --git a/src/main/java/com/codeit/side/chat/application/port/out/ChatMemberRepository.java b/src/main/java/com/codeit/side/chat/application/port/out/ChatMemberRepository.java index 7b5222d..91980cb 100644 --- a/src/main/java/com/codeit/side/chat/application/port/out/ChatMemberRepository.java +++ b/src/main/java/com/codeit/side/chat/application/port/out/ChatMemberRepository.java @@ -1,5 +1,6 @@ package com.codeit.side.chat.application.port.out; +import com.codeit.side.chat.adapter.out.persistence.entity.ChatMemberEntity; import com.codeit.side.chat.domain.command.ChatRoomCommand; import java.util.List; @@ -13,4 +14,6 @@ public interface ChatMemberRepository { boolean existsByChatRoomIdAndUserId(Long id, Long userId); void join(Long id, Long userId); + + List findAllMemberById(Long roomId); } diff --git a/src/main/java/com/codeit/side/chat/application/port/out/ChatMessageReadRepository.java b/src/main/java/com/codeit/side/chat/application/port/out/ChatMessageReadRepository.java new file mode 100644 index 0000000..0d7de1b --- /dev/null +++ b/src/main/java/com/codeit/side/chat/application/port/out/ChatMessageReadRepository.java @@ -0,0 +1,7 @@ +package com.codeit.side.chat.application.port.out; + +import java.util.List; + +public interface ChatMessageReadRepository { + void save(Long roomId, List userIds); +} diff --git a/src/main/java/com/codeit/side/chat/application/port/out/ChatMessageRepository.java b/src/main/java/com/codeit/side/chat/application/port/out/ChatMessageRepository.java index 0f7c45b..5b6bfb5 100644 --- a/src/main/java/com/codeit/side/chat/application/port/out/ChatMessageRepository.java +++ b/src/main/java/com/codeit/side/chat/application/port/out/ChatMessageRepository.java @@ -6,7 +6,7 @@ import java.util.Map; public interface ChatMessageRepository { - void save(ChatMessage chatMessage); + ChatMessage save(ChatMessage chatMessage); Map findAllLastMessageByIds(List chatRoomIds); diff --git a/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java b/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java index b106aac..cdb5978 100644 --- a/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java +++ b/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java @@ -1,5 +1,6 @@ package com.codeit.side.chat.application.service; +import com.codeit.side.chat.adapter.out.persistence.entity.ChatMemberEntity; import com.codeit.side.chat.application.port.in.ChatMessageUseCase; import com.codeit.side.chat.application.port.out.ChatMemberRepository; import com.codeit.side.chat.application.port.out.ChatMessageRepository; @@ -32,7 +33,12 @@ public class ChatMessageService implements ChatMessageUseCase { @Override @Transactional public void save(ChatMessage chatMessage) { - chatMessageRepository.save(chatMessage); + ChatMessage savedChatMessage = chatMessageRepository.save(chatMessage); + List chatMemberEntities = chatMemberRepository.findAllMemberById(savedChatMessage.getRoomId()); + List userIds = chatMemberEntities.stream() + .map(ChatMemberEntity::getUserId) + .toList(); + } @Override From 5a201a063b61bf87f6099e9d4e2156cb38491012 Mon Sep 17 00:00:00 2001 From: coen park Date: Sun, 16 Mar 2025 01:18:38 +0900 Subject: [PATCH 08/17] =?UTF-8?q?feat:=20=EB=B2=88=EA=B0=9C=20=EC=B1=84?= =?UTF-8?q?=ED=8C=85=20=EC=9D=BD=EC=9D=8C=20=EC=97=AC=EB=B6=80=20API=20?= =?UTF-8?q?=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../in/websocket/ChatWebsocketController.java | 11 ++++++++++- .../ChatMessageReadRepositoryImpl.java | 17 +++++++++++++++++ .../entity/ChatMessageReadEntity.java | 4 ++++ .../jpa/ChatMessageReadJpaRepository.java | 10 ++++++++++ .../application/port/in/ChatMessageUseCase.java | 2 ++ .../port/out/ChatMessageReadRepository.java | 2 ++ .../application/service/ChatMessageService.java | 10 +++++++++- 7 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/codeit/side/chat/adapter/out/persistence/jpa/ChatMessageReadJpaRepository.java diff --git a/src/main/java/com/codeit/side/chat/adapter/in/websocket/ChatWebsocketController.java b/src/main/java/com/codeit/side/chat/adapter/in/websocket/ChatWebsocketController.java index 2f00d3e..3008ed2 100644 --- a/src/main/java/com/codeit/side/chat/adapter/in/websocket/ChatWebsocketController.java +++ b/src/main/java/com/codeit/side/chat/adapter/in/websocket/ChatWebsocketController.java @@ -43,10 +43,19 @@ public void sendMessage( ); String destination = "/topic/room/" + id; - System.out.println("destination = " + destination); String userImage = user.isHasImage() ? "https://codeit-doit.s3.ap-northeast-2.amazonaws.com/user/%s/image.jpg".formatted(user.getId()) : ""; chatMessageUseCase.save(chatMessage); messagingTemplate.convertAndSend(destination, ChatMessageSend.of(chatMessage, userImage)); } + + @MessageMapping("/room/{id}/read") + public void readMessage( + @Header(name = "simpSessionAttributes") Map sessionAttributes, + @DestinationVariable Long id + ) { + User user = (User) sessionAttributes.get("user"); + chatMessageUseCase.findChatRoomBy(id, user.getId()); + chatMessageUseCase.read(id, user.getId()); + } } diff --git a/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMessageReadRepositoryImpl.java b/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMessageReadRepositoryImpl.java index 95652a0..e5f13c7 100644 --- a/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMessageReadRepositoryImpl.java +++ b/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMessageReadRepositoryImpl.java @@ -1,12 +1,29 @@ package com.codeit.side.chat.adapter.out.persistence; +import com.codeit.side.chat.adapter.out.persistence.entity.ChatMessageReadEntity; +import com.codeit.side.chat.adapter.out.persistence.jpa.ChatMessageReadJpaRepository; import com.codeit.side.chat.application.port.out.ChatMessageReadRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; import java.util.List; +@Repository +@RequiredArgsConstructor public class ChatMessageReadRepositoryImpl implements ChatMessageReadRepository { + private final ChatMessageReadJpaRepository chatMessageReadJpaRepository; + @Override public void save(Long roomId, List userIds) { + List chatMessageReadEntities = userIds.stream() + .map(userId -> ChatMessageReadEntity.of(roomId, userId)) + .toList(); + chatMessageReadJpaRepository.saveAll(chatMessageReadEntities); + } + @Override + public void read(Long roomId, Long userId) { + chatMessageReadJpaRepository.findAllByChatRoomIdAndUserIdAndIsReadFalse(roomId, userId) + .forEach(ChatMessageReadEntity::read); } } diff --git a/src/main/java/com/codeit/side/chat/adapter/out/persistence/entity/ChatMessageReadEntity.java b/src/main/java/com/codeit/side/chat/adapter/out/persistence/entity/ChatMessageReadEntity.java index 5f7b19a..d455b34 100644 --- a/src/main/java/com/codeit/side/chat/adapter/out/persistence/entity/ChatMessageReadEntity.java +++ b/src/main/java/com/codeit/side/chat/adapter/out/persistence/entity/ChatMessageReadEntity.java @@ -27,4 +27,8 @@ public class ChatMessageReadEntity { public static ChatMessageReadEntity of(Long chatRoomId, Long userId) { return new ChatMessageReadEntity(null, chatRoomId, userId, false); } + + public void read() { + isRead = true; + } } diff --git a/src/main/java/com/codeit/side/chat/adapter/out/persistence/jpa/ChatMessageReadJpaRepository.java b/src/main/java/com/codeit/side/chat/adapter/out/persistence/jpa/ChatMessageReadJpaRepository.java new file mode 100644 index 0000000..af8d089 --- /dev/null +++ b/src/main/java/com/codeit/side/chat/adapter/out/persistence/jpa/ChatMessageReadJpaRepository.java @@ -0,0 +1,10 @@ +package com.codeit.side.chat.adapter.out.persistence.jpa; + +import com.codeit.side.chat.adapter.out.persistence.entity.ChatMessageReadEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ChatMessageReadJpaRepository extends JpaRepository { + List findAllByChatRoomIdAndUserIdAndIsReadFalse(Long roomId, Long userId); +} diff --git a/src/main/java/com/codeit/side/chat/application/port/in/ChatMessageUseCase.java b/src/main/java/com/codeit/side/chat/application/port/in/ChatMessageUseCase.java index 1c96feb..77035db 100644 --- a/src/main/java/com/codeit/side/chat/application/port/in/ChatMessageUseCase.java +++ b/src/main/java/com/codeit/side/chat/application/port/in/ChatMessageUseCase.java @@ -23,4 +23,6 @@ public interface ChatMessageUseCase { ChatRoom getChatRoomByLighteningId(Long lighteningId); List findAllChatRoomsByLighteningIds(List lighteningIds); + + void read(Long roomId, Long userId); } diff --git a/src/main/java/com/codeit/side/chat/application/port/out/ChatMessageReadRepository.java b/src/main/java/com/codeit/side/chat/application/port/out/ChatMessageReadRepository.java index 0d7de1b..7014a21 100644 --- a/src/main/java/com/codeit/side/chat/application/port/out/ChatMessageReadRepository.java +++ b/src/main/java/com/codeit/side/chat/application/port/out/ChatMessageReadRepository.java @@ -4,4 +4,6 @@ public interface ChatMessageReadRepository { void save(Long roomId, List userIds); + + void read(Long roomId, Long userId); } diff --git a/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java b/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java index cdb5978..57cc694 100644 --- a/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java +++ b/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java @@ -3,6 +3,7 @@ import com.codeit.side.chat.adapter.out.persistence.entity.ChatMemberEntity; import com.codeit.side.chat.application.port.in.ChatMessageUseCase; import com.codeit.side.chat.application.port.out.ChatMemberRepository; +import com.codeit.side.chat.application.port.out.ChatMessageReadRepository; import com.codeit.side.chat.application.port.out.ChatMessageRepository; import com.codeit.side.chat.application.port.out.ChatRoomRepository; import com.codeit.side.chat.domain.*; @@ -29,6 +30,7 @@ public class ChatMessageService implements ChatMessageUseCase { private final UserQueryRepository userQueryRepository; private final ChatRoomRepository chatRoomRepository; private final ChatMemberRepository chatMemberRepository; + private final ChatMessageReadRepository chatMessageReadRepository; @Override @Transactional @@ -38,7 +40,7 @@ public void save(ChatMessage chatMessage) { List userIds = chatMemberEntities.stream() .map(ChatMemberEntity::getUserId) .toList(); - + chatMessageReadRepository.save(savedChatMessage.getRoomId(), userIds); } @Override @@ -122,6 +124,12 @@ public List findAllChatRoomsByLighteningIds(List lighteningIds) return chatRoomRepository.findAllByLighteningIds(lighteningIds); } + @Override + @Transactional + public void read(Long roomId, Long userId) { + chatMessageReadRepository.read(roomId, userId); + } + private List createChatRoomInfos(List chatRooms, Map allLastMessageByIds, Map idToMemberSize) { return chatRooms.stream() .map(chatRoom -> createChatRoomInfo(chatRoom, allLastMessageByIds.get(chatRoom.getId()), idToMemberSize.get(chatRoom.getId()))) From 4764b83154bbdcb30b596fbb9796097a39026a89 Mon Sep 17 00:00:00 2001 From: coen park Date: Sun, 16 Mar 2025 18:49:59 +0900 Subject: [PATCH 09/17] =?UTF-8?q?feat:=20=EB=B2=88=EA=B0=9C=20=EC=B0=B8?= =?UTF-8?q?=EA=B0=80=20=EB=82=98=EA=B0=80=EA=B8=B0=EC=8B=9C=20=EC=B1=84?= =?UTF-8?q?=ED=8C=85=EB=B0=A9=20=EC=9E=90=EB=8F=99=20=EC=B0=B8=EA=B0=80/?= =?UTF-8?q?=EB=82=98=EA=B0=80=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../persistence/ChatMemberRepositoryImpl.java | 5 ++++ .../jpa/ChatMemberJpaRepository.java | 2 ++ .../port/in/ChatMessageUseCase.java | 4 ++++ .../port/out/ChatMemberRepository.java | 2 ++ .../service/ChatMessageService.java | 23 +++++++++++++++---- .../service/LighteningService.java | 2 ++ 6 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMemberRepositoryImpl.java b/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMemberRepositoryImpl.java index c4276a2..562b0f8 100644 --- a/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMemberRepositoryImpl.java +++ b/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMemberRepositoryImpl.java @@ -46,4 +46,9 @@ public void join(Long id, Long userId) { public List findAllMemberById(Long roomId) { return chatMemberJpaRepository.findAllByChatRoomId(roomId); } + + @Override + public void leave(Long chatRoomId, Long userId) { + chatMemberJpaRepository.deleteByChatRoomIdAndUserId(chatRoomId, userId); + } } diff --git a/src/main/java/com/codeit/side/chat/adapter/out/persistence/jpa/ChatMemberJpaRepository.java b/src/main/java/com/codeit/side/chat/adapter/out/persistence/jpa/ChatMemberJpaRepository.java index 4493ae0..799e386 100644 --- a/src/main/java/com/codeit/side/chat/adapter/out/persistence/jpa/ChatMemberJpaRepository.java +++ b/src/main/java/com/codeit/side/chat/adapter/out/persistence/jpa/ChatMemberJpaRepository.java @@ -10,4 +10,6 @@ public interface ChatMemberJpaRepository extends JpaRepository findAllByChatRoomId(Long chatRoomId); Optional findByChatRoomIdAndUserId(Long chatRoomId, Long userId); + + void deleteByChatRoomIdAndUserId(Long chatRoomId, Long userId); } diff --git a/src/main/java/com/codeit/side/chat/application/port/in/ChatMessageUseCase.java b/src/main/java/com/codeit/side/chat/application/port/in/ChatMessageUseCase.java index 77035db..b8e4b67 100644 --- a/src/main/java/com/codeit/side/chat/application/port/in/ChatMessageUseCase.java +++ b/src/main/java/com/codeit/side/chat/application/port/in/ChatMessageUseCase.java @@ -25,4 +25,8 @@ public interface ChatMessageUseCase { List findAllChatRoomsByLighteningIds(List lighteningIds); void read(Long roomId, Long userId); + + void leaveChatRoom(Long id, String email); + + void joinChatRoomByLighteningId(Long id, String email); } diff --git a/src/main/java/com/codeit/side/chat/application/port/out/ChatMemberRepository.java b/src/main/java/com/codeit/side/chat/application/port/out/ChatMemberRepository.java index 91980cb..3bb66a7 100644 --- a/src/main/java/com/codeit/side/chat/application/port/out/ChatMemberRepository.java +++ b/src/main/java/com/codeit/side/chat/application/port/out/ChatMemberRepository.java @@ -16,4 +16,6 @@ public interface ChatMemberRepository { void join(Long id, Long userId); List findAllMemberById(Long roomId); + + void leave(Long chatRoomId, Long userId); } diff --git a/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java b/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java index 57cc694..8f528c3 100644 --- a/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java +++ b/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java @@ -108,10 +108,16 @@ public void joinChatRoom(Long id, String email) { User user = userQueryRepository.getByEmail(email) .toDomain(); ChatRoom chatRoom = chatRoomRepository.getBy(id); - if (chatMemberRepository.existsByChatRoomIdAndUserId(chatRoom.getId(), user.getId())) { - throw new IllegalRequestException("이미 채팅방에 참여하고 있는 사용자입니다."); - } - chatMemberRepository.join(id, user.getId()); + chatMemberRepository.join(chatRoom.getId(), user.getId()); + } + + @Override + @Transactional + public void joinChatRoomByLighteningId(Long id, String email) { + User user = userQueryRepository.getByEmail(email) + .toDomain(); + ChatRoom chatRoom = chatRoomRepository.getByLighteningId(id); + chatMemberRepository.join(chatRoom.getId(), user.getId()); } @Override @@ -130,6 +136,15 @@ public void read(Long roomId, Long userId) { chatMessageReadRepository.read(roomId, userId); } + @Override + @Transactional + public void leaveChatRoom(Long id, String email) { + User user = userQueryRepository.getByEmail(email) + .toDomain(); + ChatRoom chatRoom = chatRoomRepository.getByLighteningId(id); + chatMemberRepository.leave(chatRoom.getId(), user.getId()); + } + private List createChatRoomInfos(List chatRooms, Map allLastMessageByIds, Map idToMemberSize) { return chatRooms.stream() .map(chatRoom -> createChatRoomInfo(chatRoom, allLastMessageByIds.get(chatRoom.getId()), idToMemberSize.get(chatRoom.getId()))) diff --git a/src/main/java/com/codeit/side/lightening/application/service/LighteningService.java b/src/main/java/com/codeit/side/lightening/application/service/LighteningService.java index 30aebad..40e3354 100644 --- a/src/main/java/com/codeit/side/lightening/application/service/LighteningService.java +++ b/src/main/java/com/codeit/side/lightening/application/service/LighteningService.java @@ -56,6 +56,7 @@ public void join(String email, Long id) { Lightening lightening = lighteningReadRepository.getById(id); validateLightening(email, lightening); lighteningCommandRepository.join(email, lightening.getId()); + chatMessageUseCase.joinChatRoomByLighteningId(id, email); } @Override @@ -66,6 +67,7 @@ public void leave(String email, Long id) { throw new UserNotJoinedException(lightening.getId()); } lighteningCommandRepository.leave(email, lightening.getId()); + chatMessageUseCase.leaveChatRoom(id, email); } @Override From 0f3d6e709f73f498c17e547a7d786d80f4258ce9 Mon Sep 17 00:00:00 2001 From: coen park Date: Sun, 16 Mar 2025 20:06:00 +0900 Subject: [PATCH 10/17] =?UTF-8?q?feat:=20=EB=82=B4=EA=B0=80=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC=ED=95=9C=20=EB=B2=88=EA=B0=9C=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=82=B4=EA=B0=80=20=EC=83=9D=EC=84=B1=ED=95=9C=20=EB=B2=88?= =?UTF-8?q?=EA=B0=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../out/persistence/jpa/LighteningQueryBuilder.java | 7 +++++++ .../jpa/LighteningQueryEntityRepository.java | 12 ++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/codeit/side/lightening/adapter/out/persistence/jpa/LighteningQueryBuilder.java b/src/main/java/com/codeit/side/lightening/adapter/out/persistence/jpa/LighteningQueryBuilder.java index 312239d..022fac9 100644 --- a/src/main/java/com/codeit/side/lightening/adapter/out/persistence/jpa/LighteningQueryBuilder.java +++ b/src/main/java/com/codeit/side/lightening/adapter/out/persistence/jpa/LighteningQueryBuilder.java @@ -88,4 +88,11 @@ public LighteningQueryBuilder addMyJoinedCondition(String email) { } return this; } + + public LighteningQueryBuilder addNotHostCondition(String email) { + if (email != null) { + booleanBuilder.and(lighteningEntity.host.ne(email)); + } + return this; + } } diff --git a/src/main/java/com/codeit/side/lightening/adapter/out/persistence/jpa/LighteningQueryEntityRepository.java b/src/main/java/com/codeit/side/lightening/adapter/out/persistence/jpa/LighteningQueryEntityRepository.java index 4aafe09..581835a 100644 --- a/src/main/java/com/codeit/side/lightening/adapter/out/persistence/jpa/LighteningQueryEntityRepository.java +++ b/src/main/java/com/codeit/side/lightening/adapter/out/persistence/jpa/LighteningQueryEntityRepository.java @@ -52,28 +52,30 @@ private OrderSpecifier createOrder(String order) { private BooleanBuilder createQueryBuilder(LighteningCondition lighteningCondition, String email) { return switch (lighteningCondition.getConditionType()) { - case LIST -> listConditionBuilder(lighteningCondition); - case MY_CREATED -> myCreatedConditionBuilder(lighteningCondition); + case LIST -> listConditionBuilder(lighteningCondition, email); + case MY_CREATED -> myCreatedConditionBuilder(lighteningCondition, email); case LIKE -> likeConditionBuilder(lighteningCondition, email); case MY_JOINED -> myJoinedConditionBuilder(lighteningCondition, email); }; } - private BooleanBuilder listConditionBuilder(LighteningCondition lighteningCondition) { + private BooleanBuilder listConditionBuilder(LighteningCondition lighteningCondition, String email) { return LighteningQueryBuilder.Builder() .addIsInactiveCondition(false) .addCategoryCondition(lighteningCondition.getCategory()) .addCityCondition(lighteningCondition.getCity()) .addTownCondition(lighteningCondition.getTown()) .addTargetAtCondition(lighteningCondition.getTargetAt()) + .addNotHostCondition(email) .build(); } - private BooleanBuilder myCreatedConditionBuilder(LighteningCondition lighteningCondition) { + private BooleanBuilder myCreatedConditionBuilder(LighteningCondition lighteningCondition, String email) { return LighteningQueryBuilder.Builder() .addIsInactiveCondition(false) .addCategoryCondition(lighteningCondition.getCategory()) .addMyCreatedCondition(lighteningCondition.getCreatedBy()) + .addNotHostCondition(email) .build(); } @@ -85,6 +87,7 @@ private BooleanBuilder likeConditionBuilder(LighteningCondition lighteningCondit .addTownCondition(lighteningCondition.getTown()) .addTargetAtCondition(lighteningCondition.getTargetAt()) .addLikeCondition(email) + .addNotHostCondition(email) .build(); } @@ -93,6 +96,7 @@ private BooleanBuilder myJoinedConditionBuilder(LighteningCondition lighteningCo .addIsInactiveCondition(false) .addCategoryCondition(lighteningCondition.getCategory()) .addMyJoinedCondition(email) + .addNotHostCondition(email) .build(); } From 7ef7d747a659a20a1f51c9072247341b47621541 Mon Sep 17 00:00:00 2001 From: coen park Date: Sun, 16 Mar 2025 21:25:07 +0900 Subject: [PATCH 11/17] =?UTF-8?q?feat:=20=EC=83=88=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/codeit/side/common/config/CorsMvcConfig.java | 2 +- .../java/com/codeit/side/common/config/SecurityConfig.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java b/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java index d3a022e..fe64059 100644 --- a/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java +++ b/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java @@ -6,7 +6,7 @@ @Configuration public class CorsMvcConfig implements WebMvcConfigurer { - private static final String[] ALLOWED_ORIGINS = {"http://localhost:3000", "http://127.0.0.1:5500", "https://doitz.netlify.app/", "https://calit.netlify.app/"}; + private static final String[] ALLOWED_ORIGINS = {"http://localhost:3000", "http://127.0.0.1:5500", "https://www.thunderting.site"}; private static final String[] ALLOWED_METHODS = {"GET", "POST", "PUT", "DELETE"}; @Override diff --git a/src/main/java/com/codeit/side/common/config/SecurityConfig.java b/src/main/java/com/codeit/side/common/config/SecurityConfig.java index 63dd2aa..f90f966 100644 --- a/src/main/java/com/codeit/side/common/config/SecurityConfig.java +++ b/src/main/java/com/codeit/side/common/config/SecurityConfig.java @@ -29,8 +29,7 @@ public class SecurityConfig { private static final List ALLOWED_ORIGINS = List.of( "http://localhost:3000", "http://127.0.0.1:5500", - "https://doitz.netlify.app", - "https://calit.netlify.app" + "https://www.thunderting.site" ); private static final List ALLOWED_METHODS = List.of("GET", "POST", "PUT", "DELETE"); private static final String[] WHITE_LIST = { From c5742ec8a4ffdc966efc9c84e895c9e78605d281 Mon Sep 17 00:00:00 2001 From: coen park Date: Sun, 16 Mar 2025 21:26:21 +0900 Subject: [PATCH 12/17] =?UTF-8?q?feat:=20=EC=83=88=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../out/persistence/jpa/LighteningQueryEntityRepository.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/codeit/side/lightening/adapter/out/persistence/jpa/LighteningQueryEntityRepository.java b/src/main/java/com/codeit/side/lightening/adapter/out/persistence/jpa/LighteningQueryEntityRepository.java index 581835a..67bf4e5 100644 --- a/src/main/java/com/codeit/side/lightening/adapter/out/persistence/jpa/LighteningQueryEntityRepository.java +++ b/src/main/java/com/codeit/side/lightening/adapter/out/persistence/jpa/LighteningQueryEntityRepository.java @@ -66,7 +66,6 @@ private BooleanBuilder listConditionBuilder(LighteningCondition lighteningCondit .addCityCondition(lighteningCondition.getCity()) .addTownCondition(lighteningCondition.getTown()) .addTargetAtCondition(lighteningCondition.getTargetAt()) - .addNotHostCondition(email) .build(); } @@ -75,7 +74,6 @@ private BooleanBuilder myCreatedConditionBuilder(LighteningCondition lighteningC .addIsInactiveCondition(false) .addCategoryCondition(lighteningCondition.getCategory()) .addMyCreatedCondition(lighteningCondition.getCreatedBy()) - .addNotHostCondition(email) .build(); } @@ -87,7 +85,6 @@ private BooleanBuilder likeConditionBuilder(LighteningCondition lighteningCondit .addTownCondition(lighteningCondition.getTown()) .addTargetAtCondition(lighteningCondition.getTargetAt()) .addLikeCondition(email) - .addNotHostCondition(email) .build(); } From 777b3a6827adcf5294329afea65180ea3556b750 Mon Sep 17 00:00:00 2001 From: coen park Date: Sun, 16 Mar 2025 22:21:19 +0900 Subject: [PATCH 13/17] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=ED=95=9C=20=EA=B2=BD=EC=9A=B0=20unreadCount=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ChatMessageReadRepositoryImpl.java | 11 ++++++++ .../jpa/ChatMessageReadJpaRepository.java | 3 ++ .../port/in/ChatMessageUseCase.java | 5 ++++ .../port/out/ChatMessageReadRepository.java | 6 ++++ .../service/ChatMessageService.java | 23 +++++++++++++++ .../in/web/response/LighteningResponse.java | 2 ++ .../service/LighteningService.java | 28 ++++++++++++++----- .../lightening/domain/LighteningInfo.java | 8 ++++-- 8 files changed, 76 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMessageReadRepositoryImpl.java b/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMessageReadRepositoryImpl.java index e5f13c7..d18d9a1 100644 --- a/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMessageReadRepositoryImpl.java +++ b/src/main/java/com/codeit/side/chat/adapter/out/persistence/ChatMessageReadRepositoryImpl.java @@ -26,4 +26,15 @@ public void read(Long roomId, Long userId) { chatMessageReadJpaRepository.findAllByChatRoomIdAndUserIdAndIsReadFalse(roomId, userId) .forEach(ChatMessageReadEntity::read); } + + @Override + public List findAllUnreadMessages(Long userId, List chatRoomIds) { + return chatMessageReadJpaRepository.findAllByUserIdAndChatRoomIdInAndIsReadFalse(userId, chatRoomIds); + } + + @Override + public int findUnreadMessagesBy(Long chatRoomId, Long userId) { + return chatMessageReadJpaRepository.findAllByChatRoomIdAndUserIdAndIsReadFalse(chatRoomId, userId) + .size(); + } } diff --git a/src/main/java/com/codeit/side/chat/adapter/out/persistence/jpa/ChatMessageReadJpaRepository.java b/src/main/java/com/codeit/side/chat/adapter/out/persistence/jpa/ChatMessageReadJpaRepository.java index af8d089..e68ca79 100644 --- a/src/main/java/com/codeit/side/chat/adapter/out/persistence/jpa/ChatMessageReadJpaRepository.java +++ b/src/main/java/com/codeit/side/chat/adapter/out/persistence/jpa/ChatMessageReadJpaRepository.java @@ -3,8 +3,11 @@ import com.codeit.side.chat.adapter.out.persistence.entity.ChatMessageReadEntity; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Collection; import java.util.List; public interface ChatMessageReadJpaRepository extends JpaRepository { List findAllByChatRoomIdAndUserIdAndIsReadFalse(Long roomId, Long userId); + + List findAllByUserIdAndChatRoomIdInAndIsReadFalse(Long userId, Collection chatRoomIds); } diff --git a/src/main/java/com/codeit/side/chat/application/port/in/ChatMessageUseCase.java b/src/main/java/com/codeit/side/chat/application/port/in/ChatMessageUseCase.java index b8e4b67..fcc47ed 100644 --- a/src/main/java/com/codeit/side/chat/application/port/in/ChatMessageUseCase.java +++ b/src/main/java/com/codeit/side/chat/application/port/in/ChatMessageUseCase.java @@ -6,6 +6,7 @@ import com.codeit.side.chat.domain.ChatRoomInfo; import java.util.List; +import java.util.Map; public interface ChatMessageUseCase { void save(ChatMessage chatMessage); @@ -29,4 +30,8 @@ public interface ChatMessageUseCase { void leaveChatRoom(Long id, String email); void joinChatRoomByLighteningId(Long id, String email); + + Map countAllUnreadMessages(String email, List chatRoomIds); + + int countUnreadMessages(Long lighteningId, String email); } diff --git a/src/main/java/com/codeit/side/chat/application/port/out/ChatMessageReadRepository.java b/src/main/java/com/codeit/side/chat/application/port/out/ChatMessageReadRepository.java index 7014a21..32fe103 100644 --- a/src/main/java/com/codeit/side/chat/application/port/out/ChatMessageReadRepository.java +++ b/src/main/java/com/codeit/side/chat/application/port/out/ChatMessageReadRepository.java @@ -1,9 +1,15 @@ package com.codeit.side.chat.application.port.out; +import com.codeit.side.chat.adapter.out.persistence.entity.ChatMessageReadEntity; + import java.util.List; public interface ChatMessageReadRepository { void save(Long roomId, List userIds); void read(Long roomId, Long userId); + + List findAllUnreadMessages(Long id, List chatRoomIds); + + int findUnreadMessagesBy(Long lighteningId, Long userId); } diff --git a/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java b/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java index 8f528c3..18ca173 100644 --- a/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java +++ b/src/main/java/com/codeit/side/chat/application/service/ChatMessageService.java @@ -1,6 +1,7 @@ package com.codeit.side.chat.application.service; import com.codeit.side.chat.adapter.out.persistence.entity.ChatMemberEntity; +import com.codeit.side.chat.adapter.out.persistence.entity.ChatMessageReadEntity; import com.codeit.side.chat.application.port.in.ChatMessageUseCase; import com.codeit.side.chat.application.port.out.ChatMemberRepository; import com.codeit.side.chat.application.port.out.ChatMessageReadRepository; @@ -120,6 +121,28 @@ public void joinChatRoomByLighteningId(Long id, String email) { chatMemberRepository.join(chatRoom.getId(), user.getId()); } + @Override + public Map countAllUnreadMessages(String email, List chatRoomIds) { + if ("".equals(email)) { + return Map.of(); + } + User user = userQueryRepository.getByEmail(email) + .toDomain(); + List chatMessageReadEntities = chatMessageReadRepository.findAllUnreadMessages(user.getId(), chatRoomIds); + return chatMessageReadEntities.stream() + .collect(Collectors.groupingBy(ChatMessageReadEntity::getChatRoomId, Collectors.collectingAndThen(Collectors.counting(), Long::intValue))); + } + + @Override + public int countUnreadMessages(Long chatRoomId, String email) { + if ("".equals(email)) { + return 0; + } + User user = userQueryRepository.getByEmail(email) + .toDomain(); + return chatMessageReadRepository.findUnreadMessagesBy(chatRoomId, user.getId()); + } + @Override public ChatRoom getChatRoomByLighteningId(Long lighteningId) { return chatRoomRepository.getByLighteningId(lighteningId); diff --git a/src/main/java/com/codeit/side/lightening/adapter/in/web/response/LighteningResponse.java b/src/main/java/com/codeit/side/lightening/adapter/in/web/response/LighteningResponse.java index 5382ee7..1ad3e75 100644 --- a/src/main/java/com/codeit/side/lightening/adapter/in/web/response/LighteningResponse.java +++ b/src/main/java/com/codeit/side/lightening/adapter/in/web/response/LighteningResponse.java @@ -30,6 +30,7 @@ public record LighteningResponse( boolean isConfirmed, boolean isCompleted, Long chatRoomId, + Integer unreadCount, List participants ) { public static LighteningResponse from(String email, LighteningInfo lighteningInfo) { @@ -62,6 +63,7 @@ public static LighteningResponse from(String email, LighteningInfo lighteningInf lighteningMemberResponse.size() >= lightening.getMinCapacity(), lighteningMemberResponse.size() >= lightening.getCapacity(), lighteningInfo.getChatRoom().getId(), + lighteningInfo.getUnreadCount(), lighteningMemberResponse ); } diff --git a/src/main/java/com/codeit/side/lightening/application/service/LighteningService.java b/src/main/java/com/codeit/side/lightening/application/service/LighteningService.java index 40e3354..0b94f41 100644 --- a/src/main/java/com/codeit/side/lightening/application/service/LighteningService.java +++ b/src/main/java/com/codeit/side/lightening/application/service/LighteningService.java @@ -76,7 +76,8 @@ public LighteningInfo getById(String email, Long id) { List lighteningMember = lighteningReadRepository.findAllMembersBy(lightening.getId()); boolean isLighteningLike = lighteningReadRepository.findLighteningLikeBy(email, lightening.getId()); ChatRoom chatRoom = chatMessageUseCase.getChatRoomByLighteningId(lightening.getId()); - return createLighteningInfo(lightening, lighteningMember, chatRoom, isLighteningLike); + int unreadCount = chatMessageUseCase.countUnreadMessages(chatRoom.getId(), email); + return createLighteningInfo(lightening, lighteningMember, chatRoom, isLighteningLike, unreadCount); } @Override @@ -87,8 +88,12 @@ public List findAllBy(String email, LighteningCondition lighteni .toList(); List lighteningMembers = lighteningReadRepository.findAllMembersBy(lighteningIds); List lighteningLikes = lighteningReadRepository.findLighteningLikesBy(email, lighteningIds); - List chatRoomIds = chatMessageUseCase.findAllChatRoomsByLighteningIds(lighteningIds); - return createLighteningInfos(lightenings, lighteningMembers, chatRoomIds, lighteningLikes); + List chatRooms = chatMessageUseCase.findAllChatRoomsByLighteningIds(lighteningIds); + List chatRoomIds = chatRooms.stream() + .map(ChatRoom::getId) + .toList(); + Map idToUnreadCount = chatMessageUseCase.countAllUnreadMessages(email, chatRoomIds); + return createLighteningInfos(lightenings, lighteningMembers, chatRooms, lighteningLikes, idToUnreadCount); } @Override @@ -130,7 +135,7 @@ private List extractNotExistingLighteningIds(List lightenings, return lighteningIds; } - private List createLighteningInfos(List lightenings, List lighteningMembers, List chatRooms, List lighteningLikes) { + private List createLighteningInfos(List lightenings, List lighteningMembers, List chatRooms, List lighteningLikes, Map idToUnreadCount) { Map> idToLighteningMembers = lighteningMembers.stream() .collect(Collectors.groupingBy(LighteningMember::getLighteningId)); Map idToLighteningLike = lighteningLikes.stream() @@ -139,12 +144,21 @@ private List createLighteningInfos(List lightenings, .collect(Collectors.toMap(ChatRoom::getLighteningId, Function.identity())); return lightenings.stream() - .map(lightening -> createLighteningInfo(lightening, idToLighteningMembers.getOrDefault(lightening.getId(), List.of()), idToChatRoom.get(lightening.getId()), idToLighteningLike.containsKey(lightening.getId()))) + .map(lightening -> { + ChatRoom chatRoom = idToChatRoom.get(lightening.getId()); + return createLighteningInfo( + lightening, + idToLighteningMembers.getOrDefault(lightening.getId(), List.of()), + chatRoom, + idToLighteningLike.containsKey(lightening.getId()), + idToUnreadCount.getOrDefault(chatRoom.getLighteningId(), 0) + ); + }) .toList(); } - private LighteningInfo createLighteningInfo(Lightening lightening, List lighteningMember, ChatRoom chatRoom, boolean isLighteningLike) { - return LighteningInfo.of(lightening, lighteningMember, chatRoom, isLighteningLike); + private LighteningInfo createLighteningInfo(Lightening lightening, List lighteningMember, ChatRoom chatRoom, boolean isLighteningLike, Integer unreadCount) { + return LighteningInfo.of(lightening, lighteningMember, chatRoom, isLighteningLike, unreadCount); } private void validateLightening(String email, Lightening lightening) { diff --git a/src/main/java/com/codeit/side/lightening/domain/LighteningInfo.java b/src/main/java/com/codeit/side/lightening/domain/LighteningInfo.java index f104c50..4a8f7cb 100644 --- a/src/main/java/com/codeit/side/lightening/domain/LighteningInfo.java +++ b/src/main/java/com/codeit/side/lightening/domain/LighteningInfo.java @@ -14,13 +14,15 @@ public class LighteningInfo { private final List lighteningMembers; private final ChatRoom chatRoom; private final boolean isLiked; + private final int unreadCount; public static LighteningInfo of( Lightening lightening, List lighteningMembers, ChatRoom chatRoom, - boolean isLiked - ){ - return new LighteningInfo(lightening, lighteningMembers, chatRoom, isLiked); + boolean isLiked, + int unreadCount + ) { + return new LighteningInfo(lightening, lighteningMembers, chatRoom, isLiked, unreadCount); } } From b93b06d4ff656ab6e24279b38d6cc330caf7fc63 Mon Sep 17 00:00:00 2001 From: coen park Date: Sun, 16 Mar 2025 22:28:32 +0900 Subject: [PATCH 14/17] =?UTF-8?q?feat:=20=EB=8B=A4=EB=A5=B8=20domain?= =?UTF-8?q?=EB=8F=84=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/codeit/side/common/config/CorsMvcConfig.java | 2 +- src/main/java/com/codeit/side/common/config/SecurityConfig.java | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java b/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java index fe64059..9360e8d 100644 --- a/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java +++ b/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java @@ -6,7 +6,7 @@ @Configuration public class CorsMvcConfig implements WebMvcConfigurer { - private static final String[] ALLOWED_ORIGINS = {"http://localhost:3000", "http://127.0.0.1:5500", "https://www.thunderting.site"}; + private static final String[] ALLOWED_ORIGINS = {"http://localhost:3000", "http://127.0.0.1:5500", "https://doitz.netlify.app/", "https://calit.netlify.app/", "https://www.thunderting.site"}; private static final String[] ALLOWED_METHODS = {"GET", "POST", "PUT", "DELETE"}; @Override diff --git a/src/main/java/com/codeit/side/common/config/SecurityConfig.java b/src/main/java/com/codeit/side/common/config/SecurityConfig.java index f90f966..b49a2c0 100644 --- a/src/main/java/com/codeit/side/common/config/SecurityConfig.java +++ b/src/main/java/com/codeit/side/common/config/SecurityConfig.java @@ -29,6 +29,8 @@ public class SecurityConfig { private static final List ALLOWED_ORIGINS = List.of( "http://localhost:3000", "http://127.0.0.1:5500", + "https://doitz.netlify.app", + "https://calit.netlify.app", "https://www.thunderting.site" ); private static final List ALLOWED_METHODS = List.of("GET", "POST", "PUT", "DELETE"); From 3cc0cdfc48dfc71b144092a798dc377360e4564b Mon Sep 17 00:00:00 2001 From: coen park Date: Sun, 16 Mar 2025 22:34:26 +0900 Subject: [PATCH 15/17] =?UTF-8?q?feat:=20=EB=8B=A4=EB=A5=B8=20domain?= =?UTF-8?q?=EB=8F=84=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/codeit/side/common/config/CorsMvcConfig.java | 9 ++++++++- .../com/codeit/side/common/config/SecurityConfig.java | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java b/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java index 9360e8d..ab05886 100644 --- a/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java +++ b/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java @@ -6,7 +6,14 @@ @Configuration public class CorsMvcConfig implements WebMvcConfigurer { - private static final String[] ALLOWED_ORIGINS = {"http://localhost:3000", "http://127.0.0.1:5500", "https://doitz.netlify.app/", "https://calit.netlify.app/", "https://www.thunderting.site"}; + private static final String[] ALLOWED_ORIGINS = { + "http://localhost:3000", + "http://127.0.0.1:5500", + "https://doitz.netlify.app/", + "https://calit.netlify.app/", + "https://www.thunderting.site", + "https://thunderting.netlify.app" + }; private static final String[] ALLOWED_METHODS = {"GET", "POST", "PUT", "DELETE"}; @Override diff --git a/src/main/java/com/codeit/side/common/config/SecurityConfig.java b/src/main/java/com/codeit/side/common/config/SecurityConfig.java index b49a2c0..83840ab 100644 --- a/src/main/java/com/codeit/side/common/config/SecurityConfig.java +++ b/src/main/java/com/codeit/side/common/config/SecurityConfig.java @@ -31,7 +31,8 @@ public class SecurityConfig { "http://127.0.0.1:5500", "https://doitz.netlify.app", "https://calit.netlify.app", - "https://www.thunderting.site" + "https://www.thunderting.site", + "https://thunderting.netlify.app" ); private static final List ALLOWED_METHODS = List.of("GET", "POST", "PUT", "DELETE"); private static final String[] WHITE_LIST = { From 875c3e282abc5c0293cba03c0fa85a9016ee7a88 Mon Sep 17 00:00:00 2001 From: coen Date: Mon, 17 Mar 2025 16:57:31 +0900 Subject: [PATCH 16/17] =?UTF-8?q?feat:=20=EB=8F=84=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/codeit/side/common/config/CorsMvcConfig.java | 1 + src/main/java/com/codeit/side/common/config/SecurityConfig.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java b/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java index ab05886..a425fbb 100644 --- a/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java +++ b/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java @@ -12,6 +12,7 @@ public class CorsMvcConfig implements WebMvcConfigurer { "https://doitz.netlify.app/", "https://calit.netlify.app/", "https://www.thunderting.site", + "https://thunderting.site", "https://thunderting.netlify.app" }; private static final String[] ALLOWED_METHODS = {"GET", "POST", "PUT", "DELETE"}; diff --git a/src/main/java/com/codeit/side/common/config/SecurityConfig.java b/src/main/java/com/codeit/side/common/config/SecurityConfig.java index 83840ab..04f64a9 100644 --- a/src/main/java/com/codeit/side/common/config/SecurityConfig.java +++ b/src/main/java/com/codeit/side/common/config/SecurityConfig.java @@ -32,6 +32,7 @@ public class SecurityConfig { "https://doitz.netlify.app", "https://calit.netlify.app", "https://www.thunderting.site", + "https://thunderting.site", "https://thunderting.netlify.app" ); private static final List ALLOWED_METHODS = List.of("GET", "POST", "PUT", "DELETE"); From d531d23b184722e9232f5aae43f33faf173d703a Mon Sep 17 00:00:00 2001 From: coen park Date: Tue, 25 Mar 2025 21:52:29 +0900 Subject: [PATCH 17/17] =?UTF-8?q?feat:=20=EB=8B=A4=EB=A5=B8=20domain?= =?UTF-8?q?=EB=8F=84=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/codeit/side/common/config/CorsMvcConfig.java | 12 ++++++++---- .../codeit/side/common/config/SecurityConfig.java | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java b/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java index a425fbb..9d5cf7f 100644 --- a/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java +++ b/src/main/java/com/codeit/side/common/config/CorsMvcConfig.java @@ -9,11 +9,15 @@ public class CorsMvcConfig implements WebMvcConfigurer { private static final String[] ALLOWED_ORIGINS = { "http://localhost:3000", "http://127.0.0.1:5500", - "https://doitz.netlify.app/", - "https://calit.netlify.app/", - "https://www.thunderting.site", "https://thunderting.site", - "https://thunderting.netlify.app" + "https://doitz.netlify.app", + "https://thunderting-doitz.vercel.app", + "https://thunderting-one.vercel.app", + "https://thunderting-hong.netlify.app", + "https://thunderting-one.vercel.app", + "https://thundertingdoit.netlify.app", + "https://thunderting.netlify.app", + "https://www.thunderting-site.com", }; private static final String[] ALLOWED_METHODS = {"GET", "POST", "PUT", "DELETE"}; diff --git a/src/main/java/com/codeit/side/common/config/SecurityConfig.java b/src/main/java/com/codeit/side/common/config/SecurityConfig.java index 04f64a9..f7e62b7 100644 --- a/src/main/java/com/codeit/side/common/config/SecurityConfig.java +++ b/src/main/java/com/codeit/side/common/config/SecurityConfig.java @@ -29,11 +29,15 @@ public class SecurityConfig { private static final List ALLOWED_ORIGINS = List.of( "http://localhost:3000", "http://127.0.0.1:5500", - "https://doitz.netlify.app", - "https://calit.netlify.app", - "https://www.thunderting.site", "https://thunderting.site", - "https://thunderting.netlify.app" + "https://doitz.netlify.app", + "https://thunderting-doitz.vercel.app", + "https://thunderting-one.vercel.app", + "https://thunderting-hong.netlify.app", + "https://thunderting-one.vercel.app", + "https://thundertingdoit.netlify.app", + "https://thunderting.netlify.app", + "https://www.thunderting-site.com" ); private static final List ALLOWED_METHODS = List.of("GET", "POST", "PUT", "DELETE"); private static final String[] WHITE_LIST = {