Skip to content

Feat/#9 개인 미션 조회 API 추가 - #10

Merged
kingmingyu merged 2 commits into
developfrom
feat/#9
Jul 10, 2026
Merged

Feat/#9 개인 미션 조회 API 추가#10
kingmingyu merged 2 commits into
developfrom
feat/#9

Conversation

@kingmingyu

@kingmingyu kingmingyu commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features
    • Added an endpoint to view personal missions for the current track, including today’s completion status.
    • Personal missions are now associated with the user’s current track.
  • Bug Fixes
    • Prevented personal missions from being added to self-care tracks.
    • Limited personal missions to two per user and track, with a clear error message when the limit is reached.

@kingmingyu kingmingyu self-assigned this Jul 10, 2026
@kingmingyu kingmingyu linked an issue Jul 10, 2026 that may be closed by this pull request
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds custom mission creation constraints and track association, repository filtering, and an authenticated endpoint that returns the user’s custom missions with today’s completion status.

Changes

Custom mission flow

Layer / File(s) Summary
Custom mission contracts and queries
src/main/java/com/team4/hackerton/domain/mission/code/MissionErrorCode.java, src/main/java/com/team4/hackerton/domain/mission/code/MissionSuccessCode.java, src/main/java/com/team4/hackerton/domain/mission/entity/Mission.java, src/main/java/com/team4/hackerton/domain/mission/repository/MissionRepository.java
Adds custom-mission response codes, stores the mission track during construction, and provides user/track/type count and list queries.
Custom mission service behavior
src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java
Rejects custom missions for SELF_CARE tracks, limits each user to two custom missions per track, persists track-linked missions, and maps today’s completion status when listing missions.
Custom mission retrieval endpoint
src/main/java/com/team4/hackerton/domain/mission/controller/MissionController.java
Adds GET /api/missions/custom, delegates to the service, and returns the custom mission list using the new success code.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  actor User
  participant MissionController
  participant MissionService
  participant MissionRepository

  User->>MissionController: GET /api/missions/custom
  MissionController->>MissionService: getCustomMissions(user)
  MissionService->>MissionRepository: findByUserAndTrackAndType(user, track, USER_CUSTOM)
  MissionRepository-->>MissionService: custom missions
  MissionService-->>MissionController: MissionListResponse with completion flags
  MissionController-->>User: ApiResponse with custom mission list
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 개인 미션 조회 API 추가라는 제목이 새 custom mission 조회 엔드포인트와 관련 변경을 잘 요약합니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#9

Comment @coderabbitai help to get the list of available commands.

@kingmingyu
kingmingyu merged commit 597f883 into develop Jul 10, 2026
2 checks passed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java (1)

93-94: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate UserTrack lookup pattern.

The userTrackRepository.findByUserAndIsCurrentTrue(user).orElseThrow(...) block is now repeated across five methods in this service. Extracting a private helper (e.g., getCurrentTrack(User user)) would reduce duplication and centralize the USER_TRACK_NOT_FOUND handling.

♻️ Proposed helper extraction
+    private Track getCurrentTrack(User user) {
+        return userTrackRepository.findByUserAndIsCurrentTrue(user)
+                .orElseThrow(() -> new AppException(MissionErrorCode.USER_TRACK_NOT_FOUND))
+                .getTrack();
+    }
+
     public MissionListResponse getCustomMissions(User user) {
-        UserTrack userTrack = userTrackRepository.findByUserAndIsCurrentTrue(user)
-                .orElseThrow(() -> new AppException(MissionErrorCode.USER_TRACK_NOT_FOUND));
-
-        Track track = userTrack.getTrack();
+        Track track = getCurrentTrack(user);
         LocalDate today = LocalDate.now();

Also applies to: 112-113

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java`
around lines 93 - 94, Extract the repeated current-track lookup into a private
helper such as getCurrentTrack(User user) in MissionService, using
userTrackRepository.findByUserAndIsCurrentTrue(user) and throwing
USER_TRACK_NOT_FOUND when absent. Replace the duplicated lookup blocks across
all affected methods with calls to this helper.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java`:
- Around line 102-107: Make custom mission creation atomic in MissionService by
synchronizing the count check and Mission.ofUserCustom save operation: lock the
relevant UserTrack row through the repository query (with a transactional
boundary) or enforce an equivalent database-level constraint, so concurrent
requests cannot exceed the two-mission cap.

---

Nitpick comments:
In
`@src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java`:
- Around line 93-94: Extract the repeated current-track lookup into a private
helper such as getCurrentTrack(User user) in MissionService, using
userTrackRepository.findByUserAndIsCurrentTrue(user) and throwing
USER_TRACK_NOT_FOUND when absent. Replace the duplicated lookup blocks across
all affected methods with calls to this helper.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f084e2b9-760d-46cf-bcf0-c1e27f383eff

📥 Commits

Reviewing files that changed from the base of the PR and between 1343ac8 and 37a81ae.

📒 Files selected for processing (6)
  • src/main/java/com/team4/hackerton/domain/mission/code/MissionErrorCode.java
  • src/main/java/com/team4/hackerton/domain/mission/code/MissionSuccessCode.java
  • src/main/java/com/team4/hackerton/domain/mission/controller/MissionController.java
  • src/main/java/com/team4/hackerton/domain/mission/entity/Mission.java
  • src/main/java/com/team4/hackerton/domain/mission/repository/MissionRepository.java
  • src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java

Comment on lines +102 to +107
long customCount = missionRepository.countByUserAndTrackAndType(user, track, MissionType.USER_CUSTOM);
if (customCount >= 2) {
throw new AppException(MissionErrorCode.CUSTOM_MISSION_LIMIT_EXCEEDED);
}

Mission mission = missionRepository.save(Mission.ofUserCustom(user, track, request.getTitle()));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## MissionService outline\n'
ast-grep outline src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java --view expanded || true

printf '\n## Relevant MissionService slice\n'
sed -n '1,220p' src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java | cat -n

printf '\n## Mission repository search\n'
rg -n "countByUserAndTrackAndType|save\\(|`@Lock`|PESSIMISTIC|UserTrack|custom mission|CUSTOM_MISSION_LIMIT_EXCEEDED" src/main/java -S

printf '\n## Mission entity / related constraints search\n'
rg -n "`@Table`|uniqueConstraints|`@Column`\\(|`@Index`|`@Check`|`@Version`|`@OneToOne`|`@ManyToOne`|`@NaturalId`" src/main/java/com/team4/hackerton/domain -S

printf '\n## UserTrack / Mission entity files\n'
fd -a "Mission.java|UserTrack.java|MissionRepository.java|UserTrackRepository.java" src/main/java

Repository: 8th-COKERTHON/server-team4

Length of output: 15509


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## MissionRepository\n'
cat -n src/main/java/com/team4/hackerton/domain/mission/repository/MissionRepository.java

printf '\n## Mission entity\n'
cat -n src/main/java/com/team4/hackerton/domain/mission/entity/Mission.java

printf '\n## UserTrack entity\n'
cat -n src/main/java/com/team4/hackerton/domain/track/entity/UserTrack.java

printf '\n## MissionLog entity (for comparison on constraints)\n'
cat -n src/main/java/com/team4/hackerton/domain/mission/entity/MissionLog.java

printf '\n## Search for transaction isolation / locking annotations in mission & track packages\n'
rg -n "`@Transactional`\\(|`@Lock`|Isolation|PESSIMISTIC|OPTIMISTIC|uniqueConstraints|`@Version`|`@Check`" src/main/java/com/team4/hackerton/domain/{mission,track} -S

Repository: 8th-COKERTHON/server-team4

Length of output: 8373


Make the custom-mission cap atomic src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java:102-107
countByUserAndTrackAndType(...) and save(...) are separate steps, so concurrent requests can both pass the >= 2 check and insert a third custom mission. Lock the UserTrack row or add a DB-level guard instead of relying on count-then-insert.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java`
around lines 102 - 107, Make custom mission creation atomic in MissionService by
synchronizing the count check and Mission.ofUserCustom save operation: lock the
relevant UserTrack row through the repository query (with a transactional
boundary) or enforce an equivalent database-level constraint, so concurrent
requests cannot exceed the two-mission cap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

개인 미션 조회 API 추가, 미션 개수 제한 로직 추가

1 participant