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.
43 lines
2.1 KiB
Markdown
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"}`
|