Glowb Dev Docs
SaaS API가이드라인 V4

가이드라인 V4 저장 (상태 전이 + COMPLETED 부가작업)

가이드라인 V4 세션의 상태를 전이시키고 COMPLETED 시 모집 단계 자동화를 수행합니다.

가이드라인 V4 저장

요청 본문으로 전달된 가이드라인 편집본을 세션 문서(data)에 머지 저장하고, 상태를 DRAFT 또는 COMPLETED 로 전이시킵니다. isModify=true 인 경우 편집본 머지는 수행하되 상태/단계는 바꾸지 않고 updatedAt만 갱신.

COMPLETED 저장 시 V2 와 동일한 부가작업(모집 마감일 자동 설정, 캠페인 벡터화, 해시태그 크롤 이벤트, 모집 콘텐츠 생성, 칸반 완료, 추가금 sync)을 함께 수행합니다.

HTTP 요청

PUT /ai/guideline/v4/{collabNo}?isFirst=true&isModify=false
Authorization: Bearer {access_token}
Content-Type: application/json

Path Parameters

파라미터타입필수설명
collabNoInteger캠페인 번호

Query Parameters

파라미터타입기본값설명
isFirstBooleantruetrue: 초안(DRAFT), false: 완성본(COMPLETED)
isModifyBooleanfalsetrue: 임시저장 (상태/단계 변경 없음. updatedAt만 갱신)

Request Body (optional)

본문은 가이드라인 데이터 맵 그 자체입니다(별도 래퍼 없음). 본문에 포함된 키만 세션 문서의 data얕게 머지됩니다.

{
  "concept_one_liner": "뷰티 크리에이터를 위한 스페인 10일 올인원 여행 패키지 모집 캠페인",
  "required_appeal_points": ["..."],
  "optional_appeal_points": ["..."],
  "hashtags": ["qabrand", "스페인여행", "인플루언서캠페인"],
  "shots": {
    "beginning": [],
    "middle": [],
    "ending": []
  },
  "upload_requirements": {
    "account_name": "brand_official",
    "narration_required": true,
    "brand_tag": { "enabled": true, "tag_methods": ["PERSON_TAG", "CAPTION_TAG"] },
    "sponsor_label": { "enabled": true, "replace_ad_tag": true },
    "collaborator": { "enabled": true },
    "product_link": { "enabled": true, "channel": "DM", "link": "https://..." },
    "is_ai_suggested": false
  },
  "providedOptions": [
    {
      "id": null,
      "title": "색상",
      "selectionType": "SINGLE",
      "sortOrder": 0,
      "choices": [
        { "id": null, "value": "아이보리", "sortOrder": 0 },
        { "id": null, "value": "그레이",   "sortOrder": 1 }
      ]
    }
  ]
}

머지 규칙

케이스동작
본문에 있는 키 (값 not-null)해당 키를 data통째 교체 (예: hashtags 배열 전체 대체)
본문에 없는 키기존 data 값 유지
본문에 있으나 값이 null스킵 (기존 유지)
providedOptionsdata 에 넣지 않고 별도 RDB sync 로만 처리

프론트는 편집한 각 필드를 완전한 상태로 보내야 합니다(얕은 머지). 예를 들어 shots 를 보낼 땐 beginning/middle/ending 전체를 포함해야 누락이 없습니다.

providedOptions (별도 RDB sync)

필드타입필수설명
providedOptionsarray아니오캠페인 제공 옵션. 임시저장/DRAFT/COMPLETED 모든 경로에서 RDB 와 diff sync. 키가 없으면(null) sync 스킵
  • 각 옵션/choice 에 id 가 있으면 기존 row 갱신 시도, 없으면 신규 insert.
  • 입력에서 빠진 기존 row 는 soft delete (deleted_at 셋팅).
  • 캠페인에 PROPOSAL 신청자가 1건이라도 있으면 전체 거부 (PROVIDED_OPTION_LOCKED).
  • 자세한 정책은 캠페인 제공 옵션 개요 참고.

upload_requirements (타입드 — 추가금 자동 sync 대상)

크리에이터 업로드 항목. 단가 상승이 붙는 항목만 추가금으로 잡혀 TB_CAMPAIGN_ADDON_FEE 에 sync 된다.

필드타입추가금설명
account_namestring | null브랜드 태그/협찬 레이블/공동 작업자에서 공통으로 쓰는 계정명
narration_requiredbooleanNARRATION나레이션 삽입
brand_tag{ enabled, tag_methods }브랜드 계정 태그. tag_methods: PERSON_TAG, CAPTION_TAG
sponsor_label{ enabled, replace_ad_tag }협찬 레이블. 계정명은 account_name 사용
collaborator{ enabled }COLLABORATORenabled=true 면 추가금. 계정명은 account_name 사용
product_link{ enabled, channel, link }PRODUCT_LINK_*enabled=true 이고 channel 이 있을 때만 매핑 (아래)
is_ai_suggestedbooleanAI 추출/제안 여부

product_link.channel ↔ 추가금 매핑:

channelAddonFeeType평균 단가
DMPRODUCT_LINK_DM+50%
PROFILEPRODUCT_LINK_PROFILE+30%
CAPTIONPRODUCT_LINK_CAPTION+20%
COMMENTPRODUCT_LINK_COMMENT+20%

product_link.enabled=true 이지만 channel=null 이면 제품 링크 공유 필요 여부만 제안된 상태입니다. 제품 링크 추가금은 channelDM/PROFILE/CAPTION/COMMENT 로 확정될 때만 매핑됩니다. 구버전 product_link_required: true(boolean) 형태는 채널 정보가 없어 추가금으로 매핑되지 않으며, upload_requirements 의 모르는 키는 안전하게 무시됩니다.

권한 체크

  • userDetails.usernamecollab.id 와 다르고 ROLE_ADMIN 도 아니면 UNAUTHORIZED_ACCESS (403)
  • 기존 가이드라인이 있고 관리자가 아닌데 campaignSubStep 이 콘텐츠 제작 이후 단계면 GUIDELINE_MODIFICATION_NOT_ALLOWED

상태 전이

isModifyisFirstguidelineStatuscampaignSubStep부가작업
true(무시)변경 없음변경 없음updatedAt만 갱신
falsetrueDRAFTCAMPAIGN_GUIDELINE없음
falsefalseCOMPLETEDCREATOR_RECRUIT아래 부가작업 실행

COMPLETED 부가작업

isFirst=false, isModify=false 로 호출되면 다음을 순차/비동기 혼합으로 실행합니다:

  1. 모집 마감일 자동 설정CampaignScheduleService.updateRecruitmentEndDate(collabNo)
  2. 캠페인 벡터화 (비동기) — PythonApiService.vectorizeCampaignAsync(collabNo). 인플루언서 매칭용 벡터 인덱스 갱신.
  3. 해시태그 자동 크롤 이벤트doc.data.hashtags 가 있으면 HashtagCrawlRequestedEvent 발행. Collab.keywords 에도 콤마 join 저장.
  4. 모집 콘텐츠 비동기 생성CollabPythonReportService.forwardToPythonAsync(collabNo, userDetails). 알리미/DM/한줄어필/스토리이미지 생성 → Slack 전송.
  5. 칸반 태스크 완료TB_KANBAN_TASKtaskCode=GUIDELINE_FINAL 이 있으면 Node API (/kanban-task/{id}/complete) 호출.
  6. 추가금 syncGuidelineV4AddonFeeSyncService.syncFromGuideline(collabNo, doc). doc.data 에서 추가금 항목을 파싱해 TB_CAMPAIGN_ADDON_FEE 와 diff sync.

추가금 sync 규칙

파싱 출처 (doc.data):

  1. shots[*] — shot 의 codeAddonFeeType 이면 추가금 (예: OUTDOOR). value = additional_price(없거나 0이면 enum 기본값). scene 샷(HOOK/CTA 등)은 추가금 항목으로는 무시되지만 장면 수 카운트에 포함.
  2. upload_requirementsnarration_requiredNARRATION, collaborator.enabledCOLLABORATOR, product_link.enabled=true + product_link.channelPRODUCT_LINK_*. (account_name/brand_tag/sponsor_label 제외)
  3. shots 의 scene 총합 > 7EXTRA_SCENE 추가금 자동 추가, value = 20 × (총장면수 − 7). 기본 장면 수 한도는 7개(초반 2 + 중반 3 + 후반 2). 장면 수가 7 이하로 떨어지면 row 자동 삭제.

diff 동작:

케이스동작
신규 항목is_included=true 로 insert
기존 항목value/value_type 갱신 (is_included 는 운영자 설정 보존)
빠진 항목hard delete
SCRIPT_REVIEW / PRODUCT_RETURN삭제 제외 (캠페인 생성 시 draft 가 만드는 AMOUNT — 가이드라인 sync 가 건드리지 않음)

doc.datashots·upload_requirements 키가 모두 없으면 구조 미인식으로 sync 스킵. 둘 중 하나라도 있으면(선택 추가금이 없어도) 가이드라인 관리 타입을 diff 적용.

응답

임시저장 (isModify=true) 응답

{
  "status": 200,
  "code": null,
  "message": "가이드라인 저장 완료",
  "data": {
    "collabNo": 123,
    "isModify": true,
    "guidelineStatus": "DRAFT",
    "message": "가이드라인이 임시저장되었습니다."
  }
}

DRAFT / COMPLETED 저장 응답

{
  "status": 200,
  "code": null,
  "message": "가이드라인 저장 완료",
  "data": {
    "collabNo": 123,
    "isFirst": false,
    "guidelineStatus": "COMPLETED",
    "message": "가이드라인이 저장되었습니다."
  }
}

에러 응답

상태 코드코드설명
400CAMPAIGN_NOT_FOUND캠페인을 찾을 수 없음
400GUIDELINE_MODIFICATION_NOT_ALLOWED기존 가이드라인 존재 + 관리자 아님 + 콘텐츠 제작 단계 진입
400PROVIDED_OPTION_LOCKEDPROPOSAL 신청자 존재 + body 에 providedOptions 동봉
400(없음)"V4 세션이 없습니다. 컨셉 생성부터 시작하세요." (getSession 실패)
401-인증 실패
403UNAUTHORIZED_ACCESS해당 캠페인 소유자 아니고 관리자도 아님

API 테스트

On this page