docs(PBI-12 + /init): sprint-lifecycle runbook + MCP-tools plan + CLAUDE.md fixes (#192)
* docs(PBI-12 T-54): voeg sprint-tools toe aan mcp-integration.md
Documenteert mcp__scrum4me__create_sprint en mcp__scrum4me__update_sprint
onder de Authoring-sectie, met verwijzing naar plan-to-pbi-flow.md voor
de werkwijze.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(PBI-12 T-55): promote plan-to-pbi-flow.md naar active
- frontmatter status: draft → active
- ⚠️-tooling-banner verwijderd; tools live sinds adbea3f in scrum4me-mcp
- korte note die naar mcp-integration.md verwijst voor tool-reference
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(CLAUDE.md): /init improvements (scripts, proxy hardstop, versies)
- Stack-tabel: exacte versies Next.js 16.2, React 19.2, Tailwind v4, Prisma v7.8
- Hardstop bullet voor proxy.ts (géén middleware.ts, demo-write blokkering)
- MCP-sectie: bewuste duplicatie van lib/job-config.ts ↔ scrum4me-mcp toegelicht
- Verificatie-sectie: npm scripts-tabel (dev/test/seed/create-admin/docs/diagrams)
+ Vitest exclude + server-only mock note
- Orientatie-tabel: verwijzing toegevoegd naar docs/runbooks/plan-to-pbi-flow.md
- frontmatter last_updated: 2026-05-11
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(PBI-12): implementatieplan voor sprint MCP-tools
Plan-file voor de twee tools (create_sprint + update_sprint) die de
sprint-lifecycle uit plan-to-pbi-flow.md ondersteunen. Beslissingen:
- Eén generieke update_sprint (geen losse close/fail/archive tools)
- Géén state-machine validatie (resubmit-mechanisme zit elders)
- Auto-end_date bij CLOSED/FAILED/ARCHIVED
- Cron + create_story sprint-param uit scope (apart later)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b39c3ec2e1
commit
0a842e6841
5 changed files with 391 additions and 4 deletions
153
docs/plans/sprint-mcp-tools.md
Normal file
153
docs/plans/sprint-mcp-tools.md
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
---
|
||||
title: "Sprint MCP-tools — create_sprint & update_sprint"
|
||||
status: draft
|
||||
audience: [maintainer, ai-agent]
|
||||
language: nl
|
||||
last_updated: 2026-05-11
|
||||
applies_to: [scrum4me-mcp]
|
||||
---
|
||||
|
||||
# Plan — `create_sprint` + `update_sprint` in scrum4me-mcp
|
||||
|
||||
## Context
|
||||
|
||||
Het runbook [docs/runbooks/plan-to-pbi-flow.md](../runbooks/plan-to-pbi-flow.md) (draft) beschrijft een sprint-lifecycle als onderdeel van de plan→PBI→story→task workflow:
|
||||
|
||||
- **Bij plan-goedkeuring** opent Claude een nieuwe sprint (`status: OPEN`)
|
||||
- **Na PR-merge + verify groen** sluit Claude die sprint (`status: CLOSED`)
|
||||
- **Cron** mag stale/falende sprints later op `FAILED` zetten
|
||||
|
||||
Hiervoor zijn twee MCP-tools nodig die nog **niet** bestaan in `~/Development/scrum4me-mcp/`:
|
||||
|
||||
| Tool | Wat | Wie roept aan |
|
||||
|---|---|---|
|
||||
| `create_sprint` | Maakt nieuwe sprint, status `OPEN` | Claude bij plan-goedkeuring |
|
||||
| `update_sprint` | Wijzigt status / dates / sprint_goal | Claude bij PR-close & cron bij stale-detect |
|
||||
|
||||
Door één generieke `update_sprint` te bouwen (i.p.v. losse `close_sprint`/`fail_sprint`) is de tool-oppervlakte minimaal en zijn alle transities tussen `OPEN | CLOSED | ARCHIVED | FAILED` mogelijk.
|
||||
|
||||
## Bestaande conventies (te respecteren)
|
||||
|
||||
- **Toolpattern:** elk tool is één bestand onder `~/Development/scrum4me-mcp/src/tools/`, registreert via `register{ToolName}Tool(server: McpServer)` in `src/index.ts`. Voorbeeld-template: [scrum4me-mcp/src/tools/create-pbi.ts](https://github.com/madhura68/scrum4me-mcp/blob/main/src/tools/create-pbi.ts)
|
||||
- **DB-toegang:** direct via `import { prisma } from '../prisma.js'` — **geen** REST-tussenstap, geen Next-deps
|
||||
- **Auth:** `requireWriteAccess(token)` + `userCanAccessProduct(userId, productId)` zoals in `create-pbi.ts`
|
||||
- **Error-pad:** `withToolErrors(...)`, `toolError(...)`, `toolJson(...)` uit `../errors.js`
|
||||
- **Zod-input** apart gedefinieerd, status-enum gespiegeld uit Prisma
|
||||
- **Schema-sync:** Prisma-schema is een git-submodule in `vendor/scrum4me`; geen schema-wijzigingen nodig (Sprint-model heeft alle statussen al)
|
||||
|
||||
## Scope
|
||||
|
||||
### A. `create_sprint`
|
||||
|
||||
**Bestand:** `~/Development/scrum4me-mcp/src/tools/create-sprint.ts`
|
||||
|
||||
**Input-schema:**
|
||||
|
||||
```ts
|
||||
const inputSchema = z.object({
|
||||
product_id: z.string().min(1),
|
||||
code: z.string().min(1).max(30).optional(), // auto-generate als leeg
|
||||
sprint_goal: z.string().min(1).max(500),
|
||||
start_date: z.string().date().optional(), // ISO YYYY-MM-DD; default = today
|
||||
})
|
||||
```
|
||||
|
||||
**Gedrag:**
|
||||
|
||||
1. `requireWriteAccess(token)` → user_id
|
||||
2. `userCanAccessProduct(user_id, product_id)`
|
||||
3. **Code-generatie** (als niet meegegeven): `S-{YYYY-MM-DD}-{N}` waarbij `N` = `count(sprints van product op datum) + 1`. Dezelfde retry-on-unique-conflict pattern als `generateNextPbiCode()`.
|
||||
4. `prisma.sprint.create({ data: { product_id, code, sprint_goal, status: 'OPEN', start_date } })`
|
||||
5. Return: `{ id, code, status, start_date }`
|
||||
|
||||
**Niet doen:** géén check op bestaande OPEN-sprints (per runbook-beslissing: "altijd nieuwe sprint").
|
||||
|
||||
### B. `update_sprint`
|
||||
|
||||
**Bestand:** `~/Development/scrum4me-mcp/src/tools/update-sprint.ts`
|
||||
|
||||
**Input-schema:**
|
||||
|
||||
```ts
|
||||
const inputSchema = z.object({
|
||||
sprint_id: z.string().min(1),
|
||||
status: z.enum(['OPEN', 'CLOSED', 'ARCHIVED', 'FAILED']).optional(),
|
||||
sprint_goal: z.string().min(1).max(500).optional(),
|
||||
end_date: z.string().date().optional(),
|
||||
start_date: z.string().date().optional(),
|
||||
}).refine(d =>
|
||||
d.status !== undefined || d.sprint_goal !== undefined ||
|
||||
d.end_date !== undefined || d.start_date !== undefined,
|
||||
{ message: 'Minstens één veld vereist' }
|
||||
)
|
||||
```
|
||||
|
||||
**Gedrag:**
|
||||
|
||||
1. `requireWriteAccess(token)` → user_id
|
||||
2. Laad sprint → check `userCanAccessProduct(user_id, sprint.product_id)`
|
||||
3. **Geen state-machine validatie** in deze tool — elke status-transitie is toegestaan. Het resubmit/heropen-pad wordt elders (buiten deze MCP-tool) afgehandeld.
|
||||
4. **Auto-`end_date`:** als status naar `CLOSED`/`FAILED`/`ARCHIVED` gaat en `end_date` is niet meegegeven → set op `today()`.
|
||||
5. `prisma.sprint.update({ where: { id }, data: {...} })`
|
||||
6. Return: `{ id, code, status, start_date, end_date }`
|
||||
|
||||
### C. `index.ts` — tool-registratie
|
||||
|
||||
Twee regels toevoegen aan `~/Development/scrum4me-mcp/src/index.ts`:
|
||||
|
||||
```ts
|
||||
import { registerCreateSprintTool } from './tools/create-sprint.js'
|
||||
import { registerUpdateSprintTool } from './tools/update-sprint.js'
|
||||
// …
|
||||
registerCreateSprintTool(server)
|
||||
registerUpdateSprintTool(server)
|
||||
```
|
||||
|
||||
## Out-of-scope (apart op te pakken)
|
||||
|
||||
- **Cron auto-close/fail:** een Vercel cron-route (`/api/cron/sprint-lifecycle`) die OPEN-sprints scant, PR-status + verify check, en `update_sprint` aanroept met `CLOSED` of `FAILED`. Drempels: PR mergedAt → CLOSED, PR closed && !merged → FAILED, PR stale > 14d → FAILED. **Apart PBI** want vereist GitHub-API-koppeling en threshold-policy-besluiten.
|
||||
- **Sprint-koppeling bij `create_story`:** runbook merkt op dat als er meerdere OPEN-sprints zijn de gebruiker moet bevestigen welke. Schoner is `create_story` uitbreiden met optionele `sprint_id`-param. Klein patch in `create-story.ts`, maar **niet** in deze PBI — eerst de basis-tools werkend hebben.
|
||||
- **Sprint-events / SSE:** elke status-transitie zou een NOTIFY moeten emiteren zodat de UI live update. Bestaande pattern in [docs/patterns/realtime-notify-payload.md](../patterns/realtime-notify-payload.md). **Niet** in v1 van deze PBI — handmatige refresh acceptabel tot cron-flow er is.
|
||||
- **REST-endpoints:** `POST /api/sprints` en `PATCH /api/sprints/[id]` in de Scrum4Me-app voor UI-pariteit. **Niet** in deze PBI — MCP gaat direct via Prisma, UI kan dat later naadloos volgen.
|
||||
|
||||
## Testen
|
||||
|
||||
In `scrum4me-mcp` zelf (Vitest):
|
||||
|
||||
- `create-sprint.test.ts`: happy-path (alle velden + minimal), code-auto-generatie, code-conflict-retry, user-access-denied
|
||||
- `update-sprint.test.ts`: legal transities (×3), illegal transities (×3), auto-`end_date` bij CLOSE/FAIL/ARCHIVE, multi-field update, access-denied
|
||||
|
||||
In Scrum4Me-app: één integration-test in `__tests__/sprint-lifecycle.test.ts` die via een geseed token de MCP-tools aanroept en het Prisma-record verifieert.
|
||||
|
||||
## Implementatie-stappen (volgorde)
|
||||
|
||||
1. **`create-sprint.ts`** schrijven + registreren in `index.ts`
|
||||
2. **`update-sprint.ts`** schrijven + registreren in `index.ts`
|
||||
3. Unit-tests in scrum4me-mcp
|
||||
4. `npm run verify` in scrum4me-mcp (typecheck + tests)
|
||||
5. **Sync naar Scrum4Me-app:** `sync-schema.sh` is voor Prisma-schema; voor tool-discovery hoeft niets — MCP is een aparte service en de Scrum4Me-app importeert niets uit `scrum4me-mcp/src/tools/`
|
||||
6. Update [docs/runbooks/mcp-integration.md](../runbooks/mcp-integration.md): voeg de twee tools toe aan de tool-lijst
|
||||
7. Update [docs/runbooks/plan-to-pbi-flow.md](../runbooks/plan-to-pbi-flow.md): verwijder de ⚠️-tooling-banner; status van `draft` → `active`
|
||||
8. PR-flow zoals gewend (branch-and-commit-runbook)
|
||||
|
||||
## Open vragen — uitgesteld tot later
|
||||
|
||||
Bewust pas later beslissen (niet blokkerend voor de eerste implementatie):
|
||||
|
||||
- **`code`-conventie** — voor v1 default `S-{YYYY-MM-DD}-{N}`; later evalueren of `S-{N}` doorlopend per product (zoals PBI-N) beter past
|
||||
- **Cron-drempels** — pas relevant in de vervolg-PBI voor de cron zelf
|
||||
- **`update_sprint` zonder status-wijziging** — toegestaan (alle velden optioneel; refine eist minstens één)
|
||||
|
||||
## Risico's
|
||||
|
||||
- **Multi-sprint-context** bij `create_story`: nu impliciet (server resolveert "active sprint"). Met meerdere OPEN-sprints kan dit fout gaan. Mitigatie: korte termijn → het runbook waarschuwt, gebruiker bevestigt; lange termijn → expliciete `sprint_id` param in `create_story`.
|
||||
- **Cron racet met handmatige close:** als gebruiker `update_sprint(CLOSED)` doet vóór de cron, en cron daarna `FAILED` zet, overschrijft cron de eerdere status. Acceptabel voor v1 — last-write-wins. Het externe resubmit-mechanisme bepaalt of een sprint überhaupt nog door cron geraakt mag worden.
|
||||
- **Demo-modus:** demo-users mogen geen schrijfacties; `requireWriteAccess` checkt al op `isDemo`, dus geen extra werk.
|
||||
|
||||
## Klaar wanneer
|
||||
|
||||
- [ ] Beide tools live in scrum4me-mcp `main`
|
||||
- [ ] Tests groen
|
||||
- [ ] mcp-integration.md tool-lijst bijgewerkt
|
||||
- [ ] plan-to-pbi-flow.md banner weg + status `active`
|
||||
- [ ] Eén end-to-end smoke-test gedraaid: create_sprint → create_pbi → ... → update_sprint(CLOSED) op een lokale dev-DB
|
||||
Loading…
Add table
Add a link
Reference in a new issue