-
Notifications
You must be signed in to change notification settings - Fork 0
09 API Specification
이 페이지는 API를 어디서 확인하고 어떻게 구현하는지 설명하는 입구입니다. API 개수를 Wiki에 고정하면 구현·Notion과 쉽게 어긋나므로 수량은 적지 않습니다.
| 계약 | 원본 | 설명 |
|---|---|---|
| Server External API | 배포된 Swagger/OpenAPI | 인증 API와 Worker token API를 포함해 Client가 호출 |
| Server↔AI Runtime Internal API |
fowoco/ai의 Internal OpenAPI·JSON Schema |
Server의 AiRuntimeClient가 소비 |
| 업무 의미·Catalog |
fowoco/knowledge versioned bundle |
Intent, 필수정보, checklist, guardrail |
| 사람이 읽는 상세 설명 | Notion API 명세 | 우선순위·화면 맥락·예시·구현 메모 |
| 화면 흐름 | Figma | 어떤 API를 언제 호출하는지 확인 |
문서와 코드가 다르면 구현된 동작은 Swagger/OpenAPI와 자동 test를 우선합니다. 차이는 같은 PR에서 고치거나 Issue로 기록합니다.
-
Authenticated API: Server의
/api/v1/**, 사용자 JWT 필요 -
Token public endpoint: Server의
/public/worker-links/**, 로그인 대신 만료 token 필요 -
Internal API: AI Runtime의
/internal/v1/**, S2S 인증 필요 - External API: 위 두 Server API를 합쳐 Client가 호출하는 API라는 뜻이며 “무인증”을 뜻하지 않음
- gateway prefix를 각 Controller path에 다시 붙이지 않습니다.
- 같은 기능을
/tasks/analyze와/ai-runs처럼 두 경로로 중복 구현하지 않습니다.
아래 목록은 M3의 목표 계약입니다. 현재 구현 여부는 배포 Swagger와 각 Issue 상태를 확인하세요. 2026-07-23 기준
main에는 Health와 Auth API가 있으며, 승인·감사 8개 API는 PR #37에서 리뷰 중입니다.
GET /health현재 구현된 최소 상태 endpoint입니다. 이후 liveness·readiness를 분리할 때 실제 배포 probe와 OpenAPI를 함께 갱신합니다.
POST /api/v1/auth/login
POST /api/v1/auth/refresh
POST /api/v1/auth/logout
GET /api/v1/auth/me로그인·Refresh rotation·logout·현재 사용자/Company/Role을 담당합니다.
GET /api/v1/workers
POST /api/v1/workers
GET /api/v1/workers/{workerId}
PATCH /api/v1/workers/{workerId}
POST /api/v1/workers/{workerId}/documents
PATCH /api/v1/workers/{workerId}/documents/{documentId}
POST /api/v1/files
GET /api/v1/documents
GET /api/v1/tasks/{taskId}/document-readiness
PUT /api/v1/tasks/{taskId}/document-request-draft원본 파일보다 문서 metadata를 우선하고, 파일은 안전한 fileId reference로 연결합니다.
GET /api/v1/tasks
POST /api/v1/tasks
GET /api/v1/tasks/{taskId}
PATCH /api/v1/tasks/{taskId}
PATCH /api/v1/tasks/{taskId}/checklist-items/{itemId}
POST /api/v1/tasks/{taskId}/approval-requests
POST /api/v1/tasks/{taskId}/approve
POST /api/v1/tasks/{taskId}/reject
POST /api/v1/tasks/{taskId}/evidence
POST /api/v1/tasks/{taskId}/external-submissions
POST /api/v1/tasks/{taskId}/complete
POST /api/v1/tasks/{taskId}/cancel
GET /api/v1/tasks/{taskId}/activities
GET /api/v1/audit-events
GET /api/v1/workflow-catalogsPATCH /api/v1/tasks/{taskId}로 상태를 임의 변경하지 않습니다. approval-requests는 검토 준비 전이, reject는 READY_FOR_REVIEW → DRAFT, external-submissions는 외부 제출 reference 저장과 WAITING_EXTERNAL, cancel은 사유가 필수인 종료 Command입니다.
PR #37에 구현된 8개 endpoint는 approval-requests, approve, reject, evidence, external-submissions, complete, activities, audit-events입니다. Task CRUD·checklist·cancel·Workflow Catalog는 #6에서 이어서 구현합니다.
- 쓰기 6개:
ADMIN,HR -
activities:ADMIN,HR,VIEWER -
audit-events:ADMIN -
companyId: 요청 body가 아니라 JWT ActorContext에서 결정 - 동시성:
expected_version - 승인 재사용:
content_revision + critical_fingerprint - 감사 검색: actor/action/target/trace/date filter와 불투명 cursor
POST /api/v1/ai-runs
GET /api/v1/ai-runs/{aiRunId}
POST /api/v1/ai-runs/{aiRunId}/retry
POST /api/v1/ai-runs/{aiRunId}/candidate-decisionsPOST /api/v1/ai-runs는 오래 기다리지 않고 202 Accepted, aiRunId, statusUrl을 반환합니다. 후보는 /candidate-decisions에서 각각 ACCEPT 또는 DISCARD합니다. 기존 /confirm과 /tasks/analyze는 만들지 않습니다.
/retry는 같은 Run에 새 AiAttempt를 추가하고 FAILED → RETRYING으로 전이합니다. 이전 attempt는 보존하며 응답은 202 Accepted + 같은 aiRunId + statusUrl입니다.
AiRun 상태:
QUEUED · RUNNING · RETRYING · SUCCEEDED · FAILED
업무 판정:
NEEDS_INFO · REVIEW_REQUIRED
두 값을 같은 status enum에 섞지 않습니다.
POST /api/v1/tasks/{taskId}/worker-link
GET /public/worker-links/{token}
POST /public/worker-links/{token}/documents
POST /public/worker-links/{token}/responses근로자는 로그인하지 않습니다. token이 가리키는 승인된 Task의 최소 안내와 허용 행동만 노출합니다. Worker Link 발급은 APPROVED → WAITING_WORKER 전이를 함께 수행하며, 재발급은 상태를 중복 변경하지 않고 이전 link를 폐기한 뒤 새 token으로 회전합니다.
M4에서는 다음 그룹을 계획합니다.
- CSV/XLSX Import job·mapping·validation·commit·retry
- Today Dashboard read model
- 사업장 설정과 알림 선호
- 운영용 관측·관리 API가 정말 필요한지 검토
공식 기한·Guardrail은 사업장 설정으로 덮어쓰지 않습니다.
Server는 Provider가 아니라 AI Runtime을 호출합니다.
POST /internal/v1/analyses일반 Client가 이 endpoint를 직접 호출하지 않습니다. S2S 인증, request ID, trace context, timeout, body size 제한을 적용합니다. Request/Response 예시는 AI Run과 AI Runtime 연동에서 확인합니다.
| 항목 | 규칙 |
|---|---|
| 인증 |
/api/v1/**는 JWT, Worker endpoint는 만료 token, /internal/**는 S2S |
| tenant | body의 companyId가 아니라 인증 Context에서 결정 |
| 시간 | 시각(Instant)은 UTC ISO-8601, 날짜 전용값은 ISO YYYY-MM-DD
|
| 동시성 | 중요한 Command에 expectedVersion 또는 조건부 요청 |
| 멱등성 | 생성·retry·후보 결정·link 회전·제출에 Idempotency-Key 정책 |
| Page | OpenAPI에 cursor 또는 page 방식을 endpoint별로 명시 |
| Enum | 허용값과 unknown 처리 규칙을 OpenAPI에 모두 기재 |
| Request ID | 응답과 안전한 오류에 포함, log와 trace 연결 |
| HTTP | 의미 | 예시 |
|---|---|---|
| 400 | 형식·필드 validation 실패 | 날짜 형식 오류 |
| 401 | 인증 없음·만료 | Access Token 만료 |
| 403 | Role 또는 범위 부족 | Viewer가 근로자 수정 |
| 404 | resource 없음 또는 안전한 token 정책 | 타 Company resource |
| 409 | version·idempotency·중복 충돌 | 같은 key에 다른 payload |
| 422 | 형식은 맞지만 업무 규칙 위반 | 승인 전 Worker Link 발급 |
| 429 | 공개 link·API rate limit | 반복 제출 |
| 503 | 일시적으로 처리 불가 | AI Runtime circuit open |
오류 body에는 안전한 requestId, 안정적인 code, 사용자용 message, 필요한 field error만 넣습니다. stack trace, Provider 원문, Secret, 개인정보를 반환하지 않습니다.
- Server Issue와 저장소 경계를 확인합니다.
- Notion의 우선순위·화면·Request/Response 설명을 읽습니다.
- OpenAPI에 Role, 상태, 오류, 멱등성, 예시를 먼저 정의합니다.
- Application Service에서 tenant와 Workflow guard를 구현합니다.
- Flyway와 Repository에 tenant·unique·version 제약을 추가합니다.
- 정상, validation, 권한, 타 Company, 중복, 동시성 test를 작성합니다.
- Figma 흐름과 실제 응답이 맞는지 Client와 확인합니다.
- 같은 PR에서 Swagger·필요한 Notion/Wiki 설명을 갱신합니다.
-
P0: M3 대표 흐름과 안전을 막으므로 먼저 구현 -
P1: M4 운영 편의·고도화 -
P2: 일정에 따라 미룰 수 있는 보완
보안 endpoint는 작아 보여도 낮은 우선순위나 “쉬운 작업”으로 분류하지 않습니다.