SaaS API피드백 관리자 승인 (v4)
피드백 제출
검수 라운드의 피드백을 작성·제출합니다. 관리자 승인 게이트가 ON이면 크리에이터에게 바로 전달되지 않고 PENDING 상태로 대기합니다.
피드백 제출
검수 라운드의 피드백을 작성·제출합니다. 토글 ON이면 관리자 검토 대기(PENDING)로 들어가고 크리에이터에게 가지 않습니다.
인증 필요. 소유 기업(캠페인 작성자) 또는 관리자만 접근 가능 — 아니면 403 FORBIDDEN(code AUTH_002).
미디어(이미지/영상)를 첨부할 경우, 먼저 미디어 업로드 API로 파일을 업로드하여 mediaUrl을 받은 뒤, 해당 URL을 mediaList[].mediaUrl에 넣어 제출하세요.
승인 옵션
- 피드백 없이 즉시 승인: 이 API가 아니라 승인 API를 사용하세요. 게이트를 거치지 않고 바로 승인됩니다.
- 피드백을 남기면서 승인(
approveWithFeedback: true): 피드백은 즉시resolved처리되지만, 게이트(관리자 승인)는 그대로 거칩니다. 게이트가 모두 통과되면 재제출 요청이 아니라 승인으로 릴리즈됩니다. - 재제출 요청(기본,
approveWithFeedback미지정/false): 게이트 통과 후 피드백 달린 제출물이REJECTED(재제출 요청)로 릴리즈됩니다.
기존 피드백을 수정할 때는 id를 반드시 실어 보내세요.
id가 있으면 서버가 그 행을 제자리 수정합니다 — 수정 차수(revisionNo)·작성 시각·작성자가 보존됩니다.id가 없으면 새 행이 생기고, 차수는 제출 시점의 현재 차수로 찍힙니다.- 즉 기존 피드백을
id없이 재전송하면 1차 피드백이 2차로 뒤바뀌거나 중복 행이 쌓입니다.
HTTP 요청
POST /ai/v4/feedback/review/{reviewId}/submit
Authorization: Bearer {access_token}
Content-Type: application/jsonPath Parameters
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
reviewId | long | 예 | 검수 라운드 ID |
Request Body
items[] 하나로 자유/가이드라인 내·외 피드백 모두 담습니다. isDraft: true 면 임시저장(게이트/크리에이터 전달 없이 저장만). approveWithFeedback: true 면 피드백을 남기면서 승인(피드백 즉시 resolved + 게이트 통과 후 승인 릴리즈).
저장 규칙
| 요청의 항목 | 서버 동작 |
|---|---|
id 있음 (해당 라운드에 존재) | 그 행을 수정. revisionNo·createdAt·createdBy 보존 |
id 없음 | 새 행 생성. revisionNo = 라운드의 현재 차수 |
id 있으나 라운드에 없음 / 한 요청에 중복 | 새 행 생성 (서버 로그에 경고만 남고 에러는 아님) |
요청에 실리지 않은 기존 행은 다음 규칙으로 정리됩니다.
| 기존 행 | 요청에 없을 때 |
|---|---|
임시저장(isDraft: true) | 삭제 |
유료(billingType: PAID) | 삭제 |
| 무료 정식 피드백 | 유지 (삭제되지 않음) |
즉 임시저장분과 유료 피드백은 매 제출마다 전체 세트를 보내야 보존됩니다. 무료 정식 피드백은 보내지 않아도 남습니다.
{
"isDraft": false,
"approveWithFeedback": false,
"items": [
{
"itemId": 9001,
"feedback": "도입부에 훅이 없어요. Hook 장면을 추가해주세요.",
"highlightedText": null,
"selection": null,
"feedbackType": "GUIDELINE_UNREFLECTED",
"feedbackCategory": "영상 초반",
"feedbackItem": "HOOK",
"billingType": "FREE",
"mediaList": [
{ "mediaType": "IMAGE", "comment": "이 부분 참고", "mediaUrl": "https://storage.googleapis.com/{bucket}/feedback/9001/uuid_sample.jpg" },
{ "mediaType": "VIDEO", "startTime": 10.5, "endTime": 15.0, "comment": "이 구간 재촬영", "mediaUrl": "https://storage.googleapis.com/{bucket}/feedback/9001/uuid_clip.mp4" }
]
},
{
"id": 4521,
"itemId": 9001,
"feedback": "가이드라인에 없는 클로즈업 장면 추가 촬영 부탁드려요. (문구 수정)",
"feedbackType": "GUIDELINE_EXTRA",
"billingType": "PAID"
},
{
"id": 4522,
"itemId": 9001,
"feedback": "5~6초 구간 전면 재촬영 부탁드려요.",
"feedbackType": "FREE",
"feedbackItem": "재촬영",
"billingType": "PAID",
"paidScope": "full"
}
]
}SubmitRequest
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
isDraft | boolean | 아니오 | true: 임시저장(상태 변경·관리자 게이트·크리에이터 전달 없음). 미지정/false: 정식 제출. 정식 제출에 실린 행은 임시저장 상태가 해제되며, 임시저장 요청이 기존 정식 피드백을 임시저장으로 되돌리지는 않습니다 |
approveWithFeedback | boolean | 아니오 | true: 피드백 포함 승인 — 생성되는 피드백을 즉시 resolved 처리하고 검수 라운드에 "승인 의도"를 기억(approvedWithFeedback). 게이트는 그대로 거치며, 모두 통과되면 재제출이 아니라 승인으로 릴리즈. 미지정/false: 재제출 요청. 정식 제출 시 매번 요청값으로 갱신됨 |
items | SubmitItem[] | 예 | 피드백 목록 |
SubmitItem
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
id | long | 아니오 | 갱신할 기존 피드백 행 ID. 지정하면 새로 만들지 않고 그 행을 수정하며 수정 차수가 보존됨. 새로 작성한 피드백이면 생략 |
itemId | long | 예 | 피드백을 붙일 제출물(장면) ID. 해당 reviewId에 속해야 함 |
feedback | string | 아니오 | 피드백 내용 |
highlightedText | string | 아니오 | 하이라이트된 텍스트 |
selection | string | 아니오 | 선택 영역 정보(JSON 문자열) |
feedbackType | string | 아니오 | FREE/GUIDELINE_UNREFLECTED/GUIDELINE_EXTRA. 미지정 시 FREE |
feedbackCategory | string | 아니오 | AI 검수 카테고리 (예: 영상 초반) |
feedbackItem | string | 아니오 | AI 검수 항목 코드 (예: HOOK) |
translatedFeedback | string | 아니오 | 크리에이터 언어 번역문(선택). 해외 캠페인에서만 저장되고 한국 캠페인에서는 무시됩니다. 언어 코드는 서버가 캠페인으로 정합니다. 원문이 바뀌었는데 이 필드가 없으면 기존 번역문은 삭제됩니다. 번역문은 피드백 번역 API로 만들 수 있습니다. |
billingType | string | 아니오 | FREE/PAID. 미지정 시 FREE |
paidScope | string | 아니오 | 유료 검수 범위 partial(일부)/full(전면). 대소문자 무관, 알 수 없는 값은 미지정으로 처리. billingType: PAID 일 때만 저장되고 무료 피드백에 실으면 무시됩니다. 기존 행을 수정하면서 생략하면 기존 값을 유지합니다. 일부↔전면 변경은 내용 변경으로 보아 관리자 승인이 다시 대기로 돌아갑니다. 응답에서는 대문자(PARTIAL/FULL)로 내려갑니다 |
mediaList | MediaMeta[] | 아니오 | 미디어 메타데이터. 미디어는 먼저 업로드 API로 올려 받은 mediaUrl을 넣습니다 |
MediaMeta
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
mediaType | string | 아니오 | IMAGE / VIDEO. 미지정 시 IMAGE |
startTime | double | 아니오 | 영상 시작 시간(초) |
endTime | double | 아니오 | 영상 끝 시간(초) |
comment | string | 아니오 | 해당 미디어 코멘트 |
mediaUrl | string | 예 | 미디어 업로드 API(POST /ai/v4/feedback/media)로 받은 GCS URL. 없거나 blank면 해당 항목은 저장되지 않음 |
응답
성공 응답 (200)
{ "status": 200, "code": null, "message": "제출 완료", "data": null }에러 응답
| 상태 코드 | code | 상황 |
|---|---|---|
403 | AUTH_002 | 소유 기업/관리자가 아님 |
400 | INVALID_DATA | 검수 라운드/피드백/제출물 없음, 또는 itemId가 해당 reviewId에 속하지 않음 |