- AGENTS.md: canonical project entry point (Quick Nav, pipeline, constraints) - docs/: complete docs tree — architecture, API spec, DB schema, infra, runbook, requirements, tech stack, principles, reference ADRs, guides, tasks backlog, testing strategy - tests/README.md: test commands, structure, known gaps - README.md / CLAUDE.md / DEPLOYMENT.md: updated with canonical doc links - .archive/: backup of pre-documentation-pipeline originals - backend/uv.lock: uv dependency lockfile - Delete committed __pycache__ .pyc files (should have been gitignored) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
198 lines
7.5 KiB
Markdown
198 lines
7.5 KiB
Markdown
# API Specification — Accessible Video Processing Platform
|
|
|
|
<!-- SCOPE: api-spec | owner: ln-113 | generated: 2026-04-29 -->
|
|
|
|
**Base URL (production):** `https://ai-sandbox.oliver.solutions/video-accessibility-back`
|
|
**Base URL (local):** `http://localhost:8003`
|
|
**OpenAPI docs:** `{base_url}/docs` (Swagger UI)
|
|
|
|
All endpoints require `Authorization: Bearer <access_token>` except `/auth/login`, `/auth/refresh`, `/auth/microsoft/*`, and `/health`.
|
|
|
|
---
|
|
|
|
## Authentication
|
|
|
|
| Method | Path | Auth | Description |
|
|
|--------|------|------|-------------|
|
|
| POST | `/api/v1/auth/login` | None | Email/password login; returns access token + sets refresh cookie |
|
|
| POST | `/api/v1/auth/refresh` | Cookie | Exchange refresh cookie for new access token |
|
|
| POST | `/api/v1/auth/logout` | Bearer | Revoke refresh token, clear cookie |
|
|
| POST | `/api/v1/auth/microsoft/callback` | None | Microsoft SSO callback; validates OIDC token |
|
|
| GET | `/api/v1/auth/microsoft/login` | None | Redirect to Microsoft login |
|
|
| POST | `/api/v1/auth/change-password` | Bearer | Change own password |
|
|
|
|
**Login response fields:**
|
|
|
|
| Field | Type | Notes |
|
|
|-------|------|-------|
|
|
| access_token | string | JWT, 15-minute TTL |
|
|
| token_type | string | Always "bearer" |
|
|
| user | object | User profile (id, email, role, org_id) |
|
|
|
|
---
|
|
|
|
## Jobs
|
|
|
|
| Method | Path | Roles | Description |
|
|
|--------|------|-------|-------------|
|
|
| GET | `/api/v1/jobs` | ALL | List jobs (role-filtered: client sees own, reviewer/admin see all) |
|
|
| POST | `/api/v1/jobs` | CLIENT, ADMIN | Create job with MP4 upload |
|
|
| GET | `/api/v1/jobs/{id}` | ALL | Job detail with current status + outputs |
|
|
| DELETE | `/api/v1/jobs/{id}` | ADMIN | Delete job and GCS files |
|
|
| GET | `/api/v1/jobs/{id}/downloads` | ALL | Signed download URLs for deliverables (24h expiry) |
|
|
| POST | `/api/v1/jobs/{id}/actions/approve` | REVIEWER, ADMIN | Approve job at current QC stage |
|
|
| POST | `/api/v1/jobs/{id}/actions/reject` | REVIEWER, ADMIN | Reject job with reason |
|
|
| POST | `/api/v1/jobs/{id}/actions/feedback` | REVIEWER, ADMIN | Send QC feedback without rejection |
|
|
| POST | `/api/v1/jobs/{id}/actions/retry` | ADMIN | Retry failed task (TTS_FAILED, RENDER_FAILED) |
|
|
|
|
**Job object key fields:**
|
|
|
|
| Field | Type | Notes |
|
|
|-------|------|-------|
|
|
| _id | string | MongoDB ObjectId |
|
|
| status | string | JobStatus enum — see architecture.md |
|
|
| org_id | string | Organisation that owns the job |
|
|
| source_language | string | BCP-47 language code |
|
|
| requested_outputs | array | Output language codes requested |
|
|
| outputs | object | Per-language GCS paths |
|
|
| language_qc | object | Per-language QC state |
|
|
| created_at | datetime | ISO 8601 |
|
|
| updated_at | datetime | ISO 8601 |
|
|
| error | string | Last error message if failed |
|
|
|
|
---
|
|
|
|
## VTT Management
|
|
|
|
| Method | Path | Roles | Description |
|
|
|--------|------|-------|-------------|
|
|
| GET | `/api/v1/jobs/{id}/vtt/{lang}` | REVIEWER, ADMIN | Get VTT content for language |
|
|
| PATCH | `/api/v1/jobs/{id}/vtt/{lang}` | REVIEWER, LINGUIST, ADMIN | Update VTT content (auto-snapshots before save) |
|
|
| POST | `/api/v1/vtt/adjust-timing` | REVIEWER, ADMIN | Bulk shift all cue timings |
|
|
|
|
---
|
|
|
|
## VTT Version Control
|
|
|
|
| Method | Path | Roles | Description |
|
|
|--------|------|-------|-------------|
|
|
| GET | `/api/v1/jobs/{id}/vtt-versions/{lang}` | REVIEWER, ADMIN | List version history |
|
|
| GET | `/api/v1/jobs/{id}/vtt-versions/{lang}/{version_id}` | REVIEWER, ADMIN | Get specific version content |
|
|
| POST | `/api/v1/jobs/{id}/vtt-versions/{lang}/{version_id}/restore` | REVIEWER, ADMIN | Restore a previous version (creates new snapshot) |
|
|
| GET | `/api/v1/jobs/{id}/vtt-versions/{lang}/diff` | REVIEWER, ADMIN | Diff two versions (`?from=v1_id&to=v2_id`) |
|
|
|
|
---
|
|
|
|
## Language QC
|
|
|
|
| Method | Path | Roles | Description |
|
|
|--------|------|-------|-------------|
|
|
| GET | `/api/v1/jobs/{id}/language-qc` | REVIEWER, PM, ADMIN | Get per-language QC status for all languages |
|
|
| POST | `/api/v1/jobs/{id}/language-qc/{lang}/assign` | PM, ADMIN | Assign linguist to language |
|
|
| POST | `/api/v1/jobs/{id}/language-qc/{lang}/approve` | LINGUIST (assigned), PM, ADMIN | Approve language |
|
|
| POST | `/api/v1/jobs/{id}/language-qc/{lang}/reject` | LINGUIST (assigned), PM, ADMIN | Reject language with reason |
|
|
| POST | `/api/v1/jobs/{id}/language-qc/{lang}/feedback` | LINGUIST (assigned), PM, ADMIN | Send feedback without rejection |
|
|
|
|
---
|
|
|
|
## Glossaries
|
|
|
|
| Method | Path | Roles | Description |
|
|
|--------|------|-------|-------------|
|
|
| GET | `/api/v1/glossaries` | ALL | List glossaries for current org |
|
|
| POST | `/api/v1/glossaries` | ADMIN | Create glossary |
|
|
| GET | `/api/v1/glossaries/{id}` | ALL | Get glossary with terms |
|
|
| PUT | `/api/v1/glossaries/{id}` | ADMIN | Update glossary metadata |
|
|
| DELETE | `/api/v1/glossaries/{id}` | ADMIN | Delete glossary |
|
|
| POST | `/api/v1/glossaries/{id}/terms` | ADMIN | Add term |
|
|
| DELETE | `/api/v1/glossaries/{id}/terms/{term_id}` | ADMIN | Delete term |
|
|
|
|
---
|
|
|
|
## Files
|
|
|
|
| Method | Path | Roles | Description |
|
|
|--------|------|-------|-------------|
|
|
| POST | `/api/v1/files/upload-url` | CLIENT, ADMIN | Get signed GCS upload URL |
|
|
| GET | `/api/v1/files/{job_id}/{path}` | ALL | Get signed download URL |
|
|
|
|
---
|
|
|
|
## Users and Organisations
|
|
|
|
| Method | Path | Roles | Description |
|
|
|--------|------|-------|-------------|
|
|
| GET | `/api/v1/users/me` | ALL | Current user profile |
|
|
| GET | `/api/v1/organizations` | ADMIN | List organisations |
|
|
| POST | `/api/v1/organizations` | ADMIN | Create organisation |
|
|
| GET | `/api/v1/organizations/{id}/members` | PM, ADMIN | List org members |
|
|
| POST | `/api/v1/organizations/{id}/invite` | PM, ADMIN | Invite member |
|
|
| DELETE | `/api/v1/organizations/{id}/members/{user_id}` | PM, ADMIN | Remove member |
|
|
|
|
---
|
|
|
|
## Admin
|
|
|
|
| Method | Path | Roles | Description |
|
|
|--------|------|-------|-------------|
|
|
| GET | `/api/v1/admin/users` | ADMIN | List all users |
|
|
| PATCH | `/api/v1/admin/users/{id}` | ADMIN | Update user role or status |
|
|
| GET | `/api/v1/admin/audit-log` | ADMIN, PM | Query audit log |
|
|
|
|
---
|
|
|
|
## WebSocket
|
|
|
|
| Path | Auth | Description |
|
|
|------|------|-------------|
|
|
| `WS /api/v1/ws/jobs/{id}` | Query param `token=<access_token>` | Real-time job status updates |
|
|
| `WS /api/v1/ws/org/{org_id}` | Query param `token=<access_token>` | Org-scoped event stream |
|
|
|
|
**Message format:**
|
|
|
|
| Field | Type | Notes |
|
|
|-------|------|-------|
|
|
| type | string | `job_status_update`, `notification`, `ping` |
|
|
| job_id | string | Job ObjectId |
|
|
| status | string | New JobStatus value |
|
|
| updated_at | datetime | ISO 8601 |
|
|
|
|
---
|
|
|
|
## Health
|
|
|
|
| Method | Path | Auth | Description |
|
|
|--------|------|------|-------------|
|
|
| GET | `/health` | None | Returns `{"status":"healthy","version":"1.0.0"}` |
|
|
| GET | `/metrics` | None (internal) | Prometheus metrics |
|
|
|
|
---
|
|
|
|
## Error Response Format
|
|
|
|
All errors return:
|
|
|
|
| Field | Type | Notes |
|
|
|-------|------|-------|
|
|
| detail | string | Human-readable error message (never internal exception text) |
|
|
|
|
Common status codes:
|
|
|
|
| Code | Meaning |
|
|
|------|---------|
|
|
| 400 | Bad request / validation error |
|
|
| 401 | Unauthenticated or invalid token |
|
|
| 403 | Forbidden — insufficient role |
|
|
| 404 | Resource not found |
|
|
| 422 | Pydantic validation error |
|
|
| 429 | Rate limit exceeded |
|
|
| 500 | Internal server error (details logged, not returned) |
|
|
|
|
---
|
|
|
|
## Maintenance
|
|
|
|
**Update triggers:** New endpoint added, request/response schema changed, auth flow change.
|
|
**Verification:** All endpoints listed here exist in `backend/app/api/v1/routes_*.py`. OpenAPI schema at `/docs` matches this table.
|
|
|
|
<!-- END SCOPE: api-spec -->
|