PID 157444 · API pilot

기업–평가위원 자동 배정 API

동일 시·도 우선 · 일일 한도 · 인접 우회 · DB 잠금으로 한도 초과 차단

health: checking…

불변식: 임의의 위원·영업일에 대해 assignment(ASSIGNED|COMPLETED) 수 ≤ daily_limit 이며 daily_assignment_counter.count 와 일치한다.

curl -sS -X POST "$BASE/api/v1/assignments" \
  -H "Authorization: Bearer $ASSIGNMENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "applicationId": "app-demo-1",
    "companyId": "co-seoul-1",
    "provinceCode": "KR-11"
  }'

배정 규칙

동일 시·도 활성 위원 중 당일 배정 수 최소(동률 시 evaluator_id ASC)
동일 지역 한도 소진 시 인접 시·도 후보로 우회
인접까지 소진이면 MANUAL_PENDING

요청 한 건이 처리되는 순서

1 · 식별applicationId 중복 여부 확인
2 · 후보동일·인접 지역 후보 수집
3 · 잠금evaluator_id 오름차순 잠금
4 · 선택잠금 뒤 최신 count 비교
5 · 기록카운터와 결과를 원자적으로 저장
서울 신청 예시

서울 후보가 2/3, 1/3이고 인접 경기 후보가 0/3이어도 동일 지역 우선 규칙에 따라 서울의 1/3 위원을 선택한다.

동시에 들어와도 한도를 넘지 않는 이유

없는 일일 카운터 행은 먼저 만들고 SELECT … FOR UPDATE로 잠근다.
모든 요청이 evaluator_id ASC 순서로 잠가 교착 가능성을 줄인다.
잠금 후 최신 count로 위원을 선택하고, 카운터 증가와 배정 결과를 같은 트랜잭션에 기록한다.

중복 applicationId의 다른 입력은 충돌로 거절하고, 일시적인 DB 경합은 제한된 횟수만 재시도한다. 후보 소진은 오류 대신 MANUAL_PENDING으로 반환한다.

배정 규칙 직접 확인

시연 데이터 · offline model

먼저 신청값과 실험 조건을 고른 뒤 ① 준비 → ② 배정 실행 → ③ 카운트 조회 순서로 진행하세요. 실행 전에는 카운트 조회를 할 수 없으며, 실패가 발생하면 먼저 복구해야 합니다.

입력 대기 시연 결과 (브라우저 메모리)
applicationId—
HTTP—
errorCode—
배정 status—
evaluatorId—
당일 count조회 전
지금 무슨 일이

아직 저장된 요청이 없습니다. 입력을 확인하고 ① 요청 준비를 누르세요.

어떻게 보장하는가

실제 파일럿은 PostgreSQL 카운터 행을 evaluator_id ASC 순서로 잠근 뒤 최신 count를 비교하고, 증가와 배정 결과를 같은 트랜잭션에 기록합니다. 이 브라우저 model은 잠금·동시 재시도를 시각적으로 단순화하며 실제 API나 고객 DB에 쓰지 않습니다.

상태

ASSIGNED MANUAL_PENDING COMPLETED

엔드포인트

POST /api/v1/assignments — 배정 요청 (Bearer API key)
GET /api/v1/evaluators/{id}/daily-count — 당일 카운트
GET /api/v1/evaluators/daily-counts — 전체 카운트
PATCH /api/v1/assignments/{applicationId}/complete
GET /health — 공개
GET /v3/api-docs · Swagger UI

호출 예

첫 viewport 헤더에 동일 예제가 있습니다. Bearer 키는 환경변수 플레이스홀더만 사용합니다.

고객 환경 경계

고객 운영 DB·기존 스키마·사이트 호출 훅은 파일럿에서 연동하지 않았다. 본 파일럿은 PostgreSQL 16 레퍼런스 스택에서 동시성·규칙만 증명한다. 고객 DB 확정 시 dialect/잠금 이전은 docs/MIGRATION.md 체크리스트를 따른다.