| 구분 | SaaS (현재) | 레거시 |
|---|
| 핵심 엔티티 | CampaignApplication | ProgressTable |
| 상태 추적 | selectionStatus + phase + subStep | matchingStatus, deliveryStatus 단일 필드 |
| 계약 | ApplicationContract (전자계약, OTP, 서명, PDF) | 없음 |
| 단가 협상 | PriceNegotiation 이력 관리 (1:N) | bidPrice 필드 하나 |
| 검수 | ContentReview + ContentSubmissionItem (1차/2차) | aiCheck, personCheck 필드 |
| 배송 | ApplicationDelivery (별도 엔티티) | trackingNumber 필드 |
| 최종 제출 | FinalSubmission (링크, 파일, 재요청) | 없음 |
| 구분 필드 | Collab.isLegacy = false | Collab.isLegacy = true |
관리자 또는 기업이 새 캠페인을 생성합니다.
컨트롤러:
| HTTP | 엔드포인트 | 설명 |
|---|
| PATCH | /ai/admin/campaigns/{campaignNo} | 관리자 캠페인 생성 |
| PUT | /ai/admin/campaigns/{campaignNo} | 캠페인 수정 (기본정보, 제출물설정, 대시보드설정, 계약설정, 일정설정) |
서비스: AdminCampaignService
컨트롤러:
| HTTP | 엔드포인트 | 설명 |
|---|
| PATCH | /ai/admin/campaigns/{campaignNo} | 관리자 캠페인 생성 |
서비스: AdminCampaignService
| 필드 | 타입 | 설명 |
|---|
no | PK | 캠페인 번호 |
id | String | 작성자 ID (기업/관리자) |
title | String | 캠페인 제목 |
campaignType | Enum | PRODUCT, MONEY, BOTH, DEFAULT |
campaignSubStep | Enum | 현재 진행 단계 |
snsContentFormat | Enum | SNS 콘텐츠 형식 |
modelType | Enum | STANDARD (일반) / PERFORMANCE (성과형) |
firstReviewTypes | Set | 1차 검수 필수 제출 타입 |
secondReviewTypes | Set | 2차 검수 필수 제출 타입 |
finalSubmissionTypes | Set | 최종 제출 필수 타입 |
recruitmentStartDate | DateTime | 모집 시작일 |
recruitmentEndDate | DateTime | 모집 종료일 |
recruitmentNumber | Integer | 모집 인원 |
isLegacy | Boolean | 레거시 캠페인 여부 (기본 true) |
guidelineVersion | Integer | 가이드라인 버전 (1 or 2) |
isDoubleReview() | - | firstReviewTypes가 비어있지 않으면 2회 검수 |
캠페인 비용을 크레딧 또는 CandyPay로 결제합니다.
| HTTP | 엔드포인트 | 설명 | 컨트롤러 |
|---|
| POST | /ai/payments/collab/confirm | 캠페인 크레딧 결제 | PaymentController |
| GET | /ai/campaign-payments | 캠페인 결제 내역 조회 | CampaignPaymentController |
서비스: CandyPaymentService, CampaignPaymentService, CampaignBudgetService
| 엔티티 | 테이블 | 설명 |
|---|
| CampaignPayment | TB_CAMPAIGN_PAYMENT | 캠페인-결제 연결 |
| CampaignBudget | TB_CAMPAIGN_BUDGET | 예산 관리 (AVAILABLE → LOCKED → RELEASED) |
| CreditTransaction | TB_CREDIT_TRANSACTION | 크레딧 거래 이력 |
CampaignBudgetService.lockBudget(application, amount, createdBy)
→ 예산 가용성 확인 (checkBudgetAvailability)
→ CampaignBudget 상태: AVAILABLE → LOCKED
→ PROPOSAL 시 예산 잠금, REJECT 시 unlockBudget
콘텐츠 가이드라인을 작성합니다. v1과 v2 두 버전이 존재합니다.
| HTTP | 엔드포인트 | 설명 | 컨트롤러 |
|---|
| GET | /ai/guideline/{collabNo} | 가이드라인 조회 | ContentGuidelineController |
| PUT | /ai/guideline/{collabNo}/images | 이미지 업로드 | ContentGuidelineController |
| POST | /ai/guideline/{collabNo}/guideline/complete | 가이드라인 완료 & PDF 생성 | ContentGuidelineController |
| PUT | /ai/guideline/v2/{collabNo} | 가이드라인 v2 저장 | GuidelineV2Controller |
| GET | /ai/guideline/v2/{collabNo} | 가이드라인 v2 조회 | GuidelineV2Controller |
| PUT | /ai/business/contents/guideline/{collabNo} | 가이드라인 Upsert | BusinessContentController |
서비스: ContentGuidelineService, GuidelineV2Service
REQUESTED → DRAFT → COMPLETED
(빈템플릿 요청) → (작성 중) → (완료)
컨트롤러:
| HTTP | 엔드포인트 | 설명 |
|---|
| POST | /ai/collab-applicants | 크리에이터 지원 |
서비스: CollabApplicantService, CampaignApplicationService
지원 프로세스:
- 크리에이터가 캠페인 상세에서 지원
CampaignApplication 생성 (selectionStatus = WAITING)
- 중복 체크: 동일 SNS 계정, 동일 연락처
- SNS 계정 ID → 전체 URL 변환
- 배송지 정보 처리
컨트롤러:
| HTTP | 엔드포인트 | 설명 |
|---|
| POST | /ai/progress-table/items/admin | 관리자가 ProgressTable 레코드 직접 생성 |
matchingStatus = WAITING으로 초기화
| 필드 | 타입 | 설명 |
|---|
id | PK | 신청 ID |
collab | FK | 캠페인 |
influence | FK | 인플루언서 |
selectionStatus | Enum | WAITING, SELECTED, RESERVED, REJECTED, ELIMINATED, PROPOSAL |
phase | Enum | APPLICATION_CONTRACT, FIRST_REVIEW, SECOND_REVIEW, UPLOAD_SETTLEMENT |
adminVisible | Boolean | 기업 대시보드 노출 여부 |
sourceType | Enum | SELF_APPLIED, ADMIN_ADDED, AI_RECOMMENDED |
defaultUnitPrice | Long | 기본 단가 |
snsAccountLink | String | SNS 계정 URL |
appliedAt | DateTime | 지원 시각 |
selectedAt | DateTime | 선정 시각 |
rejectedAt | DateTime | 미선정 시각 |
관리자가 지원자를 검토하고 기업 대시보드 노출 여부를 결정합니다.
| HTTP | 엔드포인트 | 설명 | 컨트롤러 |
|---|
| GET | /ai/admin/dashboard/{campaignNo}/list | 리스트 관리 조회 (adminVisible 무관 전체) | AdminDashboardController |
| PATCH | /ai/admin/dashboard/{campaignNo}/list | 벌크 업데이트 (adminVisible, 노출가, 비고 등) | AdminDashboardController |
| GET | /ai/admin/dashboard/{campaignNo}/user-pool | 유저 풀 조회 (미지원자) | AdminDashboardController |
| GET | /ai/admin/dashboard/{campaignNo}/progress | 관리자용 진행 상황 조회 | AdminDashboardController |
서비스: AdminListManagementService, AdminUserPoolService
대시보드 조회 시 적용되는 필터링 조건입니다. 기업 대시보드와 관리자 대시보드에서 다르게 동작합니다.
| 항목 | 설명 |
|---|
| 필드 | CampaignApplication.adminVisible (Boolean) |
| 기본값 | false |
| 설정 주체 | 관리자 (벌크 업데이트) |
| 효과 | true인 지원자만 기업 대시보드에 노출 |
| 관리자 대시보드 | adminVisible 무관하게 전체 조회 |
| 항목 | 설명 |
|---|
| 필드 | Collab.applicantHidden (Boolean) |
| 기본값 | false |
| 자동 트리거 | 계약서 서명 완료 시 / CONTENT_CREATION 단계 진입 시 / 선정 크리에이터 전원 계약 서명 완료 시 |
| 효과 | true이면 SELECTED, PROPOSAL만 기업 대시보드에 표시 |
| 코드 위치 | ProgressTableService:1198-1203, ContractService.checkAndAutoHideApplicants() |
| 항목 | 설명 |
|---|
| 조건 | 동시 활성 캠페인 3개 초과 |
| 활성 기준 | selectionStatus = SELECTED + phase = DRAFT_REVIEW + schedule.endDate > now |
| 효과 | adminVisible = false 자동 처리 (기업 대시보드에서 제외) |
| 코드 위치 | AdminListManagementService:425-440 |
| 항목 | 설명 |
|---|
| 대상 | 크리에이터 마이페이지 (본인 캠페인 목록) |
| 조건 | selectionStatus = REJECTED이고 rejectedAt < now - 7일이면 숨김 |
| 효과 | 크리에이터에게 오래된 탈락 건 미노출 |
| 코드 위치 | CampaignApplicationRepository.findByInfluenceExcludeOldRejected() |
| 항목 | 설명 |
|---|
| 조건 | 계약서 2건 이상 서명 완료 시 |
| 효과 | PROPOSAL/SELECTED/ELIMINATED 아닌 나머지 지원자 일괄 REJECTED |
| 코드 위치 | AdminListManagementService:587-598 |
→ 1차 필터: adminVisible = true 만 조회
→ 2차 필터: applicantHidden = true 이면 SELECTED/PROPOSAL 만 표시
관리자가 크리에이터에게 단가를 제안합니다.
| HTTP | 엔드포인트 | 설명 | 컨트롤러 |
|---|
| POST | /ai/admin/dashboard/{campaignNo}/price-negotiations | 단가 제안 전송 (벌크) | AdminDashboardController |
서비스: AdminPriceNegotiationService
| 필드 | 타입 | 설명 |
|---|
id | PK | 협상 ID |
application | FK | 신청 건 |
proposedPrice | Long | 제안 금액 (KRW) |
type | Enum | PENDING, ACCEPT, REJECT |
proposedBy | String | ”ADMIN” 또는 “CREATOR” |
respondedAt | DateTime | 응답 시각 |
단가 관련 보조 엔티티:
| 필드 | 설명 |
|---|
quotePrice | 기준가 (원래 단가) |
currentPrice | 글로우비 특별가 (기업에 노출되는 가격) |
matchScore | AI 매칭 점수 (코사인 유사도) |
recommendReason | 추천 사유 |
기업이 크리에이터를 선정하면 예산이 잠금 처리됩니다.
→ CampaignApplication.selectionStatus = SELECTED
→ CampaignApplication.selectedAt = now
→ CampaignBudgetService.lockBudget(application, amount)
→ CampaignBudget 상태: AVAILABLE → LOCKED
→ CampaignApplication.phase = APPLICATION_CONTRACT
예산 가용성 체크: 선정 전 checkBudgetAvailability(collabNo, amount) 호출하여 잔여 예산 확인.
| HTTP | 엔드포인트 | 설명 |
|---|
| POST | /ai/contract/send | 선정 크리에이터에게 계약서 발송 |
| GET | /ai/contract/campaign/{collabNo} | 캠페인 계약서 목록 조회 |
| GET | /ai/contract/{contractId}/audit | 감사 추적 로그 조회 |
| HTTP | 엔드포인트 | 설명 |
|---|
| GET | /ai/contract/{contractId} | 계약서 조회 (최초 열람 시 OPENED) |
| 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 | 첨부서류 업로드 (신분증, 사업자등록증, 통장사본) |
서비스: ContractService
컨트롤러: ContractController (/ai/contract)
레거시 캠페인에는 전자계약 기능이 없습니다. 계약은 외부에서 진행됩니다.
| 필드 | 타입 | 설명 |
|---|
id | PK | 계약서 ID |
application | FK | 신청 건 |
status | Enum | DRAFT → SENT → OPENED → FILLED → OTP_VERIFIED → SIGNED |
stageName, realName | String | 크리에이터 활동명, 실명 |
businessName | String | 사업자명 (사업자인 경우) |
bankName, bankAccountNumber, accountHolderName | String | 계좌 정보 |
registrationNumber | String | 주민등록번호/사업자등록번호 |
variableValues | JSON | 계약 템플릿 변수 (광고대금 등) |
signatureImageUrl | String | 서명 이미지 URL |
signedPdfUrl | String | 서명된 PDF URL |
documents | 1:N | 첨부 서류 (ContractDocument) |
applicantHidden = true 전환 (전원 서명 완료 시)
- PROPOSAL/SELECTED/ELIMINATED 아닌 지원자 → 일괄 REJECTED
CampaignApplication.phase → FIRST_REVIEW (2회 검수) 또는 SECOND_REVIEW (1회 검수)
- 개별 일정(ApplicationSchedule) 생성
| HTTP | 엔드포인트 | 설명 | 컨트롤러 |
|---|
| GET | /ai/influence/contents/{itemId} | 제출물 조회 (피드백 이력 포함) | ContentSubmissionController |
| GET | /ai/influence/contents/review/{reviewId} | 검수 회차 전체 제출 타입 조회 | ContentSubmissionController |
| POST | /ai/influence/contents | 제출물 생성 | ContentSubmissionController |
| PUT | /ai/influence/contents/{itemId} | 제출물 수정 (저장/제출) | ContentSubmissionController |
| PUT | /ai/influence/contents/review/{reviewId}/submit | 검수 회차 전체 일괄 제출 | ContentSubmissionController |
| HTTP | 엔드포인트 | 설명 | 컨트롤러 |
|---|
| GET | /ai/business/contents/review/{reviewId}/detail | 검수 상세 조회 | BusinessContentController |
| POST | /ai/business/contents/{itemId}/feedbacks | 피드백 추가 또는 승인 (현재 미사용) | BusinessContentController |
| POST | /ai/business/contents/review/{reviewId}/feedbacks/bulk | 벌크 피드백/승인 | BusinessContentController |
| POST | /ai/business/contents/review-request | 추가 검수 요청 | BusinessContentController |
서비스: ContentSubmissionService, ReviewStatusHelper, ApplicationPhaseService
검수 방식:
ProgressTable.aiCheck: AI 자동 검수 (GOOD, REJECT2, WAITING)
ProgressTable.personCheck: 담당자 수동 검수 (COMPLETE, WAITING)
ProgressTable.uploadStatus: CREATING → VERIFYING → RECREATING
AI 검수 플로우:
크리에이터 업로드 → Spring Boot → FastAPI (Python) → Google Gemini
→ 분석 결과 반환 → aiCheck 업데이트
컨트롤러: AiContentReviewController (/ai/review)
| HTTP | 엔드포인트 | 설명 |
|---|
| POST | /ai/review/video | AI 영상 검수 (Gemini) |
| POST | /ai/review/blog | AI 블로그 PDF 검수 (Gemini) |
| 필드 | 타입 | 설명 |
|---|
id | PK | 검수 ID |
application | FK | 신청 건 |
reviewRound | Integer | 검수 회차 (1 또는 2) |
status | Enum | PENDING, REVIEWING, APPROVED, REJECTED |
uploadApproved | Boolean | 2차 검수 통과 = 업로드 허용 |
feedbackDeadline | DateTime | 피드백 반영 마감일 |
maxFeedbackCount | Integer | 최대 피드백 횟수 (기본 1) |
currentFeedbackCount | Integer | 현재 피드백 횟수 |
| 필드 | 타입 | 설명 |
|---|
id | PK | 제출물 ID |
review | FK | 소속 검수 |
itemType | Enum | 제출 타입 |
filePath | TEXT | 파일 경로 (영상/사진) |
editorState | LONGTEXT | Lexical 에디터 상태 (텍스트 콘텐츠) |
status | Enum | PENDING, REVIEWING, APPROVED, REJECTED |
isSubmitted | Boolean | 제출 여부 (false = 임시저장) |
currentVersion | Integer | 버전 번호 |
| 필드 | 타입 | 설명 |
|---|
feedback | TEXT | 피드백 내용 |
feedbackType | Enum | FREE, GUIDELINE_UNREFLECTED, GUIDELINE_EXTRA |
resolved | Boolean | 해결 여부 |
isDraft | Boolean | 임시 저장 (크리에이터에게 미노출) |
checkedByCreator | Boolean | 크리에이터가 “반영완료” 체크 |
| 타입 | 설명 | 검수 단계 |
|---|
| SCRIPT_VIDEO | 영상 스크립트 | 1차 검수 |
| SCRIPT_BLOG | 블로그 스크립트 | 1차 & 2차 |
| VIDEO | 영상 | 2차 검수 |
| PHOTO | 사진 | 2차 검수 |
| CAPTION | 캡션 | 2차 검수 |
| HASHTAG | 해시태그 | 2차 검수 |
| 타입 | 설명 | 크레딧 차감 |
|---|
| FEEDBACK_NOT_REFLECTED | 크리에이터가 피드백 미반영 | 없음 |
| OUTSIDE_GUIDELINE | 가이드라인 외 추가 요청 | 50,000 크레딧 |
2차 검수 승인 후 크리에이터가 최종 결과물을 제출합니다.
| HTTP | 엔드포인트 | 설명 | 컨트롤러 |
|---|
| POST | /ai/business/contents/upload-date | 업로드일 선택 (OPTIMAL/CANDIDATE) | BusinessContentController |
| POST | /ai/business/contents/final-submissions/bulk | 벌크 최종 제출물 조회 | BusinessContentController |
| POST | /ai/business/contents/final-submission/{applicationId}/re-request | 재요청 | BusinessContentController |
서비스: FinalSubmissionService
| 필드 | 타입 | 설명 |
|---|
id | PK | ID |
application | 1:1 FK | 신청 건 |
contentLink | String | 업로드된 콘텐츠 링크 |
partnershipCode | String | 파트너십 코드 |
cleanFilePath | String | 클린본 파일 |
finalFilePath | String | 최종본 파일 |
isSubmitted | Boolean | 제출 여부 |
uploadDateType | String | OPTIMAL 또는 CANDIDATE |
uploadDate | DateTime | 업로드 예정일 (OPTIMAL) |
candidateDates | JSON | 후보 날짜 (CANDIDATE) |
reRequestTypes | JSON | 재요청 항목 |
| 타입 | 설명 |
|---|
| CONTENT_LINK | 업로드한 콘텐츠 링크 |
| PARTNERSHIP_CODE | 파트너십 코드 |
| CLEAN_FILE | 클린본 파일 |
| FINAL_FILE | 최종본 파일 |
| 타입 | 동작 |
|---|
| OPTIMAL | 자동으로 3일 후 설정 + 개별 업로드 허용일 일정 생성 |
| CANDIDATE | 후보 날짜를 관리자에게 이메일 발송 |
checkAndMarkSettlementReady(collab):
→ SELECTED 전원의 FinalSubmission.isSubmitted = true 확인
→ Collab.settlementReady = true
→ Collab.settlementMailScheduledDate = 20영업일 이내 마지막 목요일 계산
→ Collab.campaignSubStep → RESULT_SUMMARY (첫 제출 시)
- 실행: 매주 목요일 오전 10시 (KST)
- 클래스:
SettlementMailScheduler
- 조건:
settlementReady = true AND settlementMailSent = false AND settlementMailScheduledDate = 오늘
기준일 = settlementReady가 true로 전환된 날
20영업일 후 = 기준일로부터 토/일 제외 20일 후
발송 예정일 = 20영업일 이내 마지막 목요일
예시: 4/2(수) 전원 제출 완료 → 20영업일 후 = 4/30(수) → 마지막 목요일 = 4/24(목) 발송
| 컬럼 | 설명 |
|---|
| 크리에이터명 | 활동명 또는 실명 |
| 연락처, 이메일 | 인플루언서 정보 |
| 계약금액 (세전) | 광고대금 |
| 부가서비스 | 추가 서비스 금액 |
| 총액 | 계약금액 + 부가서비스 |
| 세금 | 개인: 3.3% / 사업자: 없음 |
| 입금액 (세후) | 총액 - 세금 |
| 사업자 여부 | 개인 / 사업자 |
| 계좌번호, 입금자명, 은행 | 계좌 정보 |
| 신분증번호 | 주민등록번호/사업자번호 |
| 계약서 PDF, 신분증/사업자등록증, 통장사본 | 서류 URL |
| 필드 | 타입 | 설명 |
|---|
settlementReady | Boolean | 전원 최종 제출 완료 여부 |
settlementMailSent | Boolean | 정산 메일 발송 완료 여부 |
settlementMailSentAt | DateTime | 발송 시각 |
settlementMailScheduledDate | LocalDate | 발송 예정일 |
캠페인 전체 일정을 관리합니다.
| 필드 | 설명 |
|---|
phase | CampaignPhase (아래 참조) |
startDate, endDate | 단계 기간 |
isCompleted | 완료 여부 |
isDelayed | 지연 여부 |
| 순서 | Phase | 설명 |
|---|
| 1 | RECRUITMENT | 모집 |
| 2 | EXCLUSION_SELECTION | 협업 제안 |
| 3 | CONTRACT_CREATION | 계약서 작성 |
| 4 | DRAFT_SUBMISSION | 제품 배송 |
| 5* | SCRIPT_SUBMISSION | 스크립트 제출 (이중 검수만) |
| 6* | SCRIPT_REVIEW | 스크립트 검수 (이중 검수만) |
| 7 | DRAFT_REVIEW | 제작물 제출 |
| 8 | VIDEO_PRODUCTION | 제작물 검수 및 업로드 허용 |
| 9 | VIDEO_REVIEW | 재제출 or 업로드 |
| 10 | UPLOAD | 최종 업로드 허용 |
| 11 | UPLOAD_APPROVAL | 최종업로드 |
| 12 | SETTLEMENT | 정산 |
크리에이터별 마감일을 관리합니다.
| Phase | 설명 | 자동 설정 시점 |
|---|
| SCRIPT_SUBMISSION_DEADLINE | 스크립트 제출 마감 | SELECTED 시 (2회 검수: +2일) |
| SCRIPT_REVIEW_DEADLINE | 스크립트 검수 마감 | 스크립트 제출 시 (익영업일 +1일) |
| CONTENT_SUBMISSION_DEADLINE | 제작물 제출 마감 | SELECTED 시 (1회 검수: +4일) / 스크립트 승인 시 (+4일) |
| CONTENT_REVIEW_DEADLINE | 제작물 검수 마감 | 제작물 제출 시 (익영업일 +1일) |
| FEEDBACK_DEADLINE | 피드백 반영 마감 | 피드백 발생 시 (+4일) |
| UPLOAD_ALLOWED_DATE | 업로드 허용일 | 업로드일 설정 시 |