docs: architectuur en spec bijgewerkt na implementatie
- Next.js 15 → 16 in architecture doc en stack-tabel - ProductMember model toegevoegd aan datamodel-sectie en Prisma schema excerpt - implementation_plan veld gedocumenteerd bij tasks tabel - lib/product-access.ts en components/products|settings toegevoegd aan projectstructuur - Functionele spec: MVP-scope bijgewerkt met teambeheer; scope-bullet uitnodigingsflow aangepast - Rolbeheer-spec: acceptatiecriterium "geen effect in v1" vervangen door Developer-vereiste voor teams - v2 backlog: multi-user item herschreven naar uitnodigingsflow (basis teambeheer is nu v1) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
357b1e32e8
commit
45011a3347
3 changed files with 76 additions and 38 deletions
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
## Architectuursamenvatting
|
||||
|
||||
Scrum4Me is een desktop-first Next.js 15 webapplicatie die server-side wordt gerenderd en gedeployed op Vercel. De database is PostgreSQL via Neon, aangestuurd via Prisma v7. Authenticatie is custom username/password via iron-session — geen externe auth-provider, geen e-mail. De REST API voor Claude Code-integratie loopt via Next.js Route Handlers, beveiligd met API-tokens. Drag-and-drop in de planningsschermen wordt afgehandeld door dnd-kit.
|
||||
Scrum4Me is een desktop-first Next.js 16 webapplicatie die server-side wordt gerenderd en gedeployed op Vercel. De database is PostgreSQL via Neon, aangestuurd via Prisma v7. Authenticatie is custom username/password via iron-session — geen externe auth-provider, geen e-mail. De REST API voor Claude Code-integratie loopt via Next.js Route Handlers, beveiligd met API-tokens. Drag-and-drop in de planningsschermen wordt afgehandeld door dnd-kit.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -15,10 +15,10 @@ Scrum4Me is een desktop-first Next.js 15 webapplicatie die server-side wordt ger
|
|||
|
||||
| Laag | Technologie | Rationale |
|
||||
|---|---|---|
|
||||
| Frontend framework | Next.js 15 (App Router) | Stabiel, wijdverbreid, naadloze Vercel-deployment; SSR vereist voor auth-cookie-management |
|
||||
| UI runtime | React 19 | Standaard bij Next.js 15; brengt `useActionState`, `useFormStatus` en de React Compiler (experimenteel) mee — minder boilerplate bij Server Actions |
|
||||
| Frontend framework | Next.js 16 (App Router) | Stabiel, wijdverbreid, naadloze Vercel-deployment; SSR vereist voor auth-cookie-management |
|
||||
| UI runtime | React 19 | Standaard bij Next.js 16; brengt `useActionState`, `useFormStatus` en de React Compiler (experimenteel) mee — minder boilerplate bij Server Actions |
|
||||
| Taal | TypeScript (strict) | Type-veiligheid is essentieel voor een solo developer zonder reviewlaag; vangt datamodel-mismatches vroeg |
|
||||
| Client state | Zustand | Minimale boilerplate voor ephemere UI-staat (selectie, optimistische drag-and-drop volgorde); leeft naast Server Components zonder conflict; eenvoudig uitbreidbaar naar v2 teamgebruik |
|
||||
| Client state | Zustand | Minimale boilerplate voor ephemere UI-staat (selectie, optimistische drag-and-drop volgorde); leeft naast Server Components zonder conflict |
|
||||
| Styling | Tailwind CSS + shadcn/ui | Snelle iteratie; toegankelijke componentprimitieven; desktop-first layouts goed ondersteund |
|
||||
| Database (cloud) | PostgreSQL via Neon | Serverless Postgres, gratis tier voldoende voor MVP; native PostgreSQL zonder vendor lock-in |
|
||||
| ORM | Prisma v7 | Type-safe queries; PostgreSQL via adapter; migraties zijn deterministisch |
|
||||
|
|
@ -192,6 +192,7 @@ Scrum4Me is een desktop-first Next.js 15 webapplicatie die server-side wordt ger
|
|||
| sprint_id | String | FK → sprints, nullable | Denormalisatie voor snellere queries |
|
||||
| title | String | not null, max 200 | |
|
||||
| description | String | nullable, max 1000 | |
|
||||
| implementation_plan | String | nullable | Opgeslagen door Claude Code MCP via `PATCH /api/tasks/:id` |
|
||||
| priority | Int | 1–4, not null | |
|
||||
| sort_order | Float | not null | |
|
||||
| status | Enum | TO_DO \| IN_PROGRESS \| DONE | |
|
||||
|
|
@ -219,6 +220,22 @@ Scrum4Me is een desktop-first Next.js 15 webapplicatie die server-side wordt ger
|
|||
|
||||
---
|
||||
|
||||
### `product_members`
|
||||
|
||||
| Kolom | Type | Constraints | Noten |
|
||||
|---|---|---|---|
|
||||
| id | String (cuid) | PK | |
|
||||
| product_id | String | FK → products (cascade delete) | |
|
||||
| user_id | String | FK → users (cascade delete) | |
|
||||
| created_at | DateTime | default now() | |
|
||||
|
||||
**Indexes:** `(user_id)` — opzoeken van producten waarbij een gebruiker lid is
|
||||
**Constraint:** unique `(product_id, user_id)` — één lidmaatschap per gebruiker per product
|
||||
|
||||
Koppelt Developer-gebruikers aan een product backlog. De eigenaar (`products.user_id`) heeft altijd volledige toegang; via `product_members` kunnen aanvullende Developers leesrechten en schrijfrechten op stories, taken en sprints van dat product krijgen. Rollen worden niet opgeslagen in deze tabel — dat doet `user_roles`. Een gebruiker kan alleen worden toegevoegd als hij/zij de rol `DEVELOPER` heeft.
|
||||
|
||||
---
|
||||
|
||||
## Prisma Schema (excerpt)
|
||||
|
||||
```prisma
|
||||
|
|
@ -265,16 +282,17 @@ enum SprintStatus {
|
|||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
username String @unique
|
||||
password_hash String
|
||||
is_demo Boolean @default(false)
|
||||
created_at DateTime @default(now())
|
||||
updated_at DateTime @updatedAt
|
||||
roles UserRole[]
|
||||
api_tokens ApiToken[]
|
||||
products Product[]
|
||||
todos Todo[]
|
||||
id String @id @default(cuid())
|
||||
username String @unique
|
||||
password_hash String
|
||||
is_demo Boolean @default(false)
|
||||
created_at DateTime @default(now())
|
||||
updated_at DateTime @updatedAt
|
||||
roles UserRole[]
|
||||
api_tokens ApiToken[]
|
||||
products Product[]
|
||||
todos Todo[]
|
||||
product_members ProductMember[]
|
||||
}
|
||||
|
||||
model UserRole {
|
||||
|
|
@ -299,19 +317,21 @@ model ApiToken {
|
|||
}
|
||||
|
||||
model Product {
|
||||
id String @id @default(cuid())
|
||||
user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
|
||||
id String @id @default(cuid())
|
||||
user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
|
||||
user_id String
|
||||
name String
|
||||
description String?
|
||||
repo_url String?
|
||||
definition_of_done String
|
||||
archived Boolean @default(false)
|
||||
created_at DateTime @default(now())
|
||||
updated_at DateTime @updatedAt
|
||||
archived Boolean @default(false)
|
||||
created_at DateTime @default(now())
|
||||
updated_at DateTime @updatedAt
|
||||
pbis Pbi[]
|
||||
sprints Sprint[]
|
||||
stories Story[]
|
||||
todos Todo[]
|
||||
members ProductMember[]
|
||||
|
||||
@@unique([user_id, name])
|
||||
@@index([user_id, archived])
|
||||
|
|
@ -385,18 +405,19 @@ model Sprint {
|
|||
}
|
||||
|
||||
model Task {
|
||||
id String @id @default(cuid())
|
||||
story Story @relation(fields: [story_id], references: [id], onDelete: Cascade)
|
||||
story_id String
|
||||
sprint Sprint? @relation(fields: [sprint_id], references: [id])
|
||||
sprint_id String?
|
||||
title String
|
||||
description String?
|
||||
priority Int
|
||||
sort_order Float
|
||||
status TaskStatus @default(TO_DO)
|
||||
created_at DateTime @default(now())
|
||||
updated_at DateTime @updatedAt
|
||||
id String @id @default(cuid())
|
||||
story Story @relation(fields: [story_id], references: [id], onDelete: Cascade)
|
||||
story_id String
|
||||
sprint Sprint? @relation(fields: [sprint_id], references: [id])
|
||||
sprint_id String?
|
||||
title String
|
||||
description String?
|
||||
implementation_plan String?
|
||||
priority Int
|
||||
sort_order Float
|
||||
status TaskStatus @default(TO_DO)
|
||||
created_at DateTime @default(now())
|
||||
updated_at DateTime @updatedAt
|
||||
|
||||
@@index([story_id, priority, sort_order])
|
||||
@@index([sprint_id, status])
|
||||
|
|
@ -417,6 +438,19 @@ model Todo {
|
|||
@@index([user_id, done, archived])
|
||||
@@index([user_id, product_id])
|
||||
}
|
||||
|
||||
model ProductMember {
|
||||
id String @id @default(cuid())
|
||||
product Product @relation(fields: [product_id], references: [id], onDelete: Cascade)
|
||||
product_id String
|
||||
user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
|
||||
user_id String
|
||||
created_at DateTime @default(now())
|
||||
|
||||
@@unique([product_id, user_id])
|
||||
@@index([user_id])
|
||||
@@map("product_members")
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
|
@ -488,12 +522,15 @@ scrum4me/
|
|||
│ ├── split-pane/ # Gesplitst scherm component
|
||||
│ ├── backlog/ # PBI- en story-componenten
|
||||
│ ├── sprint/ # Sprint-componenten
|
||||
│ ├── products/ # ProductForm, TeamManager, ArchiveProductButton
|
||||
│ ├── settings/ # RoleManager, LeaveProductButton
|
||||
│ └── dnd/ # dnd-kit wrappers
|
||||
├── lib/
|
||||
│ ├── prisma.ts # Prisma Client singleton
|
||||
│ ├── session.ts # iron-session configuratie
|
||||
│ ├── auth.ts # login/register/token helpers
|
||||
│ ├── api-auth.ts # Bearer token middleware voor API
|
||||
│ ├── product-access.ts # productAccessFilter helper (eigenaar of teamlid)
|
||||
│ └── env.ts # Zod-gevalideerde env vars
|
||||
├── stores/ # Zustand stores
|
||||
│ ├── planner-store.ts # Optimistische drag-and-drop volgorde
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@ De MVP is klaar wanneer Lars — de primaire persona — de volledige cyclus kan
|
|||
|
||||
## v2 Backlog (na MVP)
|
||||
|
||||
- [ ] Meerdere gebruikers per Scrum Team — uitgebreide auth, rol-gebaseerde permissies, uitnodigingsflow
|
||||
- [ ] Uitnodigingsflow voor teams — e-mailuitnodiging of link-gebaseerd; nu kunnen alleen admins met toegang tot het systeem Developers toevoegen via gebruikersnaam
|
||||
- [ ] Daily Scrum scherm — voortgang per story bijhouden tijdens Sprint
|
||||
- [ ] Sprint Review scherm — demo en feedback vastleggen per story
|
||||
- [ ] Sprint Retrospective scherm — reflectie per Sprint
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@
|
|||
|
||||
## MVP-scopeverklaring
|
||||
|
||||
v1 is een single-user desktop-first fullstack webapplicatie waarmee een solo developer of klein Scrum Team meerdere softwareprojecten hiërarchisch kan plannen (product → PBI → story → taak), Sprints kan beheren via gesplitste schermen met drag-and-drop, en Claude Code kan integreren voor geautomatiseerde implementatieflows waarbij elk resultaat wordt vastgelegd in de story. De app is deployable op Vercel + Neon én volledig lokaal draaibaar.
|
||||
v1 is een desktop-first fullstack webapplicatie waarmee een solo developer of klein Scrum Team meerdere softwareprojecten hiërarchisch kan plannen (product → PBI → story → taak), Sprints kan beheren via gesplitste schermen met drag-and-drop, en Claude Code kan integreren voor geautomatiseerde implementatieflows waarbij elk resultaat wordt vastgelegd in de story. Een Product Owner kan Developers (via gebruikersnaam) aan een product backlog koppelen; zij krijgen dan schrijfrechten op stories, taken en sprints van dat product. De app is deployable op Vercel + Neon én volledig lokaal draaibaar.
|
||||
|
||||
## Expliciet buiten scope voor v1
|
||||
|
||||
- Meerdere gebruikers per Scrum Team — datastructuur is voorbereid, UI en permissies komen in v2
|
||||
- Uitnodigingsflow voor teams — Developers toevoegen via gebruikersnaam is beschikbaar; e-mailuitnodiging of link-gebaseerde onboarding komt in v2
|
||||
- E-mailverificatie bij registratie — gebruikersnaam/wachtwoord volstaat voor v1
|
||||
- Daily Scrum, Sprint Review en Sprint Retrospective schermen — v2 zodra teamgebruik mogelijk is
|
||||
- Daily Scrum, Sprint Review en Sprint Retrospective schermen — v2
|
||||
- Automatische statusupdate van stories na commit — handmatige update via UI in v1
|
||||
- Tijdregistratie, urenverantwoording en burndown-charts — buiten positionering
|
||||
- Integratie met externe tools (GitHub Issues, Linear, Jira) — v2
|
||||
|
|
@ -60,14 +60,14 @@ Gebruikers kunnen een account aanmaken en inloggen met gebruikersnaam en wachtwo
|
|||
**Persona:** Remi (v2), Lars en Dina (impliciet)
|
||||
|
||||
**Omschrijving:**
|
||||
Een gebruiker kan bij registratie of in instellingen één of meerdere Scrum-rollen aannemen: Product Owner, Scrum Master, Developer. In v1 heeft dit geen effect op zichtbare functionaliteit maar de datastructuur ondersteunt rolscheiding voor v2-teamgebruik.
|
||||
Een gebruiker kan bij registratie of in instellingen één of meerdere Scrum-rollen aannemen: Product Owner, Scrum Master, Developer. De rol Developer is relevant voor teambeheer: alleen gebruikers met de rol Developer kunnen aan een product backlog worden gekoppeld door de eigenaar.
|
||||
|
||||
**Acceptatiecriteria:**
|
||||
- [ ] Gebruiker kan bij registratie of achteraf in instellingen rollen selecteren
|
||||
- [ ] Minimaal één rol is verplicht
|
||||
- [ ] Alle drie de rollen tegelijk zijn toegestaan
|
||||
- [ ] Geselecteerde rollen zijn zichtbaar in de profielbalk
|
||||
- [ ] Rolkeuze heeft in v1 geen effect op zichtbare functionaliteit
|
||||
- [ ] Alleen gebruikers met de rol Developer kunnen als teamlid aan een product backlog worden gekoppeld
|
||||
- [ ] Demo-gebruiker heeft een vaste rol (Developer) die niet gewijzigd kan worden
|
||||
|
||||
**Data:**
|
||||
|
|
@ -386,7 +386,7 @@ De app is deployable op Vercel + Neon PostgreSQL en lokaal draaibaar met een Neo
|
|||
/products/:id/sprint (Sprint Backlog — gesplitst scherm)
|
||||
/products/:id/sprint/planning (Sprint Planning — gesplitst scherm)
|
||||
/todos (todo-lijst)
|
||||
/settings (profiel, rollen, API-tokens)
|
||||
/settings (profiel, rollen, mijn teams, API-tokens)
|
||||
/settings/tokens (API-tokenbeheer)
|
||||
```
|
||||
|
||||
|
|
@ -406,6 +406,7 @@ De app is deployable op Vercel + Neon PostgreSQL en lokaal draaibaar met een Neo
|
|||
| `sprints` | id, product_id, sprint_goal, status (ACTIVE / COMPLETED), created_at, completed_at? | Max. 1 actieve Sprint per product |
|
||||
| `tasks` | id, story_id, sprint_id, title, description, implementation_plan?, priority, sort_order, status | Status: TO_DO / IN_PROGRESS / DONE; implementation_plan door MCP |
|
||||
| `todos` | id, user_id, product_id, title, done, archived, created_at | Gekoppeld aan product backlog; verplicht in UI en API |
|
||||
| `product_members` | id, product_id, user_id, created_at | Many-to-many; alleen Developers; eigenaar via products.user_id |
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue