docs(ST-513): add docs/API.md and link from CLAUDE.md specs table
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ee9cb2a570
commit
4232aed1f7
2 changed files with 283 additions and 0 deletions
|
|
@ -21,6 +21,7 @@ Lees het relevante document voordat je aan een feature begint. Nooit gokken over
|
|||
| `docs/scrum4me-backlog.md` | Welke task bouwen, volgorde, "done when"-criteria |
|
||||
| `docs/scrum4me-personas.md` | Lars (primair), Dina, Remi — gebruik bij UI-beslissingen |
|
||||
| `docs/scrum4me-product-backlog.md` | Historische domein-backlog (referentie); seed wordt sinds ST-004 gegenereerd uit `scrum4me-backlog.md` via `prisma/seed-data/parse-backlog.ts` |
|
||||
| `docs/API.md` | REST-API contract voor Claude Code — endpoints, status-enums, foutcodes, voorbeeld-curls |
|
||||
| `docs/scrum4me-styling.md` | **Lees dit voor elk component** — MD3-kleuren, shadcn patronen |
|
||||
| `docs/agent-instruction-audit.md` | Waarom de agent-instructies zijn aangescherpt; checklist voor toekomstige wijzigingen |
|
||||
|
||||
|
|
|
|||
282
docs/API.md
Normal file
282
docs/API.md
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
# 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 <token>
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
**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 }`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue