Glowb Dev Docs
Admin APIAdmin Finance API

POST /ai/admin/finance/budget/{budgetId}/unlock

캠페인 LOCK 예산 해제 (가용 예산으로 복귀, audit row 없음)

캠페인 LOCK 예산 해제

크리에이터 제안 시 LOCK 된 CampaignBudget 한 행을 LOCKEDUNLOCKED 로 바꿉니다. 해제 금액은 그 캠페인의 가용 예산으로 즉시 복귀합니다.

글로벌 잔액(Business.remainCredit) 은 변동 없고, CreditTransaction audit row 도 만들지 않습니다 (캠페인 예산 내부 상태 변경). 해제 이력은 예산 행 상태에서 파생되어 캠페인 상세 타임라인의 BUDGET_UNLOCK 항목으로 노출됩니다.

신청건의 선정 상태(selectionStatus) 는 바뀌지 않습니다. 예산만 풀리므로 "제안 중인데 예산은 안 잡힌" 상태가 됩니다. 해당 신청건을 다시 PROPOSAL 로 전환하면 이 UNLOCKED 행이 재사용(CAMPAIGN_LOCK_REUSE)되어 그 시점 금액으로 다시 LOCK 됩니다. 제안 자체를 취소하려면 진행 테이블에서 상태를 변경하세요 (상태 변경 시 UNLOCK 이 자동으로 함께 일어납니다).

HTTP 요청

POST /ai/admin/finance/budget/{budgetId}/unlock?adminId={adminId}
Authorization: Bearer {access_token}

Request body 없음.

Path / Query Parameters

파라미터위치타입필수설명
budgetIdpathLongCampaignBudget.id. 캠페인 상세 타임라인의 budgetLock:{id} 에서 얻습니다
adminIdqueryString아니오처리자 ID. 미지정 시 admin. 서버 로그에만 남습니다

동작

budget = CampaignBudget(id = budgetId)          // 없으면 404

reject if budget.type   == DEFICIT              // 부족분 전용 API 사용
reject if budget.application == null
reject if budget.status == UNLOCKED             // 이미 해제됨

budget.status     = UNLOCKED                    // updatedAt 갱신
save budget
recalcDeficitIfEngaged(budget.collabNo)         // 부족분 lock 걸린 캠페인이면 금액 재계산

// Business.remainCredit  변동 없음
// CreditTransaction      생성 없음
// selectionStatus        변동 없음

실제 해제는 CampaignBudgetService#unlockBudget 단일 경로를 재사용합니다 (행 잠금 조회 + [CAMPAIGN_UNLOCK] 로그 + 부족분 재계산 포함).

응답 (200 OK)

{
  "status": 200,
  "code": null,
  "message": "예산 LOCK 해제 완료",
  "data": {
    "budgetId": 88,
    "collabNo": 482,
    "applicationId": 9876,
    "influenceName": "홍길동",
    "amount": 250000,
    "status": "UNLOCKED",
    "type": "NORMAL",
    "unlockedAt": "2026-07-30T14:22:11",
    "unlockedBy": "admin01"
  }
}
필드타입설명
budgetIdLong해제한 예산 행 id
collabNoInteger캠페인 번호
applicationIdLong연결된 신청건 id
influenceNameString크리에이터 이름
amountInteger가용 예산으로 복귀한 금액
statusString해제 후 상태 — 항상 UNLOCKED
typeString항상 NORMAL (DEFICIT 은 대상 아님)
unlockedAtString해제 시각 (CampaignBudget.updatedAt)
unlockedByString요청 adminId 반사값 (DB 미저장)

에러

상태code조건
409FINANCE_002이미 해제된 예산
409FINANCE_002부족분(DEFICIT) 행 — 전용 API 사용
409FINANCE_002신청건이 연결되지 않은 예산 행
404INVALID_DATA해당 budgetId 예산 없음
{
  "status": 409,
  "code": "FINANCE_002",
  "message": "이미 예산이 취소되었습니다. budgetId=88",
  "data": null
}

에러도 HTTP 200 으로 내려가고 실제 코드는 body 의 status 필드에 담깁니다. HTTP 상태만 보고 성공 판정하면 안 됩니다.

부족분(DEFICIT) lock 은 별도 API

type = DEFICIT 행(최초 입금액 80% 기준 부족분 lock)은 재계산 로직과 충돌하므로 이 API 로 해제할 수 없습니다.

DELETE /ai/campaigns/{collabNo}/budget/deficit-lock

관련 API

목적엔드포인트
LOCK 금액만 수정 (상태 유지)PATCH /ai/admin/finance/budget/{budgetId}/amount
budgetId 조회GET /ai/admin/finance/collab/{collabNo}
신청 id 기준 해제 (확장 프로그램)POST /extension/campaign-budgets/{applicationId}/unlock
캠페인 전체 해제 + 잔액 환급POST /ai/admin/campaigns/{campaignNo}/terminate

예산을 LOCK 하는 전용 API 는 없습니다. 진행 테이블에서 PROPOSAL 로 전환하거나 POST /ai/progress-table/items/bulk/proposal-with-charge 를 호출할 때 자동으로 LOCK 됩니다.

결과 확인 (DB)

SELECT id, collab_no, application_id, amount, status, type, updated_at
FROM TB_CAMPAIGN_BUDGET
WHERE id = 88;

-- 캠페인 LOCK 합계 (가용 예산 확인)
SELECT status, type, SUM(amount) AS total, COUNT(*) AS cnt
FROM TB_CAMPAIGN_BUDGET
WHERE collab_no = 482
GROUP BY status, type;

API 테스트

On this page