Glowb Dev Docs
Admin APIAdmin Campaign API

POST /ai/admin/campaigns/{campaignNo}/recruitment/reopen

캠페인 모집 마감 취소 (관리자 전용)

모집 마감 취소

마감된 모집을 다시 열고 새 모집 종료일을 지정합니다.

본 API는 관리자 전용입니다. 모집 이후 단계(선정·계약·제작) 일정은 재계산하지 않습니다. 마감을 되돌리는 것과 전체 일정을 미루는 것은 별개 결정이기 때문입니다.

HTTP 요청

POST /ai/admin/campaigns/{campaignNo}/recruitment/reopen
Authorization: Bearer {access_token}
Content-Type: application/json
{
  "recruitmentEndDate": "2026-08-25T23:59:59"
}

Path Parameters

파라미터타입필수설명
campaignNoInteger예캠페인 번호

Request Body

필드타입필수설명
recruitmentEndDateLocalDateTime예새 모집 종료일. 현재 시각 이후여야 합니다.

새 종료일을 서버가 정하지 않는 이유는, 언제까지 다시 열지가 운영 판단이기 때문입니다. 모집 종료 API가 시각을 받지 않는 것과 대비됩니다.

처리 흐름

  1. 입력 검증 — recruitmentEndDate가 없거나 과거이면 캠페인을 조회하기도 전에 거부
  2. 캠페인 조회 — 없으면 CAMPAIGN_NOT_FOUND
  3. 모집 종료일 갱신 — TB_COLLAB.recruitment_end_date = 지정한 시각
  4. 모집 단계 일정 갱신 — TB_CAMPAIGN_SCHEDULE의 phase = RECRUITMENT 행만 end_date = 지정한 시각

original_end_date는 변경하지 않습니다. 지연 일수 계산의 기준값이기 때문입니다. 모집 종료 API와 동일한 규칙입니다.

아직 모집 중인 캠페인에 호출하면 종료일 이동(연장/단축)으로 동작하고 wasClosed가 false가 됩니다.

응답

성공 응답 (200 OK)

{
  "status": 200,
  "code": null,
  "message": "모집 마감이 취소되었습니다.",
  "data": {
    "campaignNo": 2485,
    "recruitmentEndDate": "2026-08-25T23:59:59",
    "previousRecruitmentEndDate": "2026-08-18T14:32:10",
    "wasClosed": true
  }
}

wasClosed가 false면 메시지는 "모집 종료일이 변경되었습니다."로 내려갑니다.

응답 필드

필드타입설명
campaignNoInteger캠페인 번호
recruitmentEndDateLocalDateTime새로 적용된 모집 종료일
previousRecruitmentEndDateLocalDateTime변경 전 모집 종료일. 값이 없던 캠페인이면 null
wasClosedBoolean호출 시점에 마감 상태였는지 여부

에러 응답

상태 코드code사례
400RECRUITMENT_END_DATE_INVALID새 종료일 누락 또는 과거 시각
404CAMPAIGN_NOT_FOUND캠페인 없음
401—인증 실패

전원 매칭 시 자동 모집 종료

모집은 어드민이 닫지 않아도 선정 인원 전원이 계약 서명을 마치면 자동으로 마감됩니다.

판정 기준

기존 CampaignCompletionNotifier.isAllSelectedSigned를 그대로 사용합니다.

  • 서명 대기 중인 제안(PROPOSAL) 인원이 0명
  • 선정(SELECTED) 인원이 1명 이상
  • 선정 인원 전원의 최신 계약 상태가 SIGNED

모집인원(TB_COLLAB.person)은 자유텍스트(VARCHAR)라 정원 기반 판정을 쓸 수 없습니다. ReserveCascadeService도 같은 이유로 예비 승계에서 정원 기준을 배제했습니다. 이 판정은 정원을 보지 않고 "제안한 사람이 남김없이 서명했는가"만 보므로 파싱 함정이 없습니다.

트리거 지점

ReserveReleaseListener가 ReserveReleaseCheckEvent를 AFTER_COMMIT에 받는 지점입니다. 이 이벤트는 전원 서명이 완성될 수 있는 네 경로 모두가 발행합니다.

발행 지점경로
ContractService마지막 크리에이터의 계약 서명
ProgressTableService광고주의 선정 인원 제외
AdminDashboardService어드민의 선정 인원 제외
CampaignApplicationService크리에이터 자진 이탈

같은 자리에서 남은 예비(RESERVED)를 대기(WAITING)로 되돌리는 처리가 이미 일어납니다. 예비를 푸는 것과 모집을 닫는 것은 같은 판정을 공유하는 짝입니다 — 예비가 풀리고 나면 이후 제외가 발생해도 자동 충원이 없으므로, 그 시점부터 모집을 열어둘 이유가 없습니다.

자동 종료가 일어나지 않는 경우

  • 크레딧 부족으로 예비 승계가 남아 있는 경우(creditBlocked) — 입금하면 승계가 재개되므로 모집을 닫지 않습니다.
  • 이미 마감된 캠페인 — 종료일을 다시 밀지 않습니다.
  • 전원 서명 전 — 서명 대기 인원이 하나라도 있으면 닫지 않습니다.

자동 종료 이후 계약 후 제외가 발생하면 예비가 이미 해제된 상태라 자동 충원 수단이 없습니다. 이때 인원을 더 받으려면 본 마감 취소 API로 모집을 다시 열어야 합니다.

자동 종료 실패는 로그만 남기고 본 흐름(서명·제외)으로 예외를 전파하지 않습니다.

API 테스트

On this page