bouwplan templates
This commit is contained in:
74
docs/specs/api-acces-mini-ecd.md
Normal file
74
docs/specs/api-acces-mini-ecd.md
Normal file
@@ -0,0 +1,74 @@
|
||||
## API‑toegang Mini‑ECD
|
||||
|
||||
Laatste update: 2025‑11‑09 • Versie: 0.2 (MVP)
|
||||
|
||||
### Overzicht
|
||||
De Mini‑ECD API biedt server‑side endpoints in Next.js voor AI‑functionaliteit (Claude / Anthropic). In de MVP is één endpoint beschikbaar.
|
||||
|
||||
### Base URL
|
||||
- Ontwikkel (lokaal): `http://localhost:3000`
|
||||
- Productie: n.t.b. (Vercel)
|
||||
|
||||
### Authenticatie
|
||||
- **MVP**: geen externe client‑auth; endpoints dienen alleen in trusted context gebruikt te worden (server‑side calls of demo‑omgeving).
|
||||
- Claude AI authenticatie verloopt server‑side via Anthropic API key.
|
||||
|
||||
### Headers
|
||||
- `Content-Type: application/json`
|
||||
|
||||
### Endpoints
|
||||
|
||||
#### POST `/api/ai/summarize`
|
||||
- **Doel**: vat NL intake‑tekst samen in puntsgewijze bullets (max 6), neutraal en feitelijk.
|
||||
- **Request body**
|
||||
```json
|
||||
{
|
||||
"text": "string (1..20000)",
|
||||
"language": "string (optioneel, default: nl)"
|
||||
}
|
||||
```
|
||||
- **Voorbeeld (PowerShell)**
|
||||
```powershell
|
||||
Invoke-RestMethod -Uri http://localhost:3000/api/ai/summarize -Method POST -Body (@{ text = "Korte intake tekst" } | ConvertTo-Json) -ContentType "application/json"
|
||||
```
|
||||
- **Voorbeeld (curl)**
|
||||
```bash
|
||||
curl -X POST http://localhost:3000/api/ai/summarize \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"text":"Korte intake tekst"}'
|
||||
```
|
||||
- **Response (200)**
|
||||
```json
|
||||
{
|
||||
"summary": "- Bullet 1\n- Bullet 2\n..."
|
||||
}
|
||||
```
|
||||
- **Fouten**
|
||||
- 400: ongeldige body (validatie faalt)
|
||||
- 500: Claude AI fout of configuratie ontbreekt
|
||||
|
||||
### Omgevingsvariabelen
|
||||
- **Claude AI**
|
||||
- `ANTHROPIC_API_KEY` (bv. `sk-ant-...`) — vereist voor alle AI-endpoints
|
||||
- **Optioneel**
|
||||
- `ANTHROPIC_MODEL` (default `claude-3-5-sonnet-20241022`)
|
||||
|
||||
Voorbeeld in `.env.local` (lokaal): zie `/.env.example`.
|
||||
|
||||
### Implementatiedetails
|
||||
- Server helper: `src/lib/server/claude.ts` initialiseert Claude client met API key.
|
||||
- Endpoint: `src/app/api/ai/summarize/route.ts` (Next.js Route Handler met Zod‑validatie, Claude API call).
|
||||
|
||||
### Beveiliging (MVP)
|
||||
- Houd `ANTHROPIC_API_KEY` uit de client; uitsluitend server‑side gebruiken.
|
||||
- Gebruik Vercel Environment Variables in productie.
|
||||
|
||||
### Roadmap (volgende endpoints)
|
||||
- `POST /api/ai/readability` – herschrijf naar B1‑niveau.
|
||||
- `POST /api/ai/extract` – extracteer categorie/severity uit intake.
|
||||
- `POST /api/ai/generate-plan` – genereer behandelplan (Doelen, Interventies, etc.).
|
||||
|
||||
### Changelog
|
||||
- 0.2 (2025‑11‑09): Migratie naar Next.js + Claude AI (Anthropic); update van base URL naar :3000.
|
||||
- 0.1 (2025‑09‑02): Eerste versie met `summarize` endpoint en env‑richtlijnen.
|
||||
|
||||
608
docs/specs/bouwplan.md
Normal file
608
docs/specs/bouwplan.md
Normal file
@@ -0,0 +1,608 @@
|
||||
# 🚀 Mission Control — Bouwplan Mini-EPD Prototype
|
||||
|
||||
**Projectnaam:** Mini-EPD Prototype
|
||||
**Versie:** v1.0
|
||||
**Datum:** 10-11-2025
|
||||
**Auteur:** Development Team PinkRoccade GGZ
|
||||
|
||||
---
|
||||
|
||||
## 1. Doel en context
|
||||
|
||||
🎯 **Doel:** Een werkend mini-EPD prototype bouwen dat tijdens de AI-inspiratiesessie bij PinkRoccade GGZ de kernprocessen uit de GGZ demonstreert: **intake → probleemclassificatie → behandelplan**.
|
||||
|
||||
📘 **Toelichting:** Dit project focust op het zichtbaar maken van AI-waarde (samenvatten, structureren, plan genereren) in een herkenbare GGZ-workflow. De demo duurt maximaal 10 minuten en toont hoe AI zorgmedewerkers kan ondersteunen bij administratieve taken. Het systeem wordt gebouwd met fictieve data voor demonstratiedoeleinden.
|
||||
|
||||
**Belangrijkste doelen:**
|
||||
- Demonstreren van AI-toegevoegde waarde in ECD-processen
|
||||
- Herkenbare workflow voor GGZ-professionals
|
||||
- Inspiratie bieden voor AI-integratie in bestaande systemen
|
||||
- Direct bruikbare output (samenvattingen, behandelplannen) genereren
|
||||
|
||||
---
|
||||
|
||||
## 2. Uitgangspunten
|
||||
|
||||
### 2.1 Technische Stack
|
||||
|
||||
🎯 **Doel:** Complete technologie stack voor het mini-EPD prototype.
|
||||
|
||||
**Frontend:**
|
||||
- **Framework:** Next.js 14+ (App Router)
|
||||
- **Styling:** Tailwind CSS v3.4 (fallback vanaf v4 bij problemen)
|
||||
- **UI Componenten:** shadcn/ui of eigen headless componenten
|
||||
- **Rich Text Editor:** TipTap (ProseMirror basis)
|
||||
- **Iconen:** lucide-react
|
||||
- **State Management:** Zustand + React Context API
|
||||
|
||||
**Backend:**
|
||||
- **API:** Next.js Route Handlers (server-side)
|
||||
- **Database:** Supabase (PostgreSQL)
|
||||
- **Auth:** Supabase Auth
|
||||
- **Storage:** Supabase Storage
|
||||
- **AI Integration:** Claude API (Anthropic)
|
||||
|
||||
**DevOps & Tooling:**
|
||||
- **Hosting:** Vercel (EU region)
|
||||
- **Version Control:** Git/GitHub
|
||||
- **Type Safety:** TypeScript
|
||||
- **Validation:** Zod
|
||||
- **Testing:** Vitest (unit) + Playwright (E2E)
|
||||
- **PDF Export (stretch):** Chromium via Playwright/Puppeteer
|
||||
|
||||
### 2.2 Projectkaders
|
||||
|
||||
🎯 **Doel:** Vaste kaders waarbinnen het project wordt ontwikkeld.
|
||||
|
||||
- **Tijd:** 3 weken totale bouwtijd voor MVP
|
||||
- **Demo deadline:** Augustus 2025 (AI-inspiratiesessie)
|
||||
- **Budget:** Beperkt voor externe API calls (Claude AI)
|
||||
- **Team:** 1-2 developers + 1 consultant/product owner
|
||||
- **Data:** Uitsluitend fictieve demo-data (geen productiegegevens)
|
||||
- **Scope:** MVP features voor 10-minuten demo
|
||||
- **Gebruikers:** Demo-users met volledige toegang (simplified auth)
|
||||
- **Compliance:** Geen medische certificering vereist (demo only)
|
||||
|
||||
### 2.3 Programmeer Uitgangspunten
|
||||
|
||||
🎯 **Doel:** Code-kwaliteit principes en development best practices.
|
||||
|
||||
**Core Principles:**
|
||||
|
||||
- **DRY (Don't Repeat Yourself)**
|
||||
- Herbruikbare React componenten in `/src/components/ui/`
|
||||
- Shared utility functions in `/src/lib/utils/`
|
||||
- Centrale API client voor Supabase queries
|
||||
- Gedeelde prompt templates voor AI calls
|
||||
|
||||
- **SOC (Separation of Concerns)**
|
||||
- UI componenten gescheiden van business logic
|
||||
- Database queries in dedicated service layers (`/src/lib/services/`)
|
||||
- AI prompts in `/src/lib/ai/prompts/`
|
||||
- Styling via Tailwind classes, geen inline styles
|
||||
- Route handlers voor server-side operaties
|
||||
|
||||
- **KISS (Keep It Simple, Stupid)**
|
||||
- Directe Supabase queries zonder ORM overhead
|
||||
- Eenvoudige state management met Zustand
|
||||
- Minimale abstractie voor MVP scope
|
||||
- Clear component naming (e.g., `ClientList`, `IntakeEditor`)
|
||||
|
||||
- **YAGNI (You Aren't Gonna Need It)**
|
||||
- Geen multi-tenant setup voor demo
|
||||
- Basis auth zonder rollenbeheer
|
||||
- Skip complex caching voor MVP
|
||||
- Geen realtime features voor eerste versie
|
||||
|
||||
- **Security**
|
||||
- API keys alleen server-side (`ANTHROPIC_API_KEY`, `SUPABASE_SERVICE_ROLE_KEY`)
|
||||
- Input sanitization met Zod schemas
|
||||
- Row Level Security (RLS) policies in Supabase
|
||||
- CORS configuratie voor API endpoints
|
||||
- XSS protection via React's default escaping
|
||||
|
||||
---
|
||||
|
||||
## 3. Epics & Stories Overzicht
|
||||
|
||||
🎯 **Doel:** Complete overzicht van alle development epics met technische details.
|
||||
|
||||
| Epic ID | Epic Naam | Totaal Stories | Story Points | Status | Priority | Dependencies |
|
||||
|---------|-----------|----------------|--------------|--------|----------|--------------|
|
||||
| EP00 | Project Setup & Configuration | 5 | 13 | Not Started | Critical | - |
|
||||
| EP01 | Database & Data Model | 4 | 21 | Not Started | Critical | EP00 |
|
||||
| EP02 | Authentication & Authorization | 3 | 8 | Not Started | High | EP00, EP01 |
|
||||
| EP03 | Client Management | 5 | 21 | Not Started | High | EP01, EP02 |
|
||||
| EP04 | Intake Module | 6 | 34 | Not Started | Critical | EP03 |
|
||||
| EP05 | Problem Profile (DSM-light) | 4 | 21 | Not Started | High | EP04 |
|
||||
| EP06 | Treatment Plan Module | 5 | 34 | Not Started | High | EP05 |
|
||||
| EP07 | AI Integration | 5 | 34 | Not Started | Critical | EP04 |
|
||||
| EP08 | Dashboard & Navigation | 4 | 13 | Not Started | Medium | EP03 |
|
||||
| EP09 | UI Components & Styling | 5 | 21 | Not Started | Medium | EP00 |
|
||||
| EP10 | Testing & Quality Assurance | 4 | 13 | Not Started | High | All |
|
||||
| EP11 | Deployment & Demo Prep | 4 | 13 | Not Started | Critical | All |
|
||||
| EP12 | Stretch Features | 3 | 21 | Not Started | Low | EP06 |
|
||||
|
||||
**Totaal:** 57 stories | 257 story points
|
||||
|
||||
---
|
||||
|
||||
## 4. Epics & Stories (Uitwerking)
|
||||
|
||||
### Epic EP00 — Project Setup & Configuration
|
||||
**Epic Doel:** Complete development omgeving met alle tools en dependencies geconfigureerd.
|
||||
|
||||
| Story ID | Story Description | Acceptance Criteria | Story Points | Status | Dependencies |
|
||||
|----------|-------------------|---------------------|--------------|--------|--------------|
|
||||
| EP00-ST01 | **Als developer wil ik een Next.js project opzetten zodat ik kan beginnen met development** | ✅ Next.js 14+ met App Router<br>✅ TypeScript configuratie<br>✅ Folder structuur volgens conventions<br>✅ Development server draait op localhost:3000 | 3 | Not Started | - |
|
||||
| EP00-ST02 | **Als developer wil ik Tailwind CSS en UI libraries installeren zodat ik consistent kan stylen** | ✅ Tailwind CSS v3.4 werkend<br>✅ tailwind.config.ts met custom theme<br>✅ lucide-react icons beschikbaar<br>✅ shadcn/ui setup (of besluit voor custom) | 3 | Not Started | EP00-ST01 |
|
||||
| EP00-ST03 | **Als developer wil ik Supabase project aanmaken zodat ik database en auth kan gebruiken** | ✅ Supabase project in EU region<br>✅ Connection string in .env.local<br>✅ Supabase client configured<br>✅ TypeScript types generation script | 3 | Not Started | EP00-ST01 |
|
||||
| EP00-ST04 | **Als developer wil ik environment variables configureren zodat services veilig verbonden zijn** | ✅ .env.local met alle keys<br>✅ .env.example voor team<br>✅ Vercel environment variables<br>✅ Validation bij startup | 2 | Not Started | EP00-ST03 |
|
||||
| EP00-ST05 | **Als developer wil ik Git repository opzetten zodat code versiebeheerd is** | ✅ GitHub repository<br>✅ .gitignore configuratie<br>✅ Branch protection rules<br>✅ Initial commit met setup | 2 | Not Started | EP00-ST01 |
|
||||
|
||||
**Technische implementatie details:**
|
||||
- **Database:** Gebruik Supabase EU-region (Frankfurt/London)
|
||||
- **Environment variables:**
|
||||
```
|
||||
NEXT_PUBLIC_SUPABASE_URL
|
||||
NEXT_PUBLIC_SUPABASE_ANON_KEY
|
||||
SUPABASE_SERVICE_ROLE_KEY
|
||||
ANTHROPIC_API_KEY
|
||||
```
|
||||
- **Folder structuur:**
|
||||
```
|
||||
/src
|
||||
/app (routes)
|
||||
/components
|
||||
/lib (utilities, services)
|
||||
/types
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Epic EP01 — Database & Data Model
|
||||
**Epic Doel:** Complete database schema met alle tabellen en relaties volgens TO specificatie.
|
||||
|
||||
| Story ID | Story Description | Acceptance Criteria | Story Points | Status | Dependencies |
|
||||
|----------|-------------------|---------------------|--------------|--------|--------------|
|
||||
| EP01-ST01 | **Als developer wil ik database tabellen creëren zodat data opgeslagen kan worden** | ✅ Tables: clients, intake_notes, problem_profiles, treatment_plans, ai_events<br>✅ Correct data types (UUID, JSONB, etc.)<br>✅ Foreign key constraints<br>✅ Timestamps (created_at, updated_at) | 8 | Not Started | EP00-ST03 |
|
||||
| EP01-ST02 | **Als developer wil ik Row Level Security policies implementeren zodat data veilig is** | ✅ RLS enabled op alle tables<br>✅ Policies voor authenticated users<br>✅ Test queries werken correct<br>✅ Service role bypass werkt | 5 | Not Started | EP01-ST01 |
|
||||
| EP01-ST03 | **Als developer wil ik database migrations opzetten zodat schema versiebeheerd is** | ✅ Supabase migrations folder<br>✅ Initial migration script<br>✅ Rollback mogelijk<br>✅ Documentation | 3 | Not Started | EP01-ST01 |
|
||||
| EP01-ST04 | **Als developer wil ik demo data seeden zodat er test content beschikbaar is** | ✅ 3+ test cliënten<br>✅ Intake notes per cliënt<br>✅ Minimaal 1 compleet dossier<br>✅ Seed script: `npm run seed` | 5 | Not Started | EP01-ST01 |
|
||||
|
||||
**Technische implementatie details:**
|
||||
- **Database Schema (zie TO §2.3):**
|
||||
- `clients`: id (UUID), first_name, last_name, birth_date, created_at, updated_at
|
||||
- `intake_notes`: id, client_id (FK), title, tag (CHECK), content_json (JSONB), content_text
|
||||
- `problem_profiles`: id, client_id (FK), category (CHECK), severity (CHECK), remarks
|
||||
- `treatment_plans`: id, client_id (FK), version, status (CHECK), plan (JSONB)
|
||||
- `ai_events`: id, kind, client_id, request, response, duration_ms
|
||||
|
||||
- **RLS Policies (zie TO §2.4):**
|
||||
```sql
|
||||
CREATE POLICY "Allow all for authenticated users" ON [table]
|
||||
FOR ALL USING (auth.uid() IS NOT NULL);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Epic EP02 — Authentication & Authorization
|
||||
**Epic Doel:** Werkende authenticatie met Supabase Auth voor demo gebruikers.
|
||||
|
||||
| Story ID | Story Description | Acceptance Criteria | Story Points | Status | Dependencies |
|
||||
|----------|-------------------|---------------------|--------------|--------|--------------|
|
||||
| EP02-ST01 | **Als gebruiker wil ik kunnen inloggen zodat ik toegang krijg tot het systeem** | ✅ Login pagina op /auth/login<br>✅ Email/password of magic link<br>✅ Session management<br>✅ Redirect naar dashboard | 3 | Not Started | EP00-ST03, EP01-ST02 |
|
||||
| EP02-ST02 | **Als developer wil ik protected routes implementeren zodat alleen ingelogde users toegang hebben** | ✅ Middleware voor auth check<br>✅ Redirect naar login indien nodig<br>✅ Loading states tijdens auth<br>✅ Session refresh | 3 | Not Started | EP02-ST01 |
|
||||
| EP02-ST03 | **Als gebruiker wil ik kunnen uitloggen zodat mijn sessie beëindigd wordt** | ✅ Logout button in header<br>✅ Session cleanup<br>✅ Redirect naar login<br>✅ Clear local state | 2 | Not Started | EP02-ST01 |
|
||||
|
||||
**Technische implementatie details:**
|
||||
- **Auth flow:** Email/password voor demo (magic link als backup)
|
||||
- **Middleware:** Check auth in `middleware.ts`
|
||||
- **Protected routes:** Alles behalve `/auth/*`
|
||||
- **Session:** Supabase JWT tokens
|
||||
|
||||
---
|
||||
|
||||
### Epic EP03 — Client Management
|
||||
**Epic Doel:** Complete CRUD functionaliteit voor cliëntbeheer.
|
||||
|
||||
| Story ID | Story Description | Acceptance Criteria | Story Points | Status | Dependencies |
|
||||
|----------|-------------------|---------------------|--------------|--------|--------------|
|
||||
| EP03-ST01 | **Als behandelaar wil ik een cliëntenlijst zien zodat ik overzicht heb** | ✅ Tabel met: ClientID, Naam, Geboortedatum, Laatste update<br>✅ Zoekbalk voor naam/ID<br>✅ Pagination bij >20 items<br>✅ Loading skeleton | 5 | Not Started | EP01-ST01, EP02-ST02 |
|
||||
| EP03-ST02 | **Als behandelaar wil ik een nieuwe cliënt aanmaken zodat ik kan starten met intake** | ✅ Modal/drawer met formulier<br>✅ Velden: Voornaam, Achternaam, Geboortedatum<br>✅ Auto-generated UUID<br>✅ Validatie met Zod<br>✅ Success toast | 5 | Not Started | EP03-ST01 |
|
||||
| EP03-ST03 | **Als behandelaar wil ik cliëntgegevens bekijken zodat ik het dossier kan inzien** | ✅ Route: /clients/[id]<br>✅ Breadcrumb navigatie<br>✅ Tabs: Overzicht, Intakes, Profiel, Plan<br>✅ 404 handling | 5 | Not Started | EP03-ST01 |
|
||||
| EP03-ST04 | **Als behandelaar wil ik cliëntgegevens bewerken zodat ik updates kan maken** | ✅ Edit mode in detail view<br>✅ Form validation<br>✅ Optimistic updates<br>✅ Error handling | 3 | Not Started | EP03-ST03 |
|
||||
| EP03-ST05 | **Als developer wil ik Zustand store voor client state zodat data consistent blijft** | ✅ clientStore.ts setup<br>✅ Actions: setSelectedClient, updateClient<br>✅ Persistent state waar nodig<br>✅ TypeScript types | 3 | Not Started | EP00-ST01 |
|
||||
|
||||
**Technische implementatie details:**
|
||||
- **API endpoints:**
|
||||
- `POST /api/clients` - Create
|
||||
- `GET /api/clients` - List with search
|
||||
- `GET /api/clients/[id]` - Get single
|
||||
- `PATCH /api/clients/[id]` - Update
|
||||
- **Zustand store:** Central state voor selected client
|
||||
- **Validatie:** Zod schemas voor alle forms
|
||||
|
||||
---
|
||||
|
||||
### Epic EP04 — Intake Module
|
||||
**Epic Doel:** Rich text editor voor intake verslagen met TipTap integratie.
|
||||
|
||||
| Story ID | Story Description | Acceptance Criteria | Story Points | Status | Dependencies |
|
||||
|----------|-------------------|---------------------|--------------|--------|--------------|
|
||||
| EP04-ST01 | **Als behandelaar wil ik TipTap editor gebruiken zodat ik rijk opgemaakte notities kan maken** | ✅ TipTap met StarterKit<br>✅ Toolbar: Bold, Italic, Lists, etc.<br>✅ Placeholder text<br>✅ Content als ProseMirror JSON | 8 | Not Started | EP03-ST03 |
|
||||
| EP04-ST02 | **Als behandelaar wil ik intake verslagen opslaan zodat ze bewaard blijven** | ✅ Save button + Ctrl/Cmd+S<br>✅ Store in intake_notes table<br>✅ Auto-save indicator<br>✅ Success/error toasts | 5 | Not Started | EP04-ST01 |
|
||||
| EP04-ST03 | **Als behandelaar wil ik tags toevoegen aan verslagen zodat ik ze kan categoriseren** | ✅ Tag dropdown: Intake/Evaluatie/Plan<br>✅ Tag badge in lijst<br>✅ Filter op tag mogelijk<br>✅ Validation | 3 | Not Started | EP04-ST02 |
|
||||
| EP04-ST04 | **Als behandelaar wil ik oude intakes bekijken zodat ik historie kan inzien** | ✅ Lijst van intakes per cliënt<br>✅ Sorteer op datum<br>✅ Click to view/edit<br>✅ Read-only mode optie | 5 | Not Started | EP04-ST02 |
|
||||
| EP04-ST05 | **Als developer wil ik tekst extractie implementeren voor search** | ✅ Extract plain text van ProseMirror<br>✅ Store in content_text field<br>✅ Full-text search mogelijk<br>✅ Performance optimization | 5 | Not Started | EP04-ST02 |
|
||||
| EP04-ST06 | **Als behandelaar wil ik de AI-rail zien zodat AI-resultaten preview kan bekijken** | ✅ Rechter paneel (40% breedte)<br>✅ Collapsible/expandable<br>✅ Preview area voor AI output<br>✅ Action buttons: Invoegen/Annuleren | 8 | Not Started | EP04-ST01 |
|
||||
|
||||
**Technische implementatie details:**
|
||||
- **TipTap setup:**
|
||||
```typescript
|
||||
import StarterKit from '@tiptap/starter-kit'
|
||||
const editor = useEditor({
|
||||
extensions: [StarterKit],
|
||||
content: prosemirrorJSON
|
||||
})
|
||||
```
|
||||
- **Storage:** content_json (JSONB) + content_text (TEXT)
|
||||
- **API:** `/api/intakes` endpoints
|
||||
|
||||
---
|
||||
|
||||
### Epic EP05 — Problem Profile (DSM-light)
|
||||
**Epic Doel:** DSM-light categorisatie systeem met severity bepaling.
|
||||
|
||||
| Story ID | Story Description | Acceptance Criteria | Story Points | Status | Dependencies |
|
||||
|----------|-------------------|---------------------|--------------|--------|--------------|
|
||||
| EP05-ST01 | **Als behandelaar wil ik een probleem categorie selecteren zodat ik kan classificeren** | ✅ Dropdown met 6 categorieën (zie FO §4.4)<br>✅ Beschrijving per categorie<br>✅ Validation required field<br>✅ Store in problem_profiles | 5 | Not Started | EP04-ST02 |
|
||||
| EP05-ST02 | **Als behandelaar wil ik severity aangeven zodat ernst duidelijk is** | ✅ Button group: Laag/Middel/Hoog<br>✅ Kleur-coded badges<br>✅ Hover tooltips met uitleg<br>✅ Required validation | 3 | Not Started | EP05-ST01 |
|
||||
| EP05-ST03 | **Als behandelaar wil ik opmerkingen toevoegen zodat ik context kan geven** | ✅ Textarea voor vrije tekst<br>✅ Character limit (500)<br>✅ Optional field<br>✅ Markdown support | 3 | Not Started | EP05-ST01 |
|
||||
| EP05-ST04 | **Als behandelaar wil ik AI-suggestie paneel gebruiken zodat classificatie sneller gaat** | ✅ Knop "AI > Analyseer intake"<br>✅ Suggestie paneel rechts<br>✅ Shows: categorie, severity, rationale<br>✅ Accepteer/Negeer buttons<br>✅ Source highlighting in intake (zie TO §5.4) | 10 | Not Started | EP04-ST02, EP07-ST03 |
|
||||
|
||||
**Technische implementatie details:**
|
||||
- **Categorieën (enum):**
|
||||
- stemming_depressie
|
||||
- angst
|
||||
- gedrag_impuls
|
||||
- middelen_gebruik
|
||||
- cognitief
|
||||
- context_psychosociaal
|
||||
- **Severity badges:** Tailwind classes volgens UX stylesheet
|
||||
- **AI highlighting:** TipTap Decorations API
|
||||
|
||||
---
|
||||
|
||||
### Epic EP06 — Treatment Plan Module
|
||||
**Epic Doel:** Genereren en beheren van gestructureerde behandelplannen.
|
||||
|
||||
| Story ID | Story Description | Acceptance Criteria | Story Points | Status | Dependencies |
|
||||
|----------|-------------------|---------------------|--------------|--------|--------------|
|
||||
| EP06-ST01 | **Als behandelaar wil ik een behandelplan genereren zodat ik snel een opzet heb** | ✅ Knop "AI > Genereer behandelplan"<br>✅ Uses intake + profile als context<br>✅ Genereert 4 secties<br>✅ Loading state tijdens generatie | 10 | Not Started | EP05-ST01, EP07-ST04 |
|
||||
| EP06-ST02 | **Als behandelaar wil ik doelen bewerken zodat ze SMART geformuleerd zijn** | ✅ Lijst van doelen (bullets)<br>✅ Inline editing mogelijk<br>✅ Add/remove doelen<br>✅ Regenerate per doel optie | 8 | Not Started | EP06-ST01 |
|
||||
| EP06-ST03 | **Als behandelaar wil ik interventies specificeren zodat behandeling duidelijk is** | ✅ Interventie lijst<br>✅ Type + frequentie + duur<br>✅ Voorgestelde interventies<br>✅ Custom toevoegen | 5 | Not Started | EP06-ST01 |
|
||||
| EP06-ST04 | **Als behandelaar wil ik meetmomenten plannen zodat voortgang gemeten wordt** | ✅ Timeline met meetmomenten<br>✅ Na X sessies format<br>✅ Evaluatie types<br>✅ Calendar integration (stretch) | 5 | Not Started | EP06-ST01 |
|
||||
| EP06-ST05 | **Als behandelaar wil ik plan publiceren zodat het definitief wordt** | ✅ Concept vs Gepubliceerd status<br>✅ Versioning (v1, v2, etc.)<br>✅ Published timestamp<br>✅ Read-only na publicatie<br>✅ Nieuwe versie mogelijk | 6 | Not Started | EP06-ST02 |
|
||||
|
||||
**Technische implementatie details:**
|
||||
- **Plan structuur (JSONB):**
|
||||
```typescript
|
||||
{
|
||||
doelen: string[],
|
||||
interventies: string[],
|
||||
frequentie: string,
|
||||
meetmomenten: string[]
|
||||
}
|
||||
```
|
||||
- **Status flow:** concept → gepubliceerd → nieuwe versie
|
||||
- **API:** `/api/treatment-plan` endpoints
|
||||
|
||||
---
|
||||
|
||||
### Epic EP07 — AI Integration
|
||||
**Epic Doel:** Claude AI integratie voor alle AI-powered features.
|
||||
|
||||
| Story ID | Story Description | Acceptance Criteria | Story Points | Status | Dependencies |
|
||||
|----------|-------------------|---------------------|--------------|--------|--------------|
|
||||
| EP07-ST01 | **Als developer wil ik Claude API client configureren zodat AI calls mogelijk zijn** | ✅ Anthropic SDK setup<br>✅ Server-side only implementation<br>✅ Error handling<br>✅ Rate limiting logic | 5 | Not Started | EP00-ST04 |
|
||||
| EP07-ST02 | **Als behandelaar wil ik intake samenvatten met AI zodat ik snel overzicht heb** | ✅ Endpoint: /api/ai/summarize<br>✅ 5-8 bullet points output<br>✅ Nederlands, klinisch neutraal<br>✅ Max 5 sec response time | 8 | Not Started | EP07-ST01, EP04-ST06 |
|
||||
| EP07-ST03 | **Als behandelaar wil ik problemen extraheren met AI zodat classificatie sneller gaat** | ✅ Endpoint: /api/ai/extract<br>✅ Returns: category, severity, rationale<br>✅ Source sentences identificatie<br>✅ Highlighting support | 8 | Not Started | EP07-ST01 |
|
||||
| EP07-ST04 | **Als behandelaar wil ik behandelplan genereren met AI zodat ik een goede basis heb** | ✅ Endpoint: /api/ai/generate-plan<br>✅ SMART doelen formulering<br>✅ Evidence-based interventies<br>✅ Structured JSON output | 8 | Not Started | EP07-ST01 |
|
||||
| EP07-ST05 | **Als developer wil ik AI events loggen zodat gebruik gemonitord wordt** | ✅ Store in ai_events table<br>✅ Track: prompt, response, duration<br>✅ Cost calculation<br>✅ Error logging | 5 | Not Started | EP07-ST01, EP01-ST01 |
|
||||
|
||||
**Technische implementatie details:**
|
||||
- **Claude model:** claude-3-5-sonnet-20241022
|
||||
- **Prompt templates:** `/src/lib/ai/prompts/`
|
||||
- **Temperature:** 0.3 (deterministic)
|
||||
- **Max tokens:** Per endpoint verschillend
|
||||
- **Security:** API key alleen server-side
|
||||
|
||||
---
|
||||
|
||||
### Epic EP08 — Dashboard & Navigation
|
||||
**Epic Doel:** Configureerbaar dashboard met tegels en navigatie.
|
||||
|
||||
| Story ID | Story Description | Acceptance Criteria | Story Points | Status | Dependencies |
|
||||
|----------|-------------------|---------------------|--------------|--------|--------------|
|
||||
| EP08-ST01 | **Als behandelaar wil ik een dashboard zien zodat ik overzicht heb per cliënt** | ✅ 5 tegels (zie FO §4.2)<br>✅ Responsive grid layout<br>✅ Data uit verschillende tables<br>✅ Click naar detail | 5 | Not Started | EP03-ST03 |
|
||||
| EP08-ST02 | **Als behandelaar wil ik tegels configureren zodat ik kan personaliseren** | ✅ Settings icon → modal<br>✅ Checkboxes per tegel<br>✅ LocalStorage persistence<br>✅ Instant preview | 3 | Not Started | EP08-ST01 |
|
||||
| EP08-ST03 | **Als gebruiker wil ik breadcrumb navigatie zodat ik weet waar ik ben** | ✅ Breadcrumb in header<br>✅ Clickable segments<br>✅ Current page highlight<br>✅ Responsive truncation | 2 | Not Started | EP03-ST03 |
|
||||
| EP08-ST04 | **Als gebruiker wil ik sidebar navigatie zodat ik tussen modules kan wisselen** | ✅ Vertical navigation<br>✅ Active state indicator<br>✅ Icons + labels<br>✅ Collapsible op mobile | 3 | Not Started | EP03-ST03 |
|
||||
|
||||
**Technische implementatie details:**
|
||||
- **Tegels:** Basisgegevens, Laatste Intake, Probleemprofiel, Behandelplan, Afspraken
|
||||
- **Grid:** Tailwind Grid met responsive breakpoints
|
||||
- **State:** Zustand voor tegel configuratie
|
||||
|
||||
---
|
||||
|
||||
### Epic EP09 — UI Components & Styling
|
||||
**Epic Doel:** Consistente UI componenten volgens UX stylesheet.
|
||||
|
||||
| Story ID | Story Description | Acceptance Criteria | Story Points | Status | Dependencies |
|
||||
|----------|-------------------|---------------------|--------------|--------|--------------|
|
||||
| EP09-ST01 | **Als developer wil ik basis componenten bouwen zodat UI consistent is** | ✅ Button, Card, Input, Select<br>✅ Consistent met UX stylesheet<br>✅ TypeScript props<br>✅ Storybook (optional) | 5 | Not Started | EP00-ST02 |
|
||||
| EP09-ST02 | **Als developer wil ik toast notificaties implementeren zodat feedback duidelijk is** | ✅ Success/Error/Info/Warning<br>✅ Auto-dismiss na 5 sec<br>✅ Queue multiple toasts<br>✅ Accessible (aria-live) | 3 | Not Started | EP09-ST01 |
|
||||
| EP09-ST03 | **Als developer wil ik loading states implementeren zodat gebruiker weet dat er geladen wordt** | ✅ Skeleton loaders<br>✅ Spinners voor buttons<br>✅ Progress bars voor AI<br>✅ Consistent animation | 3 | Not Started | EP09-ST01 |
|
||||
| EP09-ST04 | **Als developer wil ik formulier componenten maken zodat input consistent is** | ✅ Form wrapper met validation<br>✅ Error messages styling<br>✅ Required field indicators<br>✅ Help text support | 5 | Not Started | EP09-ST01 |
|
||||
| EP09-ST05 | **Als developer wil ik dark mode ondersteunen (stretch) zodat gebruikers kunnen kiezen** | ✅ Theme toggle button<br>✅ System preference detect<br>✅ Persist preference<br>✅ All components support | 5 | Not Started | EP09-ST01 |
|
||||
|
||||
**Technische implementatie details:**
|
||||
- **Kleuren:** Zie UX stylesheet (§2-4)
|
||||
- **Component library:** shadcn/ui of custom
|
||||
- **Icons:** lucide-react consistent gebruik
|
||||
|
||||
---
|
||||
|
||||
### Epic EP10 — Testing & Quality Assurance
|
||||
**Epic Doel:** Comprehensive testing voor stabiele demo.
|
||||
|
||||
| Story ID | Story Description | Acceptance Criteria | Story Points | Status | Dependencies |
|
||||
|----------|-------------------|---------------------|--------------|--------|--------------|
|
||||
| EP10-ST01 | **Als developer wil ik unit tests schrijven zodat business logic getest is** | ✅ Vitest setup<br>✅ Utils & services tests<br>✅ 80% coverage /lib folder<br>✅ CI integration | 5 | Not Started | All features |
|
||||
| EP10-ST02 | **Als developer wil ik E2E tests schrijven zodat kritieke flows werken** | ✅ Playwright setup<br>✅ Happy path: intake → profile → plan<br>✅ Error scenarios<br>✅ Cross-browser | 5 | Not Started | All features |
|
||||
| EP10-ST03 | **Als team wil ik smoke tests uitvoeren zodat demo stabiel is** | ✅ Manual test checklist<br>✅ All features tested<br>✅ Performance acceptable<br>✅ No console errors | 2 | Not Started | All features |
|
||||
| EP10-ST04 | **Als developer wil ik accessibility testen zodat app toegankelijk is** | ✅ Keyboard navigation<br>✅ Screen reader support<br>✅ WCAG AA contrast<br>✅ Focus management | 1 | Not Started | EP09 |
|
||||
|
||||
**Technische implementatie details:**
|
||||
- **Test scenarios:** Zie FO §9 demo-scenario
|
||||
- **Performance:** <3s initial load, <5s AI responses
|
||||
- **Browser support:** Chrome, Firefox, Safari latest
|
||||
|
||||
---
|
||||
|
||||
### Epic EP11 — Deployment & Demo Prep
|
||||
**Epic Doel:** Production-ready deployment en demo voorbereiding.
|
||||
|
||||
| Story ID | Story Description | Acceptance Criteria | Story Points | Status | Dependencies |
|
||||
|----------|-------------------|---------------------|--------------|--------|--------------|
|
||||
| EP11-ST01 | **Als developer wil ik Vercel deployment configureren zodat app live is** | ✅ Vercel project setup<br>✅ EU region (Amsterdam)<br>✅ Environment variables<br>✅ Custom domain (optional) | 3 | Not Started | All features |
|
||||
| EP11-ST02 | **Als team wil ik demo data prepareren zodat presentatie smooth verloopt** | ✅ 3 complete test cliënten<br>✅ Realistic intake texts<br>✅ Pre-generated AI responses<br>✅ Backup data ready | 5 | Not Started | EP01-ST04 |
|
||||
| EP11-ST03 | **Als presenter wil ik demo script hebben zodat presentatie gestructureerd is** | ✅ 10-minute script<br>✅ Key talking points<br>✅ Backup scenarios<br>✅ Q&A anticipatie | 3 | Not Started | All features |
|
||||
| EP11-ST04 | **Als team wil ik dry-run doen zodat demo succesvol verloopt** | ✅ Complete run-through<br>✅ Timing verified (< 10 min)<br>✅ Technical issues fixed<br>✅ Feedback processed | 2 | Not Started | EP11-ST01 |
|
||||
|
||||
**Technische implementatie details:**
|
||||
- **Deployment checklist:**
|
||||
- Environment variables set
|
||||
- Database migrations run
|
||||
- Seed data loaded
|
||||
- SSL certificate active
|
||||
- Monitoring enabled
|
||||
|
||||
---
|
||||
|
||||
### Epic EP12 — Stretch Features (Optional)
|
||||
**Epic Doel:** Extra features indien tijd beschikbaar.
|
||||
|
||||
| Story ID | Story Description | Acceptance Criteria | Story Points | Status | Dependencies |
|
||||
|----------|-------------------|---------------------|--------------|--------|--------------|
|
||||
| EP12-ST01 | **Als behandelaar wil ik afspraken kunnen plannen zodat agenda gekoppeld is** | ✅ Calendar view<br>✅ Create/edit appointments<br>✅ Link to client<br>✅ Dashboard widget | 8 | Not Started | EP08-ST01 |
|
||||
| EP12-ST02 | **Als behandelaar wil ik PDF export zodat ik rapporten kan delen** | ✅ Export button<br>✅ Professional layout<br>✅ All sections included<br>✅ Download trigger | 8 | Not Started | EP06-ST05 |
|
||||
| EP12-ST03 | **Als behandelaar wil ik leesbaarheid verbeteren met AI zodat tekst B1-niveau wordt** | ✅ Endpoint: /api/ai/readability<br>✅ B1 niveau output<br>✅ Preserve medical accuracy<br>✅ Preview before apply | 5 | Not Started | EP07-ST01 |
|
||||
|
||||
---
|
||||
|
||||
## 5. Kwaliteit & Testplan
|
||||
|
||||
🎯 **Doel:** Borging van kwaliteit voor stabiele demo.
|
||||
|
||||
### Test Types
|
||||
| Test Type | Scope | Tools | Coverage Target |
|
||||
|-----------|-------|-------|-----------------|
|
||||
| Unit Tests | Services, utilities, validators | Vitest | 80% /lib folder |
|
||||
| Integration Tests | API endpoints, database queries | Vitest + MSW | All critical endpoints |
|
||||
| E2E Tests | Complete user flows | Playwright | 3 happy paths, 2 error paths |
|
||||
| Performance Tests | Load time, API response | Lighthouse | LCP <2.5s, FID <100ms |
|
||||
| Accessibility Tests | WCAG compliance | axe-core | AA compliance |
|
||||
| Security Tests | Auth, XSS, SQL injection | Manual + automated | OWASP top 10 |
|
||||
|
||||
### Critical Test Scenarios
|
||||
1. **New Client Flow**
|
||||
- Create client → Add intake → Generate summary → Extract problems → Create plan
|
||||
- Expected time: <2 minutes
|
||||
- All data persisted correctly
|
||||
|
||||
2. **AI Integration Flow**
|
||||
- Large intake text (2000+ words) → All AI features work
|
||||
- Response time <5 seconds per call
|
||||
- Graceful degradation if AI fails
|
||||
|
||||
3. **Error Handling**
|
||||
- Network failure → Appropriate error messages
|
||||
- Invalid input → Clear validation feedback
|
||||
- AI timeout → Fallback behavior
|
||||
|
||||
### Demo Checklist
|
||||
- [ ] Login with demo account works
|
||||
- [ ] Create new client (auto-generated ID)
|
||||
- [ ] Write intake with TipTap editor
|
||||
- [ ] AI summarize returns Dutch bullets
|
||||
- [ ] Problem extraction with highlighting
|
||||
- [ ] Treatment plan generation (SMART goals)
|
||||
- [ ] Publish plan (version 1)
|
||||
- [ ] Dashboard shows all data correctly
|
||||
- [ ] Navigation breadcrumbs work
|
||||
- [ ] No console errors
|
||||
- [ ] Performance acceptable (<3s loads)
|
||||
- [ ] Mobile view responsive
|
||||
|
||||
---
|
||||
|
||||
## 6. Demo & Presentatieplan
|
||||
|
||||
🎯 **Doel:** Succesvolle 10-minuten demo tijdens AI-inspiratiesessie.
|
||||
|
||||
### Demo Timeline
|
||||
| Time | Activity | Key Points | Backup Plan |
|
||||
|------|----------|------------|-------------|
|
||||
| 0:00-1:00 | **Intro** | Context mini-EPD, AI-toegevoegde waarde | Slides ready |
|
||||
| 1:00-2:30 | **Nieuwe cliënt** | Quick entry, auto ClientID, immediate start | Pre-created client |
|
||||
| 2:30-5:00 | **Intake + AI** | TipTap editor, AI summarize, source highlighting | Cached AI response |
|
||||
| 5:00-7:00 | **Profile + Plan** | DSM categorization, AI-generated plan, SMART goals | Manual input ready |
|
||||
| 7:00-8:30 | **Publiceren** | Version control, status change, dashboard update | Screenshots |
|
||||
| 8:30-10:00 | **Q&A** | Interactive discussion, next steps | FAQ prepared |
|
||||
|
||||
### Technical Setup
|
||||
- **Primary:** Live on Vercel (stable internet required)
|
||||
- **Backup 1:** Local development server
|
||||
- **Backup 2:** Recorded video demo
|
||||
- **Backup 3:** Static screenshots
|
||||
|
||||
### Key Messages
|
||||
1. AI vermindert administratieve last met 50%
|
||||
2. Consistente kwaliteit van documentatie
|
||||
3. Meer tijd voor cliëntcontact
|
||||
4. Evidence-based suggesties
|
||||
5. Privacy-first design (geen echte data)
|
||||
|
||||
---
|
||||
|
||||
## 7. Risico's & Mitigatie
|
||||
|
||||
🎯 **Doel:** Proactieve risico management voor succesvolle oplevering.
|
||||
|
||||
| Risico | Kans | Impact | Mitigatie | Owner |
|
||||
|--------|------|--------|-----------|-------|
|
||||
| **Claude API rate limits** | Hoog | Hoog | Response caching, queue implementation, fallback to OpenAI | Developer |
|
||||
| **TipTap complexiteit** | Medium | Hoog | Start simple, incremental features, fallback to textarea | Developer |
|
||||
| **Supabase RLS policies fout** | Medium | Hoog | Extensive testing, service role fallback, monitoring | Developer |
|
||||
| **AI output inconsistent** | Hoog | Medium | Prompt versioning, temperature tuning, validation layer | Developer |
|
||||
| **Demo internet uitval** | Laag | Hoog | Local setup ready, mobile hotspot backup, video recording | Presenter |
|
||||
| **Tijd tekort voor features** | Medium | Medium | MoSCoW prioritization, MVP focus, stretch clearly marked | PM |
|
||||
| **Browser compatibility** | Laag | Medium | Test on Chrome/Safari/Firefox, polyfills where needed | QA |
|
||||
| **Performance issues** | Medium | Medium | Lazy loading, code splitting, CDN for assets | Developer |
|
||||
| **Security vulnerability** | Laag | Hoog | Pen test, OWASP checklist, security headers | Developer |
|
||||
|
||||
---
|
||||
|
||||
## 8. Referenties
|
||||
|
||||
🎯 **Doel:** Koppeling naar alle relevante projectdocumentatie.
|
||||
|
||||
### Mission Control Documents
|
||||
- **PRD** — [Product Requirements Document](./prd-mini-ecd.md) - Business requirements en scope
|
||||
- **FO** — [Functioneel Ontwerp](./fo-mini-ecd.md) - User flows en functionele specificaties
|
||||
- **TO** — [Technisch Ontwerp](./to-mini-ecd.md) - Architectuur en database design
|
||||
- **UX/UI** — [Stylesheet](./ux-stylesheet.md) - Kleuren en design system
|
||||
- **API** — [API Access Document](./api-acces-mini-ecd.md) - Endpoints en authenticatie
|
||||
|
||||
### External Resources
|
||||
- **Repository:** `https://github.com/pinkroccade/mini-epd-prototype`
|
||||
- **Deployment:** `https://mini-epd.vercel.app`
|
||||
- **Supabase:** `https://app.supabase.com/project/[project-id]`
|
||||
- **Claude AI:** `https://docs.anthropic.com/claude/reference`
|
||||
- **TipTap Docs:** `https://tiptap.dev`
|
||||
- **Next.js Docs:** `https://nextjs.org/docs`
|
||||
|
||||
### Development Resources
|
||||
- **Component Library:** `https://ui.shadcn.com`
|
||||
- **Icons:** `https://lucide.dev`
|
||||
- **Tailwind:** `https://tailwindcss.com`
|
||||
|
||||
---
|
||||
|
||||
## 9. Technische Notities
|
||||
|
||||
### Database Queries Examples
|
||||
```typescript
|
||||
// Get client with full dossier
|
||||
const { data: client } = await supabase
|
||||
.from('clients')
|
||||
.select(`
|
||||
*,
|
||||
intake_notes (*),
|
||||
problem_profiles (*),
|
||||
treatment_plans (*)
|
||||
`)
|
||||
.eq('id', clientId)
|
||||
.single()
|
||||
|
||||
// Search clients
|
||||
const { data: clients } = await supabase
|
||||
.from('clients')
|
||||
.select('*')
|
||||
.ilike('last_name', `%${searchQuery}%`)
|
||||
.order('updated_at', { ascending: false })
|
||||
```
|
||||
|
||||
### AI Prompt Templates
|
||||
```typescript
|
||||
// Summarize prompt
|
||||
const SUMMARIZE_PROMPT = `
|
||||
Vat het onderstaande intake-verslag samen in 5-8 bullets.
|
||||
Schrijf in Nederlands, klinisch neutraal, zonder persoonlijke informatie.
|
||||
|
||||
Intake verslag:
|
||||
{intakeText}
|
||||
`
|
||||
|
||||
// Extract problems prompt
|
||||
const EXTRACT_PROMPT = `
|
||||
Analyseer de intake en bepaal:
|
||||
1. DSM-light categorie (kies uit: stemming_depressie, angst, gedrag_impuls, middelen_gebruik, cognitief, context_psychosociaal)
|
||||
2. Severity (laag, middel, hoog)
|
||||
3. Rationale (2-3 zinnen)
|
||||
4. Bronzinnen uit de tekst
|
||||
|
||||
Intake:
|
||||
{intakeText}
|
||||
`
|
||||
```
|
||||
|
||||
### Component Structure
|
||||
```typescript
|
||||
// Example component with proper typing
|
||||
interface ClientCardProps {
|
||||
client: Client
|
||||
onClick?: (id: string) => void
|
||||
isSelected?: boolean
|
||||
}
|
||||
|
||||
export function ClientCard({ client, onClick, isSelected }: ClientCardProps) {
|
||||
return (
|
||||
<Card
|
||||
className={cn(
|
||||
"cursor-pointer transition-shadow",
|
||||
isSelected && "ring-2 ring-primary"
|
||||
)}
|
||||
onClick={() => onClick?.(client.id)}
|
||||
>
|
||||
<CardHeader>
|
||||
<CardTitle>{client.first_name} {client.last_name}</CardTitle>
|
||||
<CardDescription>
|
||||
{format(new Date(client.birth_date), 'dd-MM-yyyy')}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Versiehistorie:**
|
||||
|
||||
| Versie | Datum | Auteur | Wijziging |
|
||||
|--------|-------|--------|-----------|
|
||||
| v1.0 | 10-11-2025 | Development Team | Initiële versie met complete epic breakdown |
|
||||
493
docs/specs/fo-mini-ecd.md
Normal file
493
docs/specs/fo-mini-ecd.md
Normal file
@@ -0,0 +1,493 @@
|
||||
# 🧩 Functioneel Ontwerp (FO) – Mini-ECD Prototype
|
||||
|
||||
**Projectnaam:** Mini-ECD Prototype
|
||||
**Versie:** v1.0 (MVP)
|
||||
**Datum:** 09-11-2025
|
||||
**Auteur:** Ontwikkelteam PinkRoccade GGZ
|
||||
|
||||
---
|
||||
|
||||
## 1. Doel en relatie met het PRD
|
||||
|
||||
🎯 **Doel van dit document:**
|
||||
Het Functioneel Ontwerp (FO) beschrijft **hoe** de Mini-ECD applicatie functioneel werkt — wat de gebruiker ziet, doet en ervaart tijdens de AI-inspiratiesessie. Waar het PRD uitlegt *wat en waarom*, laat het FO zien *hoe dit in de praktijk werkt*.
|
||||
|
||||
📘 **Context:**
|
||||
Dit FO ondersteunt de demo van max. 10 minuten waarbij we de kernflow **intake → probleemclassificatie → behandelplan** demonstreren met AI-ondersteuning. Het richt zich op de herkenbare ECD-workflow voor GGZ-professionals, met fictieve data en vereenvoudigde autorisatie.
|
||||
|
||||
**Relatie met andere documenten:**
|
||||
- **PRD**: definieert de vereisten en scope
|
||||
- **TO (Technisch Ontwerp)**: beschrijft de technische implementatie (Next.js, Supabase, Claude AI)
|
||||
- **UX Stylesheet**: specificeert kleuren en styling
|
||||
- **API Access**: documenteert de AI endpoints
|
||||
|
||||
---
|
||||
|
||||
## 2. Overzicht van de belangrijkste onderdelen
|
||||
|
||||
De applicatie bestaat uit de volgende hoofdonderdelen:
|
||||
|
||||
1. **Cliëntenlijst** — overzicht van alle cliënten met zoek- en filterfunctionaliteit
|
||||
2. **Cliëntdossier / Dashboard** — configureerbare tegels met overzicht per cliënt
|
||||
3. **Intakeverslag** — rich text editor met AI-ondersteuning
|
||||
4. **Probleemprofiel (DSM-light)** — categorisatie en severity-bepaling
|
||||
5. **Behandelplan** — gestructureerd plan met doelen, interventies en meetmomenten
|
||||
6. *(Stretch)* **Mini-agenda** — afspraken koppelen aan cliënt
|
||||
7. *(Stretch)* **Rapportage** — PDF export van dossier
|
||||
|
||||
---
|
||||
|
||||
## 3. User Stories
|
||||
|
||||
### Primaire User Stories (MVP)
|
||||
|
||||
| ID | Rol | Doel / Actie | Verwachte waarde | Prioriteit |
|
||||
|----|------|---------------|------------------|-------------|
|
||||
| US-01 | Behandelaar | Nieuwe cliënt aanmaken met basisgegevens | Kan direct starten met intake | Hoog |
|
||||
| US-02 | Behandelaar | Intakeverslag schrijven in rich text editor | Flexibel notuleren met opmaak | Hoog |
|
||||
| US-03 | Behandelaar | Intakeverslag samenvatten met AI | Tijdbesparing, sneller overzicht | Hoog |
|
||||
| US-04 | Behandelaar | Leesbaarheid verbeteren naar B1-niveau met AI | Cliëntvriendelijke communicatie | Middel |
|
||||
| US-05 | Behandelaar | AI-suggestie krijgen voor DSM-light categorie en severity | Snellere en consistentere classificatie | Hoog |
|
||||
| US-06 | Behandelaar | Behandelplan genereren op basis van intake/profiel | Efficiënter plannen, SMART-doelen | Hoog |
|
||||
| US-07 | Behandelaar | Gegenereerd plan bewerken en publiceren | Controle over eindresultaat | Hoog |
|
||||
| US-08 | Behandelaar | Configureren welke dashboard-tegels zichtbaar zijn | Personalisatie werkruimte | Laag |
|
||||
|
||||
### Secundaire User Stories (Stakeholders)
|
||||
|
||||
| ID | Rol | Doel / Actie | Verwachte waarde | Prioriteit |
|
||||
|----|------|---------------|------------------|-------------|
|
||||
| US-09 | Product Owner | Demo-flow doorlopen tijdens workshop | Begrijpt AI-toegevoegde waarde | Hoog |
|
||||
| US-10 | Developer | Zien hoe AI in ECD-proces geïntegreerd is | Inspiratie voor eigen implementaties | Middel |
|
||||
| US-11 | Manager | Overzicht van cliëntdossiers bekijken | Inzicht in werkprocessen | Laag |
|
||||
|
||||
---
|
||||
|
||||
## 4. Functionele werking per onderdeel
|
||||
|
||||
### 4.1 Cliëntenlijst
|
||||
|
||||
**Doel:** Overzicht van alle geregistreerde cliënten met mogelijkheid om nieuwe cliënten toe te voegen.
|
||||
|
||||
**Functionaliteit:**
|
||||
- **Weergave:**
|
||||
- Tabel met kolommen: ClientID, Naam (Voornaam + Achternaam), Geboortedatum, Laatste update
|
||||
- Zoekbalk bovenaan voor filteren op naam of ClientID
|
||||
- Knop **+ Nieuwe cliënt** rechtsboven
|
||||
|
||||
- **Acties:**
|
||||
- Klik op rij → navigeert naar Cliëntdossier (Dashboard)
|
||||
- Klik **+ Nieuwe cliënt** → opent modal/drawer met formulier:
|
||||
- Velden: Voornaam (verplicht), Achternaam (verplicht), Geboortedatum (datum picker)
|
||||
- Knop **Annuleren** | **Opslaan**
|
||||
- Bij opslaan: ClientID wordt automatisch gegenereerd (UUID)
|
||||
|
||||
- **States:**
|
||||
- **Leeg-staat:** "Nog geen cliënten. Klik op '+ Nieuwe cliënt' om te starten."
|
||||
- **Laden:** Skeleton loaders voor tabelrijen
|
||||
- **Fout:** Toast-melding "Kon cliënten niet laden. Probeer opnieuw."
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Cliëntdossier / Dashboard
|
||||
|
||||
**Doel:** Overzichtspagina per cliënt met configureerbare informatie-tegels.
|
||||
|
||||
**Structuur:**
|
||||
- **Topbalk:**
|
||||
- Breadcrumb: Cliënten > [Naam cliënt]
|
||||
- Rechtsboven: Knop **Instellingen** (tandwiel-icoon) → opent tegel-configuratie modal
|
||||
|
||||
- **Linkernavigatie (verticaal):**
|
||||
- Menu-items: Overzicht (actief) | Intakes | Probleemprofiel | Behandelplan | *(Afspraken)*
|
||||
- Actieve item heeft blauwe accent-bar en lichte achtergrond
|
||||
|
||||
- **Middenpaneel (tegels):**
|
||||
- Configureerbare tegels (via instellingen aan/uit te zetten):
|
||||
1. **Basisgegevens** — ClientID, Naam, Geboortedatum
|
||||
2. **Laatste Intake** — titel, datum, eerste 3 regels + "Lees meer..."
|
||||
3. **Probleemprofiel** — DSM-light categorie badge + severity badge (Laag/Middel/Hoog)
|
||||
4. **Behandelplan** — status (Concept/Gepubliceerd), aantal doelen, laatst bijgewerkt
|
||||
5. **Afspraken** — laatste afspraak + eerstvolgende 3 afspraken (optioneel, stretch)
|
||||
|
||||
**Interacties:**
|
||||
- Klik op tegel → navigeert naar desbetreffende sectie (bv. Intake-tegel → Intakes tab)
|
||||
- **Instellingen modal:**
|
||||
- Checkboxes per tegel om zichtbaarheid in/uit te schakelen
|
||||
- Knop **Opslaan** → slaat voorkeur op (per gebruiker, lokaal)
|
||||
|
||||
---
|
||||
|
||||
### 4.3 Intakeverslag
|
||||
|
||||
**Doel:** Creëren en bewerken van intake-notities met rich text en AI-ondersteuning.
|
||||
|
||||
**Layout:**
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Topbalk: Cliëntnaam | [Opslaan] [AI-acties ▼] │
|
||||
├───────────────┬─────────────────────────────────────────┤
|
||||
│ Linkernav │ Editor (hoofdpaneel) │ AI-rail │
|
||||
│ (tabs) │ TipTap rich text │ (rechts) │
|
||||
│ │ │ │
|
||||
├───────────────┴─────────────────────────┴───────────────┤
|
||||
│ Toast area (meldingen) │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Hoofdpaneel (Editor):**
|
||||
- **Formulier boven editor:**
|
||||
- Titel (optioneel): "Intake [datum]"
|
||||
- Tag dropdown: Intake | Evaluatie | Plan
|
||||
|
||||
- **TipTap rich text editor:**
|
||||
- Toolbar: Bold, Italic, Underline, Bullet list, Numbered list, Blockquote
|
||||
- Placeholder: "Noteer hier de intake-informatie..."
|
||||
- Auto-save indicator: "Opgeslagen om [tijd]" onder editor
|
||||
|
||||
- **Knoppen onder editor:**
|
||||
- **Opslaan** (primair, blauw) — slaat verslag op
|
||||
- **AI-acties** dropdown (secundair, grijs):
|
||||
- Samenvatten
|
||||
- Verbeter leesbaarheid (B1)
|
||||
- Extract problemen
|
||||
|
||||
**AI-rail (rechterpaneel):**
|
||||
- **Initieel:** Leeg met prompt "Selecteer een AI-actie om te beginnen"
|
||||
|
||||
- **Na AI-actie:**
|
||||
- **Header:** "AI-resultaat: [actienaam]" + loading spinner tijdens verwerking
|
||||
- **Content area:**
|
||||
- Voor **Samenvatten**: Bulletpoints van samenvatting
|
||||
- Voor **Leesbaarheid**: Herschreven tekst (diff-weergave optioneel)
|
||||
- Voor **Extract**: Voorgestelde categorie + severity + bronzinnen (highlighted in editor)
|
||||
- **Acties:**
|
||||
- **Invoegen** (primair) — voegt resultaat in editor toe
|
||||
- **Kopiëren** (secundair) — kopieert naar clipboard
|
||||
- **Annuleren** (ghost) — verwerpt resultaat
|
||||
|
||||
**States & feedback:**
|
||||
- **AI bezig:** Non-blocking spinner in AI-rail + "Genereren..." melding
|
||||
- **AI fout:** Foutmelding in rail: "Kon niet verwerken. Probeer opnieuw." + retry-knop
|
||||
- **Opslaan gelukt:** Groene toast "Verslag opgeslagen"
|
||||
- **Opslaan mislukt:** Rode toast "Kon niet opslaan. Controleer verbinding."
|
||||
|
||||
**AI Source Highlighting (voor Extract):**
|
||||
- Bronzinnen die AI gebruikt heeft worden gehighlight in de editor (lichtgele achtergrond)
|
||||
- Highlights verdwijnen bij Invoegen, Annuleren of nieuwe AI-actie
|
||||
|
||||
**Keyboard shortcuts:**
|
||||
- `Ctrl/Cmd+S`: Opslaan
|
||||
- `Ctrl/Cmd+K`: Zoeken in tekst
|
||||
- `Ctrl/Cmd+N`: Nieuw verslag
|
||||
|
||||
---
|
||||
|
||||
### 4.4 Probleemprofiel (DSM-light)
|
||||
|
||||
**Doel:** Categoriseren van problematiek volgens vereenvoudigde DSM-classificatie met severity-bepaling.
|
||||
|
||||
**Layout:**
|
||||
- **Formulier (links, 60%):**
|
||||
- **Categorie** (dropdown, verplicht):
|
||||
- Stemming / Depressieve klachten
|
||||
- Angststoornissen
|
||||
- Gedrags- en impulsstoornissen
|
||||
- Middelengebruik / Verslaving
|
||||
- Cognitieve stoornissen
|
||||
- Context / Psychosociaal
|
||||
- **Severity** (button group of slider):
|
||||
- Laag (grijs badge)
|
||||
- Middel (geel badge)
|
||||
- Hoog (rood badge)
|
||||
- **Opmerkingen** (textarea, optioneel): vrij tekstveld voor notities
|
||||
- **Bronverslag** (readonly): "Gebaseerd op intake [titel] van [datum]"
|
||||
|
||||
- **AI-suggestie paneel (rechts, 40%):**
|
||||
- **Trigger:** Knop **AI › Analyseer intake**
|
||||
- **Output:**
|
||||
- Voorgestelde categorie (highlight)
|
||||
- Voorgestelde severity (highlight)
|
||||
- Rationale (korte uitleg, 2-3 zinnen)
|
||||
- Bronzinnen (quotes uit intake)
|
||||
- **Acties:**
|
||||
- **Accepteer suggestie** — vult formulier automatisch in
|
||||
- **Negeer** — sluit suggestie paneel
|
||||
|
||||
**States:**
|
||||
- **Geen profiel:** "Nog geen probleemprofiel. Start met AI-analyse of vul handmatig in."
|
||||
- **AI bezig:** Skeleton loader in suggestie-paneel
|
||||
- **Opgeslagen:** Groene melding "Probleemprofiel opgeslagen" → activeert Behandelplan tab
|
||||
|
||||
---
|
||||
|
||||
### 4.5 Behandelplan
|
||||
|
||||
**Doel:** Genereren en bewerken van een gestructureerd behandelplan met SMART-doelen.
|
||||
|
||||
**Structuur:**
|
||||
- **Header:**
|
||||
- Versie-indicator: "Concept" (oranje badge) of "Versie X – Gepubliceerd" (groene badge)
|
||||
- Publicatiedatum (indien gepubliceerd)
|
||||
|
||||
- **Vier secties (cards/accordions):**
|
||||
|
||||
1. **Doelen**
|
||||
- Lijst van doelen (bullets, bewerkbaar)
|
||||
- Voorbeeld: "Cliënt ervaart minder angstklachten in sociale situaties binnen 3 maanden"
|
||||
- **Micro-AI-actie:** Knop **↻ Regenereer** per doel
|
||||
|
||||
2. **Interventies**
|
||||
- Lijst van interventies
|
||||
- Voorbeeld: "Cognitieve gedragstherapie (CGT), 12 sessies"
|
||||
- **Micro-AI-actie:** Knop **↻ Regenereer** per interventie
|
||||
|
||||
3. **Frequentie/Duur**
|
||||
- Tekstveld met suggestie
|
||||
- Voorbeeld: "Wekelijks, 12 weken, 50 minuten per sessie"
|
||||
|
||||
4. **Meetmomenten**
|
||||
- Lijst van evaluatiemomenten
|
||||
- Voorbeeld: "Na 4 sessies, na 8 sessies, afsluiting na 12 sessies"
|
||||
|
||||
**Initiële generatie:**
|
||||
- **Trigger:** Knop **AI › Genereer behandelplan** (alleen zichtbaar als probleemprofiel bestaat)
|
||||
- **Input:** Gebruikt intake-notities + probleemprofiel als context
|
||||
- **Output:** Vult alle vier secties met voorstellen
|
||||
- **Feedback:** "Plan gegenereerd. Bekijk en bewerk indien nodig." (blauwe info-toast)
|
||||
|
||||
**Bewerken:**
|
||||
- Alle velden/bullets zijn inline bewerkbaar (contentEditable of input fields)
|
||||
- **Auto-save:** Elke wijziging wordt automatisch opgeslagen als concept
|
||||
|
||||
**Publiceren:**
|
||||
- **Knop:** **Publiceer v[N]** (rechtsboven)
|
||||
- **Validatie:** Controleer of alle secties gevuld zijn
|
||||
- **Actie:**
|
||||
- Wijzigt status van "Concept" naar "Gepubliceerd"
|
||||
- Verhoogt versienummer
|
||||
- Timestamp van publicatie
|
||||
- Concept wordt read-only; nieuwe wijzigingen maken nieuwe versie aan
|
||||
- **Feedback:** "Behandelplan v1 gepubliceerd" (groene toast)
|
||||
|
||||
**States:**
|
||||
- **Geen plan:** "Nog geen behandelplan. Genereer met AI of start handmatig."
|
||||
- **Concept:** Oranje badge, bewerkbaar
|
||||
- **Gepubliceerd:** Groene badge, read-only met knop **Nieuwe versie**
|
||||
|
||||
---
|
||||
|
||||
### 4.6 Mini-agenda (stretch, optioneel)
|
||||
|
||||
**Doel:** Afspraken koppelen aan cliënt voor planning en follow-up.
|
||||
|
||||
**Functionaliteit:**
|
||||
- Kalenderweergave (week of maand)
|
||||
- **Nieuwe afspraak:**
|
||||
- Datum/tijd picker
|
||||
- Type afspraak (dropdown): Intake | Evaluatie | Behandeling
|
||||
- Locatie (optioneel)
|
||||
- Notities (optioneel)
|
||||
- **Weergave in dashboard:** laatste + eerstvolgende 3 afspraken
|
||||
|
||||
---
|
||||
|
||||
### 4.7 Rapportage (stretch, optioneel)
|
||||
|
||||
**Doel:** PDF export van volledige cliëntdossier voor archivering of delen.
|
||||
|
||||
**Functionaliteit:**
|
||||
- **Knop:** **Exporteer als PDF** in cliënt-menu
|
||||
- **Inhoud:**
|
||||
- Basisgegevens
|
||||
- Alle intakes (chronologisch)
|
||||
- Probleemprofiel
|
||||
- Behandelplan (gepubliceerde versie)
|
||||
- *(Optioneel)* Afspraken
|
||||
- **Output:** Downloads PDF met professionele opmaak (logo, headers, footers)
|
||||
|
||||
---
|
||||
|
||||
## 5. UI-overzicht (visuele structuur)
|
||||
|
||||
### Globale layout (alle schermen)
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ Topbalk: Logo | Breadcrumb | Zoeken | User menu │
|
||||
├───────────────┬──────────────────────────────────────────────┤
|
||||
│ Linkernav │ Middenpaneel (content area) │
|
||||
│ (indien actief│ → Dashboard: tegels │
|
||||
│ in dossier) │ → Intake: editor + AI-rail │
|
||||
│ │ → Profiel: formulier + suggestie │
|
||||
│ Overzicht │ → Plan: secties met doelen/interventies │
|
||||
│ Intakes │ │
|
||||
│ Profiel │ │
|
||||
│ Plan │ │
|
||||
│ (Afspraken) │ │
|
||||
├───────────────┴──────────────────────────────────────────────┤
|
||||
│ Toast area (rechtsonder): meldingen (success/error/info) │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Cliëntenlijst (geen linkernav)
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ Topbalk: Logo | Zoeken | [+ Nieuwe cliënt] │
|
||||
├──────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Cliëntenlijst │
|
||||
│ ┌────────────────────────────────────────────────────┐ │
|
||||
│ │ ID │ Naam │ Geboortedatum │ Update │ │
|
||||
│ ├───────┼──────────────────┼───────────────┼────────┤ │
|
||||
│ │ C-001 │ Jan de Vries │ 15-03-1985 │ 2u │ │
|
||||
│ │ C-002 │ Maria Jansen │ 22-07-1990 │ 1d │ │
|
||||
│ └────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Intake-editor met AI-rail
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ Jan de Vries | [Opslaan] [AI-acties ▼] │
|
||||
├───────────────┬─────────────────────┬────────────────────────┤
|
||||
│ Overzicht │ Editor │ AI-rail │
|
||||
│ Intakes ● │ ┌─────────────────┐ │ ┌──────────────────┐ │
|
||||
│ Profiel │ │ Titel: [.......]│ │ │ AI-resultaat: │ │
|
||||
│ Plan │ │ Tag: [Intake ▼] │ │ │ Samenvatting │ │
|
||||
│ │ └─────────────────┘ │ │ │ │
|
||||
│ │ │ │ • Punt 1 │ │
|
||||
│ │ Rich text area... │ │ • Punt 2 │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ │ [Invoegen] │ │
|
||||
│ │ │ │ [Annuleren] │ │
|
||||
│ │ │ └──────────────────┘ │
|
||||
│ │ [Opslaan] │ │
|
||||
├───────────────┴─────────────────────┴────────────────────────┤
|
||||
│ Toast: "Verslag opgeslagen" (groen) │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Interacties met AI (functionele beschrijving)
|
||||
|
||||
| Locatie | AI-actie | Trigger | Input | Output | Feedback |
|
||||
|----------|-----------|----------|--------|---------|----------|
|
||||
| **Intake-editor** | Samenvatten | Klik op **AI › Samenvatten** | TipTap JSON (intake-tekst) | 5-8 bullets in NL | Preview in AI-rail → Invoegen/Annuleren |
|
||||
| **Intake-editor** | Leesbaarheid (B1) | Klik op **AI › Verbeter leesbaarheid** | TipTap JSON | Herschreven tekst (B1-niveau) | Preview in AI-rail → Invoegen/Annuleren |
|
||||
| **Intake-editor** | Extract problemen | Klik op **AI › Extract problemen** | TipTap JSON | Categorie + severity + rationale + bronzinnen | Suggestie in AI-rail + highlights in editor |
|
||||
| **Probleemprofiel** | Analyseer intake | Klik op **AI › Analyseer intake** | Intake-tekst (laatste verslag) | Voorgestelde categorie + severity + rationale | Suggestie-paneel rechts → Accepteren/Negeren |
|
||||
| **Behandelplan** | Genereer plan | Klik op **AI › Genereer behandelplan** | Intake + probleemprofiel | 4 secties (doelen, interventies, frequentie, meetmomenten) | Vult alle secties → bewerkbaar |
|
||||
| **Behandelplan** | Regenereer doel | Klik op **↻** bij specifiek doel | Context (huidige doelen + intake) | Nieuw geformuleerd doel (SMART) | Vervangt huidige doel → bewerkbaar |
|
||||
|
||||
**AI-processing states:**
|
||||
- **Bezig:** Non-blocking spinner + "Genereren..." tekst
|
||||
- **Succes:** Output verschijnt in preview/suggestie-area
|
||||
- **Fout:** Rode melding "Kon niet verwerken" + retry-knop
|
||||
- **Timeout:** "AI-actie duurde te lang. Probeer opnieuw."
|
||||
|
||||
**AI-highlights (Extract problemen):**
|
||||
- Bronzinnen krijgen lichtgele achtergrond in editor
|
||||
- Highlights verdwijnen bij: Invoegen, Annuleren, of nieuwe AI-actie
|
||||
- Implementatie: TipTap Decorations API
|
||||
|
||||
---
|
||||
|
||||
## 7. Gebruikersrollen en rechten
|
||||
|
||||
**MVP:** Vereenvoudigde autorisatie — alle authenticated users hebben volledige toegang (demo-omgeving).
|
||||
|
||||
| Rol | Toegang tot | Beperkingen | Implementatie |
|
||||
|------|--------------|-------------|---------------|
|
||||
| **Demo-user** (MVP) | Alle cliëntdossiers, alle functies | Alleen fictieve data | Supabase Auth, RLS policy: `auth.uid() IS NOT NULL` |
|
||||
|
||||
**Post-MVP (Roadmap):**
|
||||
|
||||
| Rol | Toegang tot | Beperkingen |
|
||||
|------|--------------|-------------|
|
||||
| **Behandelaar** | Eigen cliëntdossiers + gedeelde dossiers | Kan alleen eigen dossiers bewerken |
|
||||
| **Manager** | Alle dossiers (read-only) | Geen bewerkingen, alleen rapportages |
|
||||
| **Admin** | Alles | Volledige CRUD + gebruikersbeheer |
|
||||
|
||||
**Toekomstige implementatie:**
|
||||
- Multi-tenant: `org_id` kolom in alle tables
|
||||
- RLS policies: `auth.jwt() ->> 'org_id' = org_id`
|
||||
- Role-based access: `auth.jwt() ->> 'role'` checks
|
||||
|
||||
---
|
||||
|
||||
## 8. UX-specificaties (koppeling met stylesheet)
|
||||
|
||||
**Kleurgebruik (zie `/docs/ux-stylesheet.md`):**
|
||||
- **Primary actions:** `#3B82F6` (blauw) — Opslaan, Publiceren, Invoegen
|
||||
- **Secondary actions:** `#334155` (grijs) — Annuleren, Terug
|
||||
- **Success feedback:** `#16A34A` (groen) — toasts, badges
|
||||
- **Warning/Concept:** `#EAB308` (geel) — concept-status
|
||||
- **Error:** `#DC2626` (rood) — foutmeldingen
|
||||
|
||||
**Module-accenten:**
|
||||
- Afspraken: groen (`#E8F8EF` bg, `#16A34A` accent)
|
||||
- Medicatie/Herinneringen: geel (`#FEF6DC` bg, `#F59E0B` accent)
|
||||
- Lab/Resultaten: oranje (`#FFEBDC` bg, `#F97316` accent)
|
||||
|
||||
**Toegankelijkheid:**
|
||||
- Alle tekst voldoet aan WCAG AA contrast (min. 4.5:1)
|
||||
- Focus rings altijd zichtbaar (2px `#3B82F6`)
|
||||
- Keyboard navigation volledig ondersteund
|
||||
- Status niet alleen met kleur: iconen + labels combineren
|
||||
|
||||
---
|
||||
|
||||
## 9. Demo-scenario (10 minuten)
|
||||
|
||||
**Voorbereiding:** Database seeden met 2-3 fictieve cliënten (1 met partial data, 1 leeg).
|
||||
|
||||
### Flow A: Nieuwe cliënt → Intake → AI Samenvatten (4 min)
|
||||
1. **Start:** Cliëntenlijst (0:00)
|
||||
2. Klik **+ Nieuwe cliënt** → vul in: "Test Demo", "Testpersoon", "01-01-1990" → Opslaan (0:30)
|
||||
3. Navigeer naar nieuwe cliënt → klik **Intakes** tab (0:45)
|
||||
4. Klik **+ Nieuw verslag** → typ demo-intake (vooraf geprepareerde tekst plakken) (1:30)
|
||||
5. Klik **AI › Samenvatten** → toon preview in AI-rail (2:00)
|
||||
6. Klik **Invoegen** → samenvatting verschijnt in editor (2:30)
|
||||
7. Klik **Opslaan** → toast "Verslag opgeslagen" (3:00)
|
||||
|
||||
### Flow B: Probleemprofiel genereren → AI suggestie (3 min)
|
||||
8. Klik **Probleemprofiel** tab (3:15)
|
||||
9. Klik **AI › Analyseer intake** → toon suggestie (categorie, severity, rationale) (4:00)
|
||||
10. Highlights verschijnen in editor (source highlighting demo) (4:30)
|
||||
11. Klik **Accepteer suggestie** → vult formulier (4:45)
|
||||
12. Klik **Opslaan** → groene toast + Behandelplan tab wordt actief (5:00)
|
||||
|
||||
### Flow C: Behandelplan genereren → Bewerken → Publiceren (3 min)
|
||||
13. Klik **Behandelplan** tab (5:15)
|
||||
14. Klik **AI › Genereer behandelplan** → toon alle vier secties (6:00)
|
||||
15. Bewerk één doel handmatig → auto-save indicator (6:45)
|
||||
16. Klik **Publiceer v1** → status wijzigt naar "Gepubliceerd" (7:30)
|
||||
17. Navigeer terug naar **Overzicht** → toon dashboard met tegels (8:00)
|
||||
18. **(Optioneel)** Demo PDF export (8:30)
|
||||
|
||||
**Afsluiting:** Q&A + discussie AI-toegevoegde waarde (8:30-10:00)
|
||||
|
||||
---
|
||||
|
||||
## 10. Bijlagen & Referenties
|
||||
|
||||
**Gerelateerde documenten:**
|
||||
- [PRD (Product Requirements Document)](./prd-mini-ecd.md)
|
||||
- [TO (Technisch Ontwerp)](./to-mini-ecd.md)
|
||||
- [UX/UI Stylesheet](./ux-stylesheet.md)
|
||||
- [API Access Document](./api-acces-mini-ecd.md)
|
||||
|
||||
**Externe referenties:**
|
||||
- TipTap editor: https://tiptap.dev
|
||||
- Supabase documentatie: https://supabase.com/docs
|
||||
- Next.js App Router: https://nextjs.org/docs/app
|
||||
- Claude AI API: https://docs.anthropic.com/claude/reference
|
||||
|
||||
---
|
||||
|
||||
**Wijzigingslog:**
|
||||
- v1.0 (09-11-2025): Initiële versie voor MVP demo
|
||||
138
docs/specs/prd-mini-ecd.md
Normal file
138
docs/specs/prd-mini-ecd.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# 📄 Product Requirements Document (PRD)
|
||||
|
||||
**Product:** Mini-ECD Prototype
|
||||
**Doel:** Demo tijdens AI-inspiratiesessie bij PinkRoccade GGZ
|
||||
**Versie:** 1.1 (MVP met DSM-light simulatie)
|
||||
**Datum:** aug 2025
|
||||
|
||||
---
|
||||
|
||||
## 1. Doelstelling
|
||||
|
||||
Een werkend **mini-ECD prototype** waarmee we tijdens de workshop de kernprocessen uit de GGZ kunnen demonstreren: **intake → probleemclassificatie → behandelplan**.
|
||||
Focus ligt op het **zichtbaar maken van AI-waarde** (samenvatten, structureren, plan genereren) in een herkenbare workflow.
|
||||
|
||||
---
|
||||
|
||||
## 2. Doelgroep
|
||||
|
||||
* **Product Owners & Managers** → inzicht in AI als hulpmiddel.
|
||||
* **Developers** → inspiratie voor AI-integratie.
|
||||
* **Consultants / GGZ-professionals** → herkenbare ECD-structuur.
|
||||
|
||||
---
|
||||
|
||||
## 3. Kernfunctionaliteiten (MVP)
|
||||
|
||||
1. **Cliënt inschrijven**
|
||||
|
||||
* Velden: Voornaam, Achternaam, Geboortedatum.
|
||||
* Automatische ClientID.
|
||||
* Verschijnt in Cliëntenlijst.
|
||||
|
||||
2. **Overzicht (Cliëntdashboard)**
|
||||
|
||||
* Tegels:
|
||||
|
||||
* Basisgegevens: ClientID, Naam, Geboortedatum.
|
||||
* Intake: verkorte weergave laatste intakeverslag.
|
||||
* Probleemprofiel: DSM-light categorie + severity-badge.
|
||||
* Behandelplan: doelen in bullets + status.
|
||||
* Afspraken: laatste afspraak + eerstvolgende 3 afspraken.
|
||||
* Configuratie: gebruiker kan via een instellingen-knop kiezen welke tegels zichtbaar zijn.
|
||||
|
||||
3. **Intake-verslag maken**
|
||||
|
||||
* Rich text editor.
|
||||
* Tags: Intake / Evaluatie / Plan.
|
||||
* Opslaan & koppelen aan cliënt.
|
||||
|
||||
4. **Probleemprofiel (DSM-light simulatie)**
|
||||
|
||||
* Dropdown categorieën (simulatie DSM-5 hoofdcategorieën):
|
||||
|
||||
* Stemming / Depressieve klachten
|
||||
* Angststoornissen
|
||||
* Gedrags- en impulsstoornissen
|
||||
* Middelengebruik / Verslaving
|
||||
* Cognitieve stoornissen
|
||||
* Context / Psychosociaal
|
||||
* Severity: Laag / Middel / Hoog.
|
||||
* Vrij veld: opmerkingen.
|
||||
* **AI-suggestie:** intake analyseren → voorstel categorie + severity.
|
||||
|
||||
5. **AI-ondersteuning bij verslag**
|
||||
|
||||
* Knoppen:
|
||||
|
||||
* *Samenvatten* (in bullets).
|
||||
* *Verbeter leesbaarheid* (B1-niveau).
|
||||
* *Extract problemen* (AI vult categorie/severity suggestie in).
|
||||
|
||||
6. **AI-voorstel behandelplan**
|
||||
|
||||
* Genereert secties: Doelen, Interventies, Frequentie/Duur, Meetmomenten.
|
||||
* Gebruiker kan bewerken of accepteren.
|
||||
|
||||
7. **Mini-agenda (optioneel, stretch)**
|
||||
|
||||
* Afspraak plannen gekoppeld aan cliënt.
|
||||
|
||||
8. **Rapport export (stretch)**
|
||||
|
||||
* PDF: cliëntgegevens + intake + probleemprofiel + behandelplan.
|
||||
|
||||
---
|
||||
|
||||
## 4. Demo-flows
|
||||
|
||||
1. **Nieuwe cliënt → Intake maken → AI Samenvatten.**
|
||||
2. **Probleemprofiel genereren → AI suggestie → severity kiezen.**
|
||||
3. **Behandelplan genereren → Accept → Opslaan.**
|
||||
*(Optioneel: afspraak plannen en rapport exporteren.)*
|
||||
|
||||
---
|
||||
|
||||
## 5. Niet in scope
|
||||
|
||||
* Autorisaties en rollenbeheer.
|
||||
* Externe koppelingen (Teams, TOPdesk, etc.).
|
||||
* Volledige DSM-5 implementatie (alleen simulatie).
|
||||
* Dit prototype is geen gevalideerd medisch hulpmiddel en dient enkel voor demonstratiedoeleinden.
|
||||
|
||||
---
|
||||
|
||||
## 6. Technische randvoorwaarden
|
||||
|
||||
* **Framework:** Next.js
|
||||
* **Styling:** Tailwind
|
||||
* **Database:** Supabase
|
||||
* **AI:** Claude AI
|
||||
* **Hosting:** Vercel (EU).
|
||||
|
||||
---
|
||||
|
||||
## 7. Succescriteria
|
||||
|
||||
* Demo duurt max. 10 minuten.
|
||||
* Herkenbare flow (intake → profiel → plan).
|
||||
* AI-output direct zichtbaar en bewerkbaar.
|
||||
* Minimaal 1 deelnemer kan live een cliënt toevoegen.
|
||||
* Deelnemers aan de workshop begrijpen de toegevoegde waarde van AI in het ECD-proces.
|
||||
|
||||
---
|
||||
|
||||
## 8. Risico’s
|
||||
|
||||
* **Privacy:** uitsluitend fictieve data.
|
||||
* **AI-output inconsistent:** prompts vooraf testen.
|
||||
* **Scope creep:** strak houden bij intake → plan.
|
||||
|
||||
---
|
||||
|
||||
## 9. Roadmap (post-demo)
|
||||
|
||||
* Autorisaties en auditlog.
|
||||
* Trendanalyse (stemming/voortgang).
|
||||
* Integratie met PinkRoccade modules.
|
||||
* Compliance en security uitbreiden.
|
||||
28
docs/specs/sync-log.json
Normal file
28
docs/specs/sync-log.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"timestamp": "2025-11-10T08:34:00Z",
|
||||
"source_folder_id": "11Vm70rVxj01gIbJzN6Kk1x_8yTbFxSg2",
|
||||
"source_folder_name": "01-project-epd-prototype",
|
||||
"destination": "./docs/specs/",
|
||||
"sync_method": "git-restore",
|
||||
"projects": [
|
||||
{
|
||||
"name": "mini-epd-prototype",
|
||||
"files_synced": 5,
|
||||
"files_failed": 0,
|
||||
"status": "success",
|
||||
"files": [
|
||||
"api-acces-mini-ecd.md",
|
||||
"fo-mini-ecd.md",
|
||||
"prd-mini-ecd.md",
|
||||
"to-mini-ecd.md",
|
||||
"ux-stylesheet.md"
|
||||
]
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"total_projects": 1,
|
||||
"total_files": 5,
|
||||
"total_failures": 0,
|
||||
"sync_status": "success"
|
||||
}
|
||||
}
|
||||
390
docs/specs/to-mini-ecd.md
Normal file
390
docs/specs/to-mini-ecd.md
Normal file
@@ -0,0 +1,390 @@
|
||||
# ⚙️ Technisch Ontwerp — Mini‑ECD (MVP)
|
||||
|
||||
**Datum:** aug 2025
|
||||
**Scope:** MVP voor demo tijdens AI‑inspiratiesessie (≤10 min)
|
||||
**Bronnen:** PRD (v1.1), UX/UI‑specificatie, FO (MVP)
|
||||
|
||||
---
|
||||
|
||||
## 0) TL;DR Stack & Keuzes
|
||||
|
||||
* **Framework**: **Next.js** (App Router)
|
||||
* **UI**: **Tailwind CSS** (v4; fallback v3.4 bij frictie) + **lucide-react** iconen; lichte componentlaag (shadcn/ui of eigen + headless)
|
||||
* **Editor**: **TipTap** (ProseMirror) met StarterKit + BasicNodes
|
||||
* **Auth & Data**: **Supabase** (PostgreSQL + Auth + Storage)
|
||||
* **AI**: **Claude** (Anthropic) via API
|
||||
* **Hosting**: **Vercel** (Next.js)
|
||||
* **PDF (stretch)**: server‑side HTML→PDF via **Chromium (playwright/puppeteer)** of cloud‑functie.
|
||||
* **Test**: **Vitest** (unit) + **Playwright** (e2e).
|
||||
|
||||
> ✅ Past bij MVP: minimale libs, AI‑calls server‑side, EU‑dataregio (Supabase EU), TipTap voor rijke tekst.
|
||||
|
||||
---
|
||||
|
||||
## 1) Architectuur
|
||||
|
||||
### 1.1 Overzicht
|
||||
|
||||
```
|
||||
Browser (UI)
|
||||
└─ Next.js (App Router)
|
||||
├─ Supabase (PostgreSQL + Auth + Storage)
|
||||
├─ Claude AI (Anthropic)
|
||||
└─ (Stretch) PDF service (Chromium in serverless)
|
||||
```
|
||||
|
||||
* **Server‑side AI‑calls**: keys blijven op de server; UI krijgt alleen resultaten.
|
||||
* **Dataflow (kern)**: Intake (TipTap) → AI‑samenvat → AI‑extract → Probleemprofiel → AI‑plan → Plan (concept → publiceer).
|
||||
|
||||
### 1.2 Routing & lagen
|
||||
|
||||
* **Pages** (App Router): `/clients`, `/clients/[id]` (tabs: overzicht/intakes/profiel/plan).
|
||||
* **API** (Next.js Route Handlers): `/api/clients`, `/api/intakes`, `/api/problem-profile`, `/api/treatment-plan`, `/api/ai/*`.
|
||||
|
||||
### 1.3 State
|
||||
|
||||
De state van de applicatie wordt beheerd met **React Context API** + **Zustand** (lichtgewicht state library). Dit is eenvoudig genoeg voor de MVP-scope. State wordt georganiseerd in `src/lib/stores/` of `src/contexts/`.
|
||||
|
||||
* **`clientStore.ts` (Zustand)**: Beheert de state gerelateerd aan cliëntdata.
|
||||
* `selectedClientId: string | null`: Houdt het ID van de actieve cliënt bij. Dit is de centrale spil van de applicatie-staat.
|
||||
* `clients: Client[]`: De lijst van alle cliënten voor de overzichtspagina.
|
||||
* `currentClientDossier: Dossier | null`: Reageert op wijzigingen in `selectedClientId`. Wanneer de ID verandert, haalt de store automatisch de volledige dossierinhoud (intakes, profiel, plan) op via Supabase.
|
||||
|
||||
* **`uiStore.ts` (Zustand)**: Beheert globale UI-state.
|
||||
* `toasts: ToastMessage[]`: Een array met actieve 'toast'-notificaties die globaal getoond kunnen worden.
|
||||
|
||||
* **Dataflow Patroon**:
|
||||
1. De UI update `selectedClientId` via Zustand action.
|
||||
2. De store triggert een Supabase query om dossierdata op te halen.
|
||||
3. React componenten die subscribed zijn via `useClientStore()` updaten automatisch.
|
||||
|
||||
* **Alternatief (MVP)**: Voor kleinere state kan ook React Context + `useState` volstaan zonder externe library.
|
||||
|
||||
Dit patroon zorgt voor een efficiënte, voorspelbare en reactieve dataflow door de hele applicatie.
|
||||
|
||||
---
|
||||
|
||||
## 2) Data‑model (Supabase / PostgreSQL)
|
||||
|
||||
### 2.1 Entiteiten
|
||||
|
||||
* **clients** — basisgegevens
|
||||
* **intake\_notes** — TipTap JSON + afgeleide velden
|
||||
* **problem\_profiles** — DSM‑light categorie + severity
|
||||
* **treatment\_plans** — JSONB plan (doelen/interventies/frequentie/meetmomenten), versie/status
|
||||
* **ai\_events** — prompts/completions (telemetrie, debugging)
|
||||
* *(Stretch)* **appointments**, **reports**
|
||||
|
||||
### 2.2 Relaties (PostgreSQL)
|
||||
|
||||
```
|
||||
clients (id UUID PRIMARY KEY)
|
||||
├── intake_notes (client_id → clients.id, FK)
|
||||
├── problem_profiles (client_id → clients.id, FK)
|
||||
└── treatment_plans (client_id → clients.id, FK)
|
||||
|
||||
ai_events (id UUID PRIMARY KEY, client_id + note_id als optionele FKs)
|
||||
```
|
||||
|
||||
**Row Level Security (RLS)**: Alle tables hebben RLS policies voor auth.users().
|
||||
|
||||
### 2.3 Tables (PostgreSQL schema)
|
||||
|
||||
> **NB**: Enums als TEXT met CHECK constraints; plan inhoud als JSONB voor flexibiliteit in MVP.
|
||||
|
||||
```typescript
|
||||
// PostgreSQL Tables Schema (TypeScript types)
|
||||
|
||||
// clients table
|
||||
interface Client {
|
||||
id: string; // UUID (auto-generated)
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
birth_date: string; // DATE (ISO 8601: YYYY-MM-DD)
|
||||
created_at: string; // TIMESTAMPTZ
|
||||
updated_at: string; // TIMESTAMPTZ
|
||||
}
|
||||
|
||||
// intake_notes table
|
||||
interface IntakeNote {
|
||||
id: string; // UUID
|
||||
client_id: string; // FK → clients.id
|
||||
title?: string;
|
||||
tag: 'Intake' | 'Evaluatie' | 'Plan'; // TEXT with CHECK
|
||||
content_json: object; // JSONB (ProseMirror document)
|
||||
content_text?: string; // TEXT (for full-text search)
|
||||
author?: string; // FK → auth.users.id (optioneel)
|
||||
created_at: string; // TIMESTAMPTZ
|
||||
updated_at: string; // TIMESTAMPTZ
|
||||
}
|
||||
|
||||
// problem_profiles table
|
||||
interface ProblemProfile {
|
||||
id: string; // UUID
|
||||
client_id: string; // FK → clients.id
|
||||
category: 'stemming_depressie' | 'angst' | 'gedrag_impuls' |
|
||||
'middelen_gebruik' | 'cognitief' | 'context_psychosociaal'; // TEXT with CHECK
|
||||
severity: 'laag' | 'middel' | 'hoog'; // TEXT with CHECK
|
||||
remarks?: string; // TEXT
|
||||
source_note_id?: string; // FK → intake_notes.id
|
||||
created_at: string; // TIMESTAMPTZ
|
||||
updated_at: string; // TIMESTAMPTZ
|
||||
}
|
||||
|
||||
// treatment_plans table
|
||||
interface TreatmentPlan {
|
||||
id: string; // UUID
|
||||
client_id: string; // FK → clients.id
|
||||
version: number; // INTEGER
|
||||
status: 'concept' | 'gepubliceerd'; // TEXT with CHECK
|
||||
plan: { // JSONB
|
||||
doelen: string[];
|
||||
interventies: string[];
|
||||
frequentie: string;
|
||||
meetmomenten: string[];
|
||||
};
|
||||
created_by?: string; // FK → auth.users.id
|
||||
created_at: string; // TIMESTAMPTZ
|
||||
published_at?: string; // TIMESTAMPTZ
|
||||
updated_at: string; // TIMESTAMPTZ
|
||||
}
|
||||
|
||||
// ai_events table (telemetrie)
|
||||
interface AiEvent {
|
||||
id: string; // UUID
|
||||
kind: 'summarize' | 'readability' | 'extract' | 'plan'; // TEXT with CHECK
|
||||
client_id?: string; // FK → clients.id (nullable)
|
||||
note_id?: string; // FK → intake_notes.id (nullable)
|
||||
request: object; // JSONB
|
||||
response: object; // JSONB
|
||||
duration_ms: number; // INTEGER
|
||||
created_at: string; // TIMESTAMPTZ
|
||||
}
|
||||
```
|
||||
|
||||
**SQL voorbeelden** voor table creation beschikbaar in `/supabase/migrations/`.
|
||||
**Supabase TypeScript types** kunnen automatisch gegenereerd worden via `supabase gen types typescript`.
|
||||
|
||||
### 2.4 Row Level Security (basis)
|
||||
|
||||
Voor demo kunnen RLS policies simpel zijn: **alle rows zichtbaar voor authenticated users**. In productie: per organisatie/therapeut scheiden met `org_id` kolom.
|
||||
|
||||
```sql
|
||||
-- Demo RLS policies (apply to all tables)
|
||||
-- Enable RLS
|
||||
ALTER TABLE clients ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE intake_notes ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE problem_profiles ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE treatment_plans ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE ai_events ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Authenticated users kunnen alles lezen/schrijven (demo only!)
|
||||
CREATE POLICY "Allow all for authenticated users" ON clients
|
||||
FOR ALL USING (auth.uid() IS NOT NULL);
|
||||
|
||||
CREATE POLICY "Allow all for authenticated users" ON intake_notes
|
||||
FOR ALL USING (auth.uid() IS NOT NULL);
|
||||
|
||||
CREATE POLICY "Allow all for authenticated users" ON problem_profiles
|
||||
FOR ALL USING (auth.uid() IS NOT NULL);
|
||||
|
||||
CREATE POLICY "Allow all for authenticated users" ON treatment_plans
|
||||
FOR ALL USING (auth.uid() IS NOT NULL);
|
||||
|
||||
CREATE POLICY "Allow all for authenticated users" ON ai_events
|
||||
FOR ALL USING (auth.uid() IS NOT NULL);
|
||||
```
|
||||
|
||||
**Productie**: Voeg `org_id` toe en filter op `auth.jwt() ->> 'org_id'`.
|
||||
|
||||
---
|
||||
|
||||
## 3) API & Endpoints (Next.js Route Handlers)
|
||||
|
||||
### 3.1 CRUD
|
||||
|
||||
* `POST /api/clients` — create
|
||||
|
||||
* `GET /api/clients?query=` — list/search
|
||||
|
||||
* `GET /api/clients/:id` — detail
|
||||
|
||||
* `PATCH /api/clients/:id` — update
|
||||
|
||||
* `POST /api/intakes` — create intake
|
||||
|
||||
* `GET /api/intakes?clientId=` — list
|
||||
|
||||
* `GET /api/intakes/:id` — detail
|
||||
|
||||
* `PATCH /api/intakes/:id` — update
|
||||
|
||||
* `POST /api/problem-profile` — create/update current
|
||||
|
||||
* `GET /api/problem-profile?clientId=` — latest
|
||||
|
||||
* `POST /api/treatment-plan` — create (concept)
|
||||
|
||||
* `PATCH /api/treatment-plan/:id/publish` — publish vN
|
||||
|
||||
### 3.2 AI‑acties
|
||||
|
||||
* `POST /api/ai/summarize` — TipTap JSON → bullets
|
||||
* `POST /api/ai/readability` — TipTap JSON → B1
|
||||
* `POST /api/ai/extract` — TipTap JSON → {category, severity, rationale}
|
||||
* `POST /api/ai/generate-plan` — {noteId | profile} → plan JSON
|
||||
|
||||
**Patroon**: alle AI‑endpoints valideren input, roepen Claude API aan server‑side, loggen in `ai_events`, geven **preview** terug. UI beslist *Insert/Apply*.
|
||||
|
||||
---
|
||||
|
||||
## 4) AI‑integratie (Claude / Anthropic)
|
||||
|
||||
### 4.1 Model & API
|
||||
|
||||
* **Model**: Claude 3.5 Sonnet (of nieuwere versie) via Anthropic API.
|
||||
* **Regio**: Anthropic API is globally distributed; data blijft binnen EU waar mogelijk.
|
||||
* **SDK**: `@anthropic-ai/sdk` (officiële Node.js SDK).
|
||||
|
||||
### 4.2 Prompt‑templates (schets)
|
||||
|
||||
* **Summarize**: *“Vat het onderstaande intake‑verslag samen in 5–8 bullets. Schrijf in NL, klinisch neutraal, zonder PII.”*
|
||||
* **Readability (B1)**: *“Herschrijf leesbaar op B1‑niveau. Behoud medische betekenis, vermijd jargon waar mogelijk.”*
|
||||
* **Extract**: *"Haal uit de tekst: DSM‑light categorie (uit 6), severity (laag/middel/hoog), met korte toelichting en quote‑bronnen."*
|
||||
* **Plan**: *"Genereer behandelplan (Doelen, Interventies, Frequentie/Duur, Meetmomenten) op basis van intake/profiel. SMART‑formuleer doelen."*
|
||||
|
||||
**Parameters (startwaarden)**:
|
||||
- `model`: "claude-3-5-sonnet-20241022" (of nieuwer)
|
||||
- `temperature`: 0.3 (deterministischer)
|
||||
- `max_tokens`: passend per taak (samenvat 800–1200, plan 1600–2400)
|
||||
|
||||
**Veiligheid**: PII-verwijdering in post-processing (heuristiek); gebruik system prompt voor extra context guards.
|
||||
|
||||
---
|
||||
|
||||
## 5) Frontend implementatie
|
||||
|
||||
### 5.1 UI‑skelet
|
||||
|
||||
* **Layout**: Topbar (cliëntcontext) + LeftNav (dossier) + Main (detail) + Toast area.
|
||||
* **Componenten**: Button, Card, Input, Select, Tabs, Badge, Dialog, Drawer, Toast, Tooltip, Breadcrumb.
|
||||
|
||||
### 5.2 TipTap
|
||||
|
||||
* **Nodes**: paragraph, heading, bold/italic/underline, bullet/ordered list, blockquote, code (optioneel).
|
||||
* **Opslag**: `content_json` (ProseMirror doc).
|
||||
* **AI‑Right‑rail**: tabs: Samenvatten, B1, Extract; acties **Preview → Insert**.
|
||||
|
||||
### 5.4 Haalbaarheidsonderzoek: AI Source Highlighting
|
||||
|
||||
Een belangrijke UX-vereiste is het visueel aanduiden (highlighten) van de bronzinnen in de intaketekst die de AI heeft gebruikt voor een suggestie. Dit is technisch goed haalbaar.
|
||||
|
||||
**Aanpak:**
|
||||
|
||||
1. **Backend API Aanpassing**: Het AI-endpoint (bv. `/api/ai/extract`) moet niet alleen de suggestie retourneren, maar ook een array van de exacte bronzinnen (`sourceSentences: string[]`).
|
||||
2. **Frontend TipTap Implementatie**:
|
||||
* De frontend gebruikt de [TipTap Decorations API](https://tiptap.dev/api/decorations) om de highlighting te realiseren. Decorations passen styling toe zonder de onderliggende content te wijzigen.
|
||||
* Bij ontvangst van de `sourceSentences` doorzoekt de frontend het TipTap-document naar de posities (`from`, `to`) van deze zinnen.
|
||||
* Voor elke gevonden positie wordt een `Decoration.inline(from, to, { class: 'ai-source-highlight' })` aangemaakt.
|
||||
3. **Styling**: Een simpele CSS-klasse `.ai-source-highlight` (bv. met een lichtgele achtergrond) wordt toegevoegd aan de globale stylesheet.
|
||||
4. **Lifecycle**: De highlights worden gewist zodra de gebruiker de suggestie accepteert, negeert, of een nieuwe AI-actie initieert.
|
||||
|
||||
**Conclusie**: De aanpak is robuust en de complexiteit is laag tot gemiddeld. Het wordt meegenomen in de PoC voor de TipTap-editor.
|
||||
|
||||
### 5.3 Toetsenbord & UX
|
||||
|
||||
* `Ctrl/Cmd+S` opslaan, `Ctrl/Cmd+K` zoek, `Ctrl/Cmd+N` nieuw verslag.
|
||||
* Leeg‑staten met CTA’s; skeletons bij laden; non‑blocking spinners bij AI.
|
||||
|
||||
---
|
||||
|
||||
## 6) Security, Privacy & Compliance (MVP‑proof)
|
||||
|
||||
* **Data**: uitsluitend fictieve demo‑data; geen echte PII.
|
||||
* **Regio's**: EU‑hosting (Supabase EU: Frankfurt/London; Claude API global).
|
||||
* **Secret handling**: API keys via Vercel Envs; nooit in client bundelen.
|
||||
* **RLS Policies**: minimaal aan; authenticated users krijgen toegang (demo).
|
||||
* **Audit (lichtgewicht)**: `ai_events` + timestamps op alle tables.
|
||||
* **CORS**: beperken tot demo‑domain.
|
||||
|
||||
---
|
||||
|
||||
## 7) Deployment & Environments
|
||||
|
||||
* **Dev**: `.env.local` met Supabase keys + Claude API key
|
||||
* **Preview/Prod**: Vercel project → `VERCEL_ENV` gates; RLS policies via Supabase migrations.
|
||||
* **Supabase**: EU-regio (Frankfurt of London), schema deploy via `supabase db push` of migrations.
|
||||
|
||||
### 7.1 Environment variables (voorbeeld)
|
||||
|
||||
```bash
|
||||
# Supabase
|
||||
NEXT_PUBLIC_SUPABASE_URL=https://xyz.supabase.co
|
||||
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ... # Public anon key (frontend safe)
|
||||
SUPABASE_SERVICE_ROLE_KEY=eyJ... # Service role key (server only!)
|
||||
|
||||
# Claude AI
|
||||
ANTHROPIC_API_KEY=sk-ant-... # Claude API key (server only!)
|
||||
|
||||
# App
|
||||
NEXT_PUBLIC_APP_URL=https://mini-ecd.example
|
||||
NODE_ENV=production
|
||||
```
|
||||
|
||||
**Security**:
|
||||
- `SUPABASE_SERVICE_ROLE_KEY` en `ANTHROPIC_API_KEY` alleen server-side gebruiken
|
||||
- Vercel Environment Variables voor productie
|
||||
- Gebruik `.env.local` voor lokale ontwikkeling (niet in git!)
|
||||
|
||||
---
|
||||
|
||||
## 8) Setup stappen (korte gids)
|
||||
|
||||
1. **Repo & deps**: init Next.js (App Router) + Tailwind + TipTap + Supabase client + Anthropic SDK.
|
||||
2. **Supabase**: project aanmaken (EU-regio) → Tables uit §2.3 aanmaken via migrations → RLS policies activeren.
|
||||
3. **Env**: Vercel + lokale `.env.local` vullen (Supabase keys + Claude API key).
|
||||
4. **Endpoints**: CRUD + AI‑routes implementeren als Next.js Route Handlers (server‑side).
|
||||
5. **Screens**: Clients list/detail, Intake editor + AI‑rail, Profiel form, Plan cards.
|
||||
6. **Smoke test**: Flow A/B/C end‑to‑end met mock data.
|
||||
7. **(Optioneel)** PDF export & afspraken tab.
|
||||
|
||||
---
|
||||
|
||||
## 9) Test & Kwaliteit
|
||||
|
||||
* **Unit**: parsers, validators, AI‑response mappers (Zod schemas).
|
||||
* **E2E (Playwright)**: Flow A/B/C met seeded data.
|
||||
* **Prompt tests**: vaste inputs → snapshot op kernvelden (niet volledige tekst).
|
||||
|
||||
---
|
||||
|
||||
## 10) Bekende beperkingen & risico's
|
||||
|
||||
* **TipTap** content search: extra index/afgeleide `content_text` nodig voor snelle zoek (PostgreSQL full-text search).
|
||||
* **Claude API rate limits**: monitor gebruik; overweeg caching voor veelvoorkomende prompts.
|
||||
* **Serverless PDF**: kan cold‑start of memory issues geven → overweeg queue/edge function.
|
||||
* **RLS Policies (demo)**: simplistisch; voor productie per organisatie/rol modelleren met `org_id`.
|
||||
|
||||
---
|
||||
|
||||
## 11) Wat ontbrak nog in je stack (aanvullingen)
|
||||
|
||||
* **Tailwind CSS** (UI‑basis) en **iconen (lucide-react)**.
|
||||
* **Auth**: Supabase Auth (magic link, email/password, of OAuth).
|
||||
* **Validatie**: **Zod** voor request/response schemas.
|
||||
* **Logging**: lichte audit via `ai_events` table + Next.js middleware.
|
||||
* **Testing**: Vitest/Playwright.
|
||||
* **PDF (stretch)**: keuze voor renderer (Puppeteer/Playwright).
|
||||
* **Type‑safety**: Supabase auto-generated types via `supabase gen types typescript`.
|
||||
|
||||
---
|
||||
|
||||
## 12) Roadmap na demo
|
||||
|
||||
* Rollen & rechten, multi‑tenant (org\_id) + stricte RLS policies.
|
||||
* Templates per zorgpad (verslag/plan).
|
||||
* Trendanalyse (meetmomenten) + grafieken.
|
||||
* Integraties (PinkRoccade modules), exportprofielen.
|
||||
* Real-time collaboratie via Supabase Realtime (optioneel).
|
||||
|
||||
---
|
||||
194
docs/specs/ux-stylesheet.md
Normal file
194
docs/specs/ux-stylesheet.md
Normal file
@@ -0,0 +1,194 @@
|
||||
# 🎨 Kleur Stylesheet – Mini‑ECD (v2, UX‑geoptimaliseerd)
|
||||
|
||||
> Doel: consistente, toegankelijke kleuren met **lage cognitieve belasting**. Accentpalet teruggebracht tot **3 modules** (Afspraken, Medicatie/Herinneringen, Lab/Resultaten). Inclusief duidelijke states en contrastrichtlijnen.
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Basiskleuren
|
||||
|
||||
* **App‑achtergrond**: `#F8FAFC`
|
||||
* **Oppervlak (kaarten/modals)**: `#FFFFFF`
|
||||
* **Sub‑oppervlak** (sekundair paneel/right‑rail): `#F1F5F9`
|
||||
* **Tekst primair**: `#0F172A`
|
||||
* **Tekst secundair**: `#475569`
|
||||
* **Borders/Dividers**: `#E2E8F0`
|
||||
|
||||
**WCAG tip:** tekst op witte of zachte pastelfondsen ≥ `#0F172A` / `#1E293B` voor AA‑contrast.
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Merk & Primaire UI
|
||||
|
||||
* **Primary / Brand**: `#3B82F6`
|
||||
|
||||
* Hover: `#2563EB`
|
||||
* Active: `#1D4ED8`
|
||||
* Subtle bg (chips, empty‑states): `#EFF6FF`
|
||||
* On‑Primary text/icon: `#FFFFFF`
|
||||
|
||||
* **Neutral CTA (secundair/terug)**: `#334155`
|
||||
|
||||
* Hover: `#1F2937`
|
||||
* On‑Neutral: `#FFFFFF`
|
||||
|
||||
---
|
||||
|
||||
## 📊 Module‑accenten (gereduceerd)
|
||||
|
||||
Gebruik **max. drie** accentfamilies. Pastel voor kaarten + een verzadigd accent voor iconen/teksten.
|
||||
|
||||
1. **Afspraken**
|
||||
|
||||
* Card bg: `#E8F8EF`
|
||||
* Accent (icon/label): `#16A34A`
|
||||
* Border: `#CDECDC`
|
||||
|
||||
2. **Medicatie / Herinneringen**
|
||||
|
||||
* Card bg: `#FEF6DC`
|
||||
* Accent: `#F59E0B`
|
||||
* Border: `#F6E7B6`
|
||||
|
||||
3. **Lab / Resultaten**
|
||||
|
||||
* Card bg: `#FFEBDC`
|
||||
* Accent: `#F97316`
|
||||
* Border: `#FFD2B8`
|
||||
|
||||
> **Toegankelijkheid:** tekst op pastelkaarten in **donkergrijs `#0F172A`**. Accentkleur enkel voor iconen/badges/kleine headings.
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Status & Feedback
|
||||
|
||||
* **Success**: `#16A34A`
|
||||
* **Warning**: `#EAB308`
|
||||
* **Error**: `#DC2626`
|
||||
* **Info**: `#3B82F6`
|
||||
|
||||
**Subtle backgrounds**
|
||||
|
||||
* Success subtle: `#ECFDF5`
|
||||
* Warning subtle: `#FEFCE8`
|
||||
* Error subtle: `#FEF2F2`
|
||||
* Info subtle: `#EFF6FF`
|
||||
|
||||
**Toasts/alerts**
|
||||
|
||||
* Tekst: `#0F172A`
|
||||
* Icon: statuskleur
|
||||
* Border: statuskleur op 30% (bijv. mix met wit)
|
||||
|
||||
---
|
||||
|
||||
## 🏷️ Badges & Labels (Severity DSM‑light)
|
||||
|
||||
* **Laag**: bg `#E5E7EB`, text `#374151`
|
||||
* **Middel**: bg `#FEF3C7`, text `#92400E`
|
||||
* **Hoog**: bg `#FEE2E2`, text `#991B1B`
|
||||
|
||||
---
|
||||
|
||||
## ✍️ Formulieren & Invoervelden
|
||||
|
||||
* **Input bg**: `#FFFFFF`
|
||||
* **Input text**: `#0F172A`
|
||||
* **Placeholder**: `#94A3B8`
|
||||
* **Border default**: `#CBD5E1`
|
||||
* **Border hover**: `#94A3B8`
|
||||
* **Focus**: 2px ring `#3B82F6` + 1px inset border `#2563EB`
|
||||
* **Disabled**: bg `#F1F5F9`, text `#94A3B8`, border `#E2E8F0`
|
||||
* **Invalid**: border `#DC2626`, help‑text `#B91C1C`
|
||||
|
||||
**Select/Dropdown**
|
||||
|
||||
* Menu bg: `#FFFFFF`
|
||||
* Hover option: `#F1F5F9`
|
||||
* Active/selected: left bar `#3B82F6`
|
||||
|
||||
---
|
||||
|
||||
## 🧩 Component‑states (Buttons/Links/Cards)
|
||||
|
||||
**Primary button**
|
||||
|
||||
* Default: bg `#3B82F6`, text `#FFFFFF`
|
||||
* Hover: bg `#2563EB`
|
||||
* Active: bg `#1D4ED8`
|
||||
* Disabled: bg `#BFDBFE`, text `#FFFFFF` @ 70%
|
||||
|
||||
**Secondary button**
|
||||
|
||||
* Default: bg `#334155`, text `#FFFFFF`
|
||||
* Hover: bg `#1F2937`
|
||||
* Disabled: bg `#CBD5E1`, text `#FFFFFF` @ 60%
|
||||
|
||||
**Ghost button**
|
||||
|
||||
* Text: `#334155`; hover bg: `#F1F5F9`
|
||||
|
||||
**Links**
|
||||
|
||||
* Default: `#2563EB`
|
||||
* Hover/Focus: underline + `#1D4ED8`
|
||||
* Visited: `#4F46E5`
|
||||
|
||||
**Cards**
|
||||
|
||||
* Default: bg `#FFFFFF`, border `#E2E8F0`, shadow sm
|
||||
* Hoverable variant: shadow md + translateY(‑1px)
|
||||
|
||||
---
|
||||
|
||||
## 🗺️ Navigatie
|
||||
|
||||
* **Sidebar item**
|
||||
|
||||
* Default text: `#334155`
|
||||
* Active: text `#0F172A`, bg `#E2E8F0`, left accent bar `#3B82F6`
|
||||
* Disabled: text `#94A3B8`
|
||||
|
||||
* **Topbar**
|
||||
|
||||
* Bg: `#FFFFFF`, border‑bottom: `#E2E8F0`
|
||||
|
||||
---
|
||||
|
||||
## 🌫️ Elevation & Focus
|
||||
|
||||
* **Shadows**
|
||||
|
||||
* sm: `0 1px 2px rgba(15,23,42,0.06)`
|
||||
* md: `0 2px 6px rgba(15,23,42,0.08)`
|
||||
* lg: `0 8px 20px rgba(15,23,42,0.10)`
|
||||
|
||||
* **Focus ring (universeel)**: 2px `#3B82F6` buiten het element + 1px contrast‑border.
|
||||
|
||||
---
|
||||
|
||||
## ♿ Toegankelijkheidsrichtlijnen
|
||||
|
||||
* Minimale contrastverhouding **AA**:
|
||||
|
||||
* Body‑tekst op wit ≥ 4.5:1 (gebruik `#0F172A`/`#1E293B`)
|
||||
* Tekst op gekleurde knoppen altijd **wit** (`#FFFFFF`) en check contrast.
|
||||
* Gebruik niet alleen kleur: combineer status met **icoon**, **label** of **shape**.
|
||||
* Focus is altijd zichtbaar (geen `outline: none`).
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Semantische tokens (aliasing)
|
||||
|
||||
Gebruik semantische namen in code i.p.v. ruwe HEX‑waarden:
|
||||
|
||||
* `--color-bg`, `--color-surface`, `--color-text`, `--color-border`
|
||||
* `--color-brand`, `--color-brand-hover`, `--color-info`, `--color-success`, `--color-warning`, `--color-error`
|
||||
* `--color-module-appointments`, `--color-module-meds`, `--color-module-labs`
|
||||
|
||||
---
|
||||
|
||||
## 📌 Notities
|
||||
|
||||
* Accentpalet bewust klein gehouden → minder visuele ruis, sneller scannen.
|
||||
* Kaarten tonen **accent** alleen in icoon/badge of kleine titel; content blijft donker op licht voor leesbaarheid.
|
||||
* Voor donker thema kunnen bovenstaande waarden gespiegeld worden met lichtere teksten en donkerder oppervlakken.
|
||||
Reference in New Issue
Block a user