# Scrum4Me REST API REST-API contract voor Claude Code en andere clients. ## Authenticatie Alle endpoints behalve `GET /api/health` vereisen een Bearer-token: ``` Authorization: Bearer ``` Tokens beheer je via Instellingen → Tokens (`/settings/tokens`). Een token is gekoppeld aan één gebruiker; een demo-account-token kan lezen maar niet schrijven (`403`). ## Status-enums De API gebruikt **lowercase** statussen. De database gebruikt UPPER_SNAKE; de vertaling gebeurt op de boundary. | Entiteit | Waarden | |---|---| | Task status | `todo`, `in_progress`, `review`, `done` | | Story status | `open`, `in_sprint`, `done` | ## Foutcodes | Code | Betekenis | |---|---| | `200` | OK | | `201` | Created | | `400` | Malformed body (bv. ongeldige JSON) | | `401` | Token ontbreekt of ongeldig | | `403` | Token heeft geen toegang (demo-account, geen lid van product) | | `404` | Resource niet gevonden | | `422` | Validatiefout — body is wel-gevormd maar niet acceptabel | | `500` | Onverwachte serverfout | --- ## Endpoints ### `GET /api/health` Health-probe. Geen authenticatie vereist. **Query params:** `?db=1` voegt een DB-ping toe. **Response (200):** ```json { "status": "ok", "version": "0.3.x", "time": "2026-04-26T20:00:00Z" } ``` Met `?db=1`: ```json { "status": "ok", "version": "0.3.x", "time": "...", "database": "ok" } ``` `database` is `"ok"` of `"down"`. De endpoint zelf retourneert altijd `200`. ```bash curl https://scrum4me.app/api/health?db=1 ``` --- ### `GET /api/products` Lijst van actieve producten waar de tokengebruiker eigenaar of lid van is. **Response (200):** ```json [ { "id": "cmofu...", "code": "SCRUM4ME", "name": "Scrum4Me", "description": "...", "repo_url": "https://github.com/...", "definition_of_done": "..." } ] ``` ```bash curl -H "Authorization: Bearer $TOKEN" https://scrum4me.app/api/products ``` --- ### `GET /api/products/:id/claude-context` Bundled context voor Claude Code: product, actieve sprint, volgende story (met tasks) en open todos van de tokengebruiker — in één call. **Response (200):** ```json { "product": { "id", "code", "name", "description", "repo_url", "definition_of_done" }, "active_sprint": { "id": "...", "sprint_goal": "...", "status": "ACTIVE" } | null, "next_story": { "id", "code", "title", "description", "acceptance_criteria", "priority", "status", "tasks": [ { "id", "code", "title", "description", "implementation_plan", "priority", "sort_order", "status" } ] } | null, "open_todos": [ { "id", "title", "description", "created_at" } ] } ``` `open_todos` is gelimiteerd op 50 items, gesorteerd op `created_at` asc. Demo-tokens kunnen dit endpoint lezen. ```bash curl -H "Authorization: Bearer $TOKEN" \ https://scrum4me.app/api/products/$PRODUCT_ID/claude-context ``` --- ### `GET /api/products/:id/next-story` Hoogst geprioriteerde open story in de actieve sprint. **Response (200):** ```json { "id": "...", "code": "ST-356", "title": "Solo Kanban-bord met DnD en Zustand", "description": "...", "acceptance_criteria": "...", "status": "in_sprint", "tasks": [ { "id": "...", "code": "ST-356.1", "title": "Store stores/solo-store.ts", "description": "...", "implementation_plan": null, "priority": 2, "sort_order": 1, "status": "todo" } ] } ``` **Foutcodes:** `404` als geen actieve sprint of geen open stories. --- ### `GET /api/sprints/:id/tasks` Lijst taken van de sprint, geordend op `(story.sort_order, task.priority, task.sort_order)`. **Query params:** `?limit=N` (default 10, max 50) **Response (200):** ```json [ { "id": "...", "code": "ST-356.1", "title": "...", "description": "...", "implementation_plan": null, "story_id": "...", "story_code": "ST-356", "priority": 2, "sort_order": 1, "status": "todo" } ] ``` --- ### `PATCH /api/stories/:id/tasks/reorder` Volgorde van taken binnen een story aanpassen. **Body:** ```json { "task_ids": ["task-id-a", "task-id-b", "task-id-c"] } ``` Alle IDs moeten bij de story horen. **Foutcodes:** `422` bij Zod-fouten of als een task_id niet tot de story behoort. --- ### `PATCH /api/tasks/:id` Status of implementation_plan bijwerken. Minstens één van beide is verplicht. Toegestane status-waarden zijn `todo`, `in_progress` en `done`. `review` wordt door deze endpoint geweigerd zolang de sprint-UI die state niet rendert — gebruik de Kanban-board voor REVIEW-overgangen. **Body:** ```json { "status": "in_progress", "implementation_plan": "..." } ``` **Response (200):** ```json { "id": "...", "status": "in_progress", "implementation_plan": "..." } ``` **Foutcodes:** `422` bij ongeldige body of onbekende status. `403` bij demo-token. --- ### `POST /api/stories/:id/log` Activiteit vastleggen op een story. **Body — IMPLEMENTATION_PLAN:** ```json { "type": "IMPLEMENTATION_PLAN", "content": "Plan: ...", "metadata": { "branch": "feat/x" } } ``` **Body — TEST_RESULT:** ```json { "type": "TEST_RESULT", "content": "Alle tests groen", "status": "PASSED", "metadata": { "ci_run": "..." } } ``` **Body — COMMIT:** ```json { "type": "COMMIT", "content": "Werk afgerond", "commit_hash": "abc123", "commit_message": "feat(ST-XXX): ...", "metadata": { "branch": "feat/x" } } ``` `metadata` is optioneel, vrij JSON-object. **Response (201):** ```json { "id": "...", "created_at": "..." } ``` --- ### `POST /api/todos` Nieuwe todo voor de tokengebruiker. **Body:** ```json { "title": "Een ding doen", "description": "Optionele uitleg, max 2000 tekens", "product_id": "cmof..." } ``` **Response (201):** ```json { "id": "...", "title": "...", "description": "...", "created_at": "..." } ``` --- ## Voorbeeldworkflow voor Claude Code 1. **Probe:** `GET /api/health?db=1` — bevestig dat de service en DB bereikbaar zijn. 2. **Context:** `GET /api/products/$ID/claude-context` — haal product, sprint, volgende story en todos op in één call. 3. **Plan vastleggen:** `POST /api/stories/$STORY_ID/log` met `type: IMPLEMENTATION_PLAN`. 4. **Per task:** `PATCH /api/tasks/$TASK_ID` met `status: "in_progress"`, daarna met `status: "done"` plus eventueel `implementation_plan`. 5. **Test:** `POST /api/stories/$STORY_ID/log` met `type: TEST_RESULT` en `status: PASSED|FAILED`. 6. **Commit:** `POST /api/stories/$STORY_ID/log` met `type: COMMIT`, `commit_hash`, `commit_message`, optioneel `metadata: { branch }`.