Glowb Dev Docs
Admin APIAdmin Dashboard API

PATCH /ai/admin/dashboard/applications/{applicationId}/prices

단건 application 가격 4종(희망가/제안가/기존가/노출가) 부분 수정 + 자동계산 트리거

단건 application 가격 4종 부분 수정

어드민이 단건 CampaignApplication의 4종 가격(희망가/제안가/기존가/노출가)을 한 번의 요청으로 부분 수정합니다.

  • 모든 가격 필드는 nullable — 전달된 필드만 변경됩니다.
  • 희망가CampaignApplication.defaultUnitPrice 에 직접 UPDATE.
  • 제안가TB_PRICE_NEGOTIATION신규 ACCEPT row INSERT (proposed_by="ADMIN", 기존 이력 보존).
  • 기존가/노출가는 두 가지 동작:
    1. 명시 전달 시 → 그 값으로 직접 upsert (MANUAL)
    2. 미전달 + 제안가 변경 시 → 제안가 기반 자동계산값 적용 (AUTO_CALCULATED)
    3. 미전달 + 제안가 미변경 시 → 손대지 않음 (UNCHANGED)
  • 응답의 updatedFields / quotePriceSource / currentPriceSource 로 실제 결과 확인.
  • 변경 사항은 INFO 로그 ([AdminPrice] ...) 로 남아 CS 감사 활용 가능.

4종 가격 ↔ 저장 위치

화면 용어요청 필드저장 위치처리 방식
희망가defaultUnitPriceTB_CAMPAIGN_APPLICATION.default_unit_priceUPDATE
제안가proposedPriceTB_PRICE_NEGOTIATION.proposed_price신규 ACCEPT row INSERT
기존가quotePriceTB_APPLICATION_MATCHING.quote_priceupsert (수동/자동)
노출가 (글로우비 특별가)currentPriceTB_APPLICATION_MATCHING.current_priceupsert (수동/자동)

자동계산 공식

Collab.feeType = PERCENT 이고 Collab.feeValue 가 양수일 때만 자동계산 트리거됨. 둘 중 하나라도 만족 못 하면 자동계산 skip (기존가/노출가는 UNCHANGED).

currentPrice = floor10000(proposedPrice × (1 + feeValue / 100))
quotePrice   = floor10000(currentPrice × 1.5)

만원 단위 버림(floor).

예시 (캠페인 1534, feeValue=15)

proposedPrice 400,000 → currentPrice 460,000 → quotePrice 690,000

ACCEPT 차단과 forceOverride

해당 신청에 이미 수락(ACCEPT)된 PriceNegotiation 이 존재할 때 제안가(proposedPrice) 변경은 기본 차단됩니다.

조건동작
ACCEPT 협상 없음정상 처리
ACCEPT 있음 + forceOverride 미전송 또는 false400 차단 ("이미 수락된 협상이 있습니다. 제안가 변경 시 forceOverride=true 가 필요합니다.")
ACCEPT 있음 + forceOverride: true정상 처리. 응답의 overrideApplied = true

희망가/기존가/노출가만 수정하는 경우엔 차단 체크가 적용되지 않습니다.

HTTP 요청

PATCH /ai/admin/dashboard/applications/{applicationId}/prices
Authorization: Bearer {access_token}
Content-Type: application/json

Path Parameters

파라미터타입필수설명
applicationIdLong신청 ID (TB_CAMPAIGN_APPLICATION.id)

Request Body

필드타입필수설명
defaultUnitPriceLong아니오희망가. 전달 시 직접 UPDATE
proposedPriceLong아니오제안가. 전달 시 PriceNegotiation 신규 ACCEPT INSERT + (옵션) quote/current 자동계산
quotePriceLong아니오기존가. 전달 시 그 값으로 강제 (MANUAL). 미전달 + proposedPrice 변경 시 자동계산
currentPriceLong아니오노출가. 전달 시 그 값으로 강제 (MANUAL). 미전달 + proposedPrice 변경 시 자동계산
forceOverrideBoolean아니오기본 false. true 시 ACCEPT 협상 존재해도 제안가 변경 허용

요청 예시 1 — 제안가만 보내고 quote/current 자동계산 (대표 케이스)

{
  "defaultUnitPrice": 400000,
  "proposedPrice": 400000
}

→ 응답: quotePriceSource=AUTO_CALCULATED, currentPriceSource=AUTO_CALCULATED

요청 예시 2 — 희망가만 정정 (다른 가격 손대지 않음)

{
  "defaultUnitPrice": 400000
}

quotePriceSource=UNCHANGED, currentPriceSource=UNCHANGED

요청 예시 3 — 자동공식 무시하고 어드민 수동 가격 강제

{
  "proposedPrice": 400000,
  "quotePrice": 500000,
  "currentPrice": 350000
}

→ 명시값 그대로 (MANUAL). 자동계산 결과 무시.

요청 예시 4 — quote/current 만 수동 조정 (제안가 미변경)

{
  "quotePrice": 500000,
  "currentPrice": 350000
}

→ 제안가는 그대로, ApplicationMatching 만 upsert. MANUAL.

요청 예시 5 — ACCEPT 차단 우회

{
  "proposedPrice": 350000,
  "forceOverride": true
}

→ 신규 ACCEPT row INSERT (기존 ACCEPT 보존). overrideApplied=true.

응답

성공 응답 (200 OK) — 예시 1 (자동계산)

{
  "status": 200,
  "code": null,
  "message": "가격 수정 완료",
  "data": {
    "applicationId": 14853,
    "updatedFields": ["defaultUnitPrice", "proposedPrice", "quotePrice", "currentPrice"],
    "defaultUnitPrice": 400000,
    "quotePrice": 690000,
    "currentPrice": 460000,
    "newPriceNegotiationId": 7501,
    "overrideApplied": false,
    "quotePriceSource": "AUTO_CALCULATED",
    "currentPriceSource": "AUTO_CALCULATED"
  }
}

성공 응답 (200 OK) — 예시 2 (희망가만)

{
  "status": 200,
  "code": null,
  "message": "가격 수정 완료",
  "data": {
    "applicationId": 14853,
    "updatedFields": ["defaultUnitPrice"],
    "defaultUnitPrice": 400000,
    "quotePrice": 690000,
    "currentPrice": 460000,
    "newPriceNegotiationId": null,
    "overrideApplied": false,
    "quotePriceSource": "UNCHANGED",
    "currentPriceSource": "UNCHANGED"
  }
}

차단 응답 (400) — ACCEPT 존재 + forceOverride 미전송

{
  "status": 400,
  "code": "REQ_001",
  "message": "이미 수락된 협상이 있습니다. 제안가 변경 시 forceOverride=true 가 필요합니다.",
  "data": null
}

에러 응답

상태 코드코드설명
400REQ_001잘못된 요청 (존재하지 않는 applicationId, 또는 ACCEPT 차단)

응답 필드

필드타입설명
applicationIdLong요청한 신청 ID
updatedFieldsList<String>실제로 변경된 필드명 목록 (UNCHANGED 인 quote/current 는 미포함)
defaultUnitPriceLong변경 후 희망가
quotePriceLong변경 후 기존가 (ApplicationMatching 미존재 시 null)
currentPriceLong변경 후 노출가
newPriceNegotiationIdLong제안가 변경 시 INSERT 된 신규 PriceNegotiation row id, 그 외 null
overrideAppliedBooleanforceOverride=true 로 ACCEPT 차단을 우회했는지
quotePriceSourceStringMANUAL / AUTO_CALCULATED / UNCHANGED
currentPriceSourceString동일

API 테스트

On this page