검수 프로세스 정책
캠페인 콘텐츠 검수(Review) 단계의 상태 판단 로직과 플로우
검수 프로세스 정책
캠페인 콘텐츠 검수(Review) 단계의 상태 판단 로직과 플로우를 정리합니다.
프론트엔드 요약 (Quick Reference)
응답 필드 한눈에 보기
캠페인 신청 목록 API 응답에서 검수 단계(FIRST_REVIEW, SECOND_REVIEW)일 때 내려오는 필드입니다.
| 필드 | 의미 | 언제 true? |
|---|---|---|
hasNewFeedback | 크리에이터가 처리할 일이 있는지 | 미반영 피드백이 있거나, 추가 검수 요청이 와서 재제출이 필요할 때 |
hasAdditionalReviewRequest | 기업이 추가 검수를 요청했는지 | 기업이 추가 검수를 요청했고, 크리에이터가 아직 완료하지 않았을 때 |
needsResubmission | 크리에이터가 지금 재제출해야 하는지 | 수정/재제출이 필요한 상태일 때 |
isSubmitted | 제출물을 제출했는지 | 크리에이터가 제출물을 제출한 상태일 때 |
hasNewFeedback은 "새 피드백"만 의미하지 않습니다.
이름과 달리 실제로는 "크리에이터에게 할 일이 있다" 라는 의미입니다.
기업이 추가 검수를 요청하면, 새 피드백이 없어도 hasNewFeedback = true가 됩니다.
hasNewFeedback = true가 되는 2가지 경우:
| 경우 | 설명 |
|---|---|
| 미반영 피드백 존재 | 기업이 남긴 피드백을 크리에이터가 아직 반영하지 않음 |
| 추가 검수 요청 존재 | 기업이 추가 검수를 요청했고 크리에이터가 아직 미완료 (새 피드백이 없어도 true) |
추가 검수 요청 2가지 유형과 응답값
기업이 추가 검수를 요청하는 경우 2가지 유형이 있습니다.
프론트 응답값(hasNewFeedback, hasAdditionalReviewRequest)은 둘 다 동일하게 true입니다.
| 유형 | 설명 | 크레딧 차감 | hasNewFeedback | hasAdditionalReviewRequest |
|---|---|---|---|---|
피드백 미반영 (FEEDBACK_NOT_REFLECTED) | 기존 피드백/가이드라인을 크리에이터가 반영 안 함 | 없음 | true | true |
가이드라인 외 요청 (OUTSIDE_GUIDELINE) | 가이드라인에 없는 새 요구사항 추가 | 50,000원 | true | true |
두 유형의 차이는 기업 측 크레딧 차감 여부와 내부 피드백 리셋 동작뿐이며, 크리에이터에게 내려가는 상태값은 동일합니다.
UI 활용 예시
if (hasNewFeedback && hasAdditionalReviewRequest) {
// "추가 검수 요청이 있습니다. 확인 후 재제출해주세요." 표시
} else if (hasNewFeedback && !hasAdditionalReviewRequest) {
// "새로운 피드백이 있습니다." 뱃지 표시
}
if (needsResubmission) {
// "재제출" CTA 버튼 활성화
}관련 코드
| 파일 | 역할 |
|---|---|
CampaignApplicationService.java | 캠페인 신청 목록 조회 시 검수 상태 계산 |
ContentSubmissionService.java | 제출물 관리, 추가 검수 요청 처리 |
ReviewStatusHelper.java | needsResubmission 등 검수 상태 헬퍼 |
ContentReview (Entity) | 검수 라운드 정보 (maxFeedbackCount, currentFeedbackCount) |
ContentFeedback (Entity) | 개별 피드백 (resolved 필드) |
AdditionalReviewRequest (Entity) | 추가 검수 요청 내역 (유형, 크레딧 차감 등) |
AdditionalReviewRequestType (Enum) | 추가 검수 요청 유형 |
CampaignApplicationItemDto | 프론트 응답 DTO |
핵심 필드 설명
ContentReview 주요 필드
| 필드 | 기본값 | 설명 |
|---|---|---|
maxFeedbackCount | 1 | 허용된 총 검수 횟수. 기업이 추가 검수를 요청할 때마다 +1 증가 |
currentFeedbackCount | 0 | 크리에이터가 완료한 검수 횟수 |
reviewRound | - | 검수 라운드 (1차 or 2차) |
ContentFeedback 주요 필드
| 필드 | 설명 |
|---|---|
resolved | 크리에이터가 해당 피드백을 반영했는지 여부 (true/false) |
추가 검수 요청 유형 (AdditionalReviewRequestType)
기업이 추가 검수를 요청할 때 2가지 유형이 있으며, 둘 다 maxFeedbackCount++을 발생시킵니다.
| 유형 | Enum | 크레딧 차감 | 피드백 리셋 | 설명 |
|---|---|---|---|---|
| 피드백 미반영 | FEEDBACK_NOT_REFLECTED | 없음 (0원) | 있음 (지정한 피드백 resolved → false) | 기존 피드백/가이드라인을 크리에이터가 반영하지 않은 경우 |
| 가이드라인 외 요청 | OUTSIDE_GUIDELINE | 50,000원 | 없음 | 가이드라인에 없는 새로운 요구사항을 추가하는 경우 |
유형별 실행되는 로직 (ContentSubmissionService.createAdditionalReviewRequest)
공통 (두 유형 모두):
maxFeedbackCount++(예: 1→2)ReviewStatus → REJECTED
FEEDBACK_NOT_REFLECTED만 추가로:
3. resetUnreflectedFeedbacksAndItems() 호출
- 지정된 피드백의
resolved → false,checkedByCreator → false - 해당 제출물
status → REJECTED
OUTSIDE_GUIDELINE만 추가로:
3. 50,000 크레딧 차감 (creditTransactionService.recordUsage)
상태 판단 로직
CampaignApplicationService.getMyApplications() 에서 ApplicationPhase가 FIRST_REVIEW 또는 SECOND_REVIEW일 때만 계산됩니다.
ContentReview가 존재하지 않으면 모든 필드는 false입니다.
hasNewFeedback - 새로운 피드백 유무
크리에이터에게 "처리할 일이 있다"는 신호입니다.
hasNewFeedback = hasUnresolvedFeedback || hasPendingAdditionalReview| 서브 조건 | 판단 기준 |
|---|---|
hasUnresolvedFeedback | 해당 리뷰의 ContentFeedback 중 resolved == false인 것이 1개라도 존재 |
hasPendingAdditionalReview | maxFeedbackCount > 1 && maxFeedbackCount > currentFeedbackCount |
true가 되는 경우
- 기업이 피드백을 남겼고, 크리에이터가 아직 반영(resolve)하지 않은 피드백이 있을 때
- 기업이 추가 검수를 요청했고, 크리에이터가 아직 완료하지 않았을 때
- 위 1, 2 둘 다 해당될 때
false가 되는 경우
- 미해결 피드백이 전부 없고 (
resolved == true) + 추가 검수 요청도 없거나 이미 완료된 경우
hasAdditionalReviewRequest - 추가 검수 요청 여부
기업이 "추가 검수를 요청했다"는 신호입니다.
hasAdditionalReviewRequest = maxFeedbackCount > 1 && maxFeedbackCount > currentFeedbackCounttrue가 되는 경우
- 기업이 추가 검수를 1회 이상 요청했고 (
maxFeedbackCount > 1) - 크리에이터가 해당 추가 검수를 아직 완료하지 않은 상태 (
currentFeedbackCount < maxFeedbackCount)
false가 되는 경우
- 추가 검수 요청이 한 번도 없었을 때 (
maxFeedbackCount == 1, 기본값) - 추가 검수가 요청되었지만 크리에이터가 모두 완료했을 때 (
currentFeedbackCount >= maxFeedbackCount)
needsResubmission - 재제출 필요 여부
ReviewStatusHelper.needsResubmission(reviewId)에서 판단합니다.
크리에이터가 지금 수정/재제출해야 하는지 여부를 나타냅니다.
필드 간 관계
hasAdditionalReviewRequest ⊂ hasNewFeedbackhasAdditionalReviewRequest가 true이면 hasNewFeedback도 반드시 true입니다.
(hasPendingAdditionalReview와 hasAdditionalReviewRequest는 동일한 조건)
유형별 상태 변경 비교
FEEDBACK_NOT_REFLECTED (피드백 미반영, 크레딧 차감 없음)
기업이 "이 피드백 반영 안 됐다"고 요청하는 경우.
[요청 직후]
maxFeedbackCount++ (예: 1→2)
지정된 피드백 resolved → false (리셋)
ReviewStatus → REJECTED
hasUnresolvedFeedback = true (피드백이 리셋되어 미해결 상태)
hasPendingAdditionalReview = true (maxFeedbackCount > currentFeedbackCount)
──────────────────────────────────
hasNewFeedback = true (둘 다 true → OR 결과 true)
hasAdditionalReviewRequest = true
[크리에이터가 피드백 반영 후 재제출]
피드백 resolved → true
currentFeedbackCount++
hasUnresolvedFeedback = false
hasPendingAdditionalReview = false (currentFeedbackCount >= maxFeedbackCount)
──────────────────────────────────
hasNewFeedback = false
hasAdditionalReviewRequest = falseOUTSIDE_GUIDELINE (가이드라인 외 요청, 50,000원 크레딧 차감)
기업이 "가이드라인에 없지만 이것도 수정해줘"라고 요청하는 경우.
[요청 직후]
maxFeedbackCount++ (예: 1→2)
50,000원 크레딧 차감
ReviewStatus → REJECTED
(피드백 리셋 없음!)
hasUnresolvedFeedback = 기존 상태 유지 (보통 false, 이미 반영 완료된 경우)
hasPendingAdditionalReview = true (maxFeedbackCount > currentFeedbackCount)
──────────────────────────────────
hasNewFeedback = true (hasPendingAdditionalReview가 true이므로)
hasAdditionalReviewRequest = true
[크리에이터가 추가 요청 반영 후 재제출]
currentFeedbackCount++
hasUnresolvedFeedback = false (기존에도 false)
hasPendingAdditionalReview = false (currentFeedbackCount >= maxFeedbackCount)
──────────────────────────────────
hasNewFeedback = false
hasAdditionalReviewRequest = false핵심 차이점 요약
FEEDBACK_NOT_REFLECTED | OUTSIDE_GUIDELINE | |
|---|---|---|
| 크레딧 차감 | 없음 | 50,000원 |
| 피드백 리셋 | 있음 (resolved → false) | 없음 |
hasNewFeedback이 true가 되는 이유 | hasUnresolvedFeedback + hasPendingAdditionalReview 둘 다 | hasPendingAdditionalReview만 |
hasAdditionalReviewRequest | true | true |
| 결과적으로 크리에이터에게 보이는 상태 | 동일 (재제출 필요) | 동일 (재제출 필요) |
결론: 프론트 입장에서 두 유형의
hasNewFeedback,hasAdditionalReviewRequest값 자체는 동일하게true입니다. 차이는 내부적으로FEEDBACK_NOT_REFLECTED는 기존 피드백을 리셋하여hasUnresolvedFeedback도 함께true가 되고,OUTSIDE_GUIDELINE은hasPendingAdditionalReview만으로hasNewFeedback이true가 된다는 점입니다.
전체 상태 변경 플로우
[1] 기업이 피드백 작성
→ ContentFeedback 생성 (resolved = false)
→ hasUnresolvedFeedback = true
→ hasNewFeedback = true
[2] 크리에이터가 피드백 반영 후 재제출
→ ContentFeedback.resolved = true
→ hasUnresolvedFeedback = false
→ (추가 검수 없으면) hasNewFeedback = false
[3-A] 기업이 추가 검수 요청 (FEEDBACK_NOT_REFLECTED)
→ maxFeedbackCount++ (예: 1→2, 2→3)
→ 지정된 피드백 resolved → false (리셋)
→ ReviewStatus → REJECTED
→ hasUnresolvedFeedback = true (리셋으로 인해)
→ hasPendingAdditionalReview = true
→ hasNewFeedback = true (두 조건 모두 true)
→ hasAdditionalReviewRequest = true
[3-B] 기업이 추가 검수 요청 (OUTSIDE_GUIDELINE, 50,000원 차감)
→ maxFeedbackCount++ (예: 1→2, 2→3)
→ 50,000원 크레딧 차감
→ ReviewStatus → REJECTED
→ (피드백 리셋 없음)
→ hasUnresolvedFeedback = 기존 상태 유지
→ hasPendingAdditionalReview = true
→ hasNewFeedback = true (hasPendingAdditionalReview로 인해)
→ hasAdditionalReviewRequest = true
[4] 크리에이터가 추가 검수 완료
→ currentFeedbackCount++
→ currentFeedbackCount >= maxFeedbackCount 이면:
→ hasPendingAdditionalReview = false
→ hasAdditionalReviewRequest = false
→ (미해결 피드백도 없으면) hasNewFeedback = false프론트엔드 활용 가이드
| 필드 | 용도 |
|---|---|
hasNewFeedback | 크리에이터 목록에서 "새 피드백" 뱃지/알림 표시 |
hasAdditionalReviewRequest | "추가 검수 요청" 안내 메시지 표시 |
needsResubmission | "재제출 필요" CTA 버튼 활성화 |
isSubmitted | 제출 완료 상태 표시 |
예시 시나리오
시나리오 1: 일반 검수 (추가 요청 없음)
| 단계 | maxFeedback | currentFeedback | unresolvedFeedback | hasNewFeedback | hasAdditionalReview |
|---|---|---|---|---|---|
| 초기 (제출 전) | 1 | 0 | 없음 | false | false |
| 기업 피드백 작성 | 1 | 0 | 있음 | true | false |
| 크리에이터 반영 완료 | 1 | 0 | 없음 | false | false |
시나리오 2: 피드백 미반영으로 추가 검수 (FEEDBACK_NOT_REFLECTED)
| 단계 | maxFeedback | currentFeedback | unresolvedFeedback | hasNewFeedback | hasAdditionalReview | 크레딧 차감 |
|---|---|---|---|---|---|---|
| 1차 피드백 반영 완료 | 1 | 0 | 없음 | false | false | - |
| 기업: 피드백 미반영 요청 | 2 | 0 | 있음 (리셋) | true | true | 없음 |
| 크리에이터 반영 후 재제출 | 2 | 1 | 없음 | false | false | - |
시나리오 3: 가이드라인 외 추가 요청 (OUTSIDE_GUIDELINE)
| 단계 | maxFeedback | currentFeedback | unresolvedFeedback | hasNewFeedback | hasAdditionalReview | 크레딧 차감 |
|---|---|---|---|---|---|---|
| 1차 피드백 반영 완료 | 1 | 0 | 없음 | false | false | - |
| 기업: 가이드라인 외 요청 | 2 | 0 | 없음 (리셋 안함) | true | true | 50,000원 |
| 크리에이터 반영 후 재제출 | 2 | 1 | 없음 | false | false | - |
시나리오 4: 추가 검수 + 미해결 피드백 동시
| 단계 | maxFeedback | currentFeedback | unresolvedFeedback | hasNewFeedback | hasAdditionalReview |
|---|---|---|---|---|---|
| 기업 추가 검수 요청 + 피드백 | 2 | 0 | 있음 | true | true |
| 피드백만 반영 (추가검수 미완) | 2 | 0 | 없음 | true | true |
| 추가 검수까지 완료 | 2 | 1 | 없음 | false | false |