[BE-53] recruitment 프레젠테이션 — API 컨트롤러·DTO·플래그
작업 내용 (설계 의도)
변경 사항
근거 TDD: “REST API 계약 recruitment 7종·인가”.
recruitment UseCase(BE-52)를 REST로 노출한다. community 컨트롤러의 @ConditionalOnProperty 즉시 롤백 패턴 재사용.
포함 (전부 신규 파일):
- presentation:
RecruitmentApiController(POST/recruitments, GET/recruitments, GET/recruitments/{id}, GET/recruitments/{id}/applications, POST/recruitments/{id}/applications, POST/recruitments/{id}/cancel),ApplicationApiController(GET/applications내 신청 목록, POST/applications/{id}/cancel) +@ConditionalOnProperty(recruitment.enabled).GET /applications: 인증 principal의 userId 기준ListMyApplicationsUseCase호출 — 쿼리로 넘어온 applicantUserId를 신뢰하지 않고 principal로 강제해 본인 신청만 조회(FR-4 취소 FE 경로 지탱, senior-pm 보강). 응답List<ApplicationResponse>.
- Request DTO(presentation):
CreateRecruitmentRequest(title/description/capacity/feeAmount/activityAt/applicationDeadline/communityId?)·ApplyRecruitmentRequest(paymentMethod/amount/currency) →toCommand(). - Response는 BE-52 application Response 그대로 반환(Controller가 Entity 직접 반환 금지).
- 인가:
@AuthenticationPrincipal UserPrincipal. communityId 소속 모집의 열람/신청 인가는 UseCase가 community 규칙 위임(BE-52 경유). - 신청 응답은 paymentId/checkoutUrl 포함(CreateBooking 응답 형태 참조).
롤백
recruitment.enabled=false면 컨트롤러 빈 미등록 → /recruitments 전 경로 404(즉시 롤백 지점).
의존
- BE-52 (recruitment UseCase)
다이어그램
처리 흐름
sequenceDiagram participant Cl as Client participant C as RecruitmentApiController participant U as ApplyRecruitmentUseCase Cl->>C: POST /recruitments/{id}/applications C->>U: execute(command) U-->>C: checkoutUrl/paymentId C-->>Cl: 200
클래스 의존
flowchart LR RC[RecruitmentApiController] --> CU[CreateRecruitmentUseCase] RC --> AU[ApplyRecruitmentUseCase] RC --> CanU[CancelRecruitmentUseCase] AC[ApplicationApiController] --> CAU[CancelApplicationUseCase] AC --> LMU[ListMyApplicationsUseCase]
테스트 케이스
- 인증 사용자가 유효 본문으로 모집을 개설하면 201/200과 모집 ID를 받는다
- 신청 요청이 checkoutUrl/paymentId를 반환한다
- 신청 0건 모집의 신청자 목록 조회가 빈 배열을 정상 반환한다
- 정원이 찬 모집 신청은 409로 응답한다
- 마감 이후 신청 취소 요청은 422로 응답한다
- 개설자가 아닌 사용자의 신청자 목록 조회는 403이다
GET /applications가 인증 principal 본인의 신청 목록만 반환하고 타인 신청은 노출하지 않는다- 신청 이력 없는 사용자의
GET /applications는 빈 배열을 정상 반환한다 - recruitment.enabled=false면 /recruitments·/applications 경로가 404다