feat: add AI docs assistant knowledge base (E0, E1)

- Add 6 FAQ markdown files for clientbeheer, intake, screening,
  behandelplan, spraak, and inloggen
- Add 2 guidelines files for interface and technical documentation
- Implement CategoryDetector for keyword-based category detection
- Implement KnowledgeLoader for loading relevant knowledge files
- Implement PromptBuilder for combining base prompt with knowledge

Part of AI Documentatie Assistent feature (Epic 0 & Epic 1)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
colinislit
2025-12-01 15:28:09 +01:00
parent 94978e7bf8
commit 651ff94fc8
11 changed files with 963 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
/**
* CategoryDetector - Analyseert gebruikersvragen en bepaalt relevante knowledge categorieën
*
* Onderdeel van de AI Documentatie Assistent (E1.S1)
*/
/**
* Alle beschikbare knowledge categorieën
*/
export const KNOWLEDGE_CATEGORIES = [
'clientbeheer',
'intake',
'screening',
'behandelplan',
'spraak',
'inloggen',
'interface',
'technisch',
] as const;
export type KnowledgeCategory = (typeof KNOWLEDGE_CATEGORIES)[number];
/**
* Keyword mapping per categorie voor vraagdetectie
*/
const CATEGORY_KEYWORDS: Record<KnowledgeCategory, string[]> = {
clientbeheer: [
'cliënt',
'client',
'patient',
'patiënt',
'aanmaken',
'zoeken',
'dossier',
],
intake: ['intake', 'gesprek', 'notitie', 'verslag'],
screening: ['screening', 'vragenlijst', 'score', 'resultaat'],
behandelplan: ['behandelplan', 'doel', 'interventie', 'plan'],
spraak: ['spraak', 'microfoon', 'dicteren', 'stem', 'transcriptie'],
inloggen: ['inloggen', 'wachtwoord', 'login', 'account'],
interface: ['menu', 'knop', 'scherm', 'navigatie', 'waar vind'],
technisch: ['api', 'fhir', 'endpoint', 'database', 'developer'],
};
/**
* Detecteert relevante knowledge categorieën op basis van een gebruikersvraag
*
* @param question - De vraag van de gebruiker
* @returns Array van gedetecteerde categorieën (kan leeg zijn)
*
* @example
* detectCategories("Hoe maak ik een intake aan?")
* // Returns: ['intake']
*
* @example
* detectCategories("Waar vind ik de cliënt gegevens?")
* // Returns: ['clientbeheer', 'interface']
*/
export function detectCategories(question: string): KnowledgeCategory[] {
const normalized = question.toLowerCase();
const detected: KnowledgeCategory[] = [];
for (const [category, keywords] of Object.entries(CATEGORY_KEYWORDS)) {
if (keywords.some((keyword) => normalized.includes(keyword))) {
detected.push(category as KnowledgeCategory);
}
}
return detected;
}

View File

@@ -0,0 +1,97 @@
import fs from 'fs/promises'
import path from 'path'
import { KnowledgeCategory } from '@/lib/docs/category-detector'
const KNOWLEDGE_DIR = path.join(process.cwd(), 'lib/docs/knowledge')
const CATEGORY_FILE_MAP: Record<KnowledgeCategory, string[]> = {
clientbeheer: ['faq_clientbeheer.md'],
intake: ['faq_intake.md'],
screening: ['faq_screening.md'],
behandelplan: ['faq_behandelplan.md'],
spraak: ['faq_spraak.md'],
inloggen: ['faq_inloggen.md'],
interface: ['guidelines_interface.md'],
technisch: ['guidelines_technisch.md'],
}
const FILE_CATEGORY_MAP = Object.entries(CATEGORY_FILE_MAP).reduce(
(acc, [category, files]) => {
for (const file of files) {
acc[file] = category as KnowledgeCategory
}
return acc
},
{} as Record<string, KnowledgeCategory>
)
const DEFAULT_FILES = ['guidelines_interface.md']
const MAX_SECTIONS = 4
export interface KnowledgeSection {
id: string
title: string
content: string
category?: KnowledgeCategory
file: string
}
const normalizeTitle = (fileName: string) =>
fileName
.replace(/_/g, ' ')
.replace(/\.mdx?$/, '')
.trim()
function extractTitle(content: string, fallback: string) {
const match = content.match(/^#\s+(.+)$/m)
return (match ? match[1] : fallback).trim()
}
async function readKnowledgeFile(fileName: string) {
const filePath = path.join(KNOWLEDGE_DIR, fileName)
const fileContent = await fs.readFile(filePath, 'utf-8')
return fileContent.trim()
}
export async function loadKnowledgeSections(
categories: KnowledgeCategory[],
options?: { limit?: number; fallbackFiles?: string[] }
): Promise<KnowledgeSection[]> {
const limit = options?.limit ?? MAX_SECTIONS
const fallbackFiles = options?.fallbackFiles ?? DEFAULT_FILES
const selectedFiles = new Set<string>()
if (categories.length === 0) {
fallbackFiles.forEach(file => selectedFiles.add(file))
} else {
for (const category of categories) {
const files = CATEGORY_FILE_MAP[category] ?? []
files.forEach(file => selectedFiles.add(file))
}
}
const filesToLoad = Array.from(selectedFiles).slice(0, limit)
const sections: KnowledgeSection[] = []
for (const fileName of filesToLoad) {
try {
const raw = await readKnowledgeFile(fileName)
if (!raw) continue
const title = extractTitle(raw, normalizeTitle(fileName))
sections.push({
id: fileName.replace(/\.mdx?$/, ''),
title,
content: raw,
category: FILE_CATEGORY_MAP[fileName],
file: fileName,
})
} catch (error) {
console.error(`Failed to load knowledge file ${fileName}:`, error)
}
}
return sections
}

View File

@@ -0,0 +1,63 @@
# FAQ Behandelplan
## Wat is een behandelplan?
Een behandelplan beschrijft de doelen van de behandeling en welke interventies worden ingezet om deze te bereiken. Het is het centrale document voor de behandeling.
## Waar vind ik het behandelplan?
1. Open het cliëntdossier
2. Ga naar de tab **Behandelplan**
## Hoe maak ik een behandelplan aan?
1. Ga naar de tab **Behandelplan** in het cliëntdossier
2. Klik op **+ Nieuw behandelplan**
3. Vul de basisinformatie in:
- Startdatum
- Einddatum (verwacht)
- Hoofdbehandelaar
4. Klik op **Aanmaken**
## Hoe voeg ik doelen toe?
1. Open het behandelplan
2. Klik op **+ Doel toevoegen**
3. Vul in:
- Doelomschrijving (wat wil de cliënt bereiken?)
- Meetbaar criterium (hoe weten we dat het doel behaald is?)
- Prioriteit (hoog/middel/laag)
4. Klik op **Opslaan**
## Hoe voeg ik interventies toe?
1. Open het behandelplan
2. Selecteer een doel
3. Klik op **+ Interventie toevoegen**
4. Vul in:
- Type interventie (bijv. CGT, EMDR, systeemtherapie)
- Frequentie (bijv. wekelijks)
- Verantwoordelijke behandelaar
5. Klik op **Opslaan**
## Kan ik de voortgang bijhouden?
Ja, bij elk doel kun je de voortgang registreren:
1. Open het doel
2. Klik op **Voortgang bijwerken**
3. Selecteer de status (niet gestart, in behandeling, behaald, niet behaald)
4. Voeg eventueel een toelichting toe
## Hoe evalueer ik het behandelplan?
Periodiek evalueer je het behandelplan met de cliënt:
1. Open het behandelplan
2. Klik op **Evaluatie toevoegen**
3. Bespreek de voortgang per doel
4. Pas indien nodig doelen of interventies aan
## Kan AI helpen bij het behandelplan?
Ja, het EPD heeft een AI-functie die kan helpen bij het opstellen van een behandelplan. De AI kan suggesties doen voor doelen en interventies op basis van de diagnose en hulpvraag. Je vindt deze functie via de **AI Assistent** knop in het behandelplan.
Let op: AI-suggesties zijn altijd een startpunt. Controleer en pas deze aan op basis van je klinische expertise.

View File

@@ -0,0 +1,55 @@
# FAQ Cliëntbeheer
## Hoe maak ik een nieuwe cliënt aan?
1. Ga naar **Cliënten** in het hoofdmenu (linkerzijbalk)
2. Klik op de knop **+ Nieuwe cliënt** rechtsboven
3. Vul de basisgegevens in:
- Voornaam en achternaam (verplicht)
- Geboortedatum
- BSN (optioneel)
- Contactgegevens (email, telefoon)
4. Klik op **Opslaan**
De nieuwe cliënt verschijnt direct in de cliëntenlijst.
## Hoe zoek ik een cliënt?
Op de **Cliënten** pagina vind je een zoekbalk bovenaan. Je kunt zoeken op:
- Naam (voor- of achternaam)
- BSN nummer
- Geboortedatum
De resultaten worden direct gefilterd terwijl je typt.
## Hoe open ik een cliëntdossier?
Klik op de naam van een cliënt in de cliëntenlijst. Dit opent het cliëntdossier met alle tabs:
- **Overzicht** - Samenvatting en recente activiteit
- **Basisgegevens** - NAW en contactgegevens
- **Intakes** - Alle intake gesprekken
- **Screening** - Screening resultaten
- **Behandelplan** - Doelen en interventies
- **Rapportage** - Verslagen en notities
## Hoe wijzig ik cliëntgegevens?
1. Open het cliëntdossier
2. Ga naar de tab **Basisgegevens**
3. Klik op **Bewerken**
4. Pas de gewenste velden aan
5. Klik op **Opslaan**
## Kan ik een cliënt verwijderen?
Ja, maar alleen als er geen actieve behandelingen zijn:
1. Open het cliëntdossier
2. Ga naar **Basisgegevens**
3. Scroll naar beneden naar **Cliënt verwijderen**
4. Bevestig de verwijdering
Let op: Verwijderde cliënten kunnen niet worden hersteld.
## Hoe exporteer ik cliëntgegevens?
Deze functie is momenteel niet beschikbaar in de huidige versie van het EPD.

View File

@@ -0,0 +1,69 @@
# FAQ Inloggen & Account
## Hoe log ik in op het EPD?
1. Ga naar de login pagina
2. Vul je e-mailadres in
3. Vul je wachtwoord in (minimaal 8 karakters)
4. Klik op **Inloggen**
Na succesvolle login word je doorgestuurd naar het cliëntenoverzicht.
## Is er een demo account?
Ja! Op de login pagina kun je klikken op **"Demo Account Proberen"** om direct in te loggen met het demo account (`demo@mini-ecd.demo`). Dit is handig om het systeem te verkennen.
## Ik ben mijn wachtwoord vergeten
1. Klik op **"Wachtwoord vergeten"** op de loginpagina
2. Vul je e-mailadres in
3. Je ontvangt een e-mail met een reset link
4. Klik op de link en stel een nieuw wachtwoord in
Let op: De reset link is 24 uur geldig.
## Wat zijn de wachtwoordeisen?
Een geldig wachtwoord moet minimaal 8 karakters bevatten. Het systeem controleert ook of het e-mailadres een geldig formaat heeft.
## Hoe maak ik een nieuw account aan?
1. Ga naar de login pagina
2. Klik op **"Account aanmaken"**
3. Vul in:
- E-mailadres (moet uniek zijn)
- Wachtwoord (min 8 karakters)
- Wachtwoord bevestiging
4. Klik op **"Registreren"**
Je wordt automatisch ingelogd na registratie.
**Let op:** Als je e-mailadres al bestaat, word je automatisch ingelogd op dat bestaande account.
## Hoe log ik uit?
1. Klik op je profielicoon rechtsboven
2. Klik op **Uitloggen**
## Kan ik op meerdere apparaten inloggen?
Ja, je kunt op meerdere apparaten tegelijk ingelogd zijn. Elke sessie is onafhankelijk en beveiligd met JWT tokens.
## Wie kan mijn gegevens zien?
Alleen geautoriseerde medewerkers met de juiste rollen kunnen cliëntgegevens inzien. Het systeem gebruikt Row Level Security (RLS) om data te isoleren:
- Je ziet alleen data van je eigen organisatie
- Behandelaars zien alleen eigen cliënten (tenzij supervisor)
## Mijn account is geblokkeerd
Neem contact op met de beheerder om je account te deblokkeren. Dit kan gebeuren na meerdere mislukte inlogpogingen.
## Hoe zit het met beveiliging?
Het EPD gebruikt:
- **Supabase Auth** voor veilig gebruikersbeheer
- **JWT tokens** in httpOnly cookies
- **RLS policies** voor data isolatie
- Geen API keys in frontend code
- Alle acties worden gelogd voor audit doeleinden

View File

@@ -0,0 +1,104 @@
# FAQ Intake
## Wat is een intake?
Een intake is het eerste gesprek met een cliënt waarin de hulpvraag wordt verkend. Na een succesvolle screening wordt een intake aangemaakt waarbij alle aspecten van de hulpvraag systematisch worden gedocumenteerd.
## Hoe start ik een nieuwe intake?
1. Open het cliëntdossier
2. Navigeer naar het tabblad **Intakes**
3. Klik op **"Nieuwe Intake"**
4. Vul het formulier in:
- **Titel**: Korte omschrijving (bijv. "Eerste intake ambulant")
- **Afdeling**: Selecteer de behandelafdeling (Volwassenen, Jeugd, Forensisch, Verslaving, Ouderen, FACT)
- **Status**: Lopend / Afgerond / Geannuleerd
- **Startdatum**: Datum van eerste contact
- **Notities**: Extra context of bijzonderheden
5. Klik op **"Intake Aanmaken"**
De intake wordt aangemaakt en je wordt doorgeleid naar de intake detail pagina.
## Welke onderdelen heeft een intake?
Elke intake bestaat uit meerdere onderdelen die via tabbladen toegankelijk zijn:
1. **Algemeen** - Basisinformatie: titel, afdeling, status, startdatum
2. **Contactmomenten** - Registreer alle contacten (gesprek, telefonisch, e-mail)
3. **Kindcheck** - Veiligheidscheck voor kinderen (jeugd-intakes)
4. **Risicotaxatie** - Suïcidaliteit, agressie, zelfverwaarlozing, middelengebruik
5. **Anamnese** - Psychiatrisch, sociaal, medisch, familie, ontwikkeling
6. **Onderzoeken** - Psychologisch, neurologisch, laboratorium, beeldvorming
7. **ROM** - Routine Outcome Monitoring vragenlijsten
8. **Diagnose** - DSM-5 classificatie (hoofddiagnose/nevendiagnose)
9. **Behandeladvies** - Geadviseerde behandeling, doelen, afspraken
## Hoe registreer ik contactmomenten?
In het tabblad **Contactmomenten**:
1. Klik op **"Voeg contactmoment toe"**
2. Vul in:
- **Datum en tijd** van het contact
- **Type contact**: Gesprek, Telefonisch, E-mail, Overig
- **Duur** in minuten
- **Notities** over het contact
3. Bekijk het chronologisch overzicht
## Hoe voer ik een risicotaxatie uit?
In het tabblad **Risicotaxatie**:
1. Selecteer het **risicotype** (suïcidaliteit, agressie, etc.)
2. Vul in:
- **Datum** van de taxatie
- **Ernst**: Laag, Matig, Hoog, Acuut
- **Bevindingen**: Beschrijving van het risico
- **Maatregelen**: Genomen acties
Voer risicotaxatie regelmatig opnieuw uit bij wijzigende situaties.
## Hoe leg ik de anamnese vast?
In het tabblad **Anamnese** kun je verschillende types vastleggen:
- Psychiatrische anamnese
- Sociale anamnese
- Medische anamnese
- Familieanamnese
- Ontwikkelingsanamnese
Per anamnese vul je de **datum**, **inhoud** en eventuele **notities** in.
## Hoe stel ik een diagnose?
In het tabblad **Diagnose**:
1. Klik op **"Diagnose toevoegen"**
2. Vul in:
- **Datum** van diagnose
- **Type**: Hoofddiagnose of Nevendiagnose
- **DSM-code** en omschrijving
- **Toelichting**: Onderbouwing van de diagnose
## Wat is de typische intake workflow?
1. Intake starten na screeningsbesluit
2. Contactmomenten plannen en vastleggen
3. Kindcheck uitvoeren (indien van toepassing)
4. Risicotaxatie uitvoeren
5. Anamnese afnemen (meerdere types)
6. Onderzoeken aanvragen en resultaten vastleggen
7. ROM-metingen uitvoeren
8. Diagnose stellen
9. Behandeladvies formuleren
10. Intake afronden (status wijzigen naar "Afgerond")
## Tips voor gebruik
**Goede praktijk:**
- Vul onderdelen meteen na het gesprek in voor beste nauwkeurigheid
- Gebruik de notitievelden voor context die niet in standaardvelden past
- Documenteer alle contactmomenten voor volledig overzicht
- Gebruik duidelijke datums om chronologie te behouden
**Let op:**
- Alle gegevens worden automatisch opgeslagen
- Verwijderde items kunnen niet worden hersteld
- Zorg voor complete documentatie voordat je de intake afrondt

View File

@@ -0,0 +1,113 @@
# FAQ Screening
## Wat is screening in het EPD?
Het screening systeem is de eerste stap in het cliënttraject. Hier wordt de hulpvraag van een nieuwe cliënt beoordeeld en wordt bepaald of de cliënt geschikt is voor intake bij de instelling.
## Waar vind ik de screening?
1. Open het cliëntdossier
2. Ga naar het tabblad **Screening**
Hier zie je vier hoofdonderdelen: hulpvraag, screeningsbesluit, documenten en activiteitenlog.
## Hoe leg ik de hulpvraag vast?
1. Klik in het tekstveld "Hulpvraag"
2. Beschrijf de hulpvraag van de cliënt in eigen woorden
3. Neem belangrijke context en achtergrond op
4. Klik op **"Opslaan"**
**Tips:**
- Wees specifiek over de aard van de hulpvraag
- Vermeld urgentie indien van toepassing
- Noteer bijzondere omstandigheden
## Hoe neem ik een screeningsbesluit?
Het screeningsbesluit is alleen zichtbaar voor psychologen en senior behandelaars.
**Bij "Geschikt voor intake":**
1. Selecteer **"Geschikt voor intake"**
2. Kies de **afdeling** waar de intake moet plaatsvinden:
- Volwassenen
- Jeugd (< 18 jaar)
- Forensisch
- Verslaving
- Ouderen (65+)
- FACT
3. Voeg optioneel **notities** toe bij het besluit
4. Klik op **"Opslaan besluit"**
**Bij "Niet geschikt":**
1. Selecteer **"Niet geschikt / doorverwijzen"**
2. Voeg **notities** toe met reden of alternatief
3. Klik op **"Opslaan besluit"**
**Let op:** Als er nog geen verwijsbrief is geüpload, wordt een waarschuwing getoond. Upload eerst een verwijsbrief voordat je een definitief besluit neemt.
## Hoe upload ik documenten?
1. Klik op **"Document toevoegen"**
2. Selecteer het **documenttype**:
- Verwijsbrief (vereist voor volledig dossier)
- Intake formulier
- Medische informatie
- Andere relevante documenten
3. Voeg optionele **notities** toe
4. Upload het bestand
5. Klik op **"Opslaan"**
## Wat is de activiteitenlog?
De activiteitenlog toont automatisch alle acties die zijn uitgevoerd tijdens de screening:
- Hulpvraag toegevoegd/gewijzigd
- Document geüpload
- Screeningsbesluit genomen
- Afdeling toegewezen
De log wordt automatisch bijgewerkt en hoeft niet handmatig beheerd te worden.
## Wie heeft toegang tot wat?
**Hulpvraag:**
- Zichtbaar voor: Alle behandelaars
- Bewerken: Alle behandelaars
**Screeningsbesluit:**
- Zichtbaar voor: Alleen psychologen en senior behandelaars
- Bewerken: Alleen psychologen en senior behandelaars
**Documenten:**
- Zichtbaar voor: Alle behandelaars met toegang tot cliënt
- Uploaden: Alle behandelaars
- Verwijderen: Alleen uploader en senior behandelaars
## Wat is de standaard screening workflow?
1. Cliënt aanmaken in het systeem
2. Naar **Screening** tabblad navigeren
3. **Hulpvraag** vastleggen
4. **Verwijsbrief** uploaden
5. Eventueel aanvullende **documenten** uploaden
6. **Screeningsbesluit** nemen
7. Bij goedkeuring: **Intake aanmaken**
## Wat gebeurt er na de screening?
**Bij goedkeuring (Geschikt voor intake):**
1. Ga naar het tabblad **Intakes**
2. Klik op **"Nieuwe Intake"**
3. Selecteer de juiste afdeling (zoals bepaald bij screening)
4. Volg de intake workflow
**Bij afwijzing (Niet geschikt):**
1. Informeer cliënt over besluit en alternatieve zorgopties
2. Dossier kan worden gearchiveerd
3. Documentatie blijft beschikbaar voor eventuele vragen
## Veelgemaakte fouten
- Vergeten verwijsbrief te uploaden
- Geen afdeling selecteren bij goedkeuring
- Onvolledige hulpvraag beschrijving

View File

@@ -0,0 +1,98 @@
# FAQ Spraakherkenning
## Wat is spraakgestuurde verslaglegging?
Met spraakgestuurde verslaglegging kun je rapportages dicteren in plaats van typen. Het systeem transcribeert spraak naar tekst in real-time via Deepgram Nova-2, geoptimaliseerd voor Nederlands.
**Kernvoordelen:**
- Sneller rapporteren (dicteren vs. typen)
- Hands-free invoer tijdens of direct na het consult
- Nederlandse spraakherkenning van hoge kwaliteit
- Visuele feedback tijdens opname
## Waar kan ik spraakherkenning gebruiken?
Spraakherkenning is beschikbaar in de **Rapportage** sectie van een cliëntdossier. Je herkent het aan de groene microfoonknop in de werkbalk van de editor.
## Hoe gebruik ik spraakherkenning?
### Stap 1: Start de opname
Klik op de **groene microfoonknop** om de spraakopname te starten.
**Wat je ziet:**
- De knop wordt oranje met een waveform animatie
- Een klein vierkant (stop-icoon) verschijnt
- De browser vraagt eenmalig om microfoontoegang
### Stap 2: Dicteer
Spreek duidelijk en in een normaal tempo. Terwijl je spreekt:
- **Live preview**: Onder de editor verschijnt een oranje balk met de tekst die wordt herkend
- **Automatische interpunctie**: Punten en komma's worden automatisch toegevoegd
- **Pauzes worden herkend**: Na een korte stilte wordt de zin als definitief opgeslagen
### Stap 3: Stop de opname
Klik op het **oranje stop-icoon** om de opname te beëindigen. De getranscribeerde tekst blijft in de editor staan.
### Stap 4: Bewerk en sla op
- Controleer de getranscribeerde tekst
- Pas eventuele fouten aan
- Klik op **Analyseer met AI** voor automatische categorisatie
- Klik op **Opslaan** om de rapportage vast te leggen
## Tips voor optimale herkenning
- Spreek in een rustige omgeving
- Houd de microfoon op normale afstand
- Dicteer natuurlijk, alsof je tegen een collega spreekt
- Vermeld bij voorkeur de cliëntnaam aan het begin
- Spreek in volledige zinnen
## Welke browsers worden ondersteund?
Spraakopname werkt in alle moderne browsers:
- Chrome (aanbevolen)
- Firefox
- Safari
- Edge
Op oudere browsers of zonder microfoon wordt de knop grijs weergegeven.
## Moet ik iets installeren?
Nee, de spraakherkenning werkt volledig in de browser. Bij eerste gebruik vraagt de browser eenmalig om toegang tot je microfoon.
## Hoe zit het met privacy?
- Audio wordt versleuteld verzonden naar Deepgram voor transcriptie
- Audio wordt **niet** opgeslagen na transcriptie
- Alleen de getranscribeerde tekst wordt bewaard in het EPD
- Deepgram is AVG-compliant
## Mijn microfoon werkt niet, wat nu?
Controleer het volgende:
1. **Browsertoestemming** - Heeft de browser toegang tot je microfoon?
- Chrome: Instellingen > Privacy en beveiliging > Site-instellingen > Microfoon
2. **Systeeminstellingen** - Staat de microfoon aan in je besturingssysteem?
3. **Juiste microfoon** - Is de juiste microfoon geselecteerd?
## Wat als de herkenning fouten maakt?
De tekst in de editor is volledig bewerkbaar. Corrigeer eventuele fouten handmatig voordat je opslaat. Voor medische termen of eigennamen kan handmatige correctie nodig zijn.
## Hoeveel mag ik dicteren?
Er geldt een limiet van 5 opnamesessies per uur per gebruiker. Dit is ruim voldoende voor normale rapportage. Bij het bereiken van de limiet verschijnt een melding.
## Bekende beperkingen
- **Achtergrondgeluid**: Veel omgevingsgeluid kan de herkenning verstoren
- **Meerdere sprekers**: Het systeem is geoptimaliseerd voor één spreker
- **Medische termen**: Sommige specialistische termen worden mogelijk niet correct herkend
- **Dialect**: Standaard Nederlands wordt het beste herkend
## Technische specificaties
- Model: Deepgram Nova-2 (geoptimaliseerd voor Nederlands)
- Latentie: < 300ms
- Nauwkeurigheid: > 95% voor duidelijke spraak

View File

@@ -0,0 +1,138 @@
# Interface Handleiding
Het Mini-EPD heeft een two-level context systeem. Desktop-first, geoptimaliseerd voor professioneel gebruik in een klinische omgeving.
## Two-Level Context System
### Level 1: Behandelaar Context
**Wanneer:** Geen cliënt geselecteerd
**Navigatie in linkerzijbalk:**
- **Dashboard** - Caseload overzicht en taken
- **Cliënten** - Zoeken en selecteren
- **Agenda** - Alle afspraken
- **Rapportage** - BI dashboards
**Use Case:** Behandelaar krijgt overzicht van de hele caseload, plant afspraken, en ziet aandachtspunten.
### Level 2: Client Dossier Context
**Wanneer:** Cliënt geselecteerd (via klik op cliënt in lijst)
**Navigatie wijzigt naar:**
- **← Cliënten** - Terug naar behandelaar context
- **Dashboard** - Dossier overzicht
- **Basisgegevens** - NAW en contactgegevens
- **Intakes** - Gesprekken en notities
- **Screening** - Hulpvraag en besluit
- **Diagnose** - DSM classificatie
- **Behandelplan** - SMART doelen en interventies
- **Rapportage** - Cliënt-specifieke verslagen
**Use Case:** Behandelaar werkt intensief met een specifieke cliënt.
## Typische Navigatie Workflow
1. **Start** - Je begint op het behandelaar dashboard met overzicht van je caseload
2. **Cliënt selecteren** - Klik op "Cliënten" in het menu
3. **Dossier openen** - Klik op een cliënt om het dossier te openen
4. **Context wijzigt** - Het menu toont nu cliënt-specifieke opties
5. **Door dossier navigeren** - Gebruik het menu om tussen secties te wisselen
6. **Terug naar overzicht** - Klik op "← Cliënten" om terug te gaan
7. **Snel wisselen** - Gebruik de dropdown in de header voor andere cliënt
8. **Zoeken** - Gebruik de zoekbalk rechtsboven om direct naar een cliënt te springen
## Layout Structuur
### Header (bovenaan)
- **Links:** Logo/branding "Mini-ECD"
- **Midden:** Client selector (toont geselecteerde cliënt met ID)
- **Rechts:** Zoekbalk "Zoek cliënt..."
### Sidebar (links, 240px)
Context-aware menu dat wijzigt afhankelijk van level 1 of 2.
### Main Content (rechts)
- Witte achtergrond
- 32px padding
- Scrollbare inhoud
## Veelgebruikte Schermen
### Behandelaar Dashboard (Level 1)
Toont:
- Caseload overzicht (aantal actieve cliënten)
- Aandachtspunten en urgente taken
- Behandelplannen in concept status
- Aankomende afspraken
### Cliëntenlijst (Level 1)
Features:
- Zoekbalk met filters (Afdeling, Team, Status)
- Recent bekeken cliënten (quick access)
- Tabel met: Naam | ID | Geboortedatum | Status | Laatste Contact
- "Nieuwe Cliënt" button rechtsboven
### Client Dashboard (Level 2)
Card grid met:
- Cliëntinformatie (ID, naam, geboortedatum)
- Laatste intake samenvatting
- Diagnose en ernst indicatie
- Behandelplan status
- Komende afspraken
## Veelgebruikte Knoppen
| Knop | Functie |
|------|---------|
| **+ Nieuw** / **+ Nieuwe [Item]** | Nieuw item aanmaken |
| **Bewerken** | Gegevens wijzigen |
| **Opslaan** | Wijzigingen bewaren |
| **Annuleren** | Wijzigingen ongedaan maken |
| **Bekijk** | Details openen |
| **Verwijderen** | Item verwijderen (met bevestiging) |
## Status Badges
Badges tonen de status met kleur:
- **Groen** (Actief/Afgerond) - Successtatus
- **Geel** (Concept/Wachtlijst) - In afwachting
- **Rood** (Hoog risico) - Ernst indicatie
- **Blauw** (Type indicator) - Informatief
## Intake Detail Panel
Bij klikken op "Bekijk" bij een intake schuift een panel in vanaf rechts (400px):
- Header met datum en sluitknop
- Algemene informatie (datum, tijd, type, duur)
- Gespreksnotities (scrollbaar)
- AI Samenvatting (indien beschikbaar)
- Bewerken en Verwijderen acties onderaan
## Tips voor Efficiënt Werken
1. **Gebruik de zijbalk** voor snelle navigatie tussen secties
2. **Client dropdown** in header voor snel wisselen tussen cliënten
3. **Zoekbalk** rechtsboven om direct naar een cliënt te springen
4. **Recent bekeken** in cliëntenlijst voor snelle toegang
5. **Sla regelmatig op** - sommige velden slaan niet automatisch op
## Toegankelijkheid
**Toetsenbord navigatie:**
- Alle knoppen en links zijn bereikbaar met Tab
- Logische volgorde door de pagina
- Duidelijk zichtbare focus indicatie
**Kleurgebruik:**
- Voldoende contrast voor leesbaarheid
- Status badges zijn ook zonder kleur te onderscheiden
## Wat zit er NIET in de MVP?
- Mobile/tablet versie (alleen desktop)
- Dark mode
- Geavanceerde filters en bulk acties
- Export naar PDF/CSV
- Push notificaties

View File

@@ -0,0 +1,119 @@
# Technische Documentatie
Deze documentatie is bedoeld voor developers en technisch beheerders.
## Architectuur Overzicht
Het Mini-EPD is gebouwd met:
- **Frontend**: Next.js 14 (App Router) + React + Tailwind CSS
- **Backend**: Next.js API Routes
- **Database**: Supabase (PostgreSQL)
- **Authenticatie**: Supabase Auth
- **Hosting**: Vercel
## FHIR R4 Standaard
Het EPD volgt de FHIR R4 standaard voor zorgdata:
### Resources
- `Patient` - Cliëntgegevens
- `Practitioner` - Behandelaar
- `Organization` - Organisatie
- `Encounter` - Contact/afspraak
- `Observation` - Observatie/meting
- `Condition` - Diagnose
- `CarePlan` - Behandelplan
### API Endpoints
```
GET /api/fhir/Patient - Lijst van patiënten
GET /api/fhir/Patient/:id - Specifieke patiënt
POST /api/fhir/Patient - Nieuwe patiënt aanmaken
PUT /api/fhir/Patient/:id - Patiënt bijwerken
DELETE /api/fhir/Patient/:id - Patiënt verwijderen
```
## Database Schema
### Belangrijke Tabellen
| Tabel | Beschrijving |
|-------|-------------|
| `patients` | Cliëntgegevens |
| `practitioners` | Behandelaars |
| `intakes` | Intake registraties |
| `intake_sections` | Sectie-inhoud van intakes |
| `treatment_plans` | Behandelplannen |
| `reports` | Rapportages |
### Row Level Security (RLS)
Alle tabellen hebben RLS policies:
- Gebruikers zien alleen data van hun organisatie
- Behandelaars zien alleen eigen cliënten (tenzij supervisor)
## Authenticatie
### Login Flow
1. Gebruiker vult credentials in
2. Supabase Auth valideert
3. JWT token wordt uitgegeven
4. Token wordt opgeslagen in httpOnly cookie
### Rollen
- `behandelaar` - Standaard rol
- `screener` - Screening toegang
- `admin` - Volledige toegang
## Environment Variables
```env
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=xxx
SUPABASE_SERVICE_ROLE_KEY=xxx
ANTHROPIC_API_KEY=xxx
DEEPGRAM_API_KEY=xxx
```
## Development
### Lokaal draaien
```bash
pnpm install
pnpm dev
```
### Database migraties
```bash
npx supabase db push
```
### Type generatie
```bash
npx supabase gen types typescript --local > lib/supabase/database.types.ts
```
## API Rate Limits
| Endpoint | Limit |
|----------|-------|
| Auth endpoints | 10/min |
| FHIR endpoints | 100/min |
| AI endpoints | 20/min |
## Monitoring & Logging
- **Vercel Analytics** - Performance monitoring
- **Supabase Logs** - Database queries en auth events
- **Console logging** - Applicatie logs (geen PII)
## Veelvoorkomende Fouten
| Code | Betekenis | Oplossing |
|------|-----------|-----------|
| 401 | Niet geauthenticeerd | Opnieuw inloggen |
| 403 | Geen toegang | Controleer rol/rechten |
| 404 | Niet gevonden | Resource bestaat niet |
| 429 | Rate limit | Wacht en probeer opnieuw |
| 500 | Server error | Neem contact op met support |

View File

@@ -0,0 +1,37 @@
import type { KnowledgeSection } from '@/lib/docs/knowledge-loader'
export const BASE_SYSTEM_PROMPT = `Je bent een vriendelijke documentatie assistent voor het Mini-ECD, een GGZ EPD (Elektronisch Patiënt Dossier) systeem.
## Jouw rol
- Beantwoord vragen over hoe het EPD systeem werkt
- Help gebruikers functies te vinden en te gebruiken
- Verwijs naar relevante documentatie secties
## Belangrijke regels
- Je ENIGE kennisbron is de onderstaande documentatie
- Beantwoord vragen ALLEEN op basis van deze informatie
- Als informatie ontbreekt: zeg eerlijk dat je het niet weet
- Verzin NOOIT informatie die niet in de documentatie staat
- Geef GEEN medisch advies of behandelsuggesties
## Jouw publiek
Zorgprofessionals (behandelaars, verpleegkundigen) die het EPD gebruiken.
## Stijl
- Schrijf in het Nederlands
- Wees beknopt maar vriendelijk
- Gebruik bullet points voor stappen
- Verwijs naar specifieke menu's en knoppen waar relevant`; // Spec A.4
export function buildSystemPrompt(sections: KnowledgeSection[]): string {
const knowledgeContent = sections.length
? sections
.map(section => {
const source = section.category ?? 'algemeen'
return `### ${section.title}\n(Bron: ${source})\n\n${section.content}`
})
.join('\n\n---\n\n')
: 'Geen relevante documentatie gevonden voor deze vraag.'
return `${BASE_SYSTEM_PROMPT}\n\n---\nDOCUMENTATIE:\n\n${knowledgeContent}\n\n---`
}