Skip to content

Feat/#11 미션 완료 응답에 트랙 완료 여부 추가 및 다음 트랙 전환 API 구현 - #13

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

Feat/#11 미션 완료 응답에 트랙 완료 여부 추가 및 다음 트랙 전환 API 구현#13
kingmingyu merged 2 commits into
developfrom
feat/#11

Conversation

@kingmingyu

@kingmingyu kingmingyu commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Added track progression after completing all required daily missions.
    • Mission completion responses now indicate whether the track is complete and provide the next track name when available.
    • Added an endpoint to proceed to the next track when eligibility requirements are met.
    • Improved mission progress tracking based on actual daily completion criteria.
  • Bug Fixes

    • Prevented users from advancing before completing the required missions and days.
    • Improved selection of daily and custom missions.

@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

Mission completion now returns track completion details, evaluates daily requirements by track type, and advances eligible users through sequential tracks. A new endpoint explicitly proceeds to the next track, while mission selection and progress calculations use the revised completion rules.

Changes

Mission Track Progression

Layer / File(s) Summary
Progression contracts and queries
src/main/java/com/team4/hackerton/domain/mission/dto/response/MissionCompleteResponse.java, src/main/java/com/team4/hackerton/domain/mission/code/*, src/main/java/com/team4/hackerton/domain/track/entity/TrackType.java, src/main/java/com/team4/hackerton/domain/mission/repository/MissionRepository.java
Defines the mission completion response, progression success/error codes, sequential track ordering, and repository queries for default and latest custom missions.
Completion and progression service logic
src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java
Selects missions by type, evaluates daily completion rules, returns completion status, advances eligible users, rejects incomplete progression, and recalculates completed-day progress.
Mission progression API wiring
src/main/java/com/team4/hackerton/domain/mission/controller/MissionController.java
Returns MissionCompleteResponse from mission completion and adds POST /api/missions/proceed for advancing to the next track.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant MissionController
  participant MissionService
  participant TrackRepository
  Client->>MissionController: POST /api/missions/proceed
  MissionController->>MissionService: proceedToNextTrack(user)
  MissionService->>MissionService: validate completed days
  MissionService->>TrackRepository: find next track
  MissionService-->>MissionController: MissionCompleteResponse
  MissionController-->>Client: API response
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 The title accurately summarizes the main change: adding track-completion info to mission completion responses and implementing next-track transition API.
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/#11

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

@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: 3

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

98-101: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Duplicated + N+1 day-completion counting.

This allDates.stream().filter(isDayCompleted).count() block is repeated verbatim in proceedToNextTrack (Line 195-197) and getMissionProgress (Line 225-227), and each isDayCompleted call issues 2–3 additional queries per date. Extracting a countCompletedDays(user, track, joinedAt) helper removes the duplication and gives one place to optimize the per-date query fan-out (e.g., pre-fetching logs/missions once).

🤖 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 98 - 101, Extract the repeated completed-day calculation into a
private countCompletedDays(user, track, joinedAt) helper and replace the
duplicated stream blocks in proceedToNextTrack and getMissionProgress with calls
to it. Preserve the existing isDayCompleted behavior while centralizing the
logic, and structure the helper as the single location for future optimization
of per-date query fan-out.
🤖 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/controller/MissionController.java`:
- Around line 54-68: Update MissionService.completeMission so track advancement
is handled consistently with the documented API contract, then revise
MissionController.completeMission’s Swagger description to match the actual
service behavior and remove the incorrect instruction to call POST
/api/missions/proceed when trackCompleted is true.

In
`@src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java`:
- Around line 107-119: Update completeMission to stop advancing the track:
remove its next-track lookup and UserTrack creation, while retaining only the
completion reporting fields (trackCompleted and nextTrackName). Keep the
transition logic exclusively in proceedToNextTrack, which already completes the
current track and creates the next UserTrack.
- Around line 133-142: Update isDayCompleted so non-SELF_CARE progression
requires the scheduled common mission but only checks for a completed
USER_CUSTOM mission when custom missions exist; return true after the common
mission for users with no custom missions, while preserving the existing
custom-completion requirement when applicable.

---

Nitpick comments:
In
`@src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java`:
- Around line 98-101: Extract the repeated completed-day calculation into a
private countCompletedDays(user, track, joinedAt) helper and replace the
duplicated stream blocks in proceedToNextTrack and getMissionProgress with calls
to it. Preserve the existing isDayCompleted behavior while centralizing the
logic, and structure the helper as the single location for future optimization
of per-date query fan-out.
🪄 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: 02dbd3b7-a3a8-4e26-9d63-0f1c3c8edb4b

📥 Commits

Reviewing files that changed from the base of the PR and between dbd23f7 and 88981be.

📒 Files selected for processing (7)
  • 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/dto/response/MissionCompleteResponse.java
  • src/main/java/com/team4/hackerton/domain/mission/repository/MissionRepository.java
  • src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java
  • src/main/java/com/team4/hackerton/domain/track/entity/TrackType.java

Comment on lines +54 to 68
description = "특정 미션을 오늘 완료 처리합니다. 하루에 같은 미션은 1번만 완료할 수 있습니다.\n\n"
+ "- 응답의 `trackCompleted`가 `true`이면 `POST /api/missions/proceed`를 호출하여 다음 트랙으로 이동하세요."
)
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "미션 완료 성공"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "미션을 찾을 수 없음 (MISSION404_2)", content = @Content(schema = @Schema(hidden = true))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "409", description = "이미 완료한 미션 (MISSION409_1)", content = @Content(schema = @Schema(hidden = true)))
})
@PostMapping("/{missionId}/complete")
public ApiResponse<Void> completeMission(
public ApiResponse<MissionCompleteResponse> completeMission(
@AuthenticationPrincipal CustomUserDetails userDetails,
@PathVariable Long missionId) {
missionService.completeMission(userDetails.getUser(), missionId);
return ApiResponse.onSuccess(MissionSuccessCode.COMPLETE_MISSION_SUCCESS);
MissionCompleteResponse response = missionService.completeMission(userDetails.getUser(), missionId);
return ApiResponse.onSuccess(MissionSuccessCode.COMPLETE_MISSION_SUCCESS, response);
}

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 | 🟠 Major | ⚡ Quick win

The doc instructs clients to call POST /api/missions/proceed when trackCompleted is true, but the service already advances the track inside completeMission. This is the downstream symptom of the service-layer issue flagged in MissionService.completeMission (Line 107-119); resolving it there keeps this contract consistent.

🤖 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/controller/MissionController.java`
around lines 54 - 68, Update MissionService.completeMission so track advancement
is handled consistently with the documented API contract, then revise
MissionController.completeMission’s Swagger description to match the actual
service behavior and remove the incorrect instruction to call POST
/api/missions/proceed when trackCompleted is true.

Comment on lines +107 to +119
userTrack.complete(today);

TrackType nextType = track.getTrackType().next();
if (nextType == null) {
return new MissionCompleteResponse(true, null);
}

Track nextTrack = trackRepository.findByTrackType(nextType)
.orElseThrow(() -> new AppException(TrackErrorCode.TRACK_NOT_FOUND));
userTrackRepository.save(new UserTrack(user, nextTrack, today));

return new MissionCompleteResponse(true, nextType.getDisplayName());
}

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 | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the service and controller to inspect the relevant methods and docs.
ast-grep outline src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java --view expanded
printf '\n---\n'
ast-grep outline src/main/java/com/team4/hackerton/domain/mission/controller/MissionController.java --view expanded
printf '\n---\n'
ast-grep outline src/main/java/com/team4/hackerton/domain/mission/dto/MissionCompleteResponse.java --view expanded
printf '\n---\n'
ast-grep outline src/main/java/com/team4/hackerton/domain/mission/dto --view expanded

Repository: 8th-COKERTHON/server-team4

Length of output: 1598


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read only the relevant slices after locating line numbers.
sed -n '1,260p' src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java
printf '\n---CONTROLLER---\n'
sed -n '1,260p' src/main/java/com/team4/hackerton/domain/mission/controller/MissionController.java

Repository: 8th-COKERTHON/server-team4

Length of output: 18642


completeMission should not advance the track here. proceedToNextTrack already calls userTrack.complete(today) and creates the next UserTrack, so this path is mutating the same state twice and makes the /complete/proceed flow inconsistent. Keep completeMission to reporting trackCompleted/nextTrackName only, and leave the transition to proceedToNextTrack.

🤖 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 107 - 119, Update completeMission to stop advancing the track:
remove its next-track lookup and UserTrack creation, while retaining only the
completion reporting fields (trackCompleted and nextTrackName). Keep the
transition logic exclusively in proceedToNextTrack, which already completes the
current track and creates the next UserTrack.

Comment on lines +133 to +142
} else {
if (defaultMissions.isEmpty()) return false;
long dayIndex = ChronoUnit.DAYS.between(joinedAt, date);
Mission todayCommon = defaultMissions.get((int) (dayIndex % defaultMissions.size()));
if (!completedMissionIds.contains(todayCommon.getId())) return false;

Set<Long> customMissionIds = missionRepository.findByUserAndTrackAndType(user, track, MissionType.USER_CUSTOM)
.stream().map(Mission::getId).collect(Collectors.toSet());
return completedMissionIds.stream().anyMatch(customMissionIds::contains);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the target file around the reported lines
sed -n '1,240p' src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java

# Search for related mission type logic and custom mission limits
rg -n "SELF_CARE|USER_CUSTOM|isDayCompleted|defaultMissions|completedMissionIds|custom mission|customMissions|missionRepository.findByUserAndTrackAndType" src/main/java

Repository: 8th-COKERTHON/server-team4

Length of output: 16602


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,240p' src/main/java/com/team4/hackerton/domain/mission/service/MissionService.java

printf '\n--- SEARCH ---\n'
rg -n "SELF_CARE|USER_CUSTOM|isDayCompleted|defaultMissions|completedMissionIds|custom mission|customMissions|missionRepository.findByUserAndTrackAndType" src/main/java

Repository: 8th-COKERTHON/server-team4

Length of output: 16618


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map mission-related files and inspect the service and entity definitions.
git ls-files | rg '^src/main/java/.+Mission|^src/main/java/.+Track|^src/main/java/.+MissionType|^src/main/java/.+MissionRepository|^src/main/java/.+TrackRepository'

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

printf '\n--- Search for custom-mission constraints ---\n'
rg -n "0-2|2개|USER_CUSTOM|SELF_CARE|create.*custom|add.*custom|findByUserAndTrackAndType|isDayCompleted|completedMissionIds" src/main/java

Repository: 8th-COKERTHON/server-team4

Length of output: 7715


Non-SELF_CARE progression is gated on an optional custom mission.
isDayCompleted requires a completed USER_CUSTOM mission after the common mission, but custom missions are optional and capped at 2. A user with no custom mission can never count a day as complete, so track progress gets stuck.

🤖 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 133 - 142, Update isDayCompleted so non-SELF_CARE progression
requires the scheduled common mission but only checks for a completed
USER_CUSTOM mission when custom missions exist; return true after the common
mission for users with no custom missions, while preserving the existing
custom-completion requirement when applicable.

@kingmingyu
kingmingyu merged commit ce82944 into develop Jul 10, 2026
2 checks passed
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.

미션 완료 시 트랙 자동 업데이트 로직 추가

1 participant