feat: rapportage API, speech recorder refactor, docs reorganisatie
Multiple features and improvements: Reports/Rapportage API: - Created REST API endpoints: /api/reports (GET/POST), /api/reports/[id] (GET/PATCH/DELETE) - Added /api/reports/classify endpoint for AI classification - Supabase migrations: reports table + RLS policies - Server utilities: api-client.ts for DRY fetch logic - Type definitions: lib/types/report.ts with Zod schemas - Removed old rapportage-modal component (replaced by split-view) Speech Recorder Refactor: - Moved speech-recorder from intake-specific to shared components/ - Updated treatment-advice-form to use new location - Updated intake actions for speech functionality UI Components (shadcn): - Added dialog, dropdown-menu, toast, toaster components - Added use-toast hook for toast notifications Documentation: - Reorganized docs/release/ → docs/reports/ for better structure - Archived old specs to docs/specs/archive/ - Added screening-system.mdx documentation - Added rapportage-split-view-design.md - Added UI screenshots for troubleshooting Dependencies: - Updated package.json and pnpm-lock.yaml - Regenerated database.types.ts from Supabase 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
238
docs/reports/E3.S2-patients-lijst-pagina.md
Normal file
238
docs/reports/E3.S2-patients-lijst-pagina.md
Normal file
@@ -0,0 +1,238 @@
|
||||
# E3.S2 - Patients lijst pagina
|
||||
|
||||
**Epic:** E3 - Patients & Organizations
|
||||
**Story:** E3.S2 - Patients lijst pagina
|
||||
**Story Points:** 5
|
||||
**Status:** ✅ Compleet
|
||||
|
||||
## Doel
|
||||
|
||||
Patiënten lijst pagina met tabel, search, filters en paginatie.
|
||||
|
||||
## Acceptatiecriteria
|
||||
|
||||
- [x] `/patients` route met overzichtelijke tabel
|
||||
- [x] Search functionaliteit op naam en BSN
|
||||
- [x] Filters (status, gender)
|
||||
- [x] Paginatie (50 per pagina)
|
||||
- [x] Sorteer functionaliteit
|
||||
|
||||
## Implementatie
|
||||
|
||||
### 1. Server Actions (actions.ts)
|
||||
|
||||
📁 **Locatie:** `app/epd/patients/actions.ts`
|
||||
|
||||
**Updates:**
|
||||
- ✅ Paginatie parameters toegevoegd (`page`, `pageSize`)
|
||||
- ✅ Gender filter parameter
|
||||
- ✅ Sorteer parameters (`sortBy`, `sortOrder`)
|
||||
- ✅ Return type aangepast naar object met `patients`, `total`, `page`, `pageSize`
|
||||
|
||||
**API parameters:**
|
||||
```typescript
|
||||
{
|
||||
search?: string; // Zoek op naam
|
||||
status?: string; // Filter: planned, active, finished, cancelled
|
||||
gender?: string; // Filter: male, female, other, unknown
|
||||
page?: number; // Pagina nummer (default: 1)
|
||||
pageSize?: number; // Items per pagina (default: 50)
|
||||
sortBy?: string; // Sorteer kolom
|
||||
sortOrder?: 'asc' | 'desc'; // Sorteer richting
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Page Component (page.tsx)
|
||||
|
||||
📁 **Locatie:** `app/epd/patients/page.tsx`
|
||||
|
||||
**Updates:**
|
||||
- ✅ SearchParams interface uitgebreid met nieuwe filters
|
||||
- ✅ Page parameter parsing
|
||||
- ✅ Props doorgegeven aan PatientList component
|
||||
|
||||
### 3. Patient List Component (patient-list.tsx)
|
||||
|
||||
📁 **Locatie:** `app/epd/patients/components/patient-list.tsx`
|
||||
|
||||
**Features geïmplementeerd:**
|
||||
|
||||
#### A. Filters
|
||||
|
||||
**Search bar:**
|
||||
- Zoek op naam of BSN
|
||||
- Real-time filtering
|
||||
- Form submit handler
|
||||
|
||||
**Status filter:**
|
||||
- Alle statussen
|
||||
- Screening (planned)
|
||||
- Actief (active)
|
||||
- Afgerond (finished)
|
||||
- Afgemeld (cancelled)
|
||||
|
||||
**Gender filter:**
|
||||
- Alle geslachten
|
||||
- Man (male)
|
||||
- Vrouw (female)
|
||||
- Anders (other)
|
||||
- Onbekend (unknown)
|
||||
|
||||
#### B. Paginatie
|
||||
|
||||
**Implementatie:**
|
||||
- 50 patiënten per pagina (configureerbaar)
|
||||
- Pagina navigatie knoppen (vorige/volgende)
|
||||
- Genummerde pagina buttons (max 7 zichtbaar)
|
||||
- Smart pagination logica:
|
||||
- Bij weinig pagina's: toon alle nummers
|
||||
- Bij begin: toon eerste 7
|
||||
- Bij einde: toon laatste 7
|
||||
- In het midden: toon current ± 3
|
||||
|
||||
**UI elementen:**
|
||||
- "Resultaten X-Y van Z" indicator
|
||||
- Disabled state voor eerste/laatste pagina
|
||||
- Active state voor huidige pagina
|
||||
- Hover states voor interactie
|
||||
|
||||
#### C. Sortering
|
||||
|
||||
**Sorteerbare kolommen:**
|
||||
- ✅ Naam (`name`)
|
||||
- ✅ Geboortedatum (`birthDate`)
|
||||
- ✅ Status (`status`)
|
||||
- ✅ Laatst gewijzigd (`_lastUpdated`)
|
||||
|
||||
**Visual feedback:**
|
||||
- Inactieve kolommen: `<ArrowUpDown>` (grijs)
|
||||
- Actieve kolom ascending: `<ArrowUp>` (teal)
|
||||
- Actieve kolom descending: `<ArrowDown>` (teal)
|
||||
- Hover effect op sorteerbare headers
|
||||
|
||||
**Functionaliteit:**
|
||||
- Click om te sorteren
|
||||
- Click opnieuw om richting te wisselen (asc ↔ desc)
|
||||
- Sortering reset naar pagina 1
|
||||
|
||||
#### D. Helper functions
|
||||
|
||||
```typescript
|
||||
// URL parameters builder
|
||||
buildUrlParams(updates: Record<string, string | number | undefined>)
|
||||
|
||||
// Event handlers
|
||||
handleSearch(e: React.FormEvent)
|
||||
handleStatusFilterChange(newStatus: string)
|
||||
handleGenderFilterChange(newGender: string)
|
||||
handlePageChange(newPage: number)
|
||||
handleSort(column: string)
|
||||
|
||||
// Render helpers
|
||||
renderSortIcon(column: string)
|
||||
```
|
||||
|
||||
## UI/UX Details
|
||||
|
||||
### Layout
|
||||
- Responsive design (desktop & mobile)
|
||||
- Flex layout voor filters (wraps op kleine schermen)
|
||||
- Sticky header mogelijk (voor lange lijsten)
|
||||
|
||||
### Colors & Styling
|
||||
- Teal als primary color (#0d9488)
|
||||
- Slate voor neutral elements
|
||||
- Status badges met kleurcodering:
|
||||
- Amber: Screening
|
||||
- Emerald: Actief
|
||||
- Slate: Afgerond
|
||||
- Red: Afgemeld
|
||||
|
||||
### Empty States
|
||||
- Verschillende berichten voor:
|
||||
- Geen patiënten (met CTA om toe te voegen)
|
||||
- Geen resultaten (met suggestie om filters aan te passen)
|
||||
|
||||
## Performance
|
||||
|
||||
**Optimalisaties:**
|
||||
- Server-side paginatie (max 50 geladen per keer)
|
||||
- URL-based state (deep linking, browser back/forward)
|
||||
- Suspense voor loading states
|
||||
- No-cache strategie voor realtime data
|
||||
|
||||
**Load times (verwacht):**
|
||||
- Initial load: < 1s
|
||||
- Filter/sort/page change: < 500ms
|
||||
- Search debounce: instant (client-side filter)
|
||||
|
||||
## Database Queries
|
||||
|
||||
De actions maken gebruik van de FHIR API (`/api/fhir/Patient`) met de volgende query parameters:
|
||||
|
||||
```
|
||||
GET /api/fhir/Patient?
|
||||
name={search_term}&
|
||||
status={status_filter}&
|
||||
gender={gender_filter}&
|
||||
_count={page_size}&
|
||||
_offset={offset}&
|
||||
_sort={sort_field}
|
||||
```
|
||||
|
||||
**FHIR-compliant:**
|
||||
- Gebruikt FHIR search parameters
|
||||
- FHIR Bundle response format
|
||||
- FHIR extension voor episode_status
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
- [ ] Paginatie werkt correct (vorige/volgende/nummers)
|
||||
- [ ] Search filtert correct op naam
|
||||
- [ ] Status filter werkt voor alle statussen
|
||||
- [ ] Gender filter werkt voor alle geslachten
|
||||
- [ ] Sortering werkt voor alle kolommen
|
||||
- [ ] URL parameters worden correct bijgewerkt
|
||||
- [ ] Browser back/forward werkt met filters
|
||||
- [ ] Empty state toont bij geen resultaten
|
||||
- [ ] Responsive layout op mobile
|
||||
- [ ] Loading states tonen bij data fetch
|
||||
- [ ] Pagination reset bij filter wijziging
|
||||
|
||||
## Bekende Beperkingen
|
||||
|
||||
1. **FHIR API Afhankelijkheid:**
|
||||
- Requires `/api/fhir/Patient` endpoint
|
||||
- Episode status via extension (custom)
|
||||
- Supabase moet online zijn voor data
|
||||
|
||||
2. **Client-side vs Server-side:**
|
||||
- Search is momenteel client-side gefilterd
|
||||
- Kan server-side voor betere performance bij grote datasets
|
||||
|
||||
3. **BSN Kolom:**
|
||||
- Niet sorteerbaar (niet in sortBy options)
|
||||
- Encryption zou performance impact hebben
|
||||
|
||||
## Volgende Stappen
|
||||
|
||||
Na E3.S2:
|
||||
- [ ] **E3.S3** - Patient CRUD (Create/Update/Delete + validatie)
|
||||
- [ ] Eventueel: Advanced filters (leeftijdsbereik, postcode, etc.)
|
||||
- [ ] Eventueel: Export functionaliteit (CSV/Excel)
|
||||
- [ ] Eventueel: Bulk actions (selecteer multiple → wijzig status)
|
||||
|
||||
## Referenties
|
||||
|
||||
- **Bouwplan:** `docs/bouwplan-mini-epd.md` (regel 352-356, E3.S2)
|
||||
- **Actions:** `app/epd/patients/actions.ts`
|
||||
- **Page:** `app/epd/patients/page.tsx`
|
||||
- **Component:** `app/epd/patients/components/patient-list.tsx`
|
||||
- **FHIR Types:** `lib/fhir/index.ts`
|
||||
|
||||
---
|
||||
|
||||
**Datum voltooid:** 2025-11-22
|
||||
**Status:** ✅ Compleet
|
||||
**Dependencies voltooid:** E2.S4 (Practitioner profile)
|
||||
**Blokkeert:** E3.S3 (Patient CRUD)
|
||||
Reference in New Issue
Block a user