기업 서비스 이용 계약서 — 개요 및 플로우
기업 광고주와 Glowb 간 서비스 이용 계약서 전체 흐름, 상태 구조, 케이스별 가이드
이 문서는 기업 광고주 ↔ Glowb 서비스 이용 계약서입니다. 크리에이터 광고 계약서는 전자계약 API를 참고하세요.
인증 정책
/ai/business/contract/** 모든 엔드포인트는 JWT 인증 없이 호출 가능합니다 (회원가입 직후 토큰 발급 전 단계 지원). 다만 식별을 위해 memberId 쿼리 파라미터는 필수이며, 임의의 memberId 입력으로 타 기업의 계약 진행/조회/인감 변경이 가능하므로 클라이언트단에서 자기 자신의 memberId만 전달되도록 통제해야 합니다.
관리자 API (/ai/admin/business-contracts/**)는 ADMIN 권한 토큰 필요.
기업 서비스 이용 계약서
상태 구조
계약 관련 상태는 두 곳에서 독립적으로 관리됩니다.
1. TB_BUSINESS_CONTRACT.status — 계약 진행 상태
계약서 한 건의 진행 단계를 추적합니다.
| 값 | 설명 | 전환 API |
|---|---|---|
PENDING | 계약 생성됨 (미열람) | 자동 생성 |
SENT | 관리자가 발송함 | POST /ai/admin/business-contracts/{id}/send |
OPENED | 계약서 열람됨 | POST /ai/business/contract/process?step=OPEN |
FILLED | 기업 정보 입력 완료 | POST /ai/business/contract/process?step=FILL |
SIGNED | 서명(인감 업로드) 완료 | POST /ai/business/contract/process?step=SIGN |
REJECTED | 어드민 거절 → 종결 (voided_pdf_url 에 VOID 합성본 보존) | PATCH /ai/admin/business-contracts/{id}/review?decision=REJECTED |
2. TB_BUSINESS.contract_sign_status — 캠페인 허용 여부
기업 계정 단위의 캠페인 생성 권한을 나타냅니다.
| 값 | 의미 | 캠페인 생성 | 프론트 안내 |
|---|---|---|---|
NONE | 서명된 계약 없음 또는 검수 거절됨 | ❌ 403 차단 | "계약서 작성이 필요합니다" |
PENDING | 서명 완료, 어드민 검수 대기 중 | ❌ 403 차단 | "Glowb에서 계약서를 확인 중입니다" |
SIGNED | 어드민 검수 승인 완료 | ✅ 가능 | — |
EXCEPTION | 관리자 지정 예외 계정 | ✅ 가능 | — |
step=SIGN 호출만으로는 캠페인이 풀리지 않습니다. 서명 직후엔 PENDING이며, 어드민이 PATCH /ai/admin/business-contracts/{id}/review?decision=APPROVED를 호출해야 SIGNED로 전환됩니다. 이는 인감 파일 검증 등을 위한 사람 검수 단계입니다.
3. TB_BUSINESS_CONTRACT.approval_status — 계약서별 검수 상태
각 계약서 row의 어드민 검수 결과를 보존합니다. 서명 전 단계에서는 NULL.
| 값 | 의미 | 진입 시점 |
|---|---|---|
NULL | 서명 전 (PENDING/SENT/OPENED/FILLED) | 기본값 |
PENDING_APPROVAL | 서명 완료, 검수 대기 | step=SIGN 직후 |
APPROVED | 어드민 승인 | PATCH /review?decision=APPROVED |
REJECTED | 어드민 거절 | PATCH /review?decision=REJECTED |
케이스별 진행 가이드
Case 1. 신규 가입자 (회원가입 3번째 섹션)
회원가입 직후 바로 계약서 작성을 진행합니다.
1. GET /ai/business/contract/template?memberId={id}
→ 빈 계약서 PDF URL 반환 (내용 확인용, 선택사항)
2. POST /ai/business/contract/process?memberId={id}&step=OPEN
→ 계약 레코드 없으면 자동 생성 + OPENED 처리
→ status: PENDING → OPENED
3. POST /ai/business/contract/process?memberId={id}&step=FILL
form: data={"businessName","license","address","representative"}
→ status: OPENED → FILLED
4. POST /ai/business/contract/process?memberId={id}&step=SIGN
form: stamp=인감이미지.png
→ 계약서 PDF 생성 + SHA-256 해시 저장
→ status: FILLED → SIGNED
→ approval_status = PENDING_APPROVAL
→ TB_BUSINESS.contract_sign_status = PENDING (검수 대기, 캠페인 차단)
5. (어드민) PATCH /ai/admin/business-contracts/{id}/review?adminId=...&decision=APPROVED
→ approval_status = APPROVED
→ TB_BUSINESS.contract_sign_status = SIGNED (캠페인 허용)Case 2. 기존 가입자 (관리자가 계약서 발송)
이미 가입된 계정에 관리자가 계약서 작성을 요청하는 경우입니다.
1. POST /ai/admin/business-contracts/{businessId}/send?adminId={id}
→ 계약 레코드 생성 + SENT 처리
2. GET /ai/business/contract/template?memberId={id} (선택)
3. POST /ai/business/contract/process?memberId={id}&step=OPEN
→ status: SENT → OPENED
4. POST /ai/business/contract/process?memberId={id}&step=FILL
5. POST /ai/business/contract/process?memberId={id}&step=SIGN
→ TB_BUSINESS.contract_sign_status = PENDING (검수 대기)
6. (어드민) PATCH /ai/admin/business-contracts/{businessId}/review?decision=APPROVED
→ TB_BUSINESS.contract_sign_status = SIGNEDCase 3. 재계약 (인감 변경 등)
SIGNED 완료 후 인감을 변경하거나 재계약이 필요한 경우입니다.
POST /ai/business/contract/process?memberId={id}&step=OPEN
→ 기존 SIGNED 계약과 별개로 새 계약 레코드 자동 생성
→ 이전 계약은 이력으로 보존
이후 step=FILL → step=SIGN 동일하게 진행TB_BUSINESS_CONTRACT에 UNIQUE 제약이 없어 한 기업이 여러 계약 레코드를 가질 수 있습니다. 서비스 레이어에서 진행 중인 계약(미서명) 1건을 관리합니다.
감사 로그
모든 단계에서 TB_BUSINESS_CONTRACT_AUDIT_LOG에 기록됩니다.
| 이벤트 | 기록 시점 | actor_type |
|---|---|---|
CREATED | 계약서 최초 생성 | BUSINESS |
SENT | 관리자 발송 | ADMIN |
OPENED | 계약서 열람 | BUSINESS |
FILLED | 기업 정보 입력 | BUSINESS |
SIGNED | 인감 업로드 완료 | BUSINESS |
EXCEPTION_GRANTED | 예외 계정 설정 | ADMIN |
EXCEPTION_REVOKED | 예외 계정 해제 | ADMIN |
APPROVED | 어드민 검수 승인 | ADMIN |
REJECTED | 어드민 검수 거절 (notes에 사유 기록) | ADMIN |
기록 항목: IP 주소, User-Agent, 타임스탬프, 메모(pdfHash 등)