From 91af1988ac7ed12b7ae45d0056e51b98272afe98 Mon Sep 17 00:00:00 2001 From: jher235 Date: Tue, 30 Dec 2025 14:32:21 +0900 Subject: [PATCH 01/11] =?UTF-8?q?[#674]=20refactor:=20TeamNumber=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=EC=9D=98=20required=20?= =?UTF-8?q?=EB=A5=BC=20false=EB=A1=9C=20=EB=B3=80=EA=B2=BD,=20=EB=AF=B8?= =?UTF-8?q?=EC=85=98=20=EB=AA=A9=EB=A1=9D=20=EC=9D=91=EB=8B=B5=EB=8F=84=20?= =?UTF-8?q?=EB=8B=A4=EB=A5=B4=EA=B2=8C=20=EC=A3=BC=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../appjamuser/AppjamUserInfo.java | 5 +++++ .../mission/AppjamMissionService.java | 12 ++++++++--- .../app/application/mission/MissionInfo.java | 10 +++++++++ .../org/sopt/app/facade/MissionFacade.java | 21 +++++++++++++------ .../appjamtamp/AppjamtampController.java | 5 ++--- 5 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/sopt/app/application/appjamuser/AppjamUserInfo.java b/src/main/java/org/sopt/app/application/appjamuser/AppjamUserInfo.java index afd69f57..4ad5d23c 100644 --- a/src/main/java/org/sopt/app/application/appjamuser/AppjamUserInfo.java +++ b/src/main/java/org/sopt/app/application/appjamuser/AppjamUserInfo.java @@ -25,5 +25,10 @@ public static TeamSummary from(AppjamUser appjamUser) { .teamName(appjamUser.getTeamName()) .build(); } + + public static TeamSummary empty() { + return TeamSummary.builder() + .build(); + } } } diff --git a/src/main/java/org/sopt/app/application/mission/AppjamMissionService.java b/src/main/java/org/sopt/app/application/mission/AppjamMissionService.java index 5eb403f3..29f296ee 100644 --- a/src/main/java/org/sopt/app/application/mission/AppjamMissionService.java +++ b/src/main/java/org/sopt/app/application/mission/AppjamMissionService.java @@ -30,8 +30,14 @@ public class AppjamMissionService { private final StampRepository stampRepository; private final SoptampUserRepository soptampUserRepository; + public List getDisplayedMissions() { + val displayedMissions = missionRepository.findAllByDisplay(true); + return displayedMissions.stream() + .map(AppjamMissionInfo::createWhenUncompleted) + .toList(); + } - public List getAllMissions(TeamNumber teamNumber) { + public List getMissionsByTeam(TeamNumber teamNumber) { val userIds = getTeamUserIds(teamNumber); val stampsByMissionId = getStampMapByUserIds(userIds); val soptampUserByUserId = getSoptampUserMapByUserIds(userIds); @@ -42,9 +48,9 @@ public List getAllMissions(TeamNumber teamNumber) { .toList(); } - public List getMissionsByCondition(TeamNumber teamNumber, + public List getMissionsByTeamAndCondition(TeamNumber teamNumber, boolean isCompleted) { - List allMissions = getAllMissions(teamNumber); + List allMissions = getMissionsByTeam(teamNumber); return allMissions.stream() .filter(mission -> Objects.equals(mission.isCompleted(), isCompleted)) diff --git a/src/main/java/org/sopt/app/application/mission/MissionInfo.java b/src/main/java/org/sopt/app/application/mission/MissionInfo.java index d2cd0271..c4cc4150 100755 --- a/src/main/java/org/sopt/app/application/mission/MissionInfo.java +++ b/src/main/java/org/sopt/app/application/mission/MissionInfo.java @@ -63,6 +63,16 @@ public static AppjamMissionInfo of( .isCompleted(isCompleted) .build(); } + + public static AppjamMissionInfo createWhenUncompleted(Mission mission) { + return AppjamMissionInfo.builder() + .id(mission.getId()) + .title(mission.getTitle()) + .level(mission.getLevel()) + .profileImage(mission.getProfileImage()) + .isCompleted(false) + .build(); + } } @Getter diff --git a/src/main/java/org/sopt/app/facade/MissionFacade.java b/src/main/java/org/sopt/app/facade/MissionFacade.java index 925f9949..7db1be6e 100644 --- a/src/main/java/org/sopt/app/facade/MissionFacade.java +++ b/src/main/java/org/sopt/app/facade/MissionFacade.java @@ -1,12 +1,14 @@ package org.sopt.app.facade; -import java.util.Optional; import lombok.RequiredArgsConstructor; import lombok.val; +import org.sopt.app.application.appjamuser.AppjamUserInfo.TeamSummary; import org.sopt.app.application.appjamuser.AppjamUserService; import org.sopt.app.application.mission.AppjamMissionService; import org.sopt.app.application.mission.MissionInfo.AppjamMissionInfos; +import org.sopt.app.application.mission.MissionService; import org.sopt.app.domain.enums.TeamNumber; +import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -16,19 +18,26 @@ public class MissionFacade { private final AppjamMissionService appjamMissionService; private final AppjamUserService appjamUserService; + private final MissionService missionService; @Transactional(readOnly = true) public AppjamMissionInfos getTeamMissions( - TeamNumber teamNumber, - Optional complete + @Nullable TeamNumber teamNumber, + @Nullable Boolean complete ) { + if (teamNumber == null) { + val missions = appjamMissionService.getDisplayedMissions(); + return AppjamMissionInfos.of(TeamSummary.empty(), missions); + } + val teamSummary = appjamUserService.getTeamSummaryByTeamNumber(teamNumber); - if (complete.isPresent()) { + if (complete != null) { return AppjamMissionInfos.of( teamSummary, - appjamMissionService.getMissionsByCondition(teamNumber, complete.get())); + appjamMissionService.getMissionsByTeamAndCondition(teamNumber, complete)); } - return AppjamMissionInfos.of(teamSummary, appjamMissionService.getAllMissions(teamNumber)); + return AppjamMissionInfos.of(teamSummary, + appjamMissionService.getMissionsByTeam(teamNumber)); } } diff --git a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampController.java b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampController.java index 10c5d2e6..1979472d 100644 --- a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampController.java +++ b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampController.java @@ -6,7 +6,6 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import jakarta.validation.Valid; -import java.util.Optional; import lombok.AllArgsConstructor; import lombok.val; import org.sopt.app.domain.enums.TeamNumber; @@ -38,10 +37,10 @@ public class AppjamtampController { }) @GetMapping("/mission") public ResponseEntity getMissions( - @RequestParam TeamNumber teamNumber, + @RequestParam(required = false) TeamNumber teamNumber, @RequestParam(required = false) Boolean isCompleted ) { - val result = missionFacade.getTeamMissions(teamNumber, Optional.ofNullable(isCompleted)); + val result = missionFacade.getTeamMissions(teamNumber, isCompleted); val response = appjamtampResponseMapper.of(result); return ResponseEntity.ok(response); } From 5212fb1c9d9f094bd423cfe507f8e83b65fddfa8 Mon Sep 17 00:00:00 2001 From: jher235 Date: Tue, 30 Dec 2025 15:09:26 +0900 Subject: [PATCH 02/11] =?UTF-8?q?[#674]=20feat:=20=EC=95=B1=EC=9E=BC=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=20=EC=A0=95=EB=B3=B4=20DTO=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 --- .../appjamuser/AppjamUserInfo.java | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/sopt/app/application/appjamuser/AppjamUserInfo.java b/src/main/java/org/sopt/app/application/appjamuser/AppjamUserInfo.java index 4ad5d23c..43fa5baa 100644 --- a/src/main/java/org/sopt/app/application/appjamuser/AppjamUserInfo.java +++ b/src/main/java/org/sopt/app/application/appjamuser/AppjamUserInfo.java @@ -20,8 +20,8 @@ public static class TeamSummary { private String teamName; public static TeamSummary from(AppjamUser appjamUser) { - return TeamSummary.builder(). - teamNumber(appjamUser.getTeamNumber()) + return TeamSummary.builder() + .teamNumber(appjamUser.getTeamNumber()) .teamName(appjamUser.getTeamName()) .build(); } @@ -31,4 +31,28 @@ public static TeamSummary empty() { .build(); } } + + @Getter + @Builder + @ToString + public static class AppjamUserStatus { + + private TeamNumber teamNumber; + private String teamName; + private boolean isAppjamJoined; + + public static AppjamUserStatus appjamJoined(AppjamUser appjamUser) { + return AppjamUserStatus.builder() + .teamNumber(appjamUser.getTeamNumber()) + .teamName(appjamUser.getTeamName()) + .isAppjamJoined(true) + .build(); + } + + public static AppjamUserStatus appjamNotJoined() { + return AppjamUserStatus.builder() + .isAppjamJoined(false) + .build(); + } + } } From 83d95d8b666b355c0bb778d2c67956f66c8ff46b Mon Sep 17 00:00:00 2001 From: jher235 Date: Tue, 30 Dec 2025 15:10:01 +0900 Subject: [PATCH 03/11] =?UTF-8?q?[#674]=20feat:=20=EC=95=B1=EC=9E=BC?= =?UTF-8?q?=ED=83=AC=ED=94=84=20=EB=AF=B8=EC=85=98=20=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=8B=9C=20=EC=9A=94=EC=B2=AD=ED=95=9C=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=EC=9D=98=20=EC=95=B1=EC=9E=BC=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=EB=A1=9C=20=EB=B0=98=ED=99=98=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/appjamuser/AppjamUserService.java | 13 ++++++++++--- .../sopt/app/application/mission/MissionInfo.java | 6 ++++++ .../java/org/sopt/app/facade/MissionFacade.java | 9 +++++++-- .../appjamtamp/AppjamtampController.java | 3 ++- .../presentation/appjamtamp/AppjamtampResponse.java | 4 ++++ 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/sopt/app/application/appjamuser/AppjamUserService.java b/src/main/java/org/sopt/app/application/appjamuser/AppjamUserService.java index 1e316f7c..6ab8f823 100644 --- a/src/main/java/org/sopt/app/application/appjamuser/AppjamUserService.java +++ b/src/main/java/org/sopt/app/application/appjamuser/AppjamUserService.java @@ -1,10 +1,11 @@ package org.sopt.app.application.appjamuser; import lombok.RequiredArgsConstructor; +import lombok.val; +import org.sopt.app.application.appjamuser.AppjamUserInfo.AppjamUserStatus; import org.sopt.app.application.appjamuser.AppjamUserInfo.TeamSummary; import org.sopt.app.common.exception.NotFoundException; import org.sopt.app.common.response.ErrorCode; -import org.sopt.app.domain.entity.AppjamUser; import org.sopt.app.domain.enums.TeamNumber; import org.sopt.app.interfaces.postgres.AppjamUserRepository; import org.springframework.stereotype.Service; @@ -15,14 +16,20 @@ public class AppjamUserService { private final AppjamUserRepository appjamUserRepository; + public AppjamUserStatus getAppjamUserStatus(Long userId) { + return appjamUserRepository.findByUserId(userId) + .map(AppjamUserStatus::appjamJoined) + .orElseGet(AppjamUserStatus::appjamNotJoined); + } + public TeamSummary getTeamSummaryByTeamNumber(TeamNumber teamNumber) { - AppjamUser appjamUser = appjamUserRepository.findTopByTeamNumberOrderById(teamNumber) + val appjamUser = appjamUserRepository.findTopByTeamNumberOrderById(teamNumber) .orElseThrow(() -> new NotFoundException(ErrorCode.TEAM_NOT_FOUND)); return TeamSummary.from(appjamUser); } public TeamSummary getTeamSummaryByUserId(Long userId) { - AppjamUser appjamUser = appjamUserRepository.findByUserId(userId) + val appjamUser = appjamUserRepository.findByUserId(userId) .orElseThrow(() -> new NotFoundException(ErrorCode.TEAM_NOT_FOUND)); return TeamSummary.from(appjamUser); } diff --git a/src/main/java/org/sopt/app/application/mission/MissionInfo.java b/src/main/java/org/sopt/app/application/mission/MissionInfo.java index c4cc4150..0e8e8c12 100755 --- a/src/main/java/org/sopt/app/application/mission/MissionInfo.java +++ b/src/main/java/org/sopt/app/application/mission/MissionInfo.java @@ -6,6 +6,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.ToString; +import org.sopt.app.application.appjamuser.AppjamUserInfo.AppjamUserStatus; import org.sopt.app.application.appjamuser.AppjamUserInfo.TeamSummary; import org.sopt.app.domain.entity.soptamp.Mission; import org.sopt.app.domain.enums.TeamNumber; @@ -80,15 +81,20 @@ public static AppjamMissionInfo createWhenUncompleted(Mission mission) { @ToString public static class AppjamMissionInfos { + private TeamNumber myTeamNumber; + private boolean isAppjamJoined; private TeamNumber teamNumber; private String teamName; private List missions; public static AppjamMissionInfos of( + AppjamUserStatus appjamUserStatus, TeamSummary teamSummary, List missions ) { return AppjamMissionInfos.builder() + .myTeamNumber(appjamUserStatus.getTeamNumber()) + .isAppjamJoined(appjamUserStatus.isAppjamJoined()) .teamNumber(teamSummary.getTeamNumber()) .teamName(teamSummary.getTeamName()) .missions(missions) diff --git a/src/main/java/org/sopt/app/facade/MissionFacade.java b/src/main/java/org/sopt/app/facade/MissionFacade.java index 7db1be6e..0c551bdb 100644 --- a/src/main/java/org/sopt/app/facade/MissionFacade.java +++ b/src/main/java/org/sopt/app/facade/MissionFacade.java @@ -2,6 +2,7 @@ import lombok.RequiredArgsConstructor; import lombok.val; +import org.sopt.app.application.appjamuser.AppjamUserInfo.AppjamUserStatus; import org.sopt.app.application.appjamuser.AppjamUserInfo.TeamSummary; import org.sopt.app.application.appjamuser.AppjamUserService; import org.sopt.app.application.mission.AppjamMissionService; @@ -22,21 +23,25 @@ public class MissionFacade { @Transactional(readOnly = true) public AppjamMissionInfos getTeamMissions( + Long userId, @Nullable TeamNumber teamNumber, @Nullable Boolean complete ) { if (teamNumber == null) { val missions = appjamMissionService.getDisplayedMissions(); - return AppjamMissionInfos.of(TeamSummary.empty(), missions); + return AppjamMissionInfos.of(AppjamUserStatus.appjamNotJoined(), TeamSummary.empty(), + missions); } val teamSummary = appjamUserService.getTeamSummaryByTeamNumber(teamNumber); + val appjamUserStatus = appjamUserService.getAppjamUserStatus(userId); if (complete != null) { return AppjamMissionInfos.of( + appjamUserStatus, teamSummary, appjamMissionService.getMissionsByTeamAndCondition(teamNumber, complete)); } - return AppjamMissionInfos.of(teamSummary, + return AppjamMissionInfos.of(appjamUserStatus, teamSummary, appjamMissionService.getMissionsByTeam(teamNumber)); } diff --git a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampController.java b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampController.java index 1979472d..a964a387 100644 --- a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampController.java +++ b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampController.java @@ -37,10 +37,11 @@ public class AppjamtampController { }) @GetMapping("/mission") public ResponseEntity getMissions( + @AuthenticationPrincipal Long userId, @RequestParam(required = false) TeamNumber teamNumber, @RequestParam(required = false) Boolean isCompleted ) { - val result = missionFacade.getTeamMissions(teamNumber, isCompleted); + val result = missionFacade.getTeamMissions(userId, teamNumber, isCompleted); val response = appjamtampResponseMapper.of(result); return ResponseEntity.ok(response); } diff --git a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampResponse.java b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampResponse.java index 1ebee5a2..fc90f66c 100644 --- a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampResponse.java +++ b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampResponse.java @@ -38,6 +38,10 @@ public static class AppjamMissionResponse { @AllArgsConstructor(access = AccessLevel.PUBLIC) public static class AppjamMissionResponses { + @Schema(description = "요청자의 팀 번호", example = "FIRST") + private TeamNumber myTeamNumber; + @Schema(description = "앱잼 참여 여부", example = "true") + private boolean isAppjamJoined; @Schema(description = "팀 번호", example = "FIRST") private TeamNumber teamNumber; @Schema(description = "팀 이름", example = "보핏") From f0f045816a01d1082665f821e2a4e3eb96bbde3f Mon Sep 17 00:00:00 2001 From: jher235 Date: Tue, 30 Dec 2025 17:18:13 +0900 Subject: [PATCH 04/11] =?UTF-8?q?[#674]=20refactor:=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=EC=88=98=20=EC=A6=9D=EA=B0=80=20=EB=A1=9C=EC=A7=81=20=ED=8A=B8?= =?UTF-8?q?=EB=9E=9C=EC=9E=AD=EC=85=98=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/sopt/app/application/stamp/StampService.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/sopt/app/application/stamp/StampService.java b/src/main/java/org/sopt/app/application/stamp/StampService.java index a83f8acf..bdd889a1 100755 --- a/src/main/java/org/sopt/app/application/stamp/StampService.java +++ b/src/main/java/org/sopt/app/application/stamp/StampService.java @@ -1,9 +1,9 @@ package org.sopt.app.application.stamp; +import jakarta.validation.Valid; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import jakarta.validation.Valid; import java.util.Objects; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -20,6 +20,7 @@ import org.sopt.app.presentation.stamp.StampRequest.RegisterStampRequest; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; @@ -242,7 +243,8 @@ public int getStampClapCount(Long stampId) { .getClapCount(); } - @Transactional + // TODO: 비동기로 별도 스레드 혹은 이벤트로 처리하도록 변경 + @Transactional(propagation = Propagation.REQUIRES_NEW) public void increaseViewCountById(Long stampId) { stampRepository.increaseViewCount(stampId); } From cd51cfe2b7c8a32761a0deca51870fe15dedb07a Mon Sep 17 00:00:00 2001 From: jher235 Date: Tue, 30 Dec 2025 17:20:26 +0900 Subject: [PATCH 05/11] =?UTF-8?q?[#674]=20feat:=20=EC=95=B1=EC=9E=BC?= =?UTF-8?q?=ED=83=AC=ED=94=84=20=EB=AF=B8=EC=85=98=20=EC=A0=9C=EC=B6=9C=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 --- .../application/stamp/AppjamStampService.java | 41 +++++++++++++++++++ .../sopt/app/application/stamp/StampInfo.java | 15 +++++++ .../sopt/app/common/response/ErrorCode.java | 3 +- .../org/sopt/app/facade/AppjamtampFacade.java | 24 +++++++++++ .../org/sopt/app/facade/MissionFacade.java | 2 - .../interfaces/postgres/StampRepository.java | 2 + .../appjamtamp/AppjamtampRequest.java | 23 +++++++++++ 7 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/sopt/app/application/stamp/AppjamStampService.java diff --git a/src/main/java/org/sopt/app/application/stamp/AppjamStampService.java b/src/main/java/org/sopt/app/application/stamp/AppjamStampService.java new file mode 100644 index 00000000..32859cb4 --- /dev/null +++ b/src/main/java/org/sopt/app/application/stamp/AppjamStampService.java @@ -0,0 +1,41 @@ +package org.sopt.app.application.stamp; + +import lombok.RequiredArgsConstructor; +import lombok.val; +import org.sopt.app.common.exception.BadRequestException; +import org.sopt.app.common.response.ErrorCode; +import org.sopt.app.domain.entity.AppjamUser; +import org.sopt.app.domain.enums.TeamNumber; +import org.sopt.app.interfaces.postgres.AppjamUserRepository; +import org.sopt.app.interfaces.postgres.StampRepository; +import org.sopt.app.presentation.appjamtamp.AppjamtampRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class AppjamStampService { + + private final AppjamUserRepository appjamUserRepository; + private final StampRepository stampRepository; + + @Transactional(readOnly = true) + public void checkDuplicateStamp(TeamNumber teamNumber, Long missionId) { + val appjamUsers = appjamUserRepository.findAllByTeamNumber(teamNumber); + val isDuplicated = stampRepository.existsByUserIdInAndMissionId( + appjamUsers.stream().map(AppjamUser::getId).toList(), missionId); + if (isDuplicated) { + throw new BadRequestException(ErrorCode.DUPLICATE_STAMP); + } + } + + @Transactional + public StampInfo.Stamp uploadStamp( + AppjamtampRequest.RegisterStampRequest stampRequest, + Long userId + ) { + val stamp = stampRequest.toStamp(userId); + val newStamp = stampRepository.save(stamp); + return StampInfo.Stamp.from(newStamp); + } +} diff --git a/src/main/java/org/sopt/app/application/stamp/StampInfo.java b/src/main/java/org/sopt/app/application/stamp/StampInfo.java index acb35286..e597e54c 100755 --- a/src/main/java/org/sopt/app/application/stamp/StampInfo.java +++ b/src/main/java/org/sopt/app/application/stamp/StampInfo.java @@ -30,6 +30,21 @@ public static class Stamp { private LocalDateTime updatedAt; private int clapCount; private int viewCount; + + public static StampInfo.Stamp from(org.sopt.app.domain.entity.soptamp.Stamp stamp) { + return Stamp.builder() + .id(stamp.getId()) + .contents(stamp.getContents()) + .images(stamp.getImages()) + .userId(stamp.getUserId()) + .missionId(stamp.getMissionId()) + .activityDate(stamp.getActivityDate()) + .createdAt(stamp.getCreatedAt()) + .updatedAt(stamp.getUpdatedAt()) + .clapCount(stamp.getClapCount()) + .viewCount(stamp.getViewCount()) + .build(); + } } @Getter diff --git a/src/main/java/org/sopt/app/common/response/ErrorCode.java b/src/main/java/org/sopt/app/common/response/ErrorCode.java index 5b8cc144..bf87fca0 100755 --- a/src/main/java/org/sopt/app/common/response/ErrorCode.java +++ b/src/main/java/org/sopt/app/common/response/ErrorCode.java @@ -61,8 +61,9 @@ public enum ErrorCode { // MISSION MISSION_NOT_FOUND("존재하지 않는 미션입니다.", HttpStatus.NOT_FOUND), - //TEAM + // TEAM TEAM_NOT_FOUND("존재하지 않는 팀입니다.", HttpStatus.NOT_FOUND), + TEAM_FORBIDDEN("해당 팀에 대한 권한이 없습니다.", HttpStatus.FORBIDDEN), // STAMP STAMP_NOT_FOUND("존재하지 않는 스탬프입니다.", HttpStatus.BAD_REQUEST), diff --git a/src/main/java/org/sopt/app/facade/AppjamtampFacade.java b/src/main/java/org/sopt/app/facade/AppjamtampFacade.java index d56ac9ac..da0d5a16 100644 --- a/src/main/java/org/sopt/app/facade/AppjamtampFacade.java +++ b/src/main/java/org/sopt/app/facade/AppjamtampFacade.java @@ -4,12 +4,19 @@ import lombok.RequiredArgsConstructor; import lombok.val; import org.sopt.app.application.appjamuser.AppjamUserService; +import org.sopt.app.application.mission.MissionInfo.Level; +import org.sopt.app.application.mission.MissionService; import org.sopt.app.application.platform.PlatformService; import org.sopt.app.application.soptamp.SoptampUserFinder; +import org.sopt.app.application.soptamp.SoptampUserService; +import org.sopt.app.application.stamp.AppjamStampService; import org.sopt.app.application.stamp.ClapService; import org.sopt.app.application.stamp.StampInfo; import org.sopt.app.application.stamp.StampInfo.AppjamtampView; import org.sopt.app.application.stamp.StampService; +import org.sopt.app.common.exception.BadRequestException; +import org.sopt.app.common.response.ErrorCode; +import org.sopt.app.presentation.appjamtamp.AppjamtampRequest.RegisterStampRequest; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -22,6 +29,9 @@ public class AppjamtampFacade { private final StampService stampService; private final ClapService clapService; private final AppjamUserService appjamUserService; + private final AppjamStampService appjamStampService; + private final SoptampUserService soptampUserService; + private final MissionService missionService; @Transactional(readOnly = true) public AppjamtampView getAppjamtamps(Long requestUserId, Long missionId, String nickname) { @@ -42,4 +52,18 @@ public AppjamtampView getAppjamtamps(Long requestUserId, Long missionId, String teamSummary ); } + + @Transactional + public StampInfo.Stamp uploadStamp(Long userId, RegisterStampRequest registerStampRequest) { + val appjamUserStatus = appjamUserService.getAppjamUserStatus(userId); + if (!appjamUserStatus.isAppjamJoined()) { + throw new BadRequestException(ErrorCode.TEAM_FORBIDDEN); + } + appjamStampService.checkDuplicateStamp(appjamUserStatus.getTeamNumber(), + registerStampRequest.getMissionId()); + val result = appjamStampService.uploadStamp(registerStampRequest, userId); + Level mission = missionService.getMissionLevelById(registerStampRequest.getMissionId()); + soptampUserService.addPointByLevel(userId, mission.getLevel()); + return result; + } } diff --git a/src/main/java/org/sopt/app/facade/MissionFacade.java b/src/main/java/org/sopt/app/facade/MissionFacade.java index 0c551bdb..f5714848 100644 --- a/src/main/java/org/sopt/app/facade/MissionFacade.java +++ b/src/main/java/org/sopt/app/facade/MissionFacade.java @@ -7,7 +7,6 @@ import org.sopt.app.application.appjamuser.AppjamUserService; import org.sopt.app.application.mission.AppjamMissionService; import org.sopt.app.application.mission.MissionInfo.AppjamMissionInfos; -import org.sopt.app.application.mission.MissionService; import org.sopt.app.domain.enums.TeamNumber; import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; @@ -19,7 +18,6 @@ public class MissionFacade { private final AppjamMissionService appjamMissionService; private final AppjamUserService appjamUserService; - private final MissionService missionService; @Transactional(readOnly = true) public AppjamMissionInfos getTeamMissions( diff --git a/src/main/java/org/sopt/app/interfaces/postgres/StampRepository.java b/src/main/java/org/sopt/app/interfaces/postgres/StampRepository.java index 96c3fcfd..34a8089e 100755 --- a/src/main/java/org/sopt/app/interfaces/postgres/StampRepository.java +++ b/src/main/java/org/sopt/app/interfaces/postgres/StampRepository.java @@ -22,6 +22,8 @@ public interface StampRepository extends JpaRepository, StampReposi List findAllByUserIdIn(Collection userIds); + boolean existsByUserIdInAndMissionId(Collection userIds, Long missionId); + @Modifying(clearAutomatically = true, flushAutomatically = true) @Query(""" update Stamp s set s.viewCount = s.viewCount + 1 diff --git a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampRequest.java b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampRequest.java index 97c1d869..532cfa61 100644 --- a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampRequest.java +++ b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampRequest.java @@ -2,10 +2,13 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; +import java.util.List; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; +import org.sopt.app.domain.entity.soptamp.Stamp; +import org.sopt.app.presentation.stamp.StampRequest.BaseStampRequest; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class AppjamtampRequest { @@ -23,4 +26,24 @@ public static class FindStampRequest { private String nickname; } + @Getter + @NoArgsConstructor(access = AccessLevel.PRIVATE) + public static class RegisterStampRequest extends BaseStampRequest { + + public RegisterStampRequest(Long missionId, String image, String contents, + String activityDate) { + super(missionId, image, contents, activityDate); + } + + public Stamp toStamp(Long userId) { + return Stamp.builder() + .contents(this.getContents()) + .images(List.of(this.getImage())) + .missionId(this.getMissionId()) + .activityDate(this.getActivityDate()) + .userId(userId) + .build(); + } + } + } From b9cb920dc5c4859eb1c1336106fd3fbad266c955 Mon Sep 17 00:00:00 2001 From: jher235 Date: Tue, 30 Dec 2025 17:22:37 +0900 Subject: [PATCH 06/11] =?UTF-8?q?[#674]=20feat:=20=EC=95=B1=EC=9E=BC?= =?UTF-8?q?=ED=83=AC=ED=94=84=20=EB=AF=B8=EC=85=98=20=EB=AF=B8=EC=85=98=20?= =?UTF-8?q?=EC=A0=9C=EC=B6=9C=20presentation=20layer=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../appjamtamp/AppjamtampController.java | 19 ++++++++++++ .../appjamtamp/AppjamtampResponse.java | 31 +++++++++++++++++++ .../appjamtamp/AppjamtampResponseMapper.java | 13 +++++--- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampController.java b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampController.java index a964a387..27d00f48 100644 --- a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampController.java +++ b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampController.java @@ -16,6 +16,8 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -61,4 +63,21 @@ public ResponseEntity getMissions( val response = appjamtampResponseMapper.of(result); return ResponseEntity.ok(response); } + + @Operation(summary = "앱잼탬프 스탬프 제출하기") + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "success"), + @ApiResponse(responseCode = "401", description = "duplicate stamp"), + @ApiResponse(responseCode = "403", description = "no team", content = @Content), + @ApiResponse(responseCode = "500", description = "server error", content = @Content) + }) + @PostMapping("/stamp") + public ResponseEntity getMissions( + @AuthenticationPrincipal Long userId, + @Valid @RequestBody AppjamtampRequest.RegisterStampRequest request + ) { + val result = appjamtampFacade.uploadStamp(userId, request); + val response = appjamtampResponseMapper.of(result); + return ResponseEntity.ok(response); + } } \ No newline at end of file diff --git a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampResponse.java b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampResponse.java index fc90f66c..041cf4f2 100644 --- a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampResponse.java +++ b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampResponse.java @@ -48,6 +48,11 @@ public static class AppjamMissionResponses { private String teamName; @Schema(description = "미션 정보") private List missions; + + @JsonProperty("isAppjamJoined") + public boolean isAppjamJoined() { + return isAppjamJoined; + } } @Getter @@ -92,4 +97,30 @@ public boolean isMine() { return isMine; } } + + @Getter + @AllArgsConstructor(access = AccessLevel.PUBLIC) + @NoArgsConstructor(access = AccessLevel.PRIVATE) + @Builder + public static class StampMain { + + @Schema(description = "스탬프 아이디", example = "1") + private Long id; + @Schema(description = "스탬프 내용", example = "모각공했다!") + private String contents; + @Schema(description = "스탬프 이미지", example = "[https://s3.ap-northeast-2.amazonaws.com/example/283aab53-22e3-46da-85ec-146c99f82ed4.jpeg]") + private List images; + @Schema(description = "활동 날짜", example = "2024.04.08") + private String activityDate; + @Schema(description = "스탬프 생성 일시", example = "2023-03-29T18:39:42.106369") + private LocalDateTime createdAt; + @Schema(description = "스탬프 수정 일시", example = "2023-03-29T18:39:42.106369") + private LocalDateTime updatedAt; + @Schema(description = "미션 아이디", example = "3") + private Long missionId; + @Schema(description = "총 박수 횟수", example = "124") + private int clapCount; + @Schema(description = "조회수", example = "58") + private int viewCount; + } } diff --git a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampResponseMapper.java b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampResponseMapper.java index 06d6b2a3..52a1b70d 100644 --- a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampResponseMapper.java +++ b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampResponseMapper.java @@ -1,7 +1,6 @@ package org.sopt.app.presentation.appjamtamp; import java.util.List; - import org.mapstruct.InjectionStrategy; import org.mapstruct.Mapper; import org.mapstruct.Mapping; @@ -9,6 +8,7 @@ import org.sopt.app.application.appjamrank.AppjamRankInfo; import org.sopt.app.application.mission.MissionInfo.AppjamMissionInfo; import org.sopt.app.application.mission.MissionInfo.AppjamMissionInfos; +import org.sopt.app.application.stamp.StampInfo; import org.sopt.app.application.stamp.StampInfo.AppjamtampView; import org.sopt.app.presentation.appjamrank.AppjamRankResponse; import org.sopt.app.presentation.appjamtamp.AppjamtampResponse.AppjamMissionResponse; @@ -21,6 +21,8 @@ ) public interface AppjamtampResponseMapper { + AppjamtampResponse.StampMain of(StampInfo.Stamp stampInfo); + AppjamMissionResponses of(AppjamMissionInfos missionList); AppjamRankResponse.AppjamtampRankResponse toResponse(AppjamRankInfo.TeamRank teamRank); @@ -29,7 +31,8 @@ public interface AppjamtampResponseMapper { @Mapping(source = "completed", target = "isCompleted") AppjamMissionResponse toResponse(AppjamMissionInfo info); - default AppjamRankResponse.AppjamtampRankListResponse of(AppjamRankInfo.RankList appjamRankList) { + default AppjamRankResponse.AppjamtampRankListResponse of( + AppjamRankInfo.RankList appjamRankList) { List ranks = appjamRankList.getRanks().stream() .map(this::toResponse) .toList(); @@ -37,8 +40,10 @@ default AppjamRankResponse.AppjamtampRankListResponse of(AppjamRankInfo.RankList return new AppjamRankResponse.AppjamtampRankListResponse(ranks); } - default AppjamRankResponse.AppjamTodayRankListResponse of(AppjamRankInfo.TodayTeamRankList todayTeamRankList) { - List ranks = todayTeamRankList.getRanks().stream() + default AppjamRankResponse.AppjamTodayRankListResponse of( + AppjamRankInfo.TodayTeamRankList todayTeamRankList) { + List ranks = todayTeamRankList.getRanks() + .stream() .map(teamRank -> new AppjamRankResponse.AppjamTodayTeamRankResponse( teamRank.getRank(), teamRank.getTeamName(), From 7653ec3f6ca239b78047ae6149fb2f8e114bb0f2 Mon Sep 17 00:00:00 2001 From: jher235 Date: Tue, 30 Dec 2025 17:23:31 +0900 Subject: [PATCH 07/11] =?UTF-8?q?[#674]=20feat:=20=EC=95=B1=EC=9E=BC?= =?UTF-8?q?=ED=83=AC=ED=94=84=20=EB=AF=B8=EC=85=98=20=EB=93=B1=EB=A1=9D?= =?UTF-8?q?=EC=9D=98=20isAppjamJoined=20=ED=95=84=EB=93=9C=20=EB=B3=80?= =?UTF-8?q?=ED=99=98=20=EB=AA=85=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/presentation/appjamtamp/AppjamtampResponseMapper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampResponseMapper.java b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampResponseMapper.java index 52a1b70d..974c5d22 100644 --- a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampResponseMapper.java +++ b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampResponseMapper.java @@ -23,6 +23,7 @@ public interface AppjamtampResponseMapper { AppjamtampResponse.StampMain of(StampInfo.Stamp stampInfo); + @Mapping(source = "appjamJoined", target = "isAppjamJoined") AppjamMissionResponses of(AppjamMissionInfos missionList); AppjamRankResponse.AppjamtampRankResponse toResponse(AppjamRankInfo.TeamRank teamRank); From ac0815fa35784e41def732d0f9efcf279aa89957 Mon Sep 17 00:00:00 2001 From: jher235 Date: Tue, 30 Dec 2025 17:52:34 +0900 Subject: [PATCH 08/11] =?UTF-8?q?[#674]=20feat:=20=EC=95=B1=EC=9E=BC=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=A1=B0=ED=9A=8C=20API=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 --- .../org/sopt/app/facade/AppjamtampFacade.java | 5 ++++ .../app/presentation/user/UserController.java | 13 ++++++++- .../app/presentation/user/UserResponse.java | 28 ++++++++++++++++--- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/sopt/app/facade/AppjamtampFacade.java b/src/main/java/org/sopt/app/facade/AppjamtampFacade.java index da0d5a16..c6875fef 100644 --- a/src/main/java/org/sopt/app/facade/AppjamtampFacade.java +++ b/src/main/java/org/sopt/app/facade/AppjamtampFacade.java @@ -3,6 +3,7 @@ import java.util.Objects; import lombok.RequiredArgsConstructor; import lombok.val; +import org.sopt.app.application.appjamuser.AppjamUserInfo.AppjamUserStatus; import org.sopt.app.application.appjamuser.AppjamUserService; import org.sopt.app.application.mission.MissionInfo.Level; import org.sopt.app.application.mission.MissionService; @@ -66,4 +67,8 @@ public StampInfo.Stamp uploadStamp(Long userId, RegisterStampRequest registerSta soptampUserService.addPointByLevel(userId, mission.getLevel()); return result; } + + public AppjamUserStatus getAppjampStatus(Long userId){ + return appjamUserService.getAppjamUserStatus(userId); + } } diff --git a/src/main/java/org/sopt/app/presentation/user/UserController.java b/src/main/java/org/sopt/app/presentation/user/UserController.java index ede57108..4cc19a95 100755 --- a/src/main/java/org/sopt/app/presentation/user/UserController.java +++ b/src/main/java/org/sopt/app/presentation/user/UserController.java @@ -11,7 +11,6 @@ import java.util.Comparator; import java.util.List; import java.util.Optional; - import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import lombok.val; @@ -23,11 +22,13 @@ import org.sopt.app.common.utils.ActivityDurationCalculator; import org.sopt.app.domain.enums.IconType; import org.sopt.app.domain.enums.SoptPart; +import org.sopt.app.facade.AppjamtampFacade; import org.sopt.app.facade.AuthFacade; import org.sopt.app.facade.PokeFacade; import org.sopt.app.facade.RankFacade; import org.sopt.app.facade.SoptampFacade; import org.sopt.app.facade.UserFacade; +import org.sopt.app.presentation.user.UserResponse.AppjamStatusResponse; import org.sopt.app.presentation.user.UserResponse.SoptLog; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; @@ -52,6 +53,7 @@ public class UserController { private final PokeFacade pokeFacade; private final RankFacade rankFacade; private final UserFacade userFacade; + private final AppjamtampFacade appjamtampFacade; private final FortuneService fortuneService; private final PlatformService platformService; @@ -155,4 +157,13 @@ public ResponseEntity getMySoptLog( return ResponseEntity.ok(response); } + + @Operation(summary = "앱잼 팀 정보 조회") + @GetMapping("/appjam-info") + public ResponseEntity getTeamInfo( + @AuthenticationPrincipal Long userId + ) { + val result = appjamtampFacade.getAppjampStatus(userId); + return ResponseEntity.ok(AppjamStatusResponse.from(result)); + } } diff --git a/src/main/java/org/sopt/app/presentation/user/UserResponse.java b/src/main/java/org/sopt/app/presentation/user/UserResponse.java index ea2915ea..217ca11e 100755 --- a/src/main/java/org/sopt/app/presentation/user/UserResponse.java +++ b/src/main/java/org/sopt/app/presentation/user/UserResponse.java @@ -1,21 +1,21 @@ package org.sopt.app.presentation.user; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; import java.util.stream.Collectors; - import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.ToString; +import org.sopt.app.application.appjamuser.AppjamUserInfo.AppjamUserStatus; import org.sopt.app.application.appservice.dto.AppServiceInfo; import org.sopt.app.application.playground.dto.PlaygroundProfileInfo.PlaygroundProfile; import org.sopt.app.domain.enums.SoptPart; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; +import org.sopt.app.domain.enums.TeamNumber; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class UserResponse { @@ -318,4 +318,24 @@ public static MySoptLog ofActive( ); } } + + @Getter + @Builder + @ToString + public static class AppjamStatusResponse { + @Schema(description = "팀 번호") + private TeamNumber teamNumber; + @Schema(description = "팀 이름") + private String teamName; + @Schema(description = "앱잼 참여 여부") + private boolean isAppjamJoined; + + public static AppjamStatusResponse from(AppjamUserStatus appjamUserStatus){ + return AppjamStatusResponse.builder() + .teamNumber(appjamUserStatus.getTeamNumber()) + .teamName(appjamUserStatus.getTeamName()) + .isAppjamJoined(appjamUserStatus.isAppjamJoined()) + .build(); + } + } } From 5f7b73d4d80f8111352024b658d4597f6f6e975b Mon Sep 17 00:00:00 2001 From: jher235 Date: Tue, 30 Dec 2025 18:09:54 +0900 Subject: [PATCH 09/11] =?UTF-8?q?[#674]=20refactor:=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=EB=AA=85=EC=9D=84=20isAppjamJoined=20=EB=A1=9C=20=EB=AA=85?= =?UTF-8?q?=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/sopt/app/presentation/user/UserResponse.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/org/sopt/app/presentation/user/UserResponse.java b/src/main/java/org/sopt/app/presentation/user/UserResponse.java index 217ca11e..8c7d158a 100755 --- a/src/main/java/org/sopt/app/presentation/user/UserResponse.java +++ b/src/main/java/org/sopt/app/presentation/user/UserResponse.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; import java.util.stream.Collectors; @@ -330,6 +331,11 @@ public static class AppjamStatusResponse { @Schema(description = "앱잼 참여 여부") private boolean isAppjamJoined; + @JsonProperty("isAppjamJoined") + public boolean isAppjamJoined() { + return isAppjamJoined; + } + public static AppjamStatusResponse from(AppjamUserStatus appjamUserStatus){ return AppjamStatusResponse.builder() .teamNumber(appjamUserStatus.getTeamNumber()) From e41ec299f18cfa209d564913d3a68fd99f94a25c Mon Sep 17 00:00:00 2001 From: jher235 Date: Wed, 31 Dec 2025 20:06:38 +0900 Subject: [PATCH 10/11] =?UTF-8?q?[#674]=20chore:=20=EC=8A=A4=ED=83=AC?= =?UTF-8?q?=ED=94=84=20=EC=A4=91=EB=B3=B5=20=EC=A0=9C=EC=B6=9C=20swagger?= =?UTF-8?q?=20=EC=97=90=EB=9F=AC=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/presentation/appjamtamp/AppjamtampController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampController.java b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampController.java index 27d00f48..aec75957 100644 --- a/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampController.java +++ b/src/main/java/org/sopt/app/presentation/appjamtamp/AppjamtampController.java @@ -67,12 +67,12 @@ public ResponseEntity getMissions( @Operation(summary = "앱잼탬프 스탬프 제출하기") @ApiResponses({ @ApiResponse(responseCode = "200", description = "success"), - @ApiResponse(responseCode = "401", description = "duplicate stamp"), @ApiResponse(responseCode = "403", description = "no team", content = @Content), + @ApiResponse(responseCode = "409", description = "duplicate stamp", content = @Content), @ApiResponse(responseCode = "500", description = "server error", content = @Content) }) @PostMapping("/stamp") - public ResponseEntity getMissions( + public ResponseEntity registerMissions( @AuthenticationPrincipal Long userId, @Valid @RequestBody AppjamtampRequest.RegisterStampRequest request ) { From 6662ecfd001c71d43f30c91bb078041bc7e2781b Mon Sep 17 00:00:00 2001 From: jher235 Date: Wed, 31 Dec 2025 20:07:24 +0900 Subject: [PATCH 11/11] =?UTF-8?q?[#674]=20fix:=20=EB=AF=B8=EC=85=98=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=20=EC=A0=9C=EC=B6=9C=20=EC=97=AC=EB=B6=80?= =?UTF-8?q?=EB=A5=BC=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8A=94=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=EC=97=90=EC=84=9C=20userId=EA=B0=80=20=EC=95=84?= =?UTF-8?q?=EB=8B=8C=20AppjamUserId=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EA=B3=A0=20=EC=9E=88=EB=8D=98=20=EB=B6=80=EB=B6=84=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 --- .../java/org/sopt/app/application/stamp/AppjamStampService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/sopt/app/application/stamp/AppjamStampService.java b/src/main/java/org/sopt/app/application/stamp/AppjamStampService.java index 32859cb4..981352f6 100644 --- a/src/main/java/org/sopt/app/application/stamp/AppjamStampService.java +++ b/src/main/java/org/sopt/app/application/stamp/AppjamStampService.java @@ -23,7 +23,7 @@ public class AppjamStampService { public void checkDuplicateStamp(TeamNumber teamNumber, Long missionId) { val appjamUsers = appjamUserRepository.findAllByTeamNumber(teamNumber); val isDuplicated = stampRepository.existsByUserIdInAndMissionId( - appjamUsers.stream().map(AppjamUser::getId).toList(), missionId); + appjamUsers.stream().map(AppjamUser::getUserId).toList(), missionId); if (isDuplicated) { throw new BadRequestException(ErrorCode.DUPLICATE_STAMP); }