POST /ai/contract/{contractId}/void
발송된 계약서를 폐기 처리합니다. 서명 완료된 계약서는 도장 합성본을 별도로 저장하고, 그 외에는 취소 상태로 변경합니다.
계약서 폐기
운영자가 계약서를 폐기 처리합니다. 계약서 내용에 오타·오기가 있어 다시 발송해야 하는 경우에 사용합니다.
| 항목 | 값 |
|---|---|
| 메서드 | POST |
| 경로 | /ai/contract/{contractId}/void |
| 인증 | Bearer Token (관리자) |
처리 방식
요청한 계약서의 현재 상태에 따라 다르게 처리됩니다.
| 현재 상태 | 처리 결과 | PDF 처리 |
|---|---|---|
SIGNED | VOIDED 로 전환 | 원본 PDF 보존 + "VOID" 도장 합성본 별도 저장 |
SENT / OPENED / FILLED / OTP_VERIFIED | CANCELED 로 전환 | 없음 (PDF 미생성 상태이므로) |
DRAFT | 거부 (400) | - |
VOIDED / CANCELED (이미 폐기됨) | 거부 (400) | - |
사이드 이펙트는 변경되지 않습니다. 선정 상태(SELECTED), 검수 라운드(ContentReview), 캠페인 단계(campaignSubStep),
신청자 숨김(applicantHidden), 다른 신청자의 미선정 처리, 인플루언서 대표 서명 등은 모두 그대로 유지됩니다.
"계약서만 무효 처리하고 선정은 유효" 시나리오를 가정합니다.
폐기 후 재발송
폐기 후 같은 신청자에게 새 계약서를 발송하려면 POST /ai/contract/send API 를 다시 호출하면 됩니다.
중복 발송 가드는 VOIDED / CANCELED 상태를 무시하므로 동일 applicationId 로 새 계약서가 정상 생성됩니다.
요청
POST /ai/contract/123/void HTTP/1.1
Host: api.glowb.com
Authorization: Bearer {access_token}
Content-Type: application/json
{
"reason": "광고대금 오기"
}curl -X POST "https://api.glowb.com/ai/contract/123/void" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{"reason": "광고대금 오기"}'const response = await fetch(`/ai/contract/${contractId}/void`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
reason: '광고대금 오기',
}),
});
const result = await response.json();Path Parameters
Prop
Type
Request Body
본문은 선택입니다. 본문 없이({} 또는 null) 호출해도 정상 처리됩니다.
Prop
Type
응답
성공 응답 — SIGNED → VOIDED (200 OK)
{
"status": 200,
"code": null,
"message": "계약서 폐기가 완료되었습니다.",
"data": {
"contractId": 123,
"applicationId": 456,
"status": "VOIDED",
"statusDisplayName": "폐기됨",
"creatorName": "크리에이터A",
"campaignTitle": "여름 선크림 캠페인",
"sentAt": "2026-04-25T10:30:00",
"signedAt": "2026-04-26T15:42:11",
"signedPdfUrl": "https://glowb-input.s3.ap-southeast-1.amazonaws.com/contract/pdf/456/123_1745740931000.pdf",
"voidedPdfUrl": "https://glowb-input.s3.ap-southeast-1.amazonaws.com/contract/voided/456/123_1745827331000.pdf",
"voidedAt": "2026-04-28T09:15:00",
"voidedReason": "광고대금 오기"
}
}성공 응답 — SENT/OPENED/FILLED/OTP_VERIFIED → CANCELED (200 OK)
{
"status": 200,
"code": null,
"message": "계약서 폐기가 완료되었습니다.",
"data": {
"contractId": 124,
"applicationId": 457,
"status": "CANCELED",
"statusDisplayName": "취소됨",
"creatorName": "크리에이터B",
"campaignTitle": "여름 선크림 캠페인",
"sentAt": "2026-04-27T14:00:00",
"signedAt": null,
"signedPdfUrl": null,
"voidedPdfUrl": null,
"voidedAt": "2026-04-28T09:15:00",
"voidedReason": null
}
}응답 필드 (ContractSummaryResponseDto)
Prop
Type
에러 응답
계약서 미존재 (404 — CONTRACT_001)
{
"status": 404,
"code": "CONTRACT_001",
"message": "존재하지 않는 계약서입니다.",
"data": null
}잘못된 상태 — DRAFT 또는 이미 폐기됨 (400 — CONTRACT_003)
{
"status": 400,
"code": "CONTRACT_003",
"message": "현재 상태에서는 해당 작업을 수행할 수 없습니다.",
"data": null
}| 발생 케이스 | 비고 |
|---|---|
| status == DRAFT 인 계약서를 폐기 시도 | 실 운영에서는 거의 발생하지 않음 (DRAFT 가 저장되는 경로 없음) |
| status == VOIDED / CANCELED 재폐기 시도 | 이미 폐기된 계약서 |
유효성 검증 실패 (400)
{
"status": 400,
"code": "VALIDATION_ERROR",
"message": "폐기 사유는 500자 이내로 입력해주세요.",
"data": null
}폐기된 계약서의 후속 동작
크리에이터 측 접근 차단 (HTTP 410)
폐기된 계약서는 크리에이터의 어떤 액션으로도 접근할 수 없습니다. 다음 엔드포인트들은 모두 410 CONTRACT_VOIDED 응답:
GET /ai/contract/{contractId}(상세 조회)PUT /ai/contract/{contractId}/creator-info(정보 입력)POST /ai/contract/{contractId}/otp/send(OTP 요청)POST /ai/contract/{contractId}/otp/verify(OTP 검증)POST /ai/contract/{contractId}/sign(서명 제출)PUT /ai/contract/{contractId}/documents(서류 첨부)
{
"status": 410,
"code": "CONTRACT_010",
"message": "폐기된 계약서입니다.",
"data": null
}관리자 측 — 목록·감사 추적은 그대로
GET /ai/contract/campaign/{collabNo}: 폐기된 계약서도 목록에 포함되어 반환됩니다 (status로 필터링).GET /ai/contract/{contractId}/audit: 폐기된 계약서의 감사 로그도 그대로 조회 가능. 폐기 이벤트(VOIDED또는CANCELED)도 시간순으로 기록되어 있습니다.
감사 로그 기록
폐기 시 ContractAuditLog 에 다음 이벤트가 추가됩니다:
| 처리 결과 | eventType | detail 예시 |
|---|---|---|
| VOIDED | VOIDED | 사유: 광고대금 오기 | voidedPdfUrl: https://... |
| CANCELED | CANCELED | 사유: 광고대금 오기 (사유 없으면 null) |
데이터베이스 영향
TB_APPLICATION_CONTRACT 테이블의 다음 4개 컬럼이 갱신됩니다 (모두 신규 컬럼):
| 컬럼 | VOIDED 처리 | CANCELED 처리 |
|---|---|---|
voided_pdf_url | 도장 합성본 PDF URL | null |
voided_at | 처리 시각 | 처리 시각 |
voided_by | 관리자 ID | 관리자 ID |
voided_reason | 입력 사유 (옵션) | 입력 사유 (옵션) |
기존 컬럼(signed_pdf_url, pdf_hash, signature_image_url, signed_at, status 등)은 status 만 변경되고 그 외에는 변경되지 않습니다. 원본 PDF 의 무결성은 보존됩니다.