[FEAT] 학습 도메인 api 기본 구현#46
Conversation
📝 WalkthroughWalkthrough학습 결과 저장 및 사용자별 진행률 조회 API가 추가되었습니다. 요청·응답 DTO, 사용자 연관 진행 엔터티, JPA 저장소, 서비스 검증·계산 로직, REST 컨트롤러와 오류 코드가 구현되었습니다. Changes학습 진행 기능
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant LearningController
participant LearningService
participant LearningRepositories
Client->>LearningController: POST /api/learnings/{learningId}/result
LearningController->>LearningService: saveResult(userId, learningId, request)
LearningService->>LearningRepositories: 사용자·학습·단계·진행 정보 조회
LearningRepositories-->>LearningService: 검증된 데이터
LearningService-->>LearningController: SaveResultResultDTO
LearningController-->>Client: ApiResponse
Client->>LearningController: GET /api/learnings/{learningId}/progress
LearningController->>LearningService: getLearningProgress(userId, learningId)
LearningService->>LearningRepositories: 전체 단계 및 완료 단계 집계
LearningRepositories-->>LearningService: 단계 수
LearningService-->>LearningController: ProgressResultDTO
LearningController-->>Client: ApiResponse
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
on1yoneprivate
left a comment
There was a problem hiding this comment.
수고하셨습니다~
코멘트 확인해 주세요!
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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/mr/domain/learning/controller/LearningController.java`:
- Around line 36-42: Update the getLearningProgress endpoint mapping to match
the agreed API contract: use `@PatchMapping` for PATCH /{learningId}/progress if
this endpoint performs progress updates, or retain `@GetMapping` only when it is
strictly read-only and revise the API documentation accordingly.
In
`@src/main/java/com/mr/domain/learning/repository/UserLearningProgressRepository.java`:
- Line 12: The progress lookup must include both user and learning step. In
src/main/java/com/mr/domain/learning/repository/UserLearningProgressRepository.java:12-12,
replace findByUser_UserIdAndLearningId with a user-and-learningStepId query
method; in
src/main/java/com/mr/domain/learning/service/LearningService.java:51-58, update
saveResult() to pass learningStep.getId() and verify the existing progress-count
query remains aligned with the requested learning ID.
In `@src/main/java/com/mr/domain/learning/service/LearningService.java`:
- Around line 48-60: Validate in the learning-step lookup flow before querying
or updating UserLearningProgress that learningStep.getLearning().getId() matches
learning.getId(); when it does not, throw or return the existing
INVALID_LEARNING_STEP error. Keep the existing not-found handling and progress
creation/update behavior unchanged for valid steps.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: f9675bec-d82f-4ba4-8362-c8b11b2a1607
📒 Files selected for processing (12)
src/main/java/com/mr/domain/learning/controller/LearningController.javasrc/main/java/com/mr/domain/learning/dto/req/LearningResultSaveRequestDTO.javasrc/main/java/com/mr/domain/learning/dto/res/LearningProgressResponseDTO.javasrc/main/java/com/mr/domain/learning/dto/res/LearningResultResponseDTO.javasrc/main/java/com/mr/domain/learning/entity/UserLearningProgress.javasrc/main/java/com/mr/domain/learning/exception/LearningErrorStatus.javasrc/main/java/com/mr/domain/learning/repository/LearningRepository.javasrc/main/java/com/mr/domain/learning/repository/LearningStepRepository.javasrc/main/java/com/mr/domain/learning/repository/UserLearningProgressRepository.javasrc/main/java/com/mr/domain/learning/service/LearningService.javasrc/main/java/com/mr/domain/user/exception/UserErrorStatus.javasrc/main/java/com/mr/domain/user/repository/UserRepository.java
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/java/com/mr/domain/learning/service/LearningService.java (1)
52-61: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win중등 생성 경쟁을 원자로 처리해 주세요.
UserLearningProgress에(user_id, learning_step_id)유니크 인덱스가 있으니 데이터 중복은 막지만,findBy...조회 후save()로 분기하는 check-then-act 구조가@Transactional하더라도 동시 요청 두 트랜잭션이 동시에 “없음”을 보고 INSERT 경쟁을 유발합니다. 이 경기는 트랜잭션이 커밋 시점에 실패로 바뀌어 500 응답을 만들 수 있으니,@Transactional(isolation = Isolation.SERIALIZABLE)/PessimisticLocklock 기반 read, 또는save()실패 후getOrCreateretry처럼 유니크 제약 위반을 우회하지 않는 전략으로 조회-생성을 묶으면 좋습니다.🤖 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/mr/domain/learning/service/LearningService.java` around lines 52 - 61, Update the UserLearningProgress lookup-and-create flow in the surrounding service method to make concurrent creation for the (user_id, learning_step_id) pair atomic, using SERIALIZABLE isolation, a pessimistic-lock read, or a save-failure retry with get-or-create behavior. Preserve the unique constraint and ensure concurrent requests resolve to the existing progress instead of propagating a uniqueness violation.
🤖 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.
Outside diff comments:
In `@src/main/java/com/mr/domain/learning/service/LearningService.java`:
- Around line 52-61: Update the UserLearningProgress lookup-and-create flow in
the surrounding service method to make concurrent creation for the (user_id,
learning_step_id) pair atomic, using SERIALIZABLE isolation, a pessimistic-lock
read, or a save-failure retry with get-or-create behavior. Preserve the unique
constraint and ensure concurrent requests resolve to the existing progress
instead of propagating a uniqueness violation.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: b0318f2e-b9c5-43a5-8722-fa842c4377da
📒 Files selected for processing (4)
src/main/java/com/mr/domain/learning/controller/LearningController.javasrc/main/java/com/mr/domain/learning/exception/LearningErrorStatus.javasrc/main/java/com/mr/domain/learning/service/LearningService.javasrc/main/java/com/mr/domain/user/exception/UserErrorStatus.java
🚧 Files skipped from review as they are similar to previous changes (2)
- src/main/java/com/mr/domain/learning/exception/LearningErrorStatus.java
- src/main/java/com/mr/domain/user/exception/UserErrorStatus.java
on1yoneprivate
left a comment
There was a problem hiding this comment.
코드래빗 제안 사항 추후에 고려해 보면 좋을 것 같습니다~
수고 많으셨어요
📍 개요
⛓️💥 관련 이슈
🛠️ 작업 내용
🔥 리뷰 요청 사항
✅ 체크리스트
📎 참고 사항
Summary by CodeRabbit
/api/learnings/{learningId}/result로 학습 결과(점수·완료 정보)를 저장하고 결과(상태 포함)를 확인할 수 있습니다./api/learnings/{learningId}/progress로 해당 학습의 진행률을 조회할 수 있습니다.