# Mini-EPD Prototype - Architectuur

## Executive Summary (C-Level)

**Mini-EPD** is een moderne, AI-gestuurde elektronische patiëntendossier (EPD) oplossing voor de Nederlandse zorgsector. Het systeem combineert spraakherkenning met intelligente intentieherkenning, waardoor zorgverleners hands-free kunnen rapporteren en navigeren.

### Kernwaarden

| Aspect | Waarde |
|--------|--------|
| **Tijdsbesparing** | 70% van commando's verwerkt in <20ms door lokale AI |
| **Gebruiksgemak** | Natuurlijke taal en spraak als primaire input |
| **Compliance** | GDPR-vriendelijk met soft deletes en audit trail |
| **Schaalbaarheid** | Serverless architectuur, horizontaal schaalbaar |
| **Integratie** | FHIR-geïnspireerd datamodel voor interoperabiliteit |

### Strategische Voordelen

1. **Lagere administratielast** - Zorgverleners dicteren notities in natuurlijke taal; AI classificeert en structureert automatisch
2. **Proactieve ondersteuning** - Systeem suggereert vervolgacties op basis van klinische protocollen
3. **Snelle implementatie** - Cloud-native stack (Vercel + Supabase) zonder on-premise infrastructuur
4. **Toekomstbestendig** - Modulaire opzet maakt toevoeging van nieuwe functionaliteit eenvoudig

### Risico's & Mitigatie

| Risico | Mitigatie |
|--------|-----------|
| AI-hallucinaties | Drie-lagen architectuur met confidence scoring; fallback naar menselijke verificatie |
| Data privacy | Row Level Security op database niveau; geen PII in logs |
| Vendor lock-in | Open standaarden (FHIR, PostgreSQL); migratiepaden beschikbaar |

---

## Technische Architectuur

### Tech Stack

| Component | Technologie | Motivatie |
|-----------|-------------|-----------|
| Frontend | Next.js 14 (App Router) | Server-side rendering, optimale SEO, moderne DX |
| Database | Supabase (PostgreSQL) | Managed database met ingebouwde auth en RLS |
| Auth | Supabase Auth + JWT | Industrie-standaard, SSR-compatibel |
| AI Classification | Claude API (Anthropic) | State-of-the-art NLP voor Nederlands |
| Speech-to-Text | Deepgram | Lage latency, hoge nauwkeurigheid |
| State Management | Zustand | Lightweight, TypeScript-native |
| Styling | Tailwind CSS + shadcn/ui | Consistente UI, snelle ontwikkeling |

---

### Cortex: Drie-Lagen AI Architectuur

Het hart van het systeem is **Cortex**, een intelligent command center dat natuurlijke taal omzet naar gestructureerde acties.

```
┌─────────────────────────────────────────────────────────────────┐
│                        GEBRUIKER INPUT                          │
│              "Maak een dagnotitie voor Jan Bakker"              │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│                    LAYER 1: REFLEX ARC                          │
│                        Latency: <20ms                           │
├─────────────────────────────────────────────────────────────────┤
│ • Regex-gebaseerde pattern matching                             │
│ • Weighted confidence scoring                                   │
│ • Verwerkt 70%+ van alle commando's lokaal                     │
│ • Escaleert bij: confidence <0.7, multi-intent, ambiguïteit    │
└─────────────────────────────────────────────────────────────────┘
                              ↓ (indien nodig)
┌─────────────────────────────────────────────────────────────────┐
│                   LAYER 2: ORCHESTRATOR                         │
│                     Model: Claude 3.5 Haiku                     │
├─────────────────────────────────────────────────────────────────┤
│ • Multi-intent detectie ("annuleer afspraak en maak notitie")  │
│ • Pronoun resolutie met actieve patiënt context                │
│ • Relatieve tijd parsing ("morgen", "volgende week")           │
│ • Context-aware entity extraction                               │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│                      LAYER 3: NUDGE                             │
│                    Proactieve Suggesties                        │
├─────────────────────────────────────────────────────────────────┤
│ • Post-actie aanbevelingen op basis van V&VN protocollen       │
│ • Voorbeeld: Na wondnotitie → suggestie voor controle-interval │
│ • Niet-intrusief: toast notifications met dismiss optie        │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│                      UI ARTIFACT BLOCKS                         │
│           DagnotatieBlock / ZoekenBlock / OverdrachtBlock       │
└─────────────────────────────────────────────────────────────────┘
```

### Intent Types

| Intent | Beschrijving | Voorbeeld |
|--------|--------------|-----------|
| `dagnotitie` | Dagelijkse rapportage aanmaken | "Noteer dat mevrouw Jansen goed geslapen heeft" |
| `zoeken` | Patiënt opzoeken | "Zoek Jan Bakker" |
| `overdracht` | Handover bekijken | "Toon overdracht van gisteren" |
| `agenda_query` | Agenda raadplegen | "Wat staat er vandaag gepland?" |
| `create_appointment` | Afspraak inplannen | "Plan een intake voor morgen 14:00" |
| `cancel_appointment` | Afspraak annuleren | "Annuleer de afspraak van vrijdag" |
| `reschedule_appointment` | Afspraak verzetten | "Verzet de afspraak naar volgende week" |

---

### Directory Structuur

```
mini-epd-prototype/
├── app/                           # Next.js App Router
│   ├── api/                       # Backend API Routes
│   │   ├── cortex/               # AI Command Center
│   │   │   ├── classify/         # Intent classificatie
│   │   │   ├── chat/             # Streaming conversatie
│   │   │   ├── patients/         # Patiënt context
│   │   │   └── agenda/           # Agenda operaties
│   │   ├── reports/              # Rapportage CRUD
│   │   ├── overdracht/           # Handover + AI summaries
│   │   ├── patients/             # Patiënt data
│   │   ├── deepgram/             # Speech-to-text
│   │   └── fhir/                 # FHIR endpoints
│   │
│   ├── epd/                       # EPD Modules (Protected)
│   │   ├── dashboard/            # Cortex Command Center
│   │   ├── verpleegrapportage/   # Nursing reports
│   │   │   └── rapportage/       # Timeline invoer
│   │   ├── patients/[id]/        # Patiënt dossier
│   │   ├── agenda/               # Kalender (FullCalendar)
│   │   └── clients/              # Cliëntenbeheer
│   │
│   └── auth/                      # Authenticatie
│       ├── login/
│       └── reset-password/
│
├── lib/                           # Shared Business Logic
│   ├── cortex/                   # Drie-lagen AI systeem
│   │   ├── types.ts              # Type definities
│   │   ├── reflex-classifier.ts  # Layer 1: Pattern matching
│   │   ├── orchestrator.ts       # Layer 2: Claude classificatie
│   │   ├── nudge.ts              # Layer 3: Suggesties
│   │   ├── entity-extractor.ts   # Entity extraction
│   │   ├── date-time-parser.ts   # Datum/tijd parsing
│   │   └── hooks/                # React hooks
│   │
│   ├── auth/                     # Auth utilities
│   │   ├── server.ts             # Server-side (API routes)
│   │   └── client.ts             # Client-side
│   │
│   ├── supabase/                 # Database layer
│   │   ├── database.types.ts     # Auto-generated types
│   │   ├── client.ts             # Browser client
│   │   └── server.ts             # SSR client
│   │
│   └── types/                    # Domain types
│       ├── report.ts             # Rapportage types
│       └── overdracht.ts         # Handover types
│
├── components/                    # React Components
│   ├── cortex/                   # Cortex UI
│   │   ├── command-center/       # Main container
│   │   │   ├── command-center.tsx
│   │   │   ├── command-input.tsx # Voice/text input
│   │   │   ├── context-bar.tsx   # Actieve patiënt
│   │   │   ├── canvas-area.tsx   # Artifact rendering
│   │   │   └── offline-banner.tsx
│   │   ├── blocks/               # Intent-specifieke UI
│   │   │   ├── dagnotitie-block.tsx
│   │   │   ├── zoeken-block.tsx
│   │   │   └── overdracht-block.tsx
│   │   └── chat/                 # Chat componenten
│   │
│   └── ui/                       # shadcn/ui (29 componenten)
│       ├── button.tsx
│       ├── dialog.tsx
│       └── ...
│
├── stores/                        # State Management
│   └── cortex-store.ts           # Zustand store
│
├── supabase/                      # Database
│   └── migrations/               # SQL migrations
│
└── docs/                          # Documentatie
    └── swift/                    # Cortex specificaties
```

---

### Data Model

#### Reports Table (Unified)

Alle rapportages worden opgeslagen in één tabel met type-discriminatie:

```sql
CREATE TABLE reports (
  id UUID PRIMARY KEY,
  patient_id UUID REFERENCES patients(id),
  type report_type NOT NULL,           -- enum
  content TEXT,
  structured_data JSONB,               -- type-specifieke velden
  created_at TIMESTAMPTZ,
  created_by UUID REFERENCES auth.users(id),
  shift_date DATE,                     -- berekend: vóór 07:00 = vorige dag
  deleted_at TIMESTAMPTZ,              -- soft delete
  ai_confidence FLOAT,
  ai_reasoning TEXT
);
```

**Report Types:**
- `voortgang` - Voortgangsrapportage
- `observatie` - Klinische observatie
- `incident` - Incident melding
- `medicatie` - Medicatie gerelateerd
- `contact` - Contact met derden
- `crisis` - Crisis interventie
- `intake` - Intake notities
- `behandeladvies` - Behandeladvies
- `vrije_notitie` - Vrije tekst
- `verpleegkundig` - Verpleegkundige notitie (met categorie)

**Verpleegkundig Categories:**
- `medicatie`, `adl`, `gedrag`, `incident`, `observatie`

#### Shift Logic

Rapporten aangemaakt vóór 07:00 worden toegewezen aan de vorige dag (nachtdienst handover):

```typescript
function calculateShiftDate(createdAt: Date): Date {
  const hour = createdAt.getHours();
  if (hour < 7) {
    return subDays(createdAt, 1);
  }
  return createdAt;
}
```

**Diensten:**
| Dienst | Tijdvak |
|--------|---------|
| Nacht | 00:00 - 07:00 |
| Ochtend | 07:00 - 12:00 |
| Middag | 12:00 - 17:00 |
| Avond | 17:00 - 24:00 |

---

### API Endpoints

#### Cortex APIs

| Method | Endpoint | Beschrijving |
|--------|----------|--------------|
| POST | `/api/cortex/classify` | Intent classificatie (Reflex + Orchestrator) |
| POST | `/api/cortex/chat` | Streaming chat (SSE) |
| GET | `/api/cortex/context` | Huidige gebruikerscontext |
| GET | `/api/cortex/patients/search` | Patiënt zoeken voor context |
| GET | `/api/cortex/agenda` | Dagagenda ophalen |
| POST | `/api/cortex/agenda/create` | Afspraak aanmaken |
| POST | `/api/cortex/agenda/cancel` | Afspraak annuleren |
| POST | `/api/cortex/agenda/reschedule` | Afspraak verzetten |

#### Report APIs

| Method | Endpoint | Beschrijving |
|--------|----------|--------------|
| GET | `/api/reports` | Lijst rapporten (filters: type, datum, patiënt) |
| POST | `/api/reports` | Rapport aanmaken |
| GET | `/api/reports/[id]` | Enkel rapport ophalen |
| PUT | `/api/reports/[id]` | Rapport bijwerken |
| DELETE | `/api/reports/[id]` | Soft delete |

#### Overdracht APIs

| Method | Endpoint | Beschrijving |
|--------|----------|--------------|
| GET | `/api/overdracht/patients` | Patiënten voor handover |
| GET | `/api/overdracht/[patientId]` | Handover data per patiënt |
| POST | `/api/overdracht/generate` | AI-gegenereerde samenvatting |

---

### State Management

**Zustand Store** (`stores/cortex-store.ts`):

```typescript
interface CortexStore {
  // Chat state
  messages: ChatMessage[];
  pendingAction: IntentAction | null;

  // Context
  activePatient: Patient | null;
  currentShift: 'nacht' | 'ochtend' | 'middag' | 'avond';

  // UI
  openArtifacts: ArtifactInstance[];
  suggestions: NudgeSuggestion[];
  patientSidebarOpen: boolean;

  // Actions
  addMessage(msg: ChatMessage): void;
  setActivePatient(patient: Patient): void;
  openArtifact(artifact: ArtifactInstance): void;
  acceptSuggestion(id: string): void;
  dismissSuggestion(id: string): void;
}
```

---

### Security

#### Row Level Security (RLS)

Alle tabellen hebben RLS policies die data toegang beperken tot geautoriseerde gebruikers:

```sql
-- Voorbeeld: users kunnen alleen hun eigen patiënten zien
CREATE POLICY "Users can view assigned patients"
  ON patients FOR SELECT
  USING (auth.uid() IN (
    SELECT user_id FROM patient_assignments
    WHERE patient_id = patients.id
  ));
```

#### Authentication Flow

```
1. Login via /auth/login
2. Supabase Auth valideert credentials
3. JWT token in httpOnly cookie
4. Middleware refresht sessie bij elk request
5. API routes valideren via createClient()
6. RLS filtert data op database niveau
```

#### Input Validation

Alle API endpoints gebruiken Zod schemas:

```typescript
const CreateReportSchema = z.object({
  patient_id: z.string().uuid(),
  type: z.enum(['voortgang', 'observatie', ...]),
  content: z.string().min(20).max(5000),
  structured_data: z.object({...}).optional()
});
```

---

### Performance

| Aspect | Implementatie | Target |
|--------|---------------|--------|
| Intent classificatie | Layer 1 Reflex | <20ms voor 70%+ requests |
| Chat responses | SSE streaming | First token <500ms |
| Patient search | Debounced input | 300ms debounce |
| Build optimization | Code splitting | Three.js in apart chunk |
| Database queries | Selective columns | Geen overbodige data |

---

### Monitoring & Audit

**AI Events Table:**

```sql
CREATE TABLE ai_events (
  id UUID PRIMARY KEY,
  kind TEXT,           -- 'classify', 'summarize', 'chat'
  request JSONB,
  response JSONB,
  duration_ms INTEGER,
  created_at TIMESTAMPTZ,
  user_id UUID
);
```

Elk AI-verzoek wordt gelogd voor:
- Compliance en audit trail
- Performance monitoring
- Model fine-tuning data

---

### Feature Flags

```typescript
// lib/config/feature-flags.ts
CORTEX_V2_ENABLED        // Drie-lagen architectuur
CORTEX_MULTI_INTENT      // Multi-intent detectie
CORTEX_NUDGE             // Proactieve suggesties
CORTEX_LOGGING           // Debug logging (dev only)
```

---

## Deployment

### Infrastructuur

```
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│     Vercel      │────▶│    Supabase     │────▶│   PostgreSQL    │
│   (Frontend +   │     │     (Auth)      │     │   (Database)    │
│   API Routes)   │     └─────────────────┘     └─────────────────┘
└─────────────────┘
        │
        ▼
┌─────────────────┐     ┌─────────────────┐
│   Claude API    │     │    Deepgram     │
│  (Anthropic)    │     │ (Speech-to-Text)│
└─────────────────┘     └─────────────────┘
```

### Environment Variables

```bash
# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...

# AI Services
ANTHROPIC_API_KEY=sk-ant-...
DEEPGRAM_API_KEY=...

# Feature Flags
NEXT_PUBLIC_CORTEX_V2=true
```

---

## Extensibility

### Nieuw Intent Toevoegen

1. Voeg toe aan `CortexIntent` type in `lib/cortex/types.ts`
2. Voeg Reflex patterns toe in `lib/cortex/reflex-classifier.ts`
3. Maak artifact block in `components/cortex/blocks/`
4. Update Orchestrator prompt (indien AI-driven)
5. Maak API endpoint (indien nodig)

### Nieuw Report Type Toevoegen

1. Voeg toe aan `REPORT_TYPES` enum in `lib/types/report.ts`
2. Voeg Zod schema toe voor validatie
3. Update UI componenten voor nieuw type
4. Voeg database migration toe indien nodig

---

## Conclusie

De Mini-EPD architectuur is ontworpen voor:

- **Snelheid**: Drie-lagen AI met <20ms lokale verwerking
- **Schaalbaarheid**: Serverless, horizontaal schaalbaar
- **Veiligheid**: RLS, JWT, Zod validatie op alle lagen
- **Uitbreidbaarheid**: Modulaire opzet met duidelijke interfaces
- **Compliance**: Audit trail, soft deletes, Nederlandse foutmeldingen

Het systeem is production-ready voor MVP deployment met duidelijke paden voor doorontwikkeling.
