SaaS API콘텐츠 검수
PUT /ai/influence/contents/review/{reviewId}/submit
검수 라운드 일괄 제출
검수 라운드 일괄 제출
검수 라운드의 모든 제출물 내용을 저장하고 일괄 제출합니다. 신규 제출과 재제출 모두 이 API를 사용합니다.
복수 스크립트 지원
스크립트 타입(SCRIPT_VIDEO, SCRIPT_BLOG)은 scriptIndex로 각 스크립트를 구분합니다.
- 기존 스크립트 수정:
itemId로 식별 - 신규 스크립트 생성:
itemId= null,scriptIndex지정 (null이면 자동 부여)
주요 동작
- 각 제출물의 내용(filePath, editorState, comment)을 저장
- 모든 제출물을 제출 상태(
isSubmitted=true)로 변경 - 해당 검수 라운드의 모든 미해결 피드백을 해결완료(
isResolved=true) 처리 - 재제출 시 이전 버전은 히스토리로 자동 저장
HTTP 요청
PUT /ai/influence/contents/review/{reviewId}/submit
Authorization: Bearer {access_token}
Content-Type: application/jsonPath Parameters
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
reviewId | long | 예 | 검수 라운드 ID |
Request Body
{
"items": [
{
"itemId": 1,
"itemType": "SCRIPT_VIDEO",
"scriptIndex": 0,
"editorState": {"root": {"children": []}},
"comment": null
},
{
"itemId": 2,
"itemType": "SCRIPT_VIDEO",
"scriptIndex": 1,
"editorState": {"root": {"children": []}},
"comment": null
},
{
"itemId": 3,
"itemType": "CAPTION",
"filePath": null,
"editorState": {"root": {"children": []}},
"comment": null
},
{
"itemId": null,
"itemType": "HASHTAG",
"filePath": null,
"editorState": {"requiredHashtags": ["#브랜드"], "additionalHashtags": ["#추가"]},
"comment": null
}
]
}Request Body 스키마
| 필드명 | 타입 | 필수 | 설명 |
|---|---|---|---|
items | array | 예 | 제출할 제출물 목록 |
items[].itemId | long | 조건부 | 제출물 ID (기존 항목 수정 시 필수, 신규 시 null) |
items[].itemType | string | 조건부 | 제출물 타입 (신규 생성 시 필수) |
items[].scriptIndex | int | 아니오 | 스크립트 순서 인덱스 (스크립트 타입 전용, null이면 자동 부여) |
items[].filePath | string | 조건부 | S3 파일 URL (VIDEO, PHOTO 타입은 필수) |
items[].editorState | object | 아니오 | Lexical 에디터 상태 JSON (SCRIPT, CAPTION, HASHTAG 타입용) |
items[].comment | string | 아니오 | 코멘트 (선택) |
VIDEO/PHOTO 타입 필수 조건
VIDEO 또는 PHOTO 타입으로 제출할 때는 반드시 filePath에 업로드된 파일 URL이 있어야 합니다.
파일 없이 제출하면 에러가 반환됩니다.
- VIDEO 타입: "영상 파일을 업로드해주세요."
- PHOTO 타입: "사진 파일을 업로드해주세요."
itemId 사용 규칙
- 기존 제출물 수정:
itemId필수,itemType무시됨 - 신규 제출물 생성:
itemId= null,itemType필수
같은 타입의 제출물이 여러 개 있을 수 있으므로 (히스토리 관리), 반드시 itemId로 식별해야 합니다.
응답
성공 응답 (200 OK)
{
"status": 200,
"code": null,
"message": "일괄 제출 완료",
"data": {
"reviewId": 88,
"items": [
{
"id": 1,
"reviewId": 88,
"itemType": "SCRIPT_VIDEO",
"scriptIndex": 0,
"editorState": {"root": {"children": []}},
"status": "REVIEWING",
"isSubmitted": true,
"submittedAt": "2025-01-14T15:30:00",
"currentVersion": 1,
"feedbacks": []
},
{
"id": 2,
"reviewId": 88,
"itemType": "SCRIPT_VIDEO",
"scriptIndex": 1,
"editorState": {"root": {"children": []}},
"status": "REVIEWING",
"isSubmitted": true,
"submittedAt": "2025-01-14T15:30:00",
"currentVersion": 1,
"feedbacks": []
},
{
"id": 3,
"reviewId": 88,
"itemType": "CAPTION",
"scriptIndex": null,
"editorState": {"root": {"children": []}},
"status": "REVIEWING",
"isSubmitted": true,
"submittedAt": "2025-01-14T15:30:00",
"currentVersion": 1,
"feedbacks": []
}
],
"resolvedFeedbackCount": 3
}
}Response Body 스키마
| 필드명 | 타입 | 설명 |
|---|---|---|
reviewId | long | 검수 라운드 ID |
items | array | 제출된 제출물 목록 |
resolvedFeedbackCount | int | 자동으로 해결완료 처리된 피드백 수 |
에러 응답
| 상황 | 상태 코드 | 메시지 |
|---|---|---|
| VIDEO 파일 없음 | 400 | 영상 파일을 업로드해주세요. |
| PHOTO 파일 없음 | 400 | 사진 파일을 업로드해주세요. |
| 제출물 타입 누락 | 400 | 신규 생성 시 제출물 타입은 필수입니다. |
| 제출물 없음 | 400 | 제출할 제출물이 없습니다. |
PUT /items/{itemId} vs PUT /review/{reviewId}/submit 차이점
| 항목 | PUT /items/{itemId} | PUT /review/{reviewId}/submit |
|---|---|---|
| 대상 | 단일 제출물 | 검수 라운드 전체 |
| 피드백 해결 | 수동 처리 필요 | 자동 일괄 해결 |
| 제출 상태 | isSubmit에 따라 결정 | 무조건 제출 처리 |
| 용도 | 개별 저장/제출 | 최종 일괄 제출 |