From f46a2b3c36333069d57fbc4795927e0ea160558d Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 01:20:14 +0900 Subject: [PATCH 01/37] =?UTF-8?q?[PC-268]=20feat:=20=EC=A7=80=EC=9D=B8=20?= =?UTF-8?q?=EA=B8=B0=EB=B0=98=20=EC=B0=A8=EB=8B=A8=EA=B8=B0=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blocker/AcquaintanceBasedBlocker.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/org/yapp/domain/match/application/blocker/AcquaintanceBasedBlocker.java b/api/src/main/java/org/yapp/domain/match/application/blocker/AcquaintanceBasedBlocker.java index 2e65caf..86000a4 100644 --- a/api/src/main/java/org/yapp/domain/match/application/blocker/AcquaintanceBasedBlocker.java +++ b/api/src/main/java/org/yapp/domain/match/application/blocker/AcquaintanceBasedBlocker.java @@ -1,8 +1,21 @@ package org.yapp.domain.match.application.blocker; +import org.springframework.stereotype.Component; +import org.yapp.domain.block.application.BlockService; +import org.yapp.domain.user.User; +import org.yapp.domain.user.application.UserService; + +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor public class AcquaintanceBasedBlocker implements Blocker { + private final BlockService blockService; + private final UserService userService; + @Override public boolean blocked(Long blockingUserId, Long blockedUserId) { - return false; + User user = userService.getUserById(blockingUserId); + return blockService.checkIfUserBlockedPhoneNumber(blockedUserId, user.getPhoneNumber()); } } From b9ae174f8a8fa064b10952f84583de73e8910405 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 01:21:24 +0900 Subject: [PATCH 02/37] =?UTF-8?q?[PC-268]=20feat:=20=EC=B0=A8=EB=8B=A8=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=20=EC=A1=B0=ED=9A=8C=20=EC=BF=BC=EB=A6=AC=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 --- .../main/java/org/yapp/domain/block/dao/BlockRepository.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/org/yapp/domain/block/dao/BlockRepository.java b/api/src/main/java/org/yapp/domain/block/dao/BlockRepository.java index 2fe32ad..2d248a1 100644 --- a/api/src/main/java/org/yapp/domain/block/dao/BlockRepository.java +++ b/api/src/main/java/org/yapp/domain/block/dao/BlockRepository.java @@ -8,5 +8,7 @@ @Repository public interface BlockRepository extends JpaRepository { - List findBlocksByUserId(Long userId); + boolean existsByUserIdAndPhoneNumber(Long userId, String phoneNumber); + + List findBlocksByUserId(Long userId); } From 32224c277c2383cc294079754f2264bbdc1504cb Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 01:21:57 +0900 Subject: [PATCH 03/37] =?UTF-8?q?[PC-268]=20feat:=20=EC=B0=A8=EB=8B=A8=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../block/application/BlockService.java | 61 +++++++++---------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/api/src/main/java/org/yapp/domain/block/application/BlockService.java b/api/src/main/java/org/yapp/domain/block/application/BlockService.java index deb9b82..54fffe0 100644 --- a/api/src/main/java/org/yapp/domain/block/application/BlockService.java +++ b/api/src/main/java/org/yapp/domain/block/application/BlockService.java @@ -1,6 +1,5 @@ package org.yapp.domain.block.application; -import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.yapp.domain.block.Block; @@ -13,37 +12,37 @@ import java.util.Set; import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; + @Service @RequiredArgsConstructor public class BlockService { - private final BlockRepository blockRepository; - - @Transactional() - public void blockPhoneNumbers(BlockCreateDto blockCreateDto) { - Long userId = blockCreateDto.userId(); - List phoneNumbers = blockCreateDto.phoneNumbers(); - List newBlocks = new ArrayList<>(); - - Set blockedPhoneNumbers = blockRepository.findBlocksByUserId(userId) - .stream() - .map(Block::getPhoneNumber) - .collect(Collectors.toSet()); - - phoneNumbers.stream() - .filter(phoneNumber -> !blockedPhoneNumbers.contains(phoneNumber)) - .forEach(phoneNumber -> { - Block block = Block.builder() - .user(User.builder().id(userId).build()) - .phoneNumber(phoneNumber) - .build(); - newBlocks.add(block); - }); - - blockRepository.saveAll(newBlocks); - } - - @Transactional(readOnly = false) - public List findBlocksByUserId(Long userId) { - return blockRepository.findBlocksByUserId(userId); - } + private final BlockRepository blockRepository; + + @Transactional() + public void blockPhoneNumbers(BlockCreateDto blockCreateDto) { + Long userId = blockCreateDto.userId(); + List phoneNumbers = blockCreateDto.phoneNumbers(); + List newBlocks = new ArrayList<>(); + + Set blockedPhoneNumbers = + blockRepository.findBlocksByUserId(userId).stream().map(Block::getPhoneNumber).collect(Collectors.toSet()); + + phoneNumbers.stream().filter(phoneNumber -> !blockedPhoneNumbers.contains(phoneNumber)).forEach(phoneNumber -> { + Block block = Block.builder().user(User.builder().id(userId).build()).phoneNumber(phoneNumber).build(); + newBlocks.add(block); + }); + + blockRepository.saveAll(newBlocks); + } + + @Transactional(readOnly = true) + public Boolean checkIfUserBlockedPhoneNumber(Long userId, String phoneNumber) { + return blockRepository.existsByUserIdAndPhoneNumber(userId, phoneNumber); + } + + @Transactional(readOnly = false) + public List findBlocksByUserId(Long userId) { + return blockRepository.findBlocksByUserId(userId); + } } From 040b2f0a2e7368d4af78087e01db7d5fecc43244 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 01:22:53 +0900 Subject: [PATCH 04/37] =?UTF-8?q?[PC-268]=20feat:=20Greedy=20=EB=A7=A4?= =?UTF-8?q?=EC=B9=AD=20=EC=95=8C=EA=B3=A0=EB=A6=AC=EC=A6=98=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../algorithm/GreedyMatchingAlgorithm.java | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 api/src/main/java/org/yapp/domain/match/application/algorithm/GreedyMatchingAlgorithm.java diff --git a/api/src/main/java/org/yapp/domain/match/application/algorithm/GreedyMatchingAlgorithm.java b/api/src/main/java/org/yapp/domain/match/application/algorithm/GreedyMatchingAlgorithm.java new file mode 100644 index 0000000..7bb06c5 --- /dev/null +++ b/api/src/main/java/org/yapp/domain/match/application/algorithm/GreedyMatchingAlgorithm.java @@ -0,0 +1,116 @@ +package org.yapp.domain.match.application.algorithm; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.PriorityQueue; +import java.util.Set; +import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; +import org.yapp.domain.match.application.MatchService; +import org.yapp.domain.match.application.blocker.Blocker; +import org.yapp.domain.profile.Profile; +import org.yapp.domain.profile.ProfileValuePick; +import org.yapp.domain.profile.application.ProfileValuePickService; + +@Primary +@RequiredArgsConstructor +@Component +public class GreedyMatchingAlgorithm implements MatchingAlgorithm { + + private final ProfileValuePickService profileValuePickService; + private final MatchService matchService; + private final List blockers; + + @Override + public List doMatch(List profiles) { + PriorityQueue priorityEdges = getPriorityEdges(profiles); + Set matchedSet = greedyMatch(priorityEdges); + List unmatchedProfiles = new ArrayList<>(); + for (Profile profile : profiles) { + if (!matchedSet.contains(profile.getUser().getId())) { + unmatchedProfiles.add(profile); + } + } + return unmatchedProfiles; + } + + private Set greedyMatch(PriorityQueue priorityEdges) { + Set matchedSet = new HashSet<>(); + while (!priorityEdges.isEmpty()) { + Edge edge = priorityEdges.poll(); + if (matchedSet.contains(edge.user1Id) || matchedSet.contains(edge.user2Id)) { + continue; + } + matchedSet.add(edge.user1Id); + matchedSet.add(edge.user2Id); + + matchService.createMatchInfo(edge.user1Id, edge.user2Id); + } + return matchedSet; + } + + private PriorityQueue getPriorityEdges(List profiles) { + PriorityQueue priorityEdgeQueue = new PriorityQueue(); + for (Profile profile1 : profiles) { + for (Profile profile2 : profiles) { + if (profile1.getId().equals(profile2.getId())) { + continue; + } + if (checkBlock(profile1.getUser().getId(), profile2.getUser().getId())) { + continue; + } + int weight = calculateWeight(profile1.getId(), profile2.getId()); + priorityEdgeQueue.add( + new Edge(weight, profile1.getUser().getId(), profile2.getUser().getId())); + } + } + return priorityEdgeQueue; + } + + private boolean checkBlock(Long blockingUserId, Long blockedUserId) { + for (Blocker blocker : blockers) { + boolean blocked = + blocker.blocked(blockingUserId, blockedUserId) || blocker.blocked(blockedUserId, + blockingUserId); + if (blocked) { + return true; + } + } + return false; + } + + private int calculateWeight(Long fromProfileId, Long toProfileId) { + List profileValuePicksOfFrom = + profileValuePickService.getAllProfileValuesByProfileId(fromProfileId); + List profileValuePicksOfTo = profileValuePickService.getAllProfileValuesByProfileId( + toProfileId); + + int valueListSize = profileValuePicksOfFrom.size(); + int sumOfWeight = 0; + for (int i = 0; i < valueListSize; i++) { + ProfileValuePick profileValuePickOfFrom = profileValuePicksOfFrom.get(i); + ProfileValuePick profileValuePickOfTo = profileValuePicksOfTo.get(i); + if (profileValuePickOfFrom.getSelectedAnswer() + .equals(profileValuePickOfTo.getSelectedAnswer())) { + sumOfWeight++; + } + } + return sumOfWeight; + } + + @AllArgsConstructor + private static class Edge implements Comparable { + + private int weight; + private Long user1Id; + private Long user2Id; + + @Override + public int compareTo(Edge o) { + return o.weight - this.weight; + } + } +} From ccd3e2c4d621cbafc2ba8886285f50b6b25dea14 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 01:23:44 +0900 Subject: [PATCH 05/37] =?UTF-8?q?[PC-268]=20feat:=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=83=9D=EC=84=B1=20=EC=A0=95=EC=A0=81=20?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A6=AC=20=EB=A9=94=EC=84=9C=EB=93=9C=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 --- .../main/java/org/yapp/domain/match/MatchInfo.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/common/src/main/java/org/yapp/domain/match/MatchInfo.java b/common/src/main/java/org/yapp/domain/match/MatchInfo.java index e66f86e..61afff5 100644 --- a/common/src/main/java/org/yapp/domain/match/MatchInfo.java +++ b/common/src/main/java/org/yapp/domain/match/MatchInfo.java @@ -12,9 +12,11 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import lombok.Getter; +import lombok.NoArgsConstructor; @Entity @Getter +@NoArgsConstructor public class MatchInfo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -42,4 +44,14 @@ public class MatchInfo { @Column(name = "user_2_accept") private Boolean user2Accepted; + + public MatchInfo(LocalDate date, User user1, User user2) { + this.date = date; + this.user1 = user1; + this.user2 = user2; + } + + public static MatchInfo createMatchInfo(User user1, User user2) { + return new MatchInfo(LocalDate.now(), user1, user2); + } } From 02f1cafecfa04aa7ea27eab2d404499ea74de7d8 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 01:24:07 +0900 Subject: [PATCH 06/37] =?UTF-8?q?[PC-268]=20feat:=20=EC=9D=B4=EC=A0=84=20?= =?UTF-8?q?=EB=A7=A4=EC=B9=AD=20=EC=97=AC=EB=B6=80=20=EA=B2=80=EC=82=AC=20?= =?UTF-8?q?=EC=BF=BC=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 --- .../org/yapp/domain/match/dao/MatchInfoRepository.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/org/yapp/domain/match/dao/MatchInfoRepository.java b/api/src/main/java/org/yapp/domain/match/dao/MatchInfoRepository.java index 9b06eb4..8a68917 100644 --- a/api/src/main/java/org/yapp/domain/match/dao/MatchInfoRepository.java +++ b/api/src/main/java/org/yapp/domain/match/dao/MatchInfoRepository.java @@ -1,13 +1,16 @@ package org.yapp.domain.match.dao; +import java.time.LocalDate; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.yapp.domain.match.MatchInfo; -import java.time.LocalDate; -import java.util.Optional; - public interface MatchInfoRepository extends JpaRepository { + @Query("SELECT mi FROM MatchInfo mi WHERE (mi.user1.id = :userId or mi.user2.id = :userId) and mi.date = :date") Optional findByUserIdAndDate(Long userId, LocalDate date); + + @Query("SELECT mi FROM MatchInfo mi WHERE (mi.user1.id = :userId1 and mi.user2.id = :userId2)") + Optional findMatchInfoByIds(Long userId1, Long userId2); } From 01025c7c935d2b476be00d0e288a5905a88b4c00 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 01:24:19 +0900 Subject: [PATCH 07/37] =?UTF-8?q?[PC-268]=20feat:=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EC=95=8C=EA=B3=A0=EB=A6=AC=EC=A6=98=20=EC=9D=B8=ED=84=B0?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/algorithm/MatchingAlgorithm.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 api/src/main/java/org/yapp/domain/match/application/algorithm/MatchingAlgorithm.java diff --git a/api/src/main/java/org/yapp/domain/match/application/algorithm/MatchingAlgorithm.java b/api/src/main/java/org/yapp/domain/match/application/algorithm/MatchingAlgorithm.java new file mode 100644 index 0000000..db59217 --- /dev/null +++ b/api/src/main/java/org/yapp/domain/match/application/algorithm/MatchingAlgorithm.java @@ -0,0 +1,15 @@ +package org.yapp.domain.match.application.algorithm; + +import java.util.List; +import org.yapp.domain.profile.Profile; + +public interface MatchingAlgorithm { + + /** + * 가치관 기반으로 매칭을 수행 + * + * @param profiles 매칭 수행할 프로필 리스트 + * @return 매칭이 이루어지지 않은 프로필 리스트 + */ + public List doMatch(List profiles); +} From a995ad1a4d3b11e11c83b7c1d2c3356da7b61530 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 01:25:32 +0900 Subject: [PATCH 08/37] =?UTF-8?q?[PC-268]=20fix:=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EC=8A=A4=EC=BC=80=EC=A4=84=EB=9F=AC=20=EC=8B=9C=EA=B0=84=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/yapp/domain/match/batch/MatchScheduler.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/org/yapp/domain/match/batch/MatchScheduler.java b/api/src/main/java/org/yapp/domain/match/batch/MatchScheduler.java index faf500f..dd92131 100644 --- a/api/src/main/java/org/yapp/domain/match/batch/MatchScheduler.java +++ b/api/src/main/java/org/yapp/domain/match/batch/MatchScheduler.java @@ -1,18 +1,21 @@ package org.yapp.domain.match.batch; +import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.yapp.domain.match.application.matcher.CoupleMatcher; -import lombok.RequiredArgsConstructor; - @Component @RequiredArgsConstructor public class MatchScheduler { + private final CoupleMatcher matcher; - - @Scheduled(cron = "0 0 22 * * *") + + /** + * 10시에 매칭을 위해 9시부터 배치 시작 + */ + @Scheduled(cron = "0 0 21 * * *") public void match() { matcher.match(); } From 760f59ef0b6a36ae82ab56cfaa6e18873fe07c62 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 01:26:11 +0900 Subject: [PATCH 09/37] =?UTF-8?q?[PC-268]=20fix:=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EB=82=B4=EC=97=AD=20=EC=A0=80=EC=9E=A5,=20=EC=9C=A0=EC=A0=80?= =?UTF-8?q?=20=EB=A7=A4=EC=B9=98=20=ED=99=95=EC=9D=B8=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../match/application/MatchService.java | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/api/src/main/java/org/yapp/domain/match/application/MatchService.java b/api/src/main/java/org/yapp/domain/match/application/MatchService.java index dfa29a3..3d10662 100644 --- a/api/src/main/java/org/yapp/domain/match/application/MatchService.java +++ b/api/src/main/java/org/yapp/domain/match/application/MatchService.java @@ -1,23 +1,32 @@ package org.yapp.domain.match.application; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.Optional; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.yapp.application.AuthenticationService; import org.yapp.domain.match.MatchInfo; import org.yapp.domain.match.dao.MatchInfoRepository; +import org.yapp.domain.user.User; +import org.yapp.domain.user.application.UserService; import org.yapp.error.dto.MatchErrorCode; import org.yapp.error.exception.ApplicationException; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; - -import lombok.RequiredArgsConstructor; - @Service @RequiredArgsConstructor public class MatchService { + private final MatchInfoRepository matchInfoRepository; private final AuthenticationService authenticationService; + private final UserService userService; + + public MatchInfo createMatchInfo(Long user1Id, Long user2Id) { + User user1 = userService.getUserById(user1Id); + User user2 = userService.getUserById(user2Id); + return matchInfoRepository.save(new MatchInfo(LocalDate.now(), user1, user2)); + } public LocalDate getMatchDate() { LocalDateTime nowDateTime = LocalDateTime.now(); @@ -30,9 +39,14 @@ public LocalDate getMatchDate() { return nowDate; } + public boolean wasUsersMatched(Long user1Id, Long user2Id) { + Optional matchInfoByIds = matchInfoRepository.findMatchInfoByIds(user1Id, user2Id); + return matchInfoByIds.isPresent(); + } + public MatchInfo getMatchInfo() { Long userId = authenticationService.getUserId(); return matchInfoRepository.findByUserIdAndDate(userId, getMatchDate()) - .orElseThrow(() -> new ApplicationException(MatchErrorCode.NOTFOUND_MATCH)); + .orElseThrow(() -> new ApplicationException(MatchErrorCode.NOTFOUND_MATCH)); } } From 29f565dee39141c972be70103a0061b06b5c3a39 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 01:27:13 +0900 Subject: [PATCH 10/37] =?UTF-8?q?[PC-268]=20fix:=20Matcher=EA=B0=80=20?= =?UTF-8?q?=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=EB=A5=BC=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../matcher/PreferenceBasedMatcher.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/api/src/main/java/org/yapp/domain/match/application/matcher/PreferenceBasedMatcher.java b/api/src/main/java/org/yapp/domain/match/application/matcher/PreferenceBasedMatcher.java index b848131..6d97254 100644 --- a/api/src/main/java/org/yapp/domain/match/application/matcher/PreferenceBasedMatcher.java +++ b/api/src/main/java/org/yapp/domain/match/application/matcher/PreferenceBasedMatcher.java @@ -1,21 +1,20 @@ package org.yapp.domain.match.application.matcher; -import org.springframework.stereotype.Component; -import org.yapp.domain.match.application.algorithm.PreferenceBasedMatchingAlgorithm; -import org.yapp.domain.profile.Profile; -import org.yapp.domain.profile.application.ProfileService; -import org.yapp.domain.profile.enums.Location; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; - import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.yapp.domain.match.application.algorithm.MatchingAlgorithm; +import org.yapp.domain.profile.Profile; +import org.yapp.domain.profile.application.ProfileService; +import org.yapp.domain.profile.enums.Location; @Component @RequiredArgsConstructor public class PreferenceBasedMatcher implements CoupleMatcher { - private final PreferenceBasedMatchingAlgorithm matchingAlgorithm; + + private final MatchingAlgorithm matchingAlgorithm; private final ProfileService profileService; @Override @@ -33,6 +32,7 @@ public void match() { } // 매칭 안되고 남은 애들 매칭하기 - matchingAlgorithm.doMatch(unmatchedProfiles); + List finalRemains = matchingAlgorithm.doMatch(unmatchedProfiles); + //TODO : 매칭 끝끝내 안된 사람들 처리 방식 논의 필요 } } From 879dab6ab6fe8d02863a2d120374e1e8aaba7c79 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 01:28:15 +0900 Subject: [PATCH 11/37] =?UTF-8?q?[PC-268]=20delete:=20=EC=95=88=EC=A0=95?= =?UTF-8?q?=20=EB=A7=A4=EC=B9=AD=20=EA=B5=AC=ED=98=84=20=EC=99=84=EC=84=B1?= =?UTF-8?q?=20=EC=A0=84=EA=B9=8C=EC=A7=80=20=ED=95=B4=EB=8B=B9=20=EC=95=8C?= =?UTF-8?q?=EA=B3=A0=EB=A6=AC=EC=A6=98=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PreferenceBasedMatchingAlgorithm.java | 58 ------------------- 1 file changed, 58 deletions(-) delete mode 100644 api/src/main/java/org/yapp/domain/match/application/algorithm/PreferenceBasedMatchingAlgorithm.java diff --git a/api/src/main/java/org/yapp/domain/match/application/algorithm/PreferenceBasedMatchingAlgorithm.java b/api/src/main/java/org/yapp/domain/match/application/algorithm/PreferenceBasedMatchingAlgorithm.java deleted file mode 100644 index 2cf56e4..0000000 --- a/api/src/main/java/org/yapp/domain/match/application/algorithm/PreferenceBasedMatchingAlgorithm.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.yapp.domain.match.application.algorithm; - -import org.springframework.stereotype.Component; -import org.yapp.domain.match.application.blocker.Blocker; -import org.yapp.domain.profile.Profile; -import org.yapp.domain.profile.ProfileValuePick; -import org.yapp.domain.profile.application.ProfileValuePickService; - -import java.util.List; - -import lombok.RequiredArgsConstructor; - -@Component -@RequiredArgsConstructor -public class PreferenceBasedMatchingAlgorithm { - private final List blockers; - private final ProfileValuePickService profileValuePickService; - - /** - * 가치관 기반으로 매칭을 수행 - * - * @param profiles 매칭 수행할 프로필 리스트 - * @return 매칭이 이루어지지 않은 프로필 리스트 - */ - public List doMatch(List profiles) { - //TODO : 효율적인 일반 그래프 매칭 알고리즘 구현 - //TODO : 요구조건 - 차단한 사용자 x, 이전에 매칭된 사용자 x, 지인 x - - return List.of(); - } - - private int calculateWeight(Long fromProfileId, Long toProfileId) { - List profileValuePicksOfFrom = - profileValuePickService.getAllProfileValuesByProfileId(fromProfileId); - List profileValuePicksOfTo = profileValuePickService.getAllProfileValuesByProfileId(toProfileId); - - int valueListSize = profileValuePicksOfFrom.size(); - int sumOfWeight = 0; - for (int i = 0; i < valueListSize; i++) { - ProfileValuePick profileValuePickOfFrom = profileValuePicksOfFrom.get(i); - ProfileValuePick profileValuePickOfTo = profileValuePicksOfTo.get(i); - if (profileValuePickOfFrom.getSelectedAnswer().equals(profileValuePickOfTo.getSelectedAnswer())) { - sumOfWeight++; - } - } - return sumOfWeight; - } - - private boolean checkBlock(Long user1, Long user2) { - for (Blocker blocker : blockers) { - boolean blocked = blocker.blocked(user1, user2); - if (blocked) { - return true; - } - } - return false; - } -} From 2bedc633c02b6ccbf3ff12563b2aeb4f9aab183b Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 01:28:30 +0900 Subject: [PATCH 12/37] =?UTF-8?q?[PC-268]=20feat:=20=EC=9D=B4=EC=A0=84=20?= =?UTF-8?q?=EB=A7=A4=EC=B9=AD=20=EA=B8=B0=EB=B0=98=20=EC=B0=A8=EB=8B=A8?= =?UTF-8?q?=EA=B8=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/blocker/PreviousMatchBlocker.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/org/yapp/domain/match/application/blocker/PreviousMatchBlocker.java b/api/src/main/java/org/yapp/domain/match/application/blocker/PreviousMatchBlocker.java index 62cf71a..5a9b5dd 100644 --- a/api/src/main/java/org/yapp/domain/match/application/blocker/PreviousMatchBlocker.java +++ b/api/src/main/java/org/yapp/domain/match/application/blocker/PreviousMatchBlocker.java @@ -1,8 +1,17 @@ package org.yapp.domain.match.application.blocker; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.yapp.domain.match.application.MatchService; + +@Component +@RequiredArgsConstructor public class PreviousMatchBlocker implements Blocker { + + private final MatchService matchService; + @Override public boolean blocked(Long blockingUserId, Long blockedUserId) { - return false; + return matchService.wasUsersMatched(blockingUserId, blockedUserId); } } From 57cd332da4d58d276760240175ed0d359b3dd43f Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 19:50:43 +0900 Subject: [PATCH 13/37] =?UTF-8?q?[PC-270]=20feat:=20=EB=A7=A4=EC=B9=98=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20ENUM=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/yapp/domain/match/enums/MatchStatus.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 common/src/main/java/org/yapp/domain/match/enums/MatchStatus.java diff --git a/common/src/main/java/org/yapp/domain/match/enums/MatchStatus.java b/common/src/main/java/org/yapp/domain/match/enums/MatchStatus.java new file mode 100644 index 0000000..9948db4 --- /dev/null +++ b/common/src/main/java/org/yapp/domain/match/enums/MatchStatus.java @@ -0,0 +1,16 @@ +package org.yapp.domain.match.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum MatchStatus { + BEFORE_OPEN("BEFORE OPEN"), + WAITING("WAITING"), + RESPONDED("RESPONDED"), + GREEN_LIGHT("GREEN_LIGHT"), + MATCHED("MATCHED"); + + private final String status; +} From 1c8b517f9ebd2d59420cc9ae46bdaf2b78b22908 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 19:51:16 +0900 Subject: [PATCH 14/37] =?UTF-8?q?[PC-270]=20feat:=20=EA=B0=80=EC=B9=98?= =?UTF-8?q?=EA=B4=80=20=ED=94=BD=20=EA=B0=9C=EC=B2=B4=20Response=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 --- .../response/MatchValuePickInnerResponse.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchValuePickInnerResponse.java diff --git a/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchValuePickInnerResponse.java b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchValuePickInnerResponse.java new file mode 100644 index 0000000..93161e0 --- /dev/null +++ b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchValuePickInnerResponse.java @@ -0,0 +1,18 @@ +package org.yapp.domain.match.presentation.dto.response; + +import java.util.Map; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +@AllArgsConstructor +public class MatchValuePickInnerResponse { + + private String category; + private String question; + private Boolean sameWithMe; + private Map answer; + private Integer answerNumber; +} From a3a29789937c4b7946dada92a2b927baed13485f Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 19:51:27 +0900 Subject: [PATCH 15/37] =?UTF-8?q?[PC-270]=20feat:=20=EA=B0=80=EC=B9=98?= =?UTF-8?q?=EA=B4=80=20=ED=94=BD=20=EB=AA=A8=EC=9D=8C=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=20Response=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/MatchValuePickResponse.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchValuePickResponse.java diff --git a/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchValuePickResponse.java b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchValuePickResponse.java new file mode 100644 index 0000000..4b19559 --- /dev/null +++ b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchValuePickResponse.java @@ -0,0 +1,17 @@ +package org.yapp.domain.match.presentation.dto.response; + +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +public class MatchValuePickResponse { + + private Long matchId; + private String shortIntroduction; + private String nickname; + private List valuePicks; +} From 1110bfdd6014d34330f9b8a38242b02d8960e4af Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 19:51:37 +0900 Subject: [PATCH 16/37] =?UTF-8?q?[PC-270]=20feat:=20=EA=B0=80=EC=B9=98?= =?UTF-8?q?=EA=B4=80=20=ED=86=A1=20=EA=B0=9C=EC=B2=B4=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=20Response=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../response/MatchValueTalkInnerResponse.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchValueTalkInnerResponse.java diff --git a/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchValueTalkInnerResponse.java b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchValueTalkInnerResponse.java new file mode 100644 index 0000000..1f22f31 --- /dev/null +++ b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchValueTalkInnerResponse.java @@ -0,0 +1,16 @@ +package org.yapp.domain.match.presentation.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +public class MatchValueTalkInnerResponse { + + private String category; + private String summary; + private String answer; + +} From 92a3759f9d97becfd536b91de188bc482a0f53ee Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 19:51:43 +0900 Subject: [PATCH 17/37] =?UTF-8?q?[PC-270]=20feat:=20=EA=B0=80=EC=B9=98?= =?UTF-8?q?=EA=B4=80=20=ED=86=A1=20=EB=AA=A8=EC=9D=8C=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=20Response=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/MatchValueTalkResponse.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchValueTalkResponse.java diff --git a/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchValueTalkResponse.java b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchValueTalkResponse.java new file mode 100644 index 0000000..331bfee --- /dev/null +++ b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchValueTalkResponse.java @@ -0,0 +1,17 @@ +package org.yapp.domain.match.presentation.dto.response; + +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +public class MatchValueTalkResponse { + + private Long matchId; + private String shortIntroduction; + private String nickname; + private List valueTalks; +} From 8157d742f8f27942cd26bccc4409fc689a32840b Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 19:52:08 +0900 Subject: [PATCH 18/37] =?UTF-8?q?[PC-270]=20feat:=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=82=AC=EC=A7=84=20Response=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/dto/response/ImageUrlResponse.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 api/src/main/java/org/yapp/domain/match/presentation/dto/response/ImageUrlResponse.java diff --git a/api/src/main/java/org/yapp/domain/match/presentation/dto/response/ImageUrlResponse.java b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/ImageUrlResponse.java new file mode 100644 index 0000000..a76b66d --- /dev/null +++ b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/ImageUrlResponse.java @@ -0,0 +1,13 @@ +package org.yapp.domain.match.presentation.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class ImageUrlResponse { + + private String url; +} From 4a35f24a01aea6ed9b172b82aa0fb2cb3d624ed8 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 19:52:26 +0900 Subject: [PATCH 19/37] =?UTF-8?q?[PC-270]=20feat:=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20Response=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/MatchInfoResponse.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchInfoResponse.java diff --git a/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchInfoResponse.java b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchInfoResponse.java new file mode 100644 index 0000000..4ae4a59 --- /dev/null +++ b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchInfoResponse.java @@ -0,0 +1,35 @@ +package org.yapp.domain.match.presentation.dto.response; + +import java.util.List; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class MatchInfoResponse { + private Long matchId; + private String matchStatus; + private String shortIntroduce; + private String nickname; + private String birthYear; + private String location; + private String job; + private Integer matchedValueCount; + private List matchedValueList; + + @Builder + public MatchInfoResponse(Long matchId, String matchStatus, String shortIntroduce, String nickname, String birthYear, + String location, String job, Integer matchedValueCount, List matchedValueList) { + this.matchId = matchId; + this.matchStatus = matchStatus; + this.shortIntroduce = shortIntroduce; + this.nickname = nickname; + this.birthYear = birthYear; + this.location = location; + this.job = job; + this.matchedValueCount = matchedValueCount; + this.matchedValueList = matchedValueList; + } +} From d321a3f29d0760b61379f96011342c8970756f02 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 19:52:34 +0900 Subject: [PATCH 20/37] =?UTF-8?q?[PC-270]=20feat:=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EA=B8=B0=EB=B3=B8=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20Response=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../response/MatchProfileBasicResponse.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchProfileBasicResponse.java diff --git a/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchProfileBasicResponse.java b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchProfileBasicResponse.java new file mode 100644 index 0000000..4afec98 --- /dev/null +++ b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/MatchProfileBasicResponse.java @@ -0,0 +1,34 @@ +package org.yapp.domain.match.presentation.dto.response; + +import java.time.LocalDate; +import java.time.Period; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.yapp.domain.profile.Profile; + +@NoArgsConstructor +@Getter +@AllArgsConstructor +public class MatchProfileBasicResponse { + + private Long matchId; + private String shortIntroduce; + private String nickname; + private String age; + private String birthYear; + private String location; + private String job; + + public static MatchProfileBasicResponse fromProfile(Long matchId, Profile profile) { + String nickname = profile.getProfileBasic().getNickname(); + LocalDate birthDate = profile.getProfileBasic().getBirthdate(); + LocalDate now = LocalDate.now(); + String age = String.valueOf(Period.between(birthDate, now).getYears()); + String birthYearFormatted = String.valueOf(birthDate.getYear()).substring(2); + String location = profile.getProfileBasic().getLocation(); + String job = profile.getProfileBasic().getJob(); + return new MatchProfileBasicResponse(matchId, "", nickname, birthYearFormatted, age, location, + job); + } +} From 252150cf28e0b1802cdac98b84705b7e51db034d Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 19:53:52 +0900 Subject: [PATCH 21/37] =?UTF-8?q?[PC-270]=20feat:=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=A1=B0=ED=9A=8C=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../match/application/MatchService.java | 194 +++++++++++++++++- 1 file changed, 192 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/org/yapp/domain/match/application/MatchService.java b/api/src/main/java/org/yapp/domain/match/application/MatchService.java index 3d10662..69c2c26 100644 --- a/api/src/main/java/org/yapp/domain/match/application/MatchService.java +++ b/api/src/main/java/org/yapp/domain/match/application/MatchService.java @@ -3,12 +3,27 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.yapp.application.AuthenticationService; import org.yapp.domain.match.MatchInfo; import org.yapp.domain.match.dao.MatchInfoRepository; +import org.yapp.domain.match.enums.MatchStatus; +import org.yapp.domain.match.presentation.dto.response.MatchInfoResponse; +import org.yapp.domain.match.presentation.dto.response.MatchProfileBasicResponse; +import org.yapp.domain.match.presentation.dto.response.MatchValuePickInnerResponse; +import org.yapp.domain.match.presentation.dto.response.MatchValuePickResponse; +import org.yapp.domain.match.presentation.dto.response.MatchValueTalkInnerResponse; +import org.yapp.domain.match.presentation.dto.response.MatchValueTalkResponse; +import org.yapp.domain.profile.Profile; +import org.yapp.domain.profile.ProfileValuePick; +import org.yapp.domain.profile.ProfileValueTalk; +import org.yapp.domain.profile.application.ProfileValuePickService; import org.yapp.domain.user.User; import org.yapp.domain.user.application.UserService; import org.yapp.error.dto.MatchErrorCode; @@ -20,14 +35,33 @@ public class MatchService { private final MatchInfoRepository matchInfoRepository; private final AuthenticationService authenticationService; + private final ProfileValuePickService profileValuePickService; private final UserService userService; + @Transactional public MatchInfo createMatchInfo(Long user1Id, Long user2Id) { User user1 = userService.getUserById(user1Id); User user2 = userService.getUserById(user2Id); return matchInfoRepository.save(new MatchInfo(LocalDate.now(), user1, user2)); } + @Transactional(readOnly = true) + public MatchProfileBasicResponse getMatchProfileBasic() { + Long userId = authenticationService.getUserId(); + MatchInfo matchInfo = getMatchInfo(userId); + + User matchedUser = getMatchedUser(userId, matchInfo); + Profile matchedProfile = matchedUser.getProfile(); + return MatchProfileBasicResponse.fromProfile(matchInfo.getId(), matchedProfile); + } + + @Transactional + public void checkPiece() { + Long userId = authenticationService.getUserId(); + MatchInfo matchInfo = getMatchInfo(userId); + matchInfo.checkPiece(userId); + } + public LocalDate getMatchDate() { LocalDateTime nowDateTime = LocalDateTime.now(); LocalDate nowDate = nowDateTime.toLocalDate(); @@ -39,14 +73,170 @@ public LocalDate getMatchDate() { return nowDate; } + @Transactional(readOnly = true) public boolean wasUsersMatched(Long user1Id, Long user2Id) { Optional matchInfoByIds = matchInfoRepository.findMatchInfoByIds(user1Id, user2Id); return matchInfoByIds.isPresent(); } - public MatchInfo getMatchInfo() { - Long userId = authenticationService.getUserId(); + @Transactional(readOnly = true) + public MatchInfo getMatchInfo(Long userId) { return matchInfoRepository.findByUserIdAndDate(userId, getMatchDate()) .orElseThrow(() -> new ApplicationException(MatchErrorCode.NOTFOUND_MATCH)); } + + @Transactional(readOnly = true) + public MatchInfoResponse getMatchInfoResponse() { + Long userId = authenticationService.getUserId(); + MatchInfo matchInfo = getMatchInfo(userId); + + User matchedUser = getMatchedUser(userId, matchInfo); + User user = userService.getUserById(userId); + List matchedValues = getMatchedValues(user.getProfile().getId(), + matchedUser.getProfile().getId()); + + //TODO : 왜 deprecated 된 ProfileBio에만 introduce가 있는지 논의가 필요 + MatchInfoResponse response = MatchInfoResponse.builder() + .matchId(matchInfo.getId()) + .matchStatus(getMatchStatus(userId, matchInfo)) + .shortIntroduce("") // Deprecated 된 BIO 에서 넣어야하는지? + .nickname(matchedUser.getProfile().getProfileBasic().getNickname()) + .birthYear( + String.valueOf(matchedUser.getProfile().getProfileBasic().getBirthdate().getYear())) + .location(matchedUser.getProfile().getProfileBasic().getLocation()) + .job(matchedUser.getProfile().getProfileBasic().getJob()) + .matchedValueCount(matchedValues.size()) + .matchedValueList(matchedValues) + .build(); + + return response; + } + + private User getMatchedUser(Long userId, MatchInfo matchInfo) { + if (userId.equals(matchInfo.getUser1().getId())) { + return matchInfo.getUser2(); + } + return matchInfo.getUser1(); + } + + private String getMatchStatus(Long userId, MatchInfo matchInfo) { + if (userId.equals(matchInfo.getUser1().getId())) { + if (!matchInfo.getUser1PieceChecked()) { + return MatchStatus.BEFORE_OPEN.getStatus(); + } + if (matchInfo.getUser1Accepted() && matchInfo.getUser2Accepted()) { + return MatchStatus.MATCHED.getStatus(); + } + if (matchInfo.getUser1Accepted()) { + return MatchStatus.RESPONDED.getStatus(); + } + if (matchInfo.getUser2Accepted()) { + return MatchStatus.GREEN_LIGHT.getStatus(); + } + return MatchStatus.WAITING.getStatus(); + } else { + if (!matchInfo.getUser2PieceChecked()) { + return MatchStatus.BEFORE_OPEN.getStatus(); + } + if (matchInfo.getUser1Accepted() && matchInfo.getUser2Accepted()) { + return MatchStatus.MATCHED.getStatus(); + } + if (matchInfo.getUser2Accepted()) { + return MatchStatus.RESPONDED.getStatus(); + } + if (matchInfo.getUser1Accepted()) { + return MatchStatus.GREEN_LIGHT.getStatus(); + } + return MatchStatus.WAITING.getStatus(); + } + } + + @Transactional(readOnly = true) + public MatchValueTalkResponse getMatchValueTalk() { + Long userId = authenticationService.getUserId(); + MatchInfo matchInfo = getMatchInfo(userId); + User matchedUser = getMatchedUser(userId, matchInfo); + List profileValueTalks = matchedUser.getProfile().getProfileValueTalks(); + List talkResponses = new ArrayList<>(); + for (ProfileValueTalk profileValueTalk : profileValueTalks) { + String summary = profileValueTalk.getSummary(); + String answer = profileValueTalk.getAnswer(); + String category = profileValueTalk.getValueTalk().getCategory(); + talkResponses.add(new MatchValueTalkInnerResponse(category, summary, answer)); + } + return new MatchValueTalkResponse(matchInfo.getId(), "", + matchedUser.getProfile().getProfileBasic().getNickname(), talkResponses); + } + + @Transactional(readOnly = true) + public MatchValuePickResponse getMatchedUserValuePicks() { + Long userId = authenticationService.getUserId(); + User user = userService.getUserById(userId); + MatchInfo matchInfo = getMatchInfo(userId); + User matchedUser = getMatchedUser(userId, matchInfo); + List matchValuePickInnerResponses = getMatchValuePickInnerResponses( + user.getProfile().getId(), matchedUser.getProfile().getId()); + + return new MatchValuePickResponse(matchInfo.getId(), "", + matchedUser.getProfile().getProfileBasic().getNickname(), matchValuePickInnerResponses); + } + + private List getMatchValuePickInnerResponses(Long fromProfileId, + Long toProfileId) { + List profileValuePicksOfFrom = + profileValuePickService.getAllProfileValuesByProfileId(fromProfileId); + List profileValuePicksOfTo = profileValuePickService.getAllProfileValuesByProfileId( + toProfileId); + + List talkInnerResponses = new ArrayList<>(); + int valueListSize = profileValuePicksOfFrom.size(); + for (int i = 0; i < valueListSize; i++) { + ProfileValuePick profileValuePickFrom = profileValuePicksOfFrom.get(i); + ProfileValuePick profileValuePickTo = profileValuePicksOfTo.get(i); + String category = profileValuePickTo.getValuePick().getCategory(); + String question = profileValuePickTo.getValuePick().getQuestion(); + Integer selectedAnswer = profileValuePickTo.getSelectedAnswer(); + Map answers = profileValuePickTo.getValuePick().getAnswers(); + if (profileValuePickTo.getSelectedAnswer().equals(profileValuePickFrom.getSelectedAnswer())) { + talkInnerResponses.add( + new MatchValuePickInnerResponse(category, question, true, answers, selectedAnswer)); + } else { + talkInnerResponses.add( + new MatchValuePickInnerResponse(category, question, false, answers, selectedAnswer) + ); + } + } + return talkInnerResponses; + } + + @Transactional(readOnly = true) + public String getMatchedUserImageUrl() { + Long userId = authenticationService.getUserId(); + MatchInfo matchInfo = getMatchInfo(userId); + User matchedUser = getMatchedUser(userId, matchInfo); + + return matchedUser.getProfile().getProfileBasic().getImageUrl(); + } + + private List getMatchedValues(Long fromProfileId, Long toProfileId) { + List profileValuePicksOfFrom = + profileValuePickService.getAllProfileValuesByProfileId(fromProfileId); + List profileValuePicksOfTo = profileValuePickService.getAllProfileValuesByProfileId( + toProfileId); + + int valueListSize = profileValuePicksOfFrom.size(); + List matchedValues = new ArrayList<>(); + for (int i = 0; i < valueListSize; i++) { + ProfileValuePick profileValuePickOfFrom = profileValuePicksOfFrom.get(i); + ProfileValuePick profileValuePickOfTo = profileValuePicksOfTo.get(i); + if (profileValuePickOfFrom.getSelectedAnswer() + .equals(profileValuePickOfTo.getSelectedAnswer())) { + Integer selectedAnswer = profileValuePickOfTo.getSelectedAnswer(); + Map answers = profileValuePickOfTo.getValuePick().getAnswers(); + String value = (String) answers.get(selectedAnswer); + matchedValues.add(value); + } + } + return matchedValues; + } } From 48b715c89f70308291d7dace34c53e21265972d0 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 19:54:16 +0900 Subject: [PATCH 22/37] =?UTF-8?q?[PC-270]=20feat:=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=ED=99=95=EC=9D=B8=20=EC=B2=B4=ED=81=AC=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/yapp/domain/match/MatchInfo.java | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/common/src/main/java/org/yapp/domain/match/MatchInfo.java b/common/src/main/java/org/yapp/domain/match/MatchInfo.java index 61afff5..35ae7e5 100644 --- a/common/src/main/java/org/yapp/domain/match/MatchInfo.java +++ b/common/src/main/java/org/yapp/domain/match/MatchInfo.java @@ -1,9 +1,5 @@ package org.yapp.domain.match; -import org.yapp.domain.user.User; - -import java.time.LocalDate; - import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -11,13 +7,16 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; +import java.time.LocalDate; import lombok.Getter; import lombok.NoArgsConstructor; +import org.yapp.domain.user.User; @Entity @Getter @NoArgsConstructor public class MatchInfo { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -30,20 +29,20 @@ public class MatchInfo { private User user1; @Column(name = "user_1_piece_checked") - private Boolean user1PieceChecked; + private Boolean user1PieceChecked = false; @Column(name = "user_1_accept") - private Boolean user1Accepted; + private Boolean user1Accepted = false; @ManyToOne @JoinColumn(name = "user_2") private User user2; @Column(name = "user_2_piece_checked") - private Boolean user2PieceChecked; + private Boolean user2PieceChecked = false; @Column(name = "user_2_accept") - private Boolean user2Accepted; + private Boolean user2Accepted = false; public MatchInfo(LocalDate date, User user1, User user2) { this.date = date; @@ -54,4 +53,12 @@ public MatchInfo(LocalDate date, User user1, User user2) { public static MatchInfo createMatchInfo(User user1, User user2) { return new MatchInfo(LocalDate.now(), user1, user2); } + + public void checkPiece(Long userId) { + if (user1.getId().equals(userId)) { + user1PieceChecked = true; + } else { + user2PieceChecked = true; + } + } } From 0ae130d6aa03f22f276d2c99366cc1fa941a14ac Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 19:59:49 +0900 Subject: [PATCH 23/37] =?UTF-8?q?[PC-270]=20feat:=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=A1=B0=ED=9A=8C=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?API=20=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=EB=93=A4=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 --- .../match/presentation/MatchController.java | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 api/src/main/java/org/yapp/domain/match/presentation/MatchController.java diff --git a/api/src/main/java/org/yapp/domain/match/presentation/MatchController.java b/api/src/main/java/org/yapp/domain/match/presentation/MatchController.java new file mode 100644 index 0000000..88970a8 --- /dev/null +++ b/api/src/main/java/org/yapp/domain/match/presentation/MatchController.java @@ -0,0 +1,73 @@ +package org.yapp.domain.match.presentation; + +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.yapp.domain.match.application.MatchService; +import org.yapp.domain.match.presentation.dto.response.ImageUrlResponse; +import org.yapp.domain.match.presentation.dto.response.MatchInfoResponse; +import org.yapp.domain.match.presentation.dto.response.MatchProfileBasicResponse; +import org.yapp.domain.match.presentation.dto.response.MatchValuePickResponse; +import org.yapp.domain.match.presentation.dto.response.MatchValueTalkResponse; +import org.yapp.util.CommonResponse; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/matches") +public class MatchController { + + private final MatchService matchService; + + @GetMapping("/infos") + @Operation(summary = "매칭 정보 조회", description = "이번 매칭의 정보를 조회합니다.", tags = {"매칭"}) + public ResponseEntity> getMatchInfo() { + MatchInfoResponse matchInfoResponse = matchService.getMatchInfoResponse(); + return ResponseEntity.status(HttpStatus.OK) + .body(CommonResponse.createSuccess(matchInfoResponse)); + } + + @PatchMapping("/pieces/check") + @Operation(summary = "매칭 조각 확인 체크", description = "이번 매칭의 조각을 확인했음을 서버에 알립니다.", tags = {"매칭"}) + public ResponseEntity> checkMatchPiece() { + matchService.checkPiece(); + return ResponseEntity.status(HttpStatus.OK).body(CommonResponse.createSuccessWithNoContent()); + } + + @GetMapping("/profiles/basic") + @Operation(summary = "매칭 프로필 기본정보 확인", description = "매칭 상대의 프로필 기본정보를 확인합니다.", tags = {"매칭"}) + public ResponseEntity> getBasicMatchProfile() { + MatchProfileBasicResponse matchProfileBasic = matchService.getMatchProfileBasic(); + return ResponseEntity.status(HttpStatus.OK) + .body(CommonResponse.createSuccess(matchProfileBasic)); + } + + @GetMapping("/values/talks") + @Operation(summary = "매칭 상대 가치관 톡 확인", description = "매칭 상대의 가치관 톡을 확인합니다.", tags = {"매칭"}) + public ResponseEntity> getMatchTalkValues() { + MatchValueTalkResponse matchValueTalk = matchService.getMatchValueTalk(); + return ResponseEntity.status(HttpStatus.OK).body(CommonResponse.createSuccess(matchValueTalk)); + } + + + @GetMapping("/values/picks") + @Operation(summary = "매칭 상대 가치관 픽 확인", description = "매칭 상대의 가치관 픽을 확인합니다.", tags = {"매칭"}) + public ResponseEntity> getMatchValuePicks() { + MatchValuePickResponse matchValuePickResponse = matchService.getMatchedUserValuePicks(); + return ResponseEntity.status(HttpStatus.OK) + .body(CommonResponse.createSuccess(matchValuePickResponse)); + } + + @GetMapping("/images") + @Operation(summary = "매칭 상대 프로필 이미지 확인", description = "매칭 상대의 프로필 이미지를 확인합니다.", tags = {"매칭"}) + public ResponseEntity> getMatchedUserImages() { + String matchedUserImageUrl = matchService.getMatchedUserImageUrl(); + ImageUrlResponse imageUrlResponse = new ImageUrlResponse(matchedUserImageUrl); + return ResponseEntity.status(HttpStatus.OK) + .body(CommonResponse.createSuccess(imageUrlResponse)); + } +} From 018e24e63f881fc865c78514e4650f662a5d675d Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 20:28:04 +0900 Subject: [PATCH 24/37] =?UTF-8?q?[PC-271]=20feat:=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EC=88=98=EB=9D=BD=20API=20=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yapp/domain/match/presentation/MatchController.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/api/src/main/java/org/yapp/domain/match/presentation/MatchController.java b/api/src/main/java/org/yapp/domain/match/presentation/MatchController.java index 88970a8..ed652fb 100644 --- a/api/src/main/java/org/yapp/domain/match/presentation/MatchController.java +++ b/api/src/main/java/org/yapp/domain/match/presentation/MatchController.java @@ -6,6 +6,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.yapp.domain.match.application.MatchService; @@ -70,4 +71,11 @@ public ResponseEntity> getMatchedUserImages() { return ResponseEntity.status(HttpStatus.OK) .body(CommonResponse.createSuccess(imageUrlResponse)); } + + @PostMapping("/accept") + @Operation(summary = "매칭 수락하기", description = "매칭을 수락합니다.", tags = {"매칭"}) + public ResponseEntity> acceptMatch() { + matchService.acceptMatch(); + return ResponseEntity.status(HttpStatus.OK).body(CommonResponse.createSuccessWithNoContent()); + } } From cc75ffb6dbdaf455ab18034a7cfdea35874783a1 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 20:28:18 +0900 Subject: [PATCH 25/37] =?UTF-8?q?[PC-271]=20feat:=20=EB=A7=A4=EC=B9=98=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=97=94=ED=8B=B0=ED=8B=B0=20=EC=88=98?= =?UTF-8?q?=EB=9D=BD=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/src/main/java/org/yapp/domain/match/MatchInfo.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/common/src/main/java/org/yapp/domain/match/MatchInfo.java b/common/src/main/java/org/yapp/domain/match/MatchInfo.java index 35ae7e5..2594ce0 100644 --- a/common/src/main/java/org/yapp/domain/match/MatchInfo.java +++ b/common/src/main/java/org/yapp/domain/match/MatchInfo.java @@ -61,4 +61,12 @@ public void checkPiece(Long userId) { user2PieceChecked = true; } } + + public void acceptPiece(Long userId) { + if (user1.getId().equals(userId)) { + user1Accepted = true; + } else { + user2Accepted = true; + } + } } From 77ea7a02e8fdcf3b1bf6d1e15996df7d9de726df Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 20:28:30 +0900 Subject: [PATCH 26/37] =?UTF-8?q?[PC-271]=20feat:=20=EB=A7=A4=EC=B9=98=20?= =?UTF-8?q?=EC=88=98=EB=9D=BD=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/yapp/domain/match/application/MatchService.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/api/src/main/java/org/yapp/domain/match/application/MatchService.java b/api/src/main/java/org/yapp/domain/match/application/MatchService.java index 69c2c26..c81da89 100644 --- a/api/src/main/java/org/yapp/domain/match/application/MatchService.java +++ b/api/src/main/java/org/yapp/domain/match/application/MatchService.java @@ -239,4 +239,11 @@ private List getMatchedValues(Long fromProfileId, Long toProfileId) { } return matchedValues; } + + @Transactional + public void acceptMatch() { + Long userId = authenticationService.getUserId(); + MatchInfo matchInfo = getMatchInfo(userId); + matchInfo.acceptPiece(userId); + } } From ea94216860d05a1a4e93c34e53bf079521c5f5d8 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 20:28:47 +0900 Subject: [PATCH 27/37] =?UTF-8?q?[PC-271]=20feat:=20=EC=97=B0=EB=9D=BD?= =?UTF-8?q?=EC=B2=98=20=EC=9D=91=EB=8B=B5=20=EA=B0=9D=EC=B2=B4=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 --- .../dto/response/ContactResponse.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 api/src/main/java/org/yapp/domain/match/presentation/dto/response/ContactResponse.java diff --git a/api/src/main/java/org/yapp/domain/match/presentation/dto/response/ContactResponse.java b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/ContactResponse.java new file mode 100644 index 0000000..2480388 --- /dev/null +++ b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/ContactResponse.java @@ -0,0 +1,15 @@ +package org.yapp.domain.match.presentation.dto.response; + +import java.util.Map; +import java.util.Objects; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +public class ContactResponse { + + private Map contacts; +} \ No newline at end of file From 1437ef191dd33b1efbe69d6d199390165cd51e93 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 20:31:55 +0900 Subject: [PATCH 28/37] =?UTF-8?q?[PC-271]=20fix:=20=EC=97=B0=EB=9D=BD?= =?UTF-8?q?=EC=B2=98=20=EC=9D=91=EB=8B=B5=20=EA=B0=9D=EC=B2=B4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../match/presentation/dto/response/ContactResponse.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/src/main/java/org/yapp/domain/match/presentation/dto/response/ContactResponse.java b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/ContactResponse.java index 2480388..72e94b0 100644 --- a/api/src/main/java/org/yapp/domain/match/presentation/dto/response/ContactResponse.java +++ b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/ContactResponse.java @@ -1,7 +1,6 @@ package org.yapp.domain.match.presentation.dto.response; import java.util.Map; -import java.util.Objects; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -11,5 +10,5 @@ @Getter public class ContactResponse { - private Map contacts; + private Map contacts; } \ No newline at end of file From 5abc497129fe5e159b66ecc4c65a3a33affdf1d5 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 20:34:55 +0900 Subject: [PATCH 29/37] =?UTF-8?q?[PC-271]=20fix:=20=EC=97=B0=EB=9D=BD?= =?UTF-8?q?=EC=B2=98=20=EC=9D=91=EB=8B=B5=20=EA=B0=9D=EC=B2=B4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/match/presentation/dto/response/ContactResponse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/org/yapp/domain/match/presentation/dto/response/ContactResponse.java b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/ContactResponse.java index 72e94b0..5cf5e1e 100644 --- a/api/src/main/java/org/yapp/domain/match/presentation/dto/response/ContactResponse.java +++ b/api/src/main/java/org/yapp/domain/match/presentation/dto/response/ContactResponse.java @@ -10,5 +10,5 @@ @Getter public class ContactResponse { - private Map contacts; + private Map contacts; } \ No newline at end of file From 227b7118c0c61baf6f09f039f509c96d7da8465f Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 20:38:24 +0900 Subject: [PATCH 30/37] =?UTF-8?q?[PC-271]=20fix:=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EC=83=81=EB=8C=80=20=EC=97=B0=EB=9D=BD=EC=B2=98=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=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 --- .../yapp/domain/match/presentation/MatchController.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/api/src/main/java/org/yapp/domain/match/presentation/MatchController.java b/api/src/main/java/org/yapp/domain/match/presentation/MatchController.java index ed652fb..68bde73 100644 --- a/api/src/main/java/org/yapp/domain/match/presentation/MatchController.java +++ b/api/src/main/java/org/yapp/domain/match/presentation/MatchController.java @@ -1,6 +1,7 @@ package org.yapp.domain.match.presentation; import io.swagger.v3.oas.annotations.Operation; +import java.util.Map; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -10,6 +11,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.yapp.domain.match.application.MatchService; +import org.yapp.domain.match.presentation.dto.response.ContactResponse; import org.yapp.domain.match.presentation.dto.response.ImageUrlResponse; import org.yapp.domain.match.presentation.dto.response.MatchInfoResponse; import org.yapp.domain.match.presentation.dto.response.MatchProfileBasicResponse; @@ -78,4 +80,11 @@ public ResponseEntity> acceptMatch() { matchService.acceptMatch(); return ResponseEntity.status(HttpStatus.OK).body(CommonResponse.createSuccessWithNoContent()); } + + @GetMapping("/contacts") + public ResponseEntity> getContacts() { + Map contacts = matchService.getContacts(); + ContactResponse contactResponse = new ContactResponse(contacts); + return ResponseEntity.status(HttpStatus.OK).body(CommonResponse.createSuccess(contactResponse)); + } } From b44f0f7c5b68e81270e70159b8cfc73ec7171d4f Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 20:38:33 +0900 Subject: [PATCH 31/37] =?UTF-8?q?[PC-271]=20fix:=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EC=88=98=EB=9D=BD=20=EC=95=88=EB=90=A8=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/src/main/java/org/yapp/error/dto/MatchErrorCode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/org/yapp/error/dto/MatchErrorCode.java b/common/src/main/java/org/yapp/error/dto/MatchErrorCode.java index 1c66c1a..5e8da18 100644 --- a/common/src/main/java/org/yapp/error/dto/MatchErrorCode.java +++ b/common/src/main/java/org/yapp/error/dto/MatchErrorCode.java @@ -1,14 +1,14 @@ package org.yapp.error.dto; -import org.springframework.http.HttpStatus; - import lombok.Getter; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; @Getter @RequiredArgsConstructor public enum MatchErrorCode implements ErrorCode { NOTFOUND_MATCH(HttpStatus.NOT_FOUND, "Match not found"), + MATCH_NOT_ACCEPTED(HttpStatus.BAD_REQUEST, "Match not accepted"), ; private final HttpStatus httpStatus; From d69c3b18b8faa87fdfdcc1826cdb6ae10e41ed0a Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 20:38:51 +0900 Subject: [PATCH 32/37] =?UTF-8?q?[PC-271]=20feat:=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EC=83=81=EB=8C=80=20=EC=97=B0=EB=9D=BD=EC=B2=98=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20API=20=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yapp/domain/match/application/MatchService.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/api/src/main/java/org/yapp/domain/match/application/MatchService.java b/api/src/main/java/org/yapp/domain/match/application/MatchService.java index c81da89..5eed84f 100644 --- a/api/src/main/java/org/yapp/domain/match/application/MatchService.java +++ b/api/src/main/java/org/yapp/domain/match/application/MatchService.java @@ -246,4 +246,15 @@ public void acceptMatch() { MatchInfo matchInfo = getMatchInfo(userId); matchInfo.acceptPiece(userId); } + + @Transactional(readOnly = true) + public Map getContacts() { + Long userId = authenticationService.getUserId(); + MatchInfo matchInfo = getMatchInfo(userId); + if (!matchInfo.getUser1Accepted() || !matchInfo.getUser2Accepted()) { + throw new ApplicationException(MatchErrorCode.MATCH_NOT_ACCEPTED); + } + User matchedUser = getMatchedUser(userId, matchInfo); + return matchedUser.getProfile().getProfileBasic().getContacts(); + } } From fecc6bbfab685130be674224d76c78b66842a036 Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 23:20:53 +0900 Subject: [PATCH 33/37] =?UTF-8?q?[PC-273]=20feat:=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EC=83=81=EB=8C=80=20=EC=B0=A8=EB=8B=A8=20API=20=EC=97=94?= =?UTF-8?q?=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/match/presentation/MatchController.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/api/src/main/java/org/yapp/domain/match/presentation/MatchController.java b/api/src/main/java/org/yapp/domain/match/presentation/MatchController.java index 68bde73..27d9695 100644 --- a/api/src/main/java/org/yapp/domain/match/presentation/MatchController.java +++ b/api/src/main/java/org/yapp/domain/match/presentation/MatchController.java @@ -7,9 +7,11 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import org.yapp.domain.block.application.DirectBlockService; import org.yapp.domain.match.application.MatchService; import org.yapp.domain.match.presentation.dto.response.ContactResponse; import org.yapp.domain.match.presentation.dto.response.ImageUrlResponse; @@ -25,6 +27,7 @@ public class MatchController { private final MatchService matchService; + private final DirectBlockService directBlockService; @GetMapping("/infos") @Operation(summary = "매칭 정보 조회", description = "이번 매칭의 정보를 조회합니다.", tags = {"매칭"}) @@ -82,9 +85,18 @@ public ResponseEntity> acceptMatch() { } @GetMapping("/contacts") + @Operation(summary = "매칭 상대 연락처 조회", description = "매칭 상대의 연락처를 조회합니다", tags = {"매칭"}) public ResponseEntity> getContacts() { Map contacts = matchService.getContacts(); ContactResponse contactResponse = new ContactResponse(contacts); return ResponseEntity.status(HttpStatus.OK).body(CommonResponse.createSuccess(contactResponse)); } + + @PostMapping("/blocks/users/{userId}") + @Operation(summary = "매칭 상대 차단", description = "매칭 상대를 차단합니다", tags = {"매칭"}) + public ResponseEntity> blockUsers( + @PathVariable(name = "userId") Long userId) { + directBlockService.blockUser(userId); + return ResponseEntity.status(HttpStatus.OK).body(CommonResponse.createSuccessWithNoContent()); + } } From fde7c232eeb88522414e7f997d14c5c8e0ea999e Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 23:21:18 +0900 Subject: [PATCH 34/37] =?UTF-8?q?[PC-273]=20feat:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=A7=81=EC=A0=91=20=EC=B0=A8=EB=8B=A8=20=EB=B0=8F=20=EC=B0=A8?= =?UTF-8?q?=EB=8B=A8=20=ED=99=95=EC=9D=B8=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../block/application/DirectBlockService.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 api/src/main/java/org/yapp/domain/block/application/DirectBlockService.java diff --git a/api/src/main/java/org/yapp/domain/block/application/DirectBlockService.java b/api/src/main/java/org/yapp/domain/block/application/DirectBlockService.java new file mode 100644 index 0000000..c017141 --- /dev/null +++ b/api/src/main/java/org/yapp/domain/block/application/DirectBlockService.java @@ -0,0 +1,26 @@ +package org.yapp.domain.block.application; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.yapp.application.AuthenticationService; +import org.yapp.domain.block.DirectBlock; +import org.yapp.domain.block.dao.DirectBlockRepository; + +@Service +@RequiredArgsConstructor +public class DirectBlockService { + + private final DirectBlockRepository directBlockRepository; + private final AuthenticationService authenticationService; + + public DirectBlock blockUser(Long blockId) { + Long userId = authenticationService.getUserId(); + return directBlockRepository.save(new DirectBlock(userId, blockId)); + } + + public boolean checkBlock(Long userId, Long partnerId) { + return directBlockRepository.existsDirectBlockByBlockingUserIdAndBlockedUserId(userId, + partnerId); + } + +} From 18539e77cfb2e1a2d24260bfef0be66ea19603af Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 23:22:29 +0900 Subject: [PATCH 35/37] =?UTF-8?q?[PC-273]=20feat:=20=EC=A7=81=EC=A0=91=20?= =?UTF-8?q?=EC=B0=A8=EB=8B=A8=20=EC=97=94=ED=8B=B0=ED=8B=B0=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 --- .../org/yapp/domain/block/DirectBlock.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 common/src/main/java/org/yapp/domain/block/DirectBlock.java diff --git a/common/src/main/java/org/yapp/domain/block/DirectBlock.java b/common/src/main/java/org/yapp/domain/block/DirectBlock.java new file mode 100644 index 0000000..34b4759 --- /dev/null +++ b/common/src/main/java/org/yapp/domain/block/DirectBlock.java @@ -0,0 +1,31 @@ +package org.yapp.domain.block; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@NoArgsConstructor +@Getter +@Table(name = "direct_block") +public class DirectBlock { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + @Column(name = "blocking_user_id") + private Long blockingUserId; + @Column(name = "blocked_user_id") + private Long blockedUserId; + + public DirectBlock(Long blockingUserId, Long blockedUserId) { + this.blockingUserId = blockingUserId; + this.blockedUserId = blockedUserId; + } +} From 257bbd3306f6d3360e8e4c94bdf1f5c215cec98d Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 23:22:36 +0900 Subject: [PATCH 36/37] =?UTF-8?q?[PC-273]=20feat:=20=EC=A7=81=EC=A0=91=20?= =?UTF-8?q?=EC=B0=A8=EB=8B=A8=20=EB=A6=AC=ED=8F=AC=EC=A7=80=ED=86=A0?= =?UTF-8?q?=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 --- .../yapp/domain/block/dao/DirectBlockRepository.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 api/src/main/java/org/yapp/domain/block/dao/DirectBlockRepository.java diff --git a/api/src/main/java/org/yapp/domain/block/dao/DirectBlockRepository.java b/api/src/main/java/org/yapp/domain/block/dao/DirectBlockRepository.java new file mode 100644 index 0000000..9935875 --- /dev/null +++ b/api/src/main/java/org/yapp/domain/block/dao/DirectBlockRepository.java @@ -0,0 +1,10 @@ +package org.yapp.domain.block.dao; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.yapp.domain.block.DirectBlock; + +public interface DirectBlockRepository extends JpaRepository { + + boolean existsDirectBlockByBlockingUserIdAndBlockedUserId(Long blockingUserId, + Long blockedUserId); +} From e0ca328920e6e7539c0ac7ac23d091f9a720448c Mon Sep 17 00:00:00 2001 From: Chanho Lee Date: Tue, 21 Jan 2025 23:22:50 +0900 Subject: [PATCH 37/37] =?UTF-8?q?[PC-273]=20feat:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=A7=81=EC=A0=91=20=EC=B0=A8=EB=8B=A8=EA=B8=B0=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/blocker/DirectBlockBasedBlocker.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/org/yapp/domain/match/application/blocker/DirectBlockBasedBlocker.java b/api/src/main/java/org/yapp/domain/match/application/blocker/DirectBlockBasedBlocker.java index ccd8332..1e35930 100644 --- a/api/src/main/java/org/yapp/domain/match/application/blocker/DirectBlockBasedBlocker.java +++ b/api/src/main/java/org/yapp/domain/match/application/blocker/DirectBlockBasedBlocker.java @@ -1,8 +1,17 @@ package org.yapp.domain.match.application.blocker; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.yapp.domain.block.application.DirectBlockService; + +@Component +@RequiredArgsConstructor public class DirectBlockBasedBlocker implements Blocker { + + private final DirectBlockService directBlockService; + @Override public boolean blocked(Long blockingUserId, Long blockedUserId) { - return false; + return directBlockService.checkBlock(blockingUserId, blockedUserId); } }