jobhunt-platform/docs/api-contract.md
hermes b77c8b0044 Bootstrap: README, ADR-0001 (LLM at decision points), data model, API contract, worker task cards
Design foundation for POC. Monorepo: FastAPI+Postgres backend, Vue 3 frontend,
Python packages (llm-gateway, artifacts, connectors). Approval gate and
token budgets are architectural constraints per measured prototype findings.
2026-07-30 17:56:07 +00:00

43 lines
2.1 KiB
Markdown

# API contract (POC)
Base: `/api`. JSON everywhere. Errors as `{error: {code, message}}` with proper HTTP status.
## Profile & CV
- `GET /profile` -> profile object (create default if none)
- `PUT /profile` -> update profile fields
- `GET /profile/sections` -> list of cv_section ordered by kind, sort_order
- `POST /profile/sections` -> create section
- `PUT /profile/sections/{id}` -> update
- `DELETE /profile/sections/{id}`
- `POST /profile/sections/{id}/ai-assist` body `{instruction: str}` -> `{suggestions: [str]}` (LLM, cheap->strong routing per config)
- `POST /profile/render-cv` -> `{artifact_id, url}` rendered PDF from current profile + sections (packages/artifacts)
## Job postings
- `POST /postings` body `{url}` -> fetch via connectors (manual_url for POC), create job_posting + application(state=discovered)
- `GET /postings` -> list
- `POST /postings/{id}/score` -> run scoring rubric vs profile -> application.state=scored, returns `{score, rationale}`
## Applications (kanban)
- `GET /applications` -> list with posting info joined
- `POST /applications/{id}/transition` body `{to}` -> guarded per data-model.md table; 409 if illegal or guard fails
- `POST /applications/{id}/artifacts` multipart upload or `{kind, content}` -> creates artifact with content_hash
- `POST /applications/{id}/artifacts/cover-letter` body `{letter_text}` -> stores user draft, returns artifact + AI critique `{comments: [{quote, suggestion, severity}]}` (LLM review, does not rewrite)
- `GET /applications/{id}/artifacts` -> list
## Approval & outbox (the gate)
- `POST /applications/{id}/approvals` body `{action, artifact_id}` -> creates pending approval (expires_at = now+24h)
- `POST /approvals/{id}/confirm` -> user confirms; verified artifact.content_hash == approval.artifact_hash or 409
- `POST /approvals/{id}/reject`
- `POST /outbox/send` body `{approval_id, payload}` -> **fails 409 unless** approval confirmed, unexpired, hash match. On success: outbox.status=sent (POC: log/echo transport pluggable; real SMTP later)
## Telemetry
- `GET /telemetry/tasks` -> task_run list (tokens, model, cost) — shows users their burn
## Health
- `GET /health` -> `{status: "ok"}`