Conversation
- Service: 공고/질문 CRUD 39개 (Given-When-Then, Mockito) - Controller: @WebMvcTest 정상/예외/Valid/Security 38개 - Integration: @SpringBootTest Testcontainers 13개 - Repository: existsByRecruitmentId 등 파생 쿼리 보강
- CreateQuestions TABLE metadata 누락: TC-008 → TC-007b (기존 TC-008=multiple과 충돌 회피) - Controller order_num @positive: EX-002 → TC-009b (기존 EX-002=limit_length와 충돌 회피)
- applicant_eval 엔티티 + applicant.final_decision 컬럼 추가 - 지원자/평가 대시보드 조회, 최종 평가 수정(대표진), 지원서별/개인 평가 조회, 개인 평가 저장(upsert) - 권한 검증(대표진 SUPER&대표진, 쓰기 본인 부문 제한) + 평가 집계 서버 계산 - 개인 평가 저장은 네이티브 ON DUPLICATE KEY UPDATE로 동시성 멱등 보장
같은 트랜잭션에서 applicant/admin 저장 직후 네이티브 INSERT 실행 시 FK 대상 미flush로 인한 위반 방지 (통합 테스트 환경 보정)
- Service(Mockito): 집계·권한·부문·예외 분기 - Controller(@WebMvcTest): 계약·@Valid·401/403 - Repository(Testcontainers): upsert insert/update/멱등/null - 통합(@SpringBootTest): 저장→집계, upsert 재저장, 권한
GET /api/v1/admin/accounts/me 엔드포인트로 인증된 본인의 id, 소속, 이름 반환
- 전체 주석 해제하여 local(sql.init always+ddl create) 시드 복구 - applicants에 final_decision 명시 (NOT NULL, DB 기본값 없음) - 차기대표진 + 부문별 평가자 admin 추가, applicant_eval 시드 5건 추가
[Feat] 지원서 평가 어드민 기능 + 관리자 본인 정보 기능
…-crud #136 recruitment admin CRUD 테스트 (REC-ADMIN-002~009)
서류 평가 결과 전달용으로 CSV에 '최종 평가' 컬럼을 추가한다. 전화번호 다음 위치에 배치하고, 값은 한글로 표기한다. (PASS→합격, FAIL→불합격, HOLD→보류, PENDING→미정)
decision 파라미터(PASS/FAIL/ALL, 기본 ALL)로 추출 범위를 지정한다. - DecisionFilter enum 신설 (ALL → final_decision 필터 미적용) - 리포지토리에 final_decision nullable 필터 조건 추가 (DB 레벨 필터) - S3 키에 추출 필터 표기하여 합격/불합격/전체 파일 구분 - decision 미지정 시 ALL로 동작하여 기존 호출과 하위호환 유지
- CsvServiceTest: '최종 평가' 컬럼 위치·한글 표기 검증 - RecruitmentServiceTest: decision=PASS 필터 전달·S3 키 표기, ALL→null 검증 - ApplicantRepositoryTest: 메서드 시그니처 변경 반영, final_decision 필터 케이스 추가 - RecruitmentIntegrationTest: decision=PASS end-to-end (합격자만 포함) 검증 - RecruitmentAdminControllerTest: decision 파라미터 전달·잘못된 값 400 검증
term 26(recruitment_id=1)에 부문별 final_decision=PASS·FAIL 지원자를 추가하여 decision=PASS/FAIL/ALL 추출 결과를 수동 검증할 수 있게 한다. (user/applicant id 5~10, 기존 지원자는 그대로 유지)
[Feat] 지원서 CSV 추출 고도화 (최종 평가 컬럼 + decision 필터)
…tion) - AdminServiceTest: 계정 CRUD·비밀번호·권한 분기 단위 테스트 (Mockito) - AdminControllerTest: HTTP 계약·@Valid·Security 슬라이스 (@WebMvcTest) - AdminRepositoryTest: soft delete 제외·정렬·평가자 풀 커스텀 쿼리 (@DataJpaTest) - AdminIntegrationTest: 생성/수정/삭제/비번 end-to-end + RefreshToken 삭제 (@SpringBootTest)
[Test] Admin 도메인 테스트 코드 작성 (#174)
📝 WalkthroughWalkthrough관리자 본인 계정 조회, 관리자 계정 조회·수정·삭제, 지원서 평가 저장·조회·최종결정, CSV 다운로드의 결정 필터, 관련 DTO/엔티티/레포지토리, 테스트와 시드 데이터가 함께 변경되었습니다. Changes관리자 계정 흐름
지원서 평가 흐름
Sequence Diagram(s)평가 저장 흐름sequenceDiagram
participant ApplicantEvaluationAdminController
participant RecruitmentService
participant ApplicantRepository
participant ApplicantEvalRepository
ApplicantEvaluationAdminController->>RecruitmentService: saveMyEvaluation(applicantId, request, currentAdmin)
RecruitmentService->>ApplicantRepository: load Applicant and verify track
RecruitmentService->>ApplicantEvalRepository: upsert(applicantId, adminId, decision, score, memo, interviewQuestion)
RecruitmentService-->>ApplicantEvaluationAdminController: MyEvaluationResponse
CSV 다운로드 흐름sequenceDiagram
participant RecruitmentAdminController
participant RecruitmentService
participant ApplicantRepository
participant CsvService
participant S3Service
RecruitmentAdminController->>RecruitmentService: downloadApplications(term, decision)
RecruitmentService->>ApplicantRepository: findSubmittedByRecruitmentIdAndTrackAndDecision(...)
RecruitmentService->>CsvService: generateCsv(applicants)
CsvService-->>RecruitmentService: CSV bytes
RecruitmentService->>S3Service: uploadCsv(...)
RecruitmentService-->>RecruitmentAdminController: uploaded file key
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
src/test/java/com/boaz/backend/domain/recruitment/service/CsvServiceTest.java (1)
140-145: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value선택 제안: 셀 분리 로직을 재사용하면 더 견고해질 수 있어요.
decisionCell은split(",")로 셀을 나누는데, 현재 고정 컬럼들엔 콤마가 없어 정상 동작합니다. 다만 위쪽generateAndExtractCell의 따옴표 인식 정규식과 분리 방식이 달라, 향후 콤마 포함 값이 끼어들면 인덱스가 어긋날 여지가 있습니다. 동일한 분리 헬퍼를 공유하면 미래 변경에 더 안전할 것 같아요. 지금 당장 문제는 아니니 참고만 부탁드립니다. 🙂🤖 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/test/java/com/boaz/backend/domain/recruitment/service/CsvServiceTest.java` around lines 140 - 145, The CSV cell extraction in decisionCell uses a different splitting approach than generateAndExtractCell, which can make the test brittle if quoted values or commas appear later. Refactor decisionCell to reuse the same CSV parsing/splitting helper already used by generateAndExtractCell, keeping the logic consistent and centered around CsvServiceTest's shared extraction flow instead of duplicating split(",") handling.src/main/java/com/boaz/backend/domain/recruitment/service/RecruitmentService.java (1)
1038-1076: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value평가자 풀 조회 +
evalByAdmin맵 빌드 로직 공통화 제안 (선택)
getApplicantEvaluators와getApplicantInterviewQuestions가 평가자 풀 조회와applicantEvalRepository.findByApplicantIdWithAdmin(...)→evalByAdmin맵 생성까지 거의 동일하게 반복하고 있어요. 응답 매핑부만 다르니, 풀+맵 빌드를 작은 private 헬퍼로 추출하면 한쪽만 고쳐도 양쪽이 어긋나는 일을 막을 수 있을 것 같습니다. 지금 동작에는 문제 없으니 여유 될 때 다듬으시면 좋겠어요. 🙂🤖 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/boaz/backend/domain/recruitment/service/RecruitmentService.java` around lines 1038 - 1076, Both getApplicantEvaluators and getApplicantInterviewQuestions duplicate the same evaluator-pool lookup and evalByAdmin map-building logic. Extract that shared work into a small private helper in RecruitmentService, then reuse it from both methods so the evaluator selection and applicantEvalRepository.findByApplicantIdWithAdmin(...) handling stay consistent; keep the response mapping differences only in the two public methods.src/test/java/com/boaz/backend/domain/recruitment/controller/ApplicantEvaluationAdminControllerTest.java (1)
150-160: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win성공 케이스에서 응답 계약까지 같이 검증해 두면 더 안전합니다.
지금은 Line 153에서
null을 반환하도록 stub 해 둬서, 서비스가 실수로null을 내려도 이 테스트는 계속 통과합니다. 이 엔드포인트는FinalDecisionResponse를 반환하므로$.data.applicant_id,$.data.final_decision까지 확인해 두면 회귀를 더 잘 잡을 수 있어요.🤖 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/test/java/com/boaz/backend/domain/recruitment/controller/ApplicantEvaluationAdminControllerTest.java` around lines 150 - 160, The success test for ApplicantEvaluationAdminController should validate the actual response contract, not just the HTTP 200 and status field. In success() for the PATCH endpoint, replace the null stub on recruitmentService.updateFinalDecision with a valid FinalDecisionResponse and assert the returned payload fields such as $.data.applicant_id and $.data.final_decision. Keep the checks in ApplicantEvaluationAdminControllerTest aligned with the controller’s FinalDecisionResponse shape so a null service return or contract regression is caught.
🤖 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/boaz/backend/domain/recruitment/controller/ApplicantEvaluationAdminController.java`:
- Around line 82-84: The OpenAPI description on
ApplicantEvaluationAdminController#getApplicantAnswers should be updated to
match the real access rule used by
ApplicantEvaluationIntegrationTest#getApplicantAnswersTrackAccess: do not
describe “대표진” as broadly allowed, and instead state that only the explicitly
permitted role (currently 차기대표진) can access other tracks while others are
restricted to their own track’s applicants. Keep the summary unchanged and
revise only the description text so it reflects the actual authorization
contract.
In
`@src/main/java/com/boaz/backend/domain/recruitment/dto/request/FinalDecisionUpdateRequest.java`:
- Around line 12-13: The FinalDecisionUpdateRequest DTO currently accepts the
full EvaluationDecision enum, which allows non-final states like HOLD or PENDING
to be persisted through RecruitmentService.updateFinalDecision() into
Applicant.finalDecision. Restrict this request to PASS/FAIL only by adding
validation at the DTO boundary or by introducing a dedicated final-decision
enum, and update updateFinalDecision() to only accept/store those two values.
---
Nitpick comments:
In
`@src/main/java/com/boaz/backend/domain/recruitment/service/RecruitmentService.java`:
- Around line 1038-1076: Both getApplicantEvaluators and
getApplicantInterviewQuestions duplicate the same evaluator-pool lookup and
evalByAdmin map-building logic. Extract that shared work into a small private
helper in RecruitmentService, then reuse it from both methods so the evaluator
selection and applicantEvalRepository.findByApplicantIdWithAdmin(...) handling
stay consistent; keep the response mapping differences only in the two public
methods.
In
`@src/test/java/com/boaz/backend/domain/recruitment/controller/ApplicantEvaluationAdminControllerTest.java`:
- Around line 150-160: The success test for ApplicantEvaluationAdminController
should validate the actual response contract, not just the HTTP 200 and status
field. In success() for the PATCH endpoint, replace the null stub on
recruitmentService.updateFinalDecision with a valid FinalDecisionResponse and
assert the returned payload fields such as $.data.applicant_id and
$.data.final_decision. Keep the checks in ApplicantEvaluationAdminControllerTest
aligned with the controller’s FinalDecisionResponse shape so a null service
return or contract regression is caught.
In
`@src/test/java/com/boaz/backend/domain/recruitment/service/CsvServiceTest.java`:
- Around line 140-145: The CSV cell extraction in decisionCell uses a different
splitting approach than generateAndExtractCell, which can make the test brittle
if quoted values or commas appear later. Refactor decisionCell to reuse the same
CSV parsing/splitting helper already used by generateAndExtractCell, keeping the
logic consistent and centered around CsvServiceTest's shared extraction flow
instead of duplicating split(",") handling.
🪄 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
Run ID: 91a4cfa0-a066-41c8-815f-2e37923ad2fa
📒 Files selected for processing (46)
src/main/java/com/boaz/backend/domain/admin/controller/AdminController.javasrc/main/java/com/boaz/backend/domain/admin/dto/request/AdminCreateRequest.javasrc/main/java/com/boaz/backend/domain/admin/dto/response/AdminMeResponse.javasrc/main/java/com/boaz/backend/domain/admin/entity/Admin.javasrc/main/java/com/boaz/backend/domain/admin/repository/AdminRepository.javasrc/main/java/com/boaz/backend/domain/admin/service/AdminService.javasrc/main/java/com/boaz/backend/domain/recruitment/controller/ApplicantEvaluationAdminController.javasrc/main/java/com/boaz/backend/domain/recruitment/controller/RecruitmentAdminController.javasrc/main/java/com/boaz/backend/domain/recruitment/dto/request/EvaluationSaveRequest.javasrc/main/java/com/boaz/backend/domain/recruitment/dto/request/FinalDecisionUpdateRequest.javasrc/main/java/com/boaz/backend/domain/recruitment/dto/response/ApplicantAnswersResponse.javasrc/main/java/com/boaz/backend/domain/recruitment/dto/response/ApplicantEvaluationResponse.javasrc/main/java/com/boaz/backend/domain/recruitment/dto/response/ApplicantEvaluatorsResponse.javasrc/main/java/com/boaz/backend/domain/recruitment/dto/response/ApplicantInterviewQuestionsResponse.javasrc/main/java/com/boaz/backend/domain/recruitment/dto/response/ApplicantSummaryResponse.javasrc/main/java/com/boaz/backend/domain/recruitment/dto/response/EvaluatorEvaluationResponse.javasrc/main/java/com/boaz/backend/domain/recruitment/dto/response/EvaluatorInterviewQuestionResponse.javasrc/main/java/com/boaz/backend/domain/recruitment/dto/response/FinalDecisionResponse.javasrc/main/java/com/boaz/backend/domain/recruitment/dto/response/MyEvaluationResponse.javasrc/main/java/com/boaz/backend/domain/recruitment/entity/Applicant.javasrc/main/java/com/boaz/backend/domain/recruitment/entity/ApplicantEval.javasrc/main/java/com/boaz/backend/domain/recruitment/entity/DecisionFilter.javasrc/main/java/com/boaz/backend/domain/recruitment/entity/EvaluationDecision.javasrc/main/java/com/boaz/backend/domain/recruitment/repository/ApplicantAnswerRepository.javasrc/main/java/com/boaz/backend/domain/recruitment/repository/ApplicantEvalRepository.javasrc/main/java/com/boaz/backend/domain/recruitment/repository/ApplicantRepository.javasrc/main/java/com/boaz/backend/domain/recruitment/service/CsvService.javasrc/main/java/com/boaz/backend/domain/recruitment/service/RecruitmentService.javasrc/main/resources/application-dev.ymlsrc/main/resources/application-prod.ymlsrc/main/resources/data.sqlsrc/test/java/com/boaz/backend/domain/admin/controller/AdminControllerTest.javasrc/test/java/com/boaz/backend/domain/admin/integration/AdminIntegrationTest.javasrc/test/java/com/boaz/backend/domain/admin/repository/AdminRepositoryTest.javasrc/test/java/com/boaz/backend/domain/admin/service/AdminServiceTest.javasrc/test/java/com/boaz/backend/domain/recruitment/controller/ApplicantEvaluationAdminControllerTest.javasrc/test/java/com/boaz/backend/domain/recruitment/controller/RecruitmentAdminControllerTest.javasrc/test/java/com/boaz/backend/domain/recruitment/integration/ApplicantEvaluationIntegrationTest.javasrc/test/java/com/boaz/backend/domain/recruitment/integration/RecruitmentIntegrationTest.javasrc/test/java/com/boaz/backend/domain/recruitment/repository/ApplicantAnswerRepositoryTest.javasrc/test/java/com/boaz/backend/domain/recruitment/repository/ApplicantEvalRepositoryTest.javasrc/test/java/com/boaz/backend/domain/recruitment/repository/ApplicantRepositoryTest.javasrc/test/java/com/boaz/backend/domain/recruitment/repository/ApplicationQuestionRepositoryTest.javasrc/test/java/com/boaz/backend/domain/recruitment/service/CsvServiceTest.javasrc/test/java/com/boaz/backend/domain/recruitment/service/RecruitmentEvaluationServiceTest.javasrc/test/java/com/boaz/backend/domain/recruitment/service/RecruitmentServiceTest.java
💡 개요
dev에 누적된 변경사항을main으로 반영하는 통합 PR 입니다. 지원자 평가 시스템 신규 기능과 CSV 추출 필터 개선, 그리고 모집 어드민·Admin 도메인 테스트 코드 보강이 포함됩니다. (포함 PR: #171, #175, #173, #176)🪐 주요 변경 사항
final_decision) 컬럼 추가 + 합격/불합격/전체(decision) 필터 추출data.sql평가·필터 테스트용 데이터 추가,application-dev/prod.yml정비✅ 상세 내용
지원자 평가 (#171)
ApplicantEval,EvaluationDecision,DecisionFilter,Applicant최종 평가 필드PUT/GET …/applicants/{id}/evaluations/me,GET …/{recruitmentId}/applicants[/evaluations],GET …/applicants/{id}/{evaluations,answers,interview-questions},PATCH …/applicants/{id}/final-decisionCSV decision 필터 (#175)
RecruitmentService/CsvService에 decision(PASS/FAIL/ALL) 필터 + 최종 평가 컬럼 반영테스트 (#173, #176)
🔔 참고 사항
UNAUTHORIZED) 단언 (노션 명세 403 표기와 불일치 — 팀 정렬 필요)docs/test/*)는 gitignore 대상이라 diff 에 미포함@CodeRabbit ignore
/accounts/me조회 API 추가AdminMeResponseDTO 추가Admin.TeamName에차기대표진추가 및 관련 Swagger 메타데이터 갱신ApplicantEval,EvaluationDecision,DecisionFilter,ApplicantEvalRepositoryfinalDecision저장/수정 기능 추가ApplicantSummaryResponse,ApplicantEvaluationResponse,ApplicantEvaluatorsResponse,ApplicantInterviewQuestionsResponse,ApplicantAnswersResponse,FinalDecisionResponse,MyEvaluationResponse등final_decision컬럼 추가,decision(PASS/FAIL/ALL) 필터 지원application-dev.yml,application-prod.yml에admin.bigdataboaz.comCORS 허용 추가data.sql에 평가/필터링 테스트용 시드 데이터 추가 및 정리