From 8655f5a8c22449d667c80ac3b4f5daf7d02f6be4 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Mon, 2 Dec 2024 18:18:08 +0900 Subject: [PATCH 01/34] feature: find routine history --- .../repository/routine/RoutineHistoryRepository.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/soptie/server/persistence/repository/routine/RoutineHistoryRepository.java b/src/main/java/com/soptie/server/persistence/repository/routine/RoutineHistoryRepository.java index 4f07f728..350bb6b5 100644 --- a/src/main/java/com/soptie/server/persistence/repository/routine/RoutineHistoryRepository.java +++ b/src/main/java/com/soptie/server/persistence/repository/routine/RoutineHistoryRepository.java @@ -1,11 +1,14 @@ package com.soptie.server.persistence.repository.routine; import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import com.soptie.server.persistence.entity.routine.RoutineHistoryEntity; @@ -18,4 +21,12 @@ public interface RoutineHistoryRepository extends JpaRepository findByMemberIdAndCreatedAt(long memberId, LocalDate date); + + @Query("SELECT r FROM RoutineHistoryEntity r WHERE r.memberId = :memberId " + + "AND r.createdAt BETWEEN :startDateTime AND :endDateTime") + List findAllByMemberIdAndCreatedAtBetween( + @Param("memberId") long memberId, + @Param("startDateTime") LocalDateTime startDateTime, + @Param("endDateTime") LocalDateTime endDateTime + ); } From 28a1f2c515acc1a431d7627791821a75ac470161 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Mon, 2 Dec 2024 18:18:20 +0900 Subject: [PATCH 02/34] feature: find mission history --- .../repository/mission/MissionHistoryRepository.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/soptie/server/persistence/repository/mission/MissionHistoryRepository.java b/src/main/java/com/soptie/server/persistence/repository/mission/MissionHistoryRepository.java index cfbb9272..7456a21c 100644 --- a/src/main/java/com/soptie/server/persistence/repository/mission/MissionHistoryRepository.java +++ b/src/main/java/com/soptie/server/persistence/repository/mission/MissionHistoryRepository.java @@ -1,10 +1,13 @@ package com.soptie.server.persistence.repository.mission; import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import com.soptie.server.persistence.entity.mission.MissionHistoryEntity; @@ -13,4 +16,12 @@ public interface MissionHistoryRepository extends JpaRepository findByMemberIdAndCreatedAt(long memberId, LocalDate date); + + @Query("SELECT m FROM MissionHistoryEntity m WHERE m.memberId = :memberId " + + "AND m.createdAt BETWEEN :startDateTime AND :endDateTime") + List findAllByMemberIdAndCreatedAtBetween( + @Param("memberId") long memberId, + @Param("startDateTime") LocalDateTime startDateTime, + @Param("endDateTime") LocalDateTime endDateTime + ); } From db0bfe371f0283245b31b27e037b40ae845591e7 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Mon, 2 Dec 2024 18:18:33 +0900 Subject: [PATCH 03/34] feature: find memo --- .../server/persistence/repository/MemoRepository.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/soptie/server/persistence/repository/MemoRepository.java b/src/main/java/com/soptie/server/persistence/repository/MemoRepository.java index 1bcc96be..c0be049b 100644 --- a/src/main/java/com/soptie/server/persistence/repository/MemoRepository.java +++ b/src/main/java/com/soptie/server/persistence/repository/MemoRepository.java @@ -1,8 +1,12 @@ package com.soptie.server.persistence.repository; +import java.time.LocalDate; +import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import com.soptie.server.persistence.entity.MemoEntity; @@ -10,4 +14,11 @@ public interface MemoRepository extends JpaRepository { Optional findByIdAndMemberId(long id, long memberId); void deleteByIdAndMemberId(long id, long memberId); + + @Query("SELECT m FROM MemoEntity m WHERE m.memberId = :memberId AND m.achievedDate BETWEEN :startDate AND :endDate") + List findAllByMemberIdAndAchievedDateBetween( + @Param("memberId") long memberId, + @Param("startDate") LocalDate startDate, + @Param("endDate") LocalDate endDate + ); } From 636d71a5c60ccfce04d6de991cdc729a0fd44f6d Mon Sep 17 00:00:00 2001 From: Chan531 Date: Mon, 2 Dec 2024 18:18:51 +0900 Subject: [PATCH 04/34] feature: add routine id --- .../entity/routine/RoutineHistoryEntity.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/soptie/server/persistence/entity/routine/RoutineHistoryEntity.java b/src/main/java/com/soptie/server/persistence/entity/routine/RoutineHistoryEntity.java index ed927ada..84eff587 100644 --- a/src/main/java/com/soptie/server/persistence/entity/routine/RoutineHistoryEntity.java +++ b/src/main/java/com/soptie/server/persistence/entity/routine/RoutineHistoryEntity.java @@ -1,5 +1,6 @@ package com.soptie.server.persistence.entity.routine; +import com.soptie.server.domain.memberroutine.RoutineHistory; import com.soptie.server.persistence.entity.BaseEntity; import jakarta.persistence.Entity; @@ -13,9 +14,21 @@ public class RoutineHistoryEntity extends BaseEntity { private long memberRoutineId; private long memberId; + private long routineId; - public RoutineHistoryEntity(long memberRoutineId, long memberId) { + public RoutineHistoryEntity(long memberRoutineId, long memberId, long routineId) { this.memberRoutineId = memberRoutineId; this.memberId = memberId; + this.routineId = routineId; + } + + public RoutineHistory toDomain() { + return RoutineHistory.builder() + .id(this.id) + .memberRoutineId(this.memberRoutineId) + .memberId(this.memberId) + .routineId(this.routineId) + .createdAt(this.createdAt) + .build(); } } From 7d43007a9b63b595cd98f218b12a57d2e2e5c851 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Mon, 2 Dec 2024 18:19:00 +0900 Subject: [PATCH 05/34] feature: add mission id --- .../entity/mission/MissionHistoryEntity.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/soptie/server/persistence/entity/mission/MissionHistoryEntity.java b/src/main/java/com/soptie/server/persistence/entity/mission/MissionHistoryEntity.java index 66e7c49d..049feed8 100644 --- a/src/main/java/com/soptie/server/persistence/entity/mission/MissionHistoryEntity.java +++ b/src/main/java/com/soptie/server/persistence/entity/mission/MissionHistoryEntity.java @@ -1,5 +1,6 @@ package com.soptie.server.persistence.entity.mission; +import com.soptie.server.domain.membermission.MissionHistory; import com.soptie.server.persistence.entity.BaseEntity; import jakarta.persistence.Entity; @@ -13,9 +14,21 @@ public class MissionHistoryEntity extends BaseEntity { private long memberMissionId; private long memberId; + private long missionId; - public MissionHistoryEntity(long memberMissionId, long memberId) { + public MissionHistoryEntity(long memberMissionId, long memberId, long missionId) { this.memberMissionId = memberMissionId; this.memberId = memberId; + this.missionId = missionId; + } + + public MissionHistory toDomain() { + return MissionHistory.builder() + .id(this.id) + .id(this.memberMissionId) + .memberId(this.memberId) + .missionId(this.missionId) + .createdAt(this.createdAt) + .build(); } } From d375c5969c97f0e7227f4a9b89666d4fcc2b97c4 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Mon, 2 Dec 2024 18:19:15 +0900 Subject: [PATCH 06/34] feature: find missions --- .../persistence/repository/mission/MissionRepository.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/soptie/server/persistence/repository/mission/MissionRepository.java b/src/main/java/com/soptie/server/persistence/repository/mission/MissionRepository.java index b8b2b6ba..09d92cfa 100644 --- a/src/main/java/com/soptie/server/persistence/repository/mission/MissionRepository.java +++ b/src/main/java/com/soptie/server/persistence/repository/mission/MissionRepository.java @@ -8,4 +8,6 @@ public interface MissionRepository extends JpaRepository { List findByChallengeIdIn(List challengeIds); + + List findByIdIn(List ids); } From 3fba8ba16fb272dbaaae11bf96fa344c27c5314a Mon Sep 17 00:00:00 2001 From: Chan531 Date: Mon, 2 Dec 2024 18:19:43 +0900 Subject: [PATCH 07/34] feature: find routine history list --- .../adapter/routine/RoutineHistoryAdapter.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/soptie/server/persistence/adapter/routine/RoutineHistoryAdapter.java b/src/main/java/com/soptie/server/persistence/adapter/routine/RoutineHistoryAdapter.java index 17130f6d..08e874ae 100644 --- a/src/main/java/com/soptie/server/persistence/adapter/routine/RoutineHistoryAdapter.java +++ b/src/main/java/com/soptie/server/persistence/adapter/routine/RoutineHistoryAdapter.java @@ -1,9 +1,13 @@ package com.soptie.server.persistence.adapter.routine; import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; import org.springframework.stereotype.Component; +import com.soptie.server.domain.memberroutine.MemberRoutine; +import com.soptie.server.domain.memberroutine.RoutineHistory; import com.soptie.server.persistence.entity.routine.RoutineHistoryEntity; import com.soptie.server.persistence.repository.routine.RoutineHistoryRepository; @@ -14,8 +18,9 @@ public class RoutineHistoryAdapter { private final RoutineHistoryRepository historyRepository; - public void save(long memberRoutineId, long memberId) { - historyRepository.save(new RoutineHistoryEntity(memberRoutineId, memberId)); + public void save(final MemberRoutine memberRoutine) { + historyRepository.save(new RoutineHistoryEntity(memberRoutine.getId(), memberRoutine.getMemberId(), + memberRoutine.getRoutineId())); } public void deleteByRoutineIdAndCreatedAt(long memberRoutineId, LocalDate date) { @@ -29,4 +34,13 @@ public void deleteById(long id) { public boolean isExistByMemberIdAndCreatedAt(final long memberId, final LocalDate date) { return historyRepository.findByMemberIdAndCreatedAt(memberId, date).isPresent(); } + + public List findAllByMemberIdAndCreatedAtBetween( + final long memberId, + final LocalDateTime startDateTime, + final LocalDateTime endDateTime + ) { + return historyRepository.findAllByMemberIdAndCreatedAtBetween(memberId, startDateTime, endDateTime).stream() + .map(RoutineHistoryEntity::toDomain).toList(); + } } From e97a6254c16add210bdffd720d05041b5e79ed5d Mon Sep 17 00:00:00 2001 From: Chan531 Date: Mon, 2 Dec 2024 18:19:56 +0900 Subject: [PATCH 08/34] feature: find mission history list --- .../adapter/mission/MissionHistoryAdapter.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/soptie/server/persistence/adapter/mission/MissionHistoryAdapter.java b/src/main/java/com/soptie/server/persistence/adapter/mission/MissionHistoryAdapter.java index b1b77f39..821a9717 100644 --- a/src/main/java/com/soptie/server/persistence/adapter/mission/MissionHistoryAdapter.java +++ b/src/main/java/com/soptie/server/persistence/adapter/mission/MissionHistoryAdapter.java @@ -1,10 +1,13 @@ package com.soptie.server.persistence.adapter.mission; import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; import org.springframework.stereotype.Component; import com.soptie.server.domain.membermission.MemberMission; +import com.soptie.server.domain.membermission.MissionHistory; import com.soptie.server.persistence.entity.mission.MissionHistoryEntity; import com.soptie.server.persistence.repository.mission.MissionHistoryRepository; @@ -16,7 +19,8 @@ public class MissionHistoryAdapter { private final MissionHistoryRepository historyRepository; public void save(final MemberMission memberMission) { - historyRepository.save(new MissionHistoryEntity(memberMission.getMissionId(), memberMission.getMemberId())); + historyRepository.save(new MissionHistoryEntity(memberMission.getMissionId(), memberMission.getMemberId(), + memberMission.getMissionId())); } public void deleteById(long historyId) { @@ -26,4 +30,13 @@ public void deleteById(long historyId) { public boolean isExistByMemberIdAndCreatedAt(final long memberId, final LocalDate date) { return historyRepository.findByMemberIdAndCreatedAt(memberId, date).isPresent(); } + + public List findAllByMemberIdAndCreatedAtBetween( + final long memberId, + final LocalDateTime startDateTime, + final LocalDateTime endDateTime + ) { + return historyRepository.findAllByMemberIdAndCreatedAtBetween(memberId, startDateTime, endDateTime).stream() + .map(MissionHistoryEntity::toDomain).toList(); + } } From 52ed9ea188115fd1476b576d2ed924811749484d Mon Sep 17 00:00:00 2001 From: Chan531 Date: Mon, 2 Dec 2024 18:20:08 +0900 Subject: [PATCH 09/34] feature: find mission list --- .../server/persistence/adapter/mission/MissionAdapter.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/soptie/server/persistence/adapter/mission/MissionAdapter.java b/src/main/java/com/soptie/server/persistence/adapter/mission/MissionAdapter.java index 32436adf..6e0eb886 100644 --- a/src/main/java/com/soptie/server/persistence/adapter/mission/MissionAdapter.java +++ b/src/main/java/com/soptie/server/persistence/adapter/mission/MissionAdapter.java @@ -26,6 +26,10 @@ public Mission findById(long missionId) { return find(missionId).toDomain(); } + public List findByIds(List ids) { + return missionRepository.findByIdIn(ids).stream().map(MissionEntity::toDomain).toList(); + } + private MissionEntity find(long id) { return missionRepository.findById(id) .orElseThrow(() -> new SoftieException(ExceptionCode.NOT_FOUND, "Mission ID: " + id)); From 37ed54a7c61c9365d7abd2593961af7395465e72 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Mon, 2 Dec 2024 18:20:16 +0900 Subject: [PATCH 10/34] feature: find memo list --- .../soptie/server/persistence/adapter/MemoAdapter.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/com/soptie/server/persistence/adapter/MemoAdapter.java b/src/main/java/com/soptie/server/persistence/adapter/MemoAdapter.java index 4d7ee415..5d0923d1 100644 --- a/src/main/java/com/soptie/server/persistence/adapter/MemoAdapter.java +++ b/src/main/java/com/soptie/server/persistence/adapter/MemoAdapter.java @@ -1,6 +1,7 @@ package com.soptie.server.persistence.adapter; import java.time.LocalDate; +import java.util.List; import com.soptie.server.common.exception.ExceptionCode; import com.soptie.server.common.exception.SoftieException; @@ -46,6 +47,15 @@ public Memo findById(final long memoId) { " Memo ID: " + memoId)).toDomain(); } + public List findAllByMemberIdAndAchievedDateBetween( + final long memberId, + final LocalDate startDate, + final LocalDate endDate + ) { + return memoRepository.findAllByMemberIdAndAchievedDateBetween(memberId, startDate, endDate).stream() + .map(MemoEntity::toDomain).toList(); + } + private MemoEntity find(final long id) { return memoRepository.findById(id) .orElseThrow(() -> new SoftieException(ExceptionCode.NOT_FOUND, "Memo ID: " + id)); From 0d62f56c292cb4375ee1145d184d455af9f26d34 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Mon, 2 Dec 2024 18:20:44 +0900 Subject: [PATCH 11/34] feature: mission history domain --- .../domain/membermission/MissionHistory.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/main/java/com/soptie/server/domain/membermission/MissionHistory.java diff --git a/src/main/java/com/soptie/server/domain/membermission/MissionHistory.java b/src/main/java/com/soptie/server/domain/membermission/MissionHistory.java new file mode 100644 index 00000000..76e04709 --- /dev/null +++ b/src/main/java/com/soptie/server/domain/membermission/MissionHistory.java @@ -0,0 +1,16 @@ +package com.soptie.server.domain.membermission; + +import java.time.LocalDateTime; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class MissionHistory { + private Long id; + private long memberMissionId; + private long memberId; + private long missionId; + private LocalDateTime createdAt; +} From 5d073456b7488d6febe9d8ffa6693db04885af90 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Mon, 2 Dec 2024 18:20:54 +0900 Subject: [PATCH 12/34] feature: routine history domain --- .../domain/memberroutine/RoutineHistory.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/main/java/com/soptie/server/domain/memberroutine/RoutineHistory.java diff --git a/src/main/java/com/soptie/server/domain/memberroutine/RoutineHistory.java b/src/main/java/com/soptie/server/domain/memberroutine/RoutineHistory.java new file mode 100644 index 00000000..c7899f86 --- /dev/null +++ b/src/main/java/com/soptie/server/domain/memberroutine/RoutineHistory.java @@ -0,0 +1,16 @@ +package com.soptie.server.domain.memberroutine; + +import java.time.LocalDateTime; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class RoutineHistory { + private Long id; + private long memberRoutineId; + private long memberId; + private long routineId; + private LocalDateTime createdAt; +} From 4ccb88eb65a16cbe2cc51aa91bbf994c491fe2ea Mon Sep 17 00:00:00 2001 From: Chan531 Date: Mon, 2 Dec 2024 18:21:09 +0900 Subject: [PATCH 13/34] refactor: change parameter --- .../domain/memberroutine/MemberRoutineService.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutineService.java b/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutineService.java index 641bed35..fcc2adb7 100644 --- a/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutineService.java +++ b/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutineService.java @@ -88,16 +88,16 @@ public AchieveMemberRoutineResponse achieveMemberRoutine(long memberId, long mem memberRoutine.achieve(); memberRoutineAdapter.update(memberRoutine); - updateHistory(memberRoutineId, isAchievedToday, memberId); + updateHistory(memberRoutine); return AchieveMemberRoutineResponse.of(memberRoutine, !isAchievedToday); } - private void updateHistory(long memberRoutineId, boolean isAchievedToday, long memberId) { - if (isAchievedToday) { - routineHistoryAdapter.deleteByRoutineIdAndCreatedAt(memberRoutineId, LocalDate.now()); + private void updateHistory(MemberRoutine memberRoutine) { + if (memberRoutine.isAchievedToday()) { + routineHistoryAdapter.deleteByRoutineIdAndCreatedAt(memberRoutine.getId(), LocalDate.now()); } else { - routineHistoryAdapter.save(memberRoutineId, memberId); + routineHistoryAdapter.save(memberRoutine); } } From d2ec454f488bc5a2c6e2cee2ab9033ad43681ba3 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Tue, 3 Dec 2024 01:52:18 +0900 Subject: [PATCH 14/34] feature: add content --- .../server/domain/membermission/MemberMissionService.java | 3 ++- .../server/domain/membermission/MissionHistory.java | 1 + .../server/domain/memberroutine/MemberRoutineService.java | 8 +++++--- .../server/domain/memberroutine/RoutineHistory.java | 1 + .../adapter/mission/MissionHistoryAdapter.java | 4 ++-- .../adapter/routine/RoutineHistoryAdapter.java | 5 +++-- .../persistence/entity/mission/MissionHistoryEntity.java | 5 ++++- .../persistence/entity/routine/RoutineHistoryEntity.java | 5 ++++- 8 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/soptie/server/domain/membermission/MemberMissionService.java b/src/main/java/com/soptie/server/domain/membermission/MemberMissionService.java index 500d2bb3..8864341a 100644 --- a/src/main/java/com/soptie/server/domain/membermission/MemberMissionService.java +++ b/src/main/java/com/soptie/server/domain/membermission/MemberMissionService.java @@ -64,13 +64,14 @@ public void achieveMemberMission(long memberId, long missionId) { ExceptionCode.NOT_AVAILABLE, "Member ID: " + memberId + ", Mission ID: " + missionId); } + val mission = missionAdapter.findById(missionId); member.getCottonInfo().addRainbowCottonCount(); memberAdapter.update(member); memberMission.achieve(); memberMissionAdapter.update(memberMission); memberMissionAdapter.flush(); memberMissionAdapter.delete(memberMission); - missionHistoryAdapter.save(memberMission); + missionHistoryAdapter.save(memberMission, mission.getContent()); } public Optional getMemberMission(long memberId) { diff --git a/src/main/java/com/soptie/server/domain/membermission/MissionHistory.java b/src/main/java/com/soptie/server/domain/membermission/MissionHistory.java index 76e04709..58c5b67d 100644 --- a/src/main/java/com/soptie/server/domain/membermission/MissionHistory.java +++ b/src/main/java/com/soptie/server/domain/membermission/MissionHistory.java @@ -12,5 +12,6 @@ public class MissionHistory { private long memberMissionId; private long memberId; private long missionId; + private String content; private LocalDateTime createdAt; } diff --git a/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutineService.java b/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutineService.java index fcc2adb7..8ad1c3b9 100644 --- a/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutineService.java +++ b/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutineService.java @@ -81,6 +81,8 @@ public AchieveMemberRoutineResponse achieveMemberRoutine(long memberId, long mem "Member ID: " + memberId + ", MemberRoutine ID: " + memberRoutineId); } + val routine = routineAdapter.findById(memberRoutine.getRoutineId()); + if (!isAchievedToday) { member.getCottonInfo().addBasicCottonCount(); memberAdapter.update(member); @@ -88,16 +90,16 @@ public AchieveMemberRoutineResponse achieveMemberRoutine(long memberId, long mem memberRoutine.achieve(); memberRoutineAdapter.update(memberRoutine); - updateHistory(memberRoutine); + updateHistory(memberRoutine, routine); return AchieveMemberRoutineResponse.of(memberRoutine, !isAchievedToday); } - private void updateHistory(MemberRoutine memberRoutine) { + private void updateHistory(MemberRoutine memberRoutine, Routine routine) { if (memberRoutine.isAchievedToday()) { routineHistoryAdapter.deleteByRoutineIdAndCreatedAt(memberRoutine.getId(), LocalDate.now()); } else { - routineHistoryAdapter.save(memberRoutine); + routineHistoryAdapter.save(memberRoutine, routine); } } diff --git a/src/main/java/com/soptie/server/domain/memberroutine/RoutineHistory.java b/src/main/java/com/soptie/server/domain/memberroutine/RoutineHistory.java index c7899f86..157c5548 100644 --- a/src/main/java/com/soptie/server/domain/memberroutine/RoutineHistory.java +++ b/src/main/java/com/soptie/server/domain/memberroutine/RoutineHistory.java @@ -12,5 +12,6 @@ public class RoutineHistory { private long memberRoutineId; private long memberId; private long routineId; + private String content; private LocalDateTime createdAt; } diff --git a/src/main/java/com/soptie/server/persistence/adapter/mission/MissionHistoryAdapter.java b/src/main/java/com/soptie/server/persistence/adapter/mission/MissionHistoryAdapter.java index 821a9717..9b49e293 100644 --- a/src/main/java/com/soptie/server/persistence/adapter/mission/MissionHistoryAdapter.java +++ b/src/main/java/com/soptie/server/persistence/adapter/mission/MissionHistoryAdapter.java @@ -18,9 +18,9 @@ public class MissionHistoryAdapter { private final MissionHistoryRepository historyRepository; - public void save(final MemberMission memberMission) { + public void save(final MemberMission memberMission, final String content) { historyRepository.save(new MissionHistoryEntity(memberMission.getMissionId(), memberMission.getMemberId(), - memberMission.getMissionId())); + memberMission.getMissionId(), content)); } public void deleteById(long historyId) { diff --git a/src/main/java/com/soptie/server/persistence/adapter/routine/RoutineHistoryAdapter.java b/src/main/java/com/soptie/server/persistence/adapter/routine/RoutineHistoryAdapter.java index 08e874ae..b2063220 100644 --- a/src/main/java/com/soptie/server/persistence/adapter/routine/RoutineHistoryAdapter.java +++ b/src/main/java/com/soptie/server/persistence/adapter/routine/RoutineHistoryAdapter.java @@ -8,6 +8,7 @@ import com.soptie.server.domain.memberroutine.MemberRoutine; import com.soptie.server.domain.memberroutine.RoutineHistory; +import com.soptie.server.domain.routine.Routine; import com.soptie.server.persistence.entity.routine.RoutineHistoryEntity; import com.soptie.server.persistence.repository.routine.RoutineHistoryRepository; @@ -18,9 +19,9 @@ public class RoutineHistoryAdapter { private final RoutineHistoryRepository historyRepository; - public void save(final MemberRoutine memberRoutine) { + public void save(final MemberRoutine memberRoutine, final Routine routine) { historyRepository.save(new RoutineHistoryEntity(memberRoutine.getId(), memberRoutine.getMemberId(), - memberRoutine.getRoutineId())); + memberRoutine.getRoutineId(), routine.getContent())); } public void deleteByRoutineIdAndCreatedAt(long memberRoutineId, LocalDate date) { diff --git a/src/main/java/com/soptie/server/persistence/entity/mission/MissionHistoryEntity.java b/src/main/java/com/soptie/server/persistence/entity/mission/MissionHistoryEntity.java index 049feed8..0f0871d9 100644 --- a/src/main/java/com/soptie/server/persistence/entity/mission/MissionHistoryEntity.java +++ b/src/main/java/com/soptie/server/persistence/entity/mission/MissionHistoryEntity.java @@ -15,11 +15,13 @@ public class MissionHistoryEntity extends BaseEntity { private long memberMissionId; private long memberId; private long missionId; + private String content; - public MissionHistoryEntity(long memberMissionId, long memberId, long missionId) { + public MissionHistoryEntity(long memberMissionId, long memberId, long missionId, String content) { this.memberMissionId = memberMissionId; this.memberId = memberId; this.missionId = missionId; + this.content = content; } public MissionHistory toDomain() { @@ -28,6 +30,7 @@ public MissionHistory toDomain() { .id(this.memberMissionId) .memberId(this.memberId) .missionId(this.missionId) + .content(this.content) .createdAt(this.createdAt) .build(); } diff --git a/src/main/java/com/soptie/server/persistence/entity/routine/RoutineHistoryEntity.java b/src/main/java/com/soptie/server/persistence/entity/routine/RoutineHistoryEntity.java index 84eff587..465bc7f4 100644 --- a/src/main/java/com/soptie/server/persistence/entity/routine/RoutineHistoryEntity.java +++ b/src/main/java/com/soptie/server/persistence/entity/routine/RoutineHistoryEntity.java @@ -15,11 +15,13 @@ public class RoutineHistoryEntity extends BaseEntity { private long memberRoutineId; private long memberId; private long routineId; + private String content; - public RoutineHistoryEntity(long memberRoutineId, long memberId, long routineId) { + public RoutineHistoryEntity(long memberRoutineId, long memberId, long routineId, String content) { this.memberRoutineId = memberRoutineId; this.memberId = memberId; this.routineId = routineId; + this.content = content; } public RoutineHistory toDomain() { @@ -28,6 +30,7 @@ public RoutineHistory toDomain() { .memberRoutineId(this.memberRoutineId) .memberId(this.memberId) .routineId(this.routineId) + .content(this.content) .createdAt(this.createdAt) .build(); } From dd482e072b3a231361cd70f8df4c44dba91b6dfc Mon Sep 17 00:00:00 2001 From: Chan531 Date: Tue, 3 Dec 2024 02:37:51 +0900 Subject: [PATCH 15/34] fix: id save error --- .../persistence/adapter/mission/MissionHistoryAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/soptie/server/persistence/adapter/mission/MissionHistoryAdapter.java b/src/main/java/com/soptie/server/persistence/adapter/mission/MissionHistoryAdapter.java index 9b49e293..99117839 100644 --- a/src/main/java/com/soptie/server/persistence/adapter/mission/MissionHistoryAdapter.java +++ b/src/main/java/com/soptie/server/persistence/adapter/mission/MissionHistoryAdapter.java @@ -19,7 +19,7 @@ public class MissionHistoryAdapter { private final MissionHistoryRepository historyRepository; public void save(final MemberMission memberMission, final String content) { - historyRepository.save(new MissionHistoryEntity(memberMission.getMissionId(), memberMission.getMemberId(), + historyRepository.save(new MissionHistoryEntity(memberMission.getId(), memberMission.getMemberId(), memberMission.getMissionId(), content)); } From b6232a91c14b24b9cd68eef632890467f4c980c6 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Tue, 3 Dec 2024 14:53:36 +0900 Subject: [PATCH 16/34] fix: save routine history error --- .../server/domain/memberroutine/MemberRoutineService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutineService.java b/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutineService.java index 8ad1c3b9..0422cad2 100644 --- a/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutineService.java +++ b/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutineService.java @@ -90,13 +90,13 @@ public AchieveMemberRoutineResponse achieveMemberRoutine(long memberId, long mem memberRoutine.achieve(); memberRoutineAdapter.update(memberRoutine); - updateHistory(memberRoutine, routine); + updateHistory(memberRoutine, routine, isAchievedToday); return AchieveMemberRoutineResponse.of(memberRoutine, !isAchievedToday); } - private void updateHistory(MemberRoutine memberRoutine, Routine routine) { - if (memberRoutine.isAchievedToday()) { + private void updateHistory(MemberRoutine memberRoutine, Routine routine, boolean isAchievedToday) { + if (isAchievedToday) { routineHistoryAdapter.deleteByRoutineIdAndCreatedAt(memberRoutine.getId(), LocalDate.now()); } else { routineHistoryAdapter.save(memberRoutine, routine); From 2a225f760f0db8091b256a2cf2b4f5b84ae1153a Mon Sep 17 00:00:00 2001 From: Chan531 Date: Tue, 3 Dec 2024 15:53:25 +0900 Subject: [PATCH 17/34] feature: add error response data --- .../server/api/controller/dto/response/ErrorResponse.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/soptie/server/api/controller/dto/response/ErrorResponse.java b/src/main/java/com/soptie/server/api/controller/dto/response/ErrorResponse.java index 00dcf93b..6f486b80 100644 --- a/src/main/java/com/soptie/server/api/controller/dto/response/ErrorResponse.java +++ b/src/main/java/com/soptie/server/api/controller/dto/response/ErrorResponse.java @@ -1,6 +1,7 @@ package com.soptie.server.api.controller.dto.response; -import static lombok.AccessLevel.*; +import static com.soptie.server.common.support.ValueConfig.BLANK; +import static lombok.AccessLevel.PRIVATE; import jakarta.validation.constraints.NotNull; import lombok.Builder; @@ -8,13 +9,15 @@ @Builder(access = PRIVATE) public record ErrorResponse( boolean success, - @NotNull String message + @NotNull String message, + @NotNull String data ) implements BaseResponse { public static ErrorResponse of(String message) { return ErrorResponse.builder() .success(false) .message(message) + .data(BLANK) .build(); } } From 9ed06d3ebb844706e35d90c63408df00b99684ca Mon Sep 17 00:00:00 2001 From: Chan531 Date: Tue, 3 Dec 2024 15:54:00 +0900 Subject: [PATCH 18/34] feature: add success message get calendar --- .../soptie/server/api/controller/generic/SuccessMessage.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/soptie/server/api/controller/generic/SuccessMessage.java b/src/main/java/com/soptie/server/api/controller/generic/SuccessMessage.java index 682689a0..3f007671 100644 --- a/src/main/java/com/soptie/server/api/controller/generic/SuccessMessage.java +++ b/src/main/java/com/soptie/server/api/controller/generic/SuccessMessage.java @@ -38,6 +38,9 @@ public enum SuccessMessage { UPDATE_MEMO("메모 수정 성공"), DELETE_MEMO("메모 삭제 성공"), + /* calendar */ + GET_CALENDAR("캘린더 조회 성공"), + /* version */ GET_VERSION("버전 조회 성공"); From b244fae8447a5d3a7e801afd5be29f5fe3693a17 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Tue, 3 Dec 2024 16:38:33 +0900 Subject: [PATCH 19/34] feature: equals and hashcode --- .../com/soptie/server/domain/theme/Theme.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/main/java/com/soptie/server/domain/theme/Theme.java b/src/main/java/com/soptie/server/domain/theme/Theme.java index 1b8c0490..1e5b8c86 100644 --- a/src/main/java/com/soptie/server/domain/theme/Theme.java +++ b/src/main/java/com/soptie/server/domain/theme/Theme.java @@ -1,5 +1,7 @@ package com.soptie.server.domain.theme; +import java.util.Objects; + import jakarta.validation.constraints.NotNull; import lombok.Builder; import lombok.Getter; @@ -16,4 +18,23 @@ public class Theme { private String description; private int sequence; private Long makerId; + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + Theme theme = (Theme)obj; + return sequence == theme.sequence && Objects.equals(id, theme.id) && Objects.equals(name, + theme.name) && Objects.equals(comment, theme.comment) && Objects.equals(description, + theme.description) && Objects.equals(makerId, theme.makerId); + } + + @Override + public int hashCode() { + return Objects.hash(id, name, comment, description, sequence, makerId); + } } From ee9e96f6815dc9c5ce955f6bb2e135033d59e34d Mon Sep 17 00:00:00 2001 From: Chan531 Date: Tue, 3 Dec 2024 16:39:02 +0900 Subject: [PATCH 20/34] feature: add note null value --- src/main/java/com/soptie/server/common/support/ValueConfig.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/soptie/server/common/support/ValueConfig.java b/src/main/java/com/soptie/server/common/support/ValueConfig.java index 4d6f2926..61457b67 100644 --- a/src/main/java/com/soptie/server/common/support/ValueConfig.java +++ b/src/main/java/com/soptie/server/common/support/ValueConfig.java @@ -50,6 +50,7 @@ public class ValueConfig { public static final int DAILY_ROUTINE_MAX_COUNT = 3; public static final String MEMBER_DOLL_CONDITION = "^[ㄱ-ㅎㅏ-ㅣ가-힣a-zA-Z]{1,10}$"; public static final long MEMBER_HAS_NOT_CHALLENGE = 0; + public static final long MEMBER_HAS_NOT_MEMO = 0; @PostConstruct protected void init() { From 616f9fddff5dda773da3d266b9d712347d4da2ef Mon Sep 17 00:00:00 2001 From: Chan531 Date: Tue, 3 Dec 2024 16:40:05 +0900 Subject: [PATCH 21/34] feature: date history response --- .../calendar/DateHistoryResponse.java | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/main/java/com/soptie/server/api/controller/dto/response/calendar/DateHistoryResponse.java diff --git a/src/main/java/com/soptie/server/api/controller/dto/response/calendar/DateHistoryResponse.java b/src/main/java/com/soptie/server/api/controller/dto/response/calendar/DateHistoryResponse.java new file mode 100644 index 00000000..d563c04f --- /dev/null +++ b/src/main/java/com/soptie/server/api/controller/dto/response/calendar/DateHistoryResponse.java @@ -0,0 +1,126 @@ +package com.soptie.server.api.controller.dto.response.calendar; + +import static lombok.AccessLevel.PRIVATE; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.soptie.server.domain.membermission.MissionHistory; +import com.soptie.server.domain.memberroutine.RoutineHistory; +import com.soptie.server.domain.theme.Theme; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Builder; +import lombok.val; + +@Builder(access = PRIVATE) +public record DateHistoryResponse( + @Schema(description = "메모 아이디 (null일 시, -1)", example = "1") + long memoId, + @Schema(description = "메모 내용", example = "이것은 메모가 아니다.") + @NotNull String memoContent, + @Schema(description = "테마와 달성 기록 정보") + @NotNull List histories +) { + + public static DateHistoryResponse of( + final long memoId, + final String memoContent, + final Map> routines, + final Map> missions + ) { + return DateHistoryResponse.builder() + .memoId(memoId) + .memoContent(memoContent) + .histories(toHistories(routines, missions)) + .build(); + } + + private static List toHistories( + final Map> routines, + final Map> missions + ) { + val histories = getHistories(routines, missions); + return histories.values().stream().toList(); + } + + private static Map getHistories( + final Map> routines, + final Map> missions + ) { + return Stream.concat(routines.keySet().stream(), missions.keySet().stream()) + .distinct() + .collect(Collectors.toMap( + theme -> theme, + theme -> HistoriesResponse.of( + theme, + routines.getOrDefault(theme, Collections.emptyList()), + missions.getOrDefault(theme, Collections.emptyList()) + ) + )); + } + + @Builder(access = PRIVATE) + private record HistoriesResponse( + @Schema(description = "테마 id", example = "1") + long themeId, + @Schema(description = "테마 이름", example = "관계 쌓기") + @NotNull String themeName, + @Schema(description = "달성 기록") + List histories + ) { + + private static HistoriesResponse of( + final Theme theme, + final List routines, + final List missions + ) { + return HistoriesResponse.builder() + .themeId(theme.getId()) + .themeName(theme.getName()) + .histories(getHistoryResponse(routines, missions)) + .build(); + } + + private static List getHistoryResponse( + final List routines, + final List missions + ) { + return Stream.concat( + routines.stream().map(HistoryResponse::createRoutines), + missions.stream().map(HistoryResponse::createMissions) + ).toList(); + } + + @Builder(access = PRIVATE) + private record HistoryResponse( + @Schema(description = "기록 id", example = "1") + long historyId, + @Schema(description = "루틴 내용", example = "밥 먹기") + @NotNull String content, + @Schema(description = "도전 루틴 여부", example = "true") + boolean isMission + ) { + + private static HistoryResponse createRoutines(final RoutineHistory history) { + return HistoryResponse.builder() + .historyId(history.getId()) + .content(history.getContent()) + .isMission(false) + .build(); + } + + private static HistoryResponse createMissions(final MissionHistory history) { + return HistoryResponse.builder() + .historyId(history.getId()) + .content(history.getContent()) + .isMission(true) + .build(); + } + } + } +} From fece1c68d3d24a23a77e7ccc151b154d8b7804d2 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Tue, 3 Dec 2024 16:40:15 +0900 Subject: [PATCH 22/34] feature: calendar get response --- .../calendar/GetCalendarResponse.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/main/java/com/soptie/server/api/controller/dto/response/calendar/GetCalendarResponse.java diff --git a/src/main/java/com/soptie/server/api/controller/dto/response/calendar/GetCalendarResponse.java b/src/main/java/com/soptie/server/api/controller/dto/response/calendar/GetCalendarResponse.java new file mode 100644 index 00000000..4660a206 --- /dev/null +++ b/src/main/java/com/soptie/server/api/controller/dto/response/calendar/GetCalendarResponse.java @@ -0,0 +1,20 @@ +package com.soptie.server.api.controller.dto.response.calendar; + +import static lombok.AccessLevel.PRIVATE; + +import java.time.LocalDate; +import java.util.Map; + +import lombok.Builder; + +@Builder(access = PRIVATE) +public record GetCalendarResponse( + Map response +) { + + public static GetCalendarResponse of(final Map response) { + return GetCalendarResponse.builder() + .response(response) + .build(); + } +} From 3aa6fb471fc755a73c0a536f613a7c863118082e Mon Sep 17 00:00:00 2001 From: Chan531 Date: Tue, 3 Dec 2024 16:40:24 +0900 Subject: [PATCH 23/34] feature: get calendar --- .../domain/calendar/CalendarService.java | 181 ++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 src/main/java/com/soptie/server/domain/calendar/CalendarService.java diff --git a/src/main/java/com/soptie/server/domain/calendar/CalendarService.java b/src/main/java/com/soptie/server/domain/calendar/CalendarService.java new file mode 100644 index 00000000..1538b73d --- /dev/null +++ b/src/main/java/com/soptie/server/domain/calendar/CalendarService.java @@ -0,0 +1,181 @@ +package com.soptie.server.domain.calendar; + +import static com.soptie.server.common.support.ValueConfig.BLANK; +import static com.soptie.server.common.support.ValueConfig.MEMBER_HAS_NOT_MEMO; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.soptie.server.api.controller.dto.response.calendar.DateHistoryResponse; +import com.soptie.server.api.controller.dto.response.calendar.GetCalendarResponse; +import com.soptie.server.domain.membermission.MissionHistory; +import com.soptie.server.domain.memberroutine.RoutineHistory; +import com.soptie.server.domain.memo.Memo; +import com.soptie.server.domain.theme.Theme; +import com.soptie.server.persistence.adapter.MemberAdapter; +import com.soptie.server.persistence.adapter.MemoAdapter; +import com.soptie.server.persistence.adapter.ThemeAdapter; +import com.soptie.server.persistence.adapter.mission.ChallengeAdapter; +import com.soptie.server.persistence.adapter.mission.MissionAdapter; +import com.soptie.server.persistence.adapter.mission.MissionHistoryAdapter; +import com.soptie.server.persistence.adapter.routine.RoutineAdapter; +import com.soptie.server.persistence.adapter.routine.RoutineHistoryAdapter; + +import lombok.RequiredArgsConstructor; +import lombok.val; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class CalendarService { + + private final MemberAdapter memberAdapter; + private final MemoAdapter memoAdapter; + private final RoutineHistoryAdapter routineHistoryAdapter; + private final MissionHistoryAdapter missionHistoryAdapter; + private final ThemeAdapter themeAdapter; + private final RoutineAdapter routineAdapter; + private final MissionAdapter missionAdapter; + private final ChallengeAdapter challengeAdapter; + + public GetCalendarResponse getCalendar(final long memberId, final int year, final int month) { + memberAdapter.findById(memberId); + val startDateTime = LocalDateTime.of(year, month, 1, 0, 0); + val endDateTime = startDateTime.plusMonths(1).withDayOfMonth(1).minusSeconds(1); + val memos = getMemos(memberId, year, month); + val routines = getRoutines(memberId, startDateTime, endDateTime); + val missions = getMissions(memberId, startDateTime, endDateTime); + return getHistories(memos, routines, missions); + } + + private Map getMemos(final long memberId, final int year, final int month) { + val startDate = LocalDate.of(year, month, 1); + val endDate = startDate.withDayOfMonth(startDate.lengthOfMonth()); + val memos = memoAdapter.findAllByMemberIdAndAchievedDateBetween(memberId, startDate, endDate); + return memos.stream() + .collect( + Collectors.toMap(Memo::getAchievedDate, memo -> memo) + ); + } + + private Map> getRoutines( + final long memberId, + final LocalDateTime startDateTime, + final LocalDateTime endDateTime + ) { + val routines = routineHistoryAdapter.findAllByMemberIdAndCreatedAtBetween(memberId, startDateTime, endDateTime); + return routines.stream() + .collect(Collectors.groupingBy( + routine -> routine.getCreatedAt().toLocalDate(), + Collectors.mapping( + routine -> routine, + Collectors.toUnmodifiableList() + ) + )); + } + + private Map> getMissions( + final long memberId, + final LocalDateTime startDateTime, + final LocalDateTime endDateTime + ) { + val missions = missionHistoryAdapter.findAllByMemberIdAndCreatedAtBetween(memberId, startDateTime, endDateTime); + return missions.stream() + .collect(Collectors.groupingBy( + mission -> mission.getCreatedAt().toLocalDate(), + Collectors.mapping( + mission -> mission, + Collectors.toUnmodifiableList() + ) + )); + } + + private GetCalendarResponse getHistories( + final Map memos, + final Map> routines, + final Map> missions + ) { + val dates = getDates(memos, routines, missions); + val dateAndHistories = getDateAndHistories(dates, memos, routines, missions); + return GetCalendarResponse.of(dateAndHistories); + } + + private Set getDates( + final Map memos, + final Map> routines, + final Map> missions + ) { + return Stream.of(memos.keySet(), routines.keySet(), missions.keySet()) + .flatMap(Set::stream) + .collect(Collectors.toUnmodifiableSet()); + } + + private Map getDateAndHistories( + final Set dates, + final Map memos, + final Map> routines, + final Map> missions + ) { + return dates.stream() + .collect(Collectors.toMap( + date -> date, + date -> getDateHistory(date, memos, routines, missions) + )); + } + + private DateHistoryResponse getDateHistory( + final LocalDate date, + final Map memos, + final Map> routines, + final Map> missions + ) { + val memo = memos.get(date); + val routineHistories = getRoutines(date, routines); + val missionHistories = getMissions(date, missions); + val memoId = memo == null ? MEMBER_HAS_NOT_MEMO : memo.getId(); + val content = memo == null ? BLANK : memo.getContent(); + return DateHistoryResponse.of(memoId, content, routineHistories, missionHistories); + } + + private Map> getRoutines( + final LocalDate date, + final Map> routines + ) { + val histories = routines.getOrDefault(date, Collections.emptyList()); + return histories.stream() + .collect(Collectors.groupingBy( + this::getRoutineTheme + )); + } + + private Theme getRoutineTheme(final RoutineHistory history) { + val routine = routineAdapter.findById(history.getRoutineId()); + return themeAdapter.findById(routine.getThemeId()); + } + + private Map> getMissions( + final LocalDate date, + final Map> missions + ) { + val histories = missions.getOrDefault(date, Collections.emptyList()); + return histories.stream() + .collect(Collectors.groupingBy( + this::getMissionTheme + )); + } + + private Theme getMissionTheme(final MissionHistory history) { + val mission = missionAdapter.findById(history.getMissionId()); + val challenge = challengeAdapter.findById(mission.getChallengeId()); + return themeAdapter.findById(challenge.getThemeId()); + } +} From 000c349442c3f35cac5a9a849d5647edd726f6f8 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Tue, 3 Dec 2024 16:40:33 +0900 Subject: [PATCH 24/34] feature: get calendar api --- .../server/api/controller/CalendarApi.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/main/java/com/soptie/server/api/controller/CalendarApi.java diff --git a/src/main/java/com/soptie/server/api/controller/CalendarApi.java b/src/main/java/com/soptie/server/api/controller/CalendarApi.java new file mode 100644 index 00000000..912ff4dc --- /dev/null +++ b/src/main/java/com/soptie/server/api/controller/CalendarApi.java @@ -0,0 +1,38 @@ +package com.soptie.server.api.controller; + +import java.security.Principal; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.soptie.server.api.controller.dto.response.SuccessResponse; +import com.soptie.server.api.controller.dto.response.calendar.GetCalendarResponse; +import com.soptie.server.api.controller.generic.SuccessMessage; +import com.soptie.server.domain.calendar.CalendarService; + +import lombok.RequiredArgsConstructor; +import lombok.val; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v3/calendars") +public class CalendarApi { + + private final CalendarService calendarService; + + @ResponseStatus(HttpStatus.OK) + @GetMapping + public SuccessResponse getCalendar( + final Principal principal, + @RequestParam final int year, + @RequestParam final int month + ) { + val memberId = Long.parseLong(principal.getName()); + val response = calendarService.getCalendar(memberId, year, month); + return SuccessResponse.success(SuccessMessage.GET_CALENDAR.getMessage(), response); + } +} From 070c4fcca1e1cee7452b4084a89f97bd89fbf0a1 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Tue, 3 Dec 2024 16:51:54 +0900 Subject: [PATCH 25/34] feature: add memo api docs --- .../soptie/server/api/controller/MemoApi.java | 3 +- .../api/controller/docs/MemoApiDocs.java | 101 ++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/soptie/server/api/controller/docs/MemoApiDocs.java diff --git a/src/main/java/com/soptie/server/api/controller/MemoApi.java b/src/main/java/com/soptie/server/api/controller/MemoApi.java index 0d3abd24..6c8afaa4 100644 --- a/src/main/java/com/soptie/server/api/controller/MemoApi.java +++ b/src/main/java/com/soptie/server/api/controller/MemoApi.java @@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import com.soptie.server.api.controller.docs.MemoApiDocs; import com.soptie.server.api.controller.dto.request.memo.CreateMemoRequest; import com.soptie.server.api.controller.dto.request.memo.ModifyMemoRequest; import com.soptie.server.api.controller.dto.response.SuccessResponse; @@ -25,7 +26,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("/api/v3/memos") -public class MemoApi { +public class MemoApi implements MemoApiDocs { private final MemoService memoService; diff --git a/src/main/java/com/soptie/server/api/controller/docs/MemoApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/MemoApiDocs.java new file mode 100644 index 00000000..ee148b03 --- /dev/null +++ b/src/main/java/com/soptie/server/api/controller/docs/MemoApiDocs.java @@ -0,0 +1,101 @@ +package com.soptie.server.api.controller.docs; + +import java.security.Principal; + +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; + +import com.soptie.server.api.controller.dto.request.memo.CreateMemoRequest; +import com.soptie.server.api.controller.dto.request.memo.ModifyMemoRequest; +import com.soptie.server.api.controller.dto.response.ErrorResponse; +import com.soptie.server.api.controller.dto.response.SuccessResponse; +import com.soptie.server.api.controller.dto.response.memo.CreateMemoResponse; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "MemoApi_v3", description = "메모 API version3") +public interface MemoApiDocs { + + @Operation( + summary = "메모 생성", + description = "메모를 생성한다.", + responses = { + @ApiResponse( + responseCode = "201", + description = "성공", + content = @Content(schema = @Schema(implementation = SuccessResponse.class))), + @ApiResponse( + responseCode = "4xx", + description = "클라이언트(요청) 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse( + responseCode = "500", + description = "서버 내부 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)))} + ) + SuccessResponse createMemo( + @Parameter(hidden = true) Principal principal, + @RequestBody CreateMemoRequest request + ); + + @Operation( + summary = "메모 수정", + description = "메모를 수정한다.", + responses = { + @ApiResponse( + responseCode = "200", + description = "성공", + content = @Content(schema = @Schema(implementation = SuccessResponse.class))), + @ApiResponse( + responseCode = "4xx", + description = "클라이언트(요청) 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse( + responseCode = "500", + description = "서버 내부 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)))} + ) + SuccessResponse modifyMemo( + @Parameter(hidden = true) Principal principal, + @Parameter( + name = "memoId", + description = "수정할 메모 id", + in = ParameterIn.PATH, + example = "1" + ) @PathVariable final long memoId, + @RequestBody ModifyMemoRequest request + ); + + @Operation( + summary = "메모 삭제", + description = "메모를 삭제한다.", + responses = { + @ApiResponse( + responseCode = "200", + description = "성공", + content = @Content(schema = @Schema(implementation = SuccessResponse.class))), + @ApiResponse( + responseCode = "4xx", + description = "클라이언트(요청) 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse( + responseCode = "500", + description = "서버 내부 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)))} + ) + SuccessResponse deleteMemo( + @Parameter(hidden = true) Principal principal, + @Parameter( + name = "memoId", + description = "삭제할 메모 id", + in = ParameterIn.PATH, + example = "1" + ) @PathVariable final long memoId + ); +} From e404ae08716b430c9dce149ff953c43ca652a491 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Tue, 3 Dec 2024 16:52:04 +0900 Subject: [PATCH 26/34] feature: add calendar api docs --- .../server/api/controller/CalendarApi.java | 3 +- .../api/controller/docs/CalendarApiDocs.java | 54 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java diff --git a/src/main/java/com/soptie/server/api/controller/CalendarApi.java b/src/main/java/com/soptie/server/api/controller/CalendarApi.java index 912ff4dc..15b51da0 100644 --- a/src/main/java/com/soptie/server/api/controller/CalendarApi.java +++ b/src/main/java/com/soptie/server/api/controller/CalendarApi.java @@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import com.soptie.server.api.controller.docs.CalendarApiDocs; import com.soptie.server.api.controller.dto.response.SuccessResponse; import com.soptie.server.api.controller.dto.response.calendar.GetCalendarResponse; import com.soptie.server.api.controller.generic.SuccessMessage; @@ -20,7 +21,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("/api/v3/calendars") -public class CalendarApi { +public class CalendarApi implements CalendarApiDocs { private final CalendarService calendarService; diff --git a/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java new file mode 100644 index 00000000..1ab004e1 --- /dev/null +++ b/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java @@ -0,0 +1,54 @@ +package com.soptie.server.api.controller.docs; + +import java.security.Principal; + +import org.springframework.web.bind.annotation.RequestParam; + +import com.soptie.server.api.controller.dto.response.ErrorResponse; +import com.soptie.server.api.controller.dto.response.SuccessResponse; +import com.soptie.server.api.controller.dto.response.calendar.GetCalendarResponse; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "CalendarApi_v3", description = "캘린더 API version3") +public interface CalendarApiDocs { + + @Operation( + summary = "캘린더 조회", + description = "루틴 달성 기록, 메모가 포함되어있는 캘린더를 조회한다.", + responses = { + @ApiResponse( + responseCode = "200", + description = "성공", + content = @Content(schema = @Schema(implementation = SuccessResponse.class))), + @ApiResponse( + responseCode = "4xx", + description = "클라이언트(요청) 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse( + responseCode = "500", + description = "서버 내부 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)))} + ) + SuccessResponse getCalendar( + @Parameter(hidden = true) Principal principal, + @Parameter( + name = "year", + description = "조회할 캘린더의 년도", + in = ParameterIn.QUERY, + example = "2024" + ) @RequestParam int year, + @Parameter( + name = "month", + description = "조회할 캘린더의 월", + in = ParameterIn.QUERY, + example = "12" + ) @RequestParam int month + ); +} From b32f7217d135df7ae8446f702ce32e0ffefed02c Mon Sep 17 00:00:00 2001 From: Chan531 Date: Wed, 4 Dec 2024 15:16:51 +0900 Subject: [PATCH 27/34] chore: edit calendar api url --- src/main/java/com/soptie/server/api/controller/CalendarApi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/soptie/server/api/controller/CalendarApi.java b/src/main/java/com/soptie/server/api/controller/CalendarApi.java index 15b51da0..081a2ed3 100644 --- a/src/main/java/com/soptie/server/api/controller/CalendarApi.java +++ b/src/main/java/com/soptie/server/api/controller/CalendarApi.java @@ -20,7 +20,7 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/api/v3/calendars") +@RequestMapping("/api/v3/calendar") public class CalendarApi implements CalendarApiDocs { private final CalendarService calendarService; From 49f7786083a230809f9c759862290eda54b6c158 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Wed, 4 Dec 2024 15:32:32 +0900 Subject: [PATCH 28/34] style: edit swagger tag and description --- .../java/com/soptie/server/api/controller/docs/AuthApiDocs.java | 2 +- .../com/soptie/server/api/controller/docs/CalendarApiDocs.java | 2 +- .../com/soptie/server/api/controller/docs/ChallengeApiDocs.java | 2 +- .../com/soptie/server/api/controller/docs/MakerApiDocs.java | 2 +- .../com/soptie/server/api/controller/docs/MemberApiDocs.java | 2 +- .../soptie/server/api/controller/docs/MemberMissionApiDocs.java | 2 +- .../server/api/controller/docs/MemberMissionApiV2Docs.java | 2 +- .../soptie/server/api/controller/docs/MemberRoutineApiDocs.java | 2 +- .../server/api/controller/docs/MemberRoutineApiV2Docs.java | 2 +- .../java/com/soptie/server/api/controller/docs/MemoApiDocs.java | 2 +- .../com/soptie/server/api/controller/docs/RoutineApiDocs.java | 2 +- .../com/soptie/server/api/controller/docs/ThemeApiDocs.java | 2 +- .../com/soptie/server/api/controller/docs/VersionApiDocs.java | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/soptie/server/api/controller/docs/AuthApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/AuthApiDocs.java index bc749e0f..37395a8f 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/AuthApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/AuthApiDocs.java @@ -17,7 +17,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -@Tag(name = "auth", description = "인증 API") +@Tag(name = "[Auth] 인증 API", description = "인증 API") public interface AuthApiDocs { @Operation( diff --git a/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java index 1ab004e1..c900a8a6 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java @@ -16,7 +16,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -@Tag(name = "CalendarApi_v3", description = "캘린더 API version3") +@Tag(name = "[Calendar] 캘린더 API Version3", description = "캘린더 API Version3") public interface CalendarApiDocs { @Operation( diff --git a/src/main/java/com/soptie/server/api/controller/docs/ChallengeApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/ChallengeApiDocs.java index 46be5965..cc2c4b57 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/ChallengeApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/ChallengeApiDocs.java @@ -16,7 +16,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -@Tag(name = "ChallengeRoutine_v2", description = "도전 루틴 API version2") +@Tag(name = "[Challenge] 도전 루틴 API", description = "도전 루틴 API version2") public interface ChallengeApiDocs { @Operation( diff --git a/src/main/java/com/soptie/server/api/controller/docs/MakerApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/MakerApiDocs.java index f60f810a..140dbf1b 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/MakerApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/MakerApiDocs.java @@ -10,7 +10,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -@Tag(name = "makers", description = "메이커 API") +@Tag(name = "[Maker] 메이커 루틴 API", description = "메이커 루틴 API") public interface MakerApiDocs { @Operation( diff --git a/src/main/java/com/soptie/server/api/controller/docs/MemberApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/MemberApiDocs.java index 7fbba897..23365076 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/MemberApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/MemberApiDocs.java @@ -21,7 +21,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -@Tag(name = "[Member] 회원 API", description = "회원 관련 api 입니다.") +@Tag(name = "[Member] 회원 API", description = "회원 API") public interface MemberApiDocs { @Operation( diff --git a/src/main/java/com/soptie/server/api/controller/docs/MemberMissionApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/MemberMissionApiDocs.java index 50699adf..fda5e587 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/MemberMissionApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/MemberMissionApiDocs.java @@ -18,7 +18,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -@Tag(name = "MemberMissionApi", description = "회원의 도전 루틴 API") +@Tag(name = "[MemberMission] 회원의 도전 루틴", description = "회원의 도전 루틴 API") public interface MemberMissionApiDocs { @Operation( diff --git a/src/main/java/com/soptie/server/api/controller/docs/MemberMissionApiV2Docs.java b/src/main/java/com/soptie/server/api/controller/docs/MemberMissionApiV2Docs.java index bdaf1970..b3083157 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/MemberMissionApiV2Docs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/MemberMissionApiV2Docs.java @@ -13,7 +13,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -@Tag(name = "MemberMissionApi_v2", description = "회원의 도전 루틴 API version2") +@Tag(name = "[MemberMission] 회원의 도전 루틴 Version2", description = "회원의 도전 루틴 API Version2") public interface MemberMissionApiV2Docs { @Operation( diff --git a/src/main/java/com/soptie/server/api/controller/docs/MemberRoutineApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/MemberRoutineApiDocs.java index 5645b85e..58cbb85b 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/MemberRoutineApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/MemberRoutineApiDocs.java @@ -18,7 +18,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -@Tag(name = "MemberRoutineApi", description = "회원의 데일리 루틴 API") +@Tag(name = "[MemberRoutine] 회원의 데일리 루틴", description = "회원의 데일리 루틴 API") public interface MemberRoutineApiDocs { @Operation( diff --git a/src/main/java/com/soptie/server/api/controller/docs/MemberRoutineApiV2Docs.java b/src/main/java/com/soptie/server/api/controller/docs/MemberRoutineApiV2Docs.java index 347c4073..77612f2e 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/MemberRoutineApiV2Docs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/MemberRoutineApiV2Docs.java @@ -17,7 +17,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -@Tag(name = "MemberRoutineApi_v2", description = "회원 데일리 루틴 API version2") +@Tag(name = "[MemberRoutine] 회원의 데일리 루틴 Version2", description = "회원의 데일리 루틴 API Version2") public interface MemberRoutineApiV2Docs { @Operation( diff --git a/src/main/java/com/soptie/server/api/controller/docs/MemoApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/MemoApiDocs.java index ee148b03..5805e3c8 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/MemoApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/MemoApiDocs.java @@ -19,7 +19,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -@Tag(name = "MemoApi_v3", description = "메모 API version3") +@Tag(name = "[Memo] 메모 API Version3", description = "메모 API Version3") public interface MemoApiDocs { @Operation( diff --git a/src/main/java/com/soptie/server/api/controller/docs/RoutineApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/RoutineApiDocs.java index 4d40bef8..8e455964 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/RoutineApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/RoutineApiDocs.java @@ -13,7 +13,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -@Tag(name = "RoutineApi_v2", description = "데일리 루틴 API version2") +@Tag(name = "[Routine] 데일리 루틴 Version2", description = "데일리 루틴 API Version2") public interface RoutineApiDocs { @Operation( diff --git a/src/main/java/com/soptie/server/api/controller/docs/ThemeApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/ThemeApiDocs.java index 950d2a5f..8262425a 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/ThemeApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/ThemeApiDocs.java @@ -10,7 +10,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -@Tag(name = "ThemeApi_v2", description = "테마 API version2") +@Tag(name = "[Theme] 테마 Version2", description = "테마 API Version2") public interface ThemeApiDocs { @Operation( diff --git a/src/main/java/com/soptie/server/api/controller/docs/VersionApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/VersionApiDocs.java index 3d102895..dcc5b2a6 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/VersionApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/VersionApiDocs.java @@ -10,7 +10,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -@Tag(name = "VersionAPI", description = "버전 API") +@Tag(name = "[Version] 버전", description = "버전 API") public interface VersionApiDocs { @Operation( From 2349b97551ddb11165b4e50a851796f1fc11dedc Mon Sep 17 00:00:00 2001 From: Chan531 Date: Wed, 4 Dec 2024 15:34:06 +0900 Subject: [PATCH 29/34] chore: add parameter required --- .../com/soptie/server/api/controller/docs/CalendarApiDocs.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java index c900a8a6..b3aac67e 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java @@ -42,12 +42,14 @@ SuccessResponse getCalendar( name = "year", description = "조회할 캘린더의 년도", in = ParameterIn.QUERY, + required = true, example = "2024" ) @RequestParam int year, @Parameter( name = "month", description = "조회할 캘린더의 월", in = ParameterIn.QUERY, + required = true, example = "12" ) @RequestParam int month ); From 844bfae15c8fb67449042b073d05dfbc298d7e7a Mon Sep 17 00:00:00 2001 From: Chan531 Date: Wed, 4 Dec 2024 15:35:35 +0900 Subject: [PATCH 30/34] chore: edit dto schema wrong description --- .../controller/dto/response/calendar/DateHistoryResponse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/soptie/server/api/controller/dto/response/calendar/DateHistoryResponse.java b/src/main/java/com/soptie/server/api/controller/dto/response/calendar/DateHistoryResponse.java index d563c04f..d2e23e28 100644 --- a/src/main/java/com/soptie/server/api/controller/dto/response/calendar/DateHistoryResponse.java +++ b/src/main/java/com/soptie/server/api/controller/dto/response/calendar/DateHistoryResponse.java @@ -19,7 +19,7 @@ @Builder(access = PRIVATE) public record DateHistoryResponse( - @Schema(description = "메모 아이디 (null일 시, -1)", example = "1") + @Schema(description = "메모 아이디 (null일 시, 0)", example = "1") long memoId, @Schema(description = "메모 내용", example = "이것은 메모가 아니다.") @NotNull String memoContent, From c59b41985fa47975dfd14c62c9903d082ddf81fd Mon Sep 17 00:00:00 2001 From: Chan531 Date: Wed, 4 Dec 2024 15:39:44 +0900 Subject: [PATCH 31/34] refactor: edit mission history constructor parameter --- .../domain/membermission/MemberMissionService.java | 2 +- .../adapter/mission/MissionHistoryAdapter.java | 6 +++--- .../entity/mission/MissionHistoryEntity.java | 12 +++++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/soptie/server/domain/membermission/MemberMissionService.java b/src/main/java/com/soptie/server/domain/membermission/MemberMissionService.java index 8864341a..c9635137 100644 --- a/src/main/java/com/soptie/server/domain/membermission/MemberMissionService.java +++ b/src/main/java/com/soptie/server/domain/membermission/MemberMissionService.java @@ -71,7 +71,7 @@ public void achieveMemberMission(long memberId, long missionId) { memberMissionAdapter.update(memberMission); memberMissionAdapter.flush(); memberMissionAdapter.delete(memberMission); - missionHistoryAdapter.save(memberMission, mission.getContent()); + missionHistoryAdapter.save(memberMission, mission); } public Optional getMemberMission(long memberId) { diff --git a/src/main/java/com/soptie/server/persistence/adapter/mission/MissionHistoryAdapter.java b/src/main/java/com/soptie/server/persistence/adapter/mission/MissionHistoryAdapter.java index 99117839..2a6a4dd5 100644 --- a/src/main/java/com/soptie/server/persistence/adapter/mission/MissionHistoryAdapter.java +++ b/src/main/java/com/soptie/server/persistence/adapter/mission/MissionHistoryAdapter.java @@ -6,6 +6,7 @@ import org.springframework.stereotype.Component; +import com.soptie.server.domain.challenge.Mission; import com.soptie.server.domain.membermission.MemberMission; import com.soptie.server.domain.membermission.MissionHistory; import com.soptie.server.persistence.entity.mission.MissionHistoryEntity; @@ -18,9 +19,8 @@ public class MissionHistoryAdapter { private final MissionHistoryRepository historyRepository; - public void save(final MemberMission memberMission, final String content) { - historyRepository.save(new MissionHistoryEntity(memberMission.getId(), memberMission.getMemberId(), - memberMission.getMissionId(), content)); + public void save(final MemberMission memberMission, final Mission mission) { + historyRepository.save(new MissionHistoryEntity(memberMission, mission)); } public void deleteById(long historyId) { diff --git a/src/main/java/com/soptie/server/persistence/entity/mission/MissionHistoryEntity.java b/src/main/java/com/soptie/server/persistence/entity/mission/MissionHistoryEntity.java index 0f0871d9..992f6411 100644 --- a/src/main/java/com/soptie/server/persistence/entity/mission/MissionHistoryEntity.java +++ b/src/main/java/com/soptie/server/persistence/entity/mission/MissionHistoryEntity.java @@ -1,5 +1,7 @@ package com.soptie.server.persistence.entity.mission; +import com.soptie.server.domain.challenge.Mission; +import com.soptie.server.domain.membermission.MemberMission; import com.soptie.server.domain.membermission.MissionHistory; import com.soptie.server.persistence.entity.BaseEntity; @@ -17,11 +19,11 @@ public class MissionHistoryEntity extends BaseEntity { private long missionId; private String content; - public MissionHistoryEntity(long memberMissionId, long memberId, long missionId, String content) { - this.memberMissionId = memberMissionId; - this.memberId = memberId; - this.missionId = missionId; - this.content = content; + public MissionHistoryEntity(final MemberMission memberMission, final Mission mission) { + this.memberMissionId = memberMission.getId(); + this.memberId = memberMission.getMemberId(); + this.missionId = mission.getId(); + this.content = mission.getContent(); } public MissionHistory toDomain() { From bb6fe25363f493264bb9f160577cd077565ea912 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Wed, 4 Dec 2024 15:41:40 +0900 Subject: [PATCH 32/34] refactor: edit routine history constructor parameter --- .../adapter/routine/RoutineHistoryAdapter.java | 3 +-- .../entity/routine/RoutineHistoryEntity.java | 12 +++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/soptie/server/persistence/adapter/routine/RoutineHistoryAdapter.java b/src/main/java/com/soptie/server/persistence/adapter/routine/RoutineHistoryAdapter.java index b2063220..116e7a8b 100644 --- a/src/main/java/com/soptie/server/persistence/adapter/routine/RoutineHistoryAdapter.java +++ b/src/main/java/com/soptie/server/persistence/adapter/routine/RoutineHistoryAdapter.java @@ -20,8 +20,7 @@ public class RoutineHistoryAdapter { private final RoutineHistoryRepository historyRepository; public void save(final MemberRoutine memberRoutine, final Routine routine) { - historyRepository.save(new RoutineHistoryEntity(memberRoutine.getId(), memberRoutine.getMemberId(), - memberRoutine.getRoutineId(), routine.getContent())); + historyRepository.save(new RoutineHistoryEntity(memberRoutine, routine)); } public void deleteByRoutineIdAndCreatedAt(long memberRoutineId, LocalDate date) { diff --git a/src/main/java/com/soptie/server/persistence/entity/routine/RoutineHistoryEntity.java b/src/main/java/com/soptie/server/persistence/entity/routine/RoutineHistoryEntity.java index 465bc7f4..eea818db 100644 --- a/src/main/java/com/soptie/server/persistence/entity/routine/RoutineHistoryEntity.java +++ b/src/main/java/com/soptie/server/persistence/entity/routine/RoutineHistoryEntity.java @@ -1,6 +1,8 @@ package com.soptie.server.persistence.entity.routine; +import com.soptie.server.domain.memberroutine.MemberRoutine; import com.soptie.server.domain.memberroutine.RoutineHistory; +import com.soptie.server.domain.routine.Routine; import com.soptie.server.persistence.entity.BaseEntity; import jakarta.persistence.Entity; @@ -17,11 +19,11 @@ public class RoutineHistoryEntity extends BaseEntity { private long routineId; private String content; - public RoutineHistoryEntity(long memberRoutineId, long memberId, long routineId, String content) { - this.memberRoutineId = memberRoutineId; - this.memberId = memberId; - this.routineId = routineId; - this.content = content; + public RoutineHistoryEntity(final MemberRoutine memberRoutine, final Routine routine) { + this.memberRoutineId = memberRoutine.getId(); + this.memberId = memberRoutine.getMemberId(); + this.routineId = routine.getId(); + this.content = routine.getContent(); } public RoutineHistory toDomain() { From 61fef6a1ddd7ab88cf675ea3857cd7082de6c700 Mon Sep 17 00:00:00 2001 From: Chan531 Date: Wed, 4 Dec 2024 15:52:42 +0900 Subject: [PATCH 33/34] chore: edit swagger api response --- .../api/controller/docs/AuthApiDocs.java | 10 ++------ .../api/controller/docs/CalendarApiDocs.java | 5 +--- .../api/controller/docs/MemberApiDocs.java | 5 +--- .../controller/docs/MemberMissionApiDocs.java | 10 ++------ .../controller/docs/MemberRoutineApiDocs.java | 5 +--- .../api/controller/docs/MemoApiDocs.java | 15 +++--------- .../api/controller/docs/RoutineApiDocs.java | 23 +++++++++++++++++-- 7 files changed, 31 insertions(+), 42 deletions(-) diff --git a/src/main/java/com/soptie/server/api/controller/docs/AuthApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/AuthApiDocs.java index 37395a8f..559d6c64 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/AuthApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/AuthApiDocs.java @@ -69,10 +69,7 @@ SuccessResponse reissueToken( summary = "로그 아웃", description = "로그 아웃을 한다.", responses = { - @ApiResponse( - responseCode = "200", - description = "성공", - content = @Content(schema = @Schema(implementation = SuccessResponse.class))), + @ApiResponse(responseCode = "200", description = "성공"), @ApiResponse( responseCode = "404", description = "유효하지 않은 회원", @@ -92,10 +89,7 @@ SuccessResponse reissueToken( summary = "회원 탈퇴", description = "회원 탈퇴를 진행한다.", responses = { - @ApiResponse( - responseCode = "200", - description = "성공", - content = @Content(schema = @Schema(implementation = SuccessResponse.class))), + @ApiResponse(responseCode = "200", description = "성공"), @ApiResponse( responseCode = "404", description = "유효하지 않은 회원", diff --git a/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java index b3aac67e..5ef0f601 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java @@ -23,10 +23,7 @@ public interface CalendarApiDocs { summary = "캘린더 조회", description = "루틴 달성 기록, 메모가 포함되어있는 캘린더를 조회한다.", responses = { - @ApiResponse( - responseCode = "200", - description = "성공", - content = @Content(schema = @Schema(implementation = SuccessResponse.class))), + @ApiResponse(responseCode = "200", description = "성공"), @ApiResponse( responseCode = "4xx", description = "클라이언트(요청) 오류", diff --git a/src/main/java/com/soptie/server/api/controller/docs/MemberApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/MemberApiDocs.java index 23365076..419722a3 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/MemberApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/MemberApiDocs.java @@ -28,10 +28,7 @@ public interface MemberApiDocs { summary = "회원 프로필 생성", description = "회원의 프로필을 생성한다.", responses = { - @ApiResponse( - responseCode = "201", - description = "CREATED success", - content = @Content(schema = @Schema(implementation = SuccessResponse.class))), + @ApiResponse(responseCode = "201", description = "Created success"), @ApiResponse( responseCode = "400", description = "유효하지 않은 인형 타입", diff --git a/src/main/java/com/soptie/server/api/controller/docs/MemberMissionApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/MemberMissionApiDocs.java index fda5e587..ff6cfafb 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/MemberMissionApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/MemberMissionApiDocs.java @@ -44,10 +44,7 @@ SuccessResponse createMemberMission( summary = "미션 삭제", description = "회원의 미션을 삭제한다.", responses = { - @ApiResponse( - responseCode = "200", - description = "OK success", - content = @Content(schema = @Schema(implementation = SuccessResponse.class))), + @ApiResponse(responseCode = "200", description = "성공"), @ApiResponse( responseCode = "4xx", description = "클라이언트(요청) 오류", @@ -71,10 +68,7 @@ SuccessResponse deleteMemberMission( summary = "미션 달성", description = "회원의 미션을 달성한다.", responses = { - @ApiResponse( - responseCode = "200", - description = "OK success", - content = @Content(schema = @Schema(implementation = SuccessResponse.class))), + @ApiResponse(responseCode = "200", description = "성공"), @ApiResponse( responseCode = "4xx", description = "클라이언트(요청) 오류", diff --git a/src/main/java/com/soptie/server/api/controller/docs/MemberRoutineApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/MemberRoutineApiDocs.java index 58cbb85b..bc230713 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/MemberRoutineApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/MemberRoutineApiDocs.java @@ -25,10 +25,7 @@ public interface MemberRoutineApiDocs { summary = "데일리 루틴 삭제", description = "회원의 데일리 루틴을 삭제한다.", responses = { - @ApiResponse( - responseCode = "200", - description = "성공", - content = @Content(schema = @Schema(implementation = SuccessResponse.class))), + @ApiResponse(responseCode = "200", description = "성공"), @ApiResponse( responseCode = "4xx", description = "클라이언트(요청) 오류", diff --git a/src/main/java/com/soptie/server/api/controller/docs/MemoApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/MemoApiDocs.java index 5805e3c8..e1243fac 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/MemoApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/MemoApiDocs.java @@ -26,10 +26,7 @@ public interface MemoApiDocs { summary = "메모 생성", description = "메모를 생성한다.", responses = { - @ApiResponse( - responseCode = "201", - description = "성공", - content = @Content(schema = @Schema(implementation = SuccessResponse.class))), + @ApiResponse(responseCode = "201", description = "CREATED Success"), @ApiResponse( responseCode = "4xx", description = "클라이언트(요청) 오류", @@ -48,10 +45,7 @@ SuccessResponse createMemo( summary = "메모 수정", description = "메모를 수정한다.", responses = { - @ApiResponse( - responseCode = "200", - description = "성공", - content = @Content(schema = @Schema(implementation = SuccessResponse.class))), + @ApiResponse(responseCode = "200", description = "성공"), @ApiResponse( responseCode = "4xx", description = "클라이언트(요청) 오류", @@ -76,10 +70,7 @@ SuccessResponse modifyMemo( summary = "메모 삭제", description = "메모를 삭제한다.", responses = { - @ApiResponse( - responseCode = "200", - description = "성공", - content = @Content(schema = @Schema(implementation = SuccessResponse.class))), + @ApiResponse(responseCode = "200", description = "성공"), @ApiResponse( responseCode = "4xx", description = "클라이언트(요청) 오류", diff --git a/src/main/java/com/soptie/server/api/controller/docs/RoutineApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/RoutineApiDocs.java index 8e455964..bc7c392e 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/RoutineApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/RoutineApiDocs.java @@ -3,6 +3,7 @@ import java.security.Principal; import java.util.LinkedHashSet; +import com.soptie.server.api.controller.dto.response.ErrorResponse; import com.soptie.server.api.controller.dto.response.SuccessResponse; import com.soptie.server.api.controller.dto.response.routine.GetRoutinesByMemberResponse; import com.soptie.server.api.controller.dto.response.routine.GetRoutinesByThemeResponse; @@ -10,6 +11,8 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; @@ -20,7 +23,15 @@ public interface RoutineApiDocs { summary = "테마 목록별 데일리 루틴 목록 조회", description = "특정 테마 목록에 속하는 데일리 루틴 목록을 조회한다.", responses = { - @ApiResponse(responseCode = "200", description = "OK Success") + @ApiResponse(responseCode = "200", description = "OK Success"), + @ApiResponse( + responseCode = "4xx", + description = "클라이언트(요청) 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse( + responseCode = "500", + description = "서버 내부 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))) } ) SuccessResponse getRoutinesByThemeIds( @@ -36,7 +47,15 @@ SuccessResponse getRoutinesByThemeIds( summary = "테마별 데일리 루틴 목록 조회", description = "특정 테마에 속하는 데일리 루틴 목록을 조회한다.", responses = { - @ApiResponse(responseCode = "200", description = "OK Success") + @ApiResponse(responseCode = "200", description = "OK Success"), + @ApiResponse( + responseCode = "4xx", + description = "클라이언트(요청) 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse( + responseCode = "500", + description = "서버 내부 오류", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))) } ) SuccessResponse getRoutinesByThemeId( From 24851bd496e425054c1794f53b60c8e9ed615a6c Mon Sep 17 00:00:00 2001 From: Chan531 Date: Wed, 4 Dec 2024 16:03:17 +0900 Subject: [PATCH 34/34] refactor: edit get calendar response --- .../server/api/controller/CalendarApi.java | 6 ++++-- .../api/controller/docs/CalendarApiDocs.java | 6 ++++-- .../calendar/GetCalendarResponse.java | 20 ------------------- .../domain/calendar/CalendarService.java | 8 +++----- 4 files changed, 11 insertions(+), 29 deletions(-) delete mode 100644 src/main/java/com/soptie/server/api/controller/dto/response/calendar/GetCalendarResponse.java diff --git a/src/main/java/com/soptie/server/api/controller/CalendarApi.java b/src/main/java/com/soptie/server/api/controller/CalendarApi.java index 081a2ed3..d7934563 100644 --- a/src/main/java/com/soptie/server/api/controller/CalendarApi.java +++ b/src/main/java/com/soptie/server/api/controller/CalendarApi.java @@ -1,6 +1,8 @@ package com.soptie.server.api.controller; import java.security.Principal; +import java.time.LocalDate; +import java.util.Map; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.GetMapping; @@ -11,7 +13,7 @@ import com.soptie.server.api.controller.docs.CalendarApiDocs; import com.soptie.server.api.controller.dto.response.SuccessResponse; -import com.soptie.server.api.controller.dto.response.calendar.GetCalendarResponse; +import com.soptie.server.api.controller.dto.response.calendar.DateHistoryResponse; import com.soptie.server.api.controller.generic.SuccessMessage; import com.soptie.server.domain.calendar.CalendarService; @@ -27,7 +29,7 @@ public class CalendarApi implements CalendarApiDocs { @ResponseStatus(HttpStatus.OK) @GetMapping - public SuccessResponse getCalendar( + public SuccessResponse> getCalendar( final Principal principal, @RequestParam final int year, @RequestParam final int month diff --git a/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java b/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java index 5ef0f601..0ab1da92 100644 --- a/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java +++ b/src/main/java/com/soptie/server/api/controller/docs/CalendarApiDocs.java @@ -1,12 +1,14 @@ package com.soptie.server.api.controller.docs; import java.security.Principal; +import java.time.LocalDate; +import java.util.Map; import org.springframework.web.bind.annotation.RequestParam; import com.soptie.server.api.controller.dto.response.ErrorResponse; import com.soptie.server.api.controller.dto.response.SuccessResponse; -import com.soptie.server.api.controller.dto.response.calendar.GetCalendarResponse; +import com.soptie.server.api.controller.dto.response.calendar.DateHistoryResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -33,7 +35,7 @@ public interface CalendarApiDocs { description = "서버 내부 오류", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))} ) - SuccessResponse getCalendar( + SuccessResponse> getCalendar( @Parameter(hidden = true) Principal principal, @Parameter( name = "year", diff --git a/src/main/java/com/soptie/server/api/controller/dto/response/calendar/GetCalendarResponse.java b/src/main/java/com/soptie/server/api/controller/dto/response/calendar/GetCalendarResponse.java deleted file mode 100644 index 4660a206..00000000 --- a/src/main/java/com/soptie/server/api/controller/dto/response/calendar/GetCalendarResponse.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.soptie.server.api.controller.dto.response.calendar; - -import static lombok.AccessLevel.PRIVATE; - -import java.time.LocalDate; -import java.util.Map; - -import lombok.Builder; - -@Builder(access = PRIVATE) -public record GetCalendarResponse( - Map response -) { - - public static GetCalendarResponse of(final Map response) { - return GetCalendarResponse.builder() - .response(response) - .build(); - } -} diff --git a/src/main/java/com/soptie/server/domain/calendar/CalendarService.java b/src/main/java/com/soptie/server/domain/calendar/CalendarService.java index 1538b73d..5cf87094 100644 --- a/src/main/java/com/soptie/server/domain/calendar/CalendarService.java +++ b/src/main/java/com/soptie/server/domain/calendar/CalendarService.java @@ -16,7 +16,6 @@ import org.springframework.transaction.annotation.Transactional; import com.soptie.server.api.controller.dto.response.calendar.DateHistoryResponse; -import com.soptie.server.api.controller.dto.response.calendar.GetCalendarResponse; import com.soptie.server.domain.membermission.MissionHistory; import com.soptie.server.domain.memberroutine.RoutineHistory; import com.soptie.server.domain.memo.Memo; @@ -47,7 +46,7 @@ public class CalendarService { private final MissionAdapter missionAdapter; private final ChallengeAdapter challengeAdapter; - public GetCalendarResponse getCalendar(final long memberId, final int year, final int month) { + public Map getCalendar(final long memberId, final int year, final int month) { memberAdapter.findById(memberId); val startDateTime = LocalDateTime.of(year, month, 1, 0, 0); val endDateTime = startDateTime.plusMonths(1).withDayOfMonth(1).minusSeconds(1); @@ -99,14 +98,13 @@ private Map> getMissions( )); } - private GetCalendarResponse getHistories( + private Map getHistories( final Map memos, final Map> routines, final Map> missions ) { val dates = getDates(memos, routines, missions); - val dateAndHistories = getDateAndHistories(dates, memos, routines, missions); - return GetCalendarResponse.of(dateAndHistories); + return getDateAndHistories(dates, memos, routines, missions); } private Set getDates(