Glowb Dev Docs
Admin API대리제출

POST /ai/admin/proxy-submission/applications/{applicationId}/review

관리자가 크리에이터 대신 1·2차 검수를 제출

검수 대리제출 (관리자용)

크리에이터가 직접 제출하지 못하는 상황에서 관리자가 1·2차 검수 제출을 대신 수행합니다. 처리 결과는 크리에이터가 웹앱에서 직접 제출한 것과 동일합니다.

매직링크와의 차이

제출 링크(매직링크)는 1회용 링크를 발급해 크리에이터가 그 링크를 열어야 제출됩니다. 크리에이터가 링크 자체를 열지 못하는 경우(화면 진입 불가, 링크 미수신 등)에는 쓸 수 없습니다. 이 API는 링크 없이 관리자가 바로 제출합니다.

처리 순서

  1. applicationId로 신청 조회
  2. reviewId가 그 신청의 검수 라운드인지 검증 (다른 신청 제출 방지)
  3. VIDEO 항목은 트랜스코딩 트리거 (웹앱·매직링크와 동일한 호출)
  4. 기존 일괄 제출(batchSubmit) 호출 → 저장 · 제출 · 히스토리 · 피드백 해결
  5. 광고주 "제출했습니다" 알림 발행

3번과 5번은 이 API가 직접 수행합니다. 크리에이터 제출 API(PUT /ai/influence/contents/review/{reviewId}/submit)를 관리자 토큰으로 그대로 호출하면 두 가지가 빠집니다. 광고주 알림은 원래 크리에이터 웹앱이 브라우저에서 발송하는 구조라, 서버 경로로 제출하면 발화하지 않습니다.

웹앱 경로는 변경되지 않았으므로 중복 발송은 발생하지 않습니다. 한 건의 제출은 웹앱·매직링크·대리제출 중 한 경로만 탑니다.

HTTP 요청

POST /ai/admin/proxy-submission/applications/{applicationId}/review
Authorization: Bearer {access_token}
Content-Type: application/json

Path Parameters

파라미터타입필수설명
applicationIdlong예대상 신청(CampaignApplication) ID

Request Body

{
  "reviewId": 1090,
  "items": [
    {
      "itemType": "VIDEO",
      "filePath": "https://storage.googleapis.com/glowb-input/campaign/content/admin/20652/...mp4"
    },
    {
      "itemType": "CAPTION",
      "editorState": "{\"root\":{\"children\":[]}}"
    },
    {
      "itemType": "HASHTAG",
      "editorState": "{\"root\":{\"children\":[]}}"
    }
  ]
}
필드명타입필수설명
reviewIdlong예제출할 검수 라운드 ID. 해당 신청의 라운드여야 합니다
itemsarray예제출물 목록 (크리에이터 일괄 제출과 동일 구조)
items[].itemIdlong조건부제출물 ID (기존 항목 수정 시 필수, 신규는 생략)
items[].itemTypestring조건부제출물 타입 (신규 시 필수). SCRIPT_VIDEO, SCRIPT_BLOG, VIDEO, PHOTO, CAPTION, HASHTAG
items[].scriptIndexinteger아니오장면 번호(0부터). SCRIPT_VIDEO/SCRIPT_BLOG 다중 장면용. 생략 시 서버가 자동 부여. 그 외 타입은 무시
items[].filePathstring조건부GCS URL. VIDEO/PHOTO는 필수이며, 비어 있으면 에러
items[].editorStatestring아니오에디터 상태 JSON을 문자열로 직렬화(stringify) 한 값
items[].commentstring아니오크리에이터 코멘트 (Lexical 에디터 JSON 문자열). 생략하면 재제출 시 이전 차수 코멘트는 비워집니다 (새 차수는 빈칸에서 시작)

editorState는 반드시 문자열입니다. 객체째 보내면 Cannot deserialize String from Object 로 실패합니다.

영상이 포함된 제출

VIDEO/PHOTO 항목의 filePath는 업로드 URL 발급으로 받은 publicUrl을 그대로 넣습니다. 업로드를 먼저 끝낸 뒤 이 API를 호출합니다.

응답

성공 응답 (200 OK) — 크리에이터 일괄 제출과 동일한 BatchResponse

{
  "status": 200,
  "code": null,
  "message": "제출 완료",
  "data": {
    "reviewId": 1090,
    "items": [ { "id": 3879, "itemType": "VIDEO", "isSubmitted": true } ],
    "resolvedFeedbackCount": 0
  }
}

에러 응답

이 서버는 에러도 HTTP 200으로 내려보내고, 실제 상태는 응답 본문의 status/code 에 담습니다. 클라이언트는 HTTP 상태가 아니라 본문을 보고 분기해야 합니다. (인증·인가 실패만 예외적으로 실제 401/403)

상황본문 status메시지
신청 없음404신청을 찾을 수 없습니다.
reviewId 누락404reviewId 는 필수입니다.
검수 라운드 없음404검수 라운드를 찾을 수 없습니다.
다른 신청의 라운드404해당 신청의 검수 라운드가 아닙니다.
제출물 없음404제출할 제출물이 없습니다.
VIDEO/PHOTO 파일 없음404영상/사진 파일을 업로드해주세요.
인증 실패HTTP 401토큰이 만료되었습니다.
ADMIN 권한 아님HTTP 403권한이 없는 요청 입니다.

감사 기록

제출 주체를 담는 컬럼이 없어 DB만 보면 크리에이터 본인 제출과 구분되지 않습니다. 누가 대신 제출했는지는 애플리케이션 로그로만 남습니다.

[AdminProxySubmission] 검수 대리제출 완료. adminId=..., applicationId=..., reviewId=..., influenceNo=...

API 테스트

On this page