Glowb Dev Docs
SaaS API이미지 충분성 판정

POST /ai/campaign/image-sufficiency

상세페이지 이미지 충분성 판정

상세페이지 이미지 충분성 판정

캠페인 썸네일·상세페이지 이미지가 가이드라인 생성에 필요한 정보를 충분히 담고 있는지 판정합니다. 프론트는 판정 결과가 INSUFFICIENT 일 때 추가 자료 요청 팝업을 띄웁니다.

Spring 은 Python 판정 API(POST /report/campaign/check-image-sufficiency)를 동기 호출하며, 응답을 그대로 전달합니다. 기존 이미지 분석(POST /ai/report/campaign/{collabNo}/analyze-images)과는 독립적으로 동작하고, 분석 결과나 캐시(product_details)를 변경하지 않습니다.

항목
메서드POST
경로/ai/campaign/image-sufficiency (별칭 /campaign/image-sufficiency)
인증필요 (ROLE_BUSINESS / ROLE_ADMIN)
Content-Typeapplication/json

Gemini 다중 이미지 판정이라 응답까지 수십 초가 걸릴 수 있습니다. 팝업이 필요한 화면 흐름에서 호출하고 응답 대기 중 로딩 상태를 표시하세요. 비동기 이미지 분석 이벤트에는 연결하지 않습니다.

요청

POST /ai/campaign/image-sufficiency HTTP/1.1
Host: api.glowb.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: application/json

{
  "campaignNo": 2309,
  "productName": "제주 호텔 숙박권",
  "imageUrls": [
    "https://cdn.example.com/thumbnail.jpg",
    "https://cdn.example.com/detail.jpg"
  ]
}
curl -X POST "https://api.glowb.com/ai/campaign/image-sufficiency" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "campaignNo": 2309,
    "productName": "제주 호텔 숙박권",
    "imageUrls": ["https://cdn.example.com/thumbnail.jpg"]
  }'
const response = await fetch('/ai/campaign/image-sufficiency', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    campaignNo,
    productName,
    imageUrls
  })
});

const { data } = await response.json();
if (data.status === 'INSUFFICIENT') {
  showAdditionalMaterialPopup();   // 다국어 고정 안내문
} else if (data.status === 'FAILED') {
  showRetryToast();
}

Request Body

Prop

Type

응답

성공 응답 (200 OK)

{
  "status": 200,
  "code": null,
  "message": "이미지 충분성 판정이 완료되었습니다.",
  "data": {
    "status": "INSUFFICIENT",
    "product_image_match": false,
    "detected_product_name": "",
    "satisfied_criteria": [],
    "missing_criteria": [
      "PRODUCT_IDENTITY",
      "CORE_BENEFIT",
      "CONCRETE_TARGET",
      "USAGE_CONDITIONS",
      "DIFFERENTIATION"
    ],
    "criteria": {
      "PRODUCT_IDENTITY": {
        "satisfied": false,
        "evidence": [],
        "reason": "상품이나 서비스명을 확인할 수 없음"
      }
    },
    "reason": "상품 식별과 핵심 혜택을 이미지에서 확인할 수 없습니다.",
    "guidance": "브랜드·서비스명과 핵심 혜택이 표시된 이미지를 추가해 주세요.",
    "requested_image_count": 2,
    "selected_image_count": 2,
    "analyzed_image_count": 2,
    "prompt_version": "product-page-sufficiency-v1"
  }
}

실제 criteria 에는 5개 조건이 모두 포함됩니다.

판정 상태 (data.status)

의미프론트 처리
SUFFICIENT충분성 조건 충족기존 생성 흐름 계속 진행
INSUFFICIENT판정은 완료됐으나 제품 불일치 또는 조건 미충족고정 안내문 팝업 표시 (시스템 오류 아님)
FAILED이미지 다운로드 또는 Gemini 판정 실패, Python 호출 실패재시도 안내 표시

프론트는 status 만 사용합니다. guidance, missing_criteria, reason 은 운영 확인·디버깅용이며 사용자 화면에 직접 표시하지 않습니다. 팝업 문구는 프론트 다국어 리소스에서 관리합니다.

상세페이지 정보가 부족합니다.
제품명과 핵심 혜택을 확인할 수 있는 이미지를 추가해 주세요.

판정 조건

코드설명
PRODUCT_IDENTITY상품·서비스명과 유형 (필수)
CORE_BENEFIT핵심 혜택·효능 (필수)
CONCRETE_TARGET구체적인 대상·구성
USAGE_CONDITIONS이용법·이용 조건
DIFFERENTIATION차별점

SUFFICIENT 가 되려면 아래를 모두 만족해야 합니다. 이미지 수 자체는 통과 조건이 아닙니다.

  • 제품명과 이미지 대상이 일치 (product_image_match)
  • PRODUCT_IDENTITY, CORE_BENEFIT 필수 충족
  • 5개 조건 중 3개 이상 충족
  • 각 충족 조건에 이미지 근거(evidence)가 1개 이상 존재

응답 필드

Prop

Type

에러 응답

상태 코드설명
400productName 누락 (VALIDATION_ERROR) / 판정할 이미지 없음 (REQ_001)
401인증 실패
403ROLE_BUSINESS · ROLE_ADMIN 권한 부족
404campaignNo 로 캠페인을 찾을 수 없음 (CAMPAIGN_NOT_FOUND)

Python 호출 실패(타임아웃·5xx·422·빈 응답)는 에러로 내리지 않고 data.statusFAILED 로 채워 HTTP 200 으로 응답합니다. 프론트가 INSUFFICIENT 와 시스템 오류를 상태 값만으로 구분할 수 있게 하기 위함입니다.

이미지 처리

  • 최대 40개 URL 사용, 초과 시 첫·마지막을 포함해 균등 선택 (Python 담당)
  • S3·CloudFront 및 일반 HTTP(S) URL 지원
  • 공개 또는 서명된 GCP HTTPS URL 지원
  • gs:// 와 인증이 필요한 비공개 GCS URL 은 미지원
  • AVIF 는 실행 환경에 따라 분석에서 제외될 수 있음

로그 · 저장 정책

  • Spring 은 campaignNo, 상태, 누락 조건, 이미지 수, 소요 시간, 프롬프트 버전을 애플리케이션 로그로 남깁니다.
  • SUFFICIENT · INSUFFICIENTINFO, 판정 실패는 WARN, Python 호출 실패는 ERROR 입니다.
  • 이미지 URL, Gemini 원문 응답, guidance 는 로그에 남기지 않습니다.
  • 판정 결과는 Spring · Python 어느 쪽에서도 DB 에 저장하지 않습니다.

API 테스트

On this page