Files
triqura-ecd/lib/types/overdracht.ts
colinislit adf6c3fb96 feat(swift): implementeer linked evidence UI voor overdracht (E5.S2)
E5.S2 compleet: Bronnotitie links met hover preview in OverdrachtBlock.
Voortgang: 66 SP / 82 SP (80%) - Epic 5 40% compleet!

Implementatie:
- Bronverwijzingen nu klikbaar met hover popover voor volledige content
- Source data enrichment in API response
- Type-specific content display (observaties, rapportages, risico's)
- Visual feedback met icons en kleuren per bron type

Components & Types:
- LinkedEvidence component (160 regels) - Reusable popover voor alle bron types
- Aandachtspunt type extended met optionele sourceData field
- enrichWithSourceData() functie in API route (48 regels)

LinkedEvidence Features:
- Hover popover met volledige bron content
- Type-specific icons: Activity (observatie), FileText (rapportage), AlertTriangle (risico)
- Click/hover trigger met underline-dotted styling
- ExternalLink icon voor visual affordance
- Popover positioning: top-start voor beste UX

Source Data per Type:
- Observaties: value + unit + interpretation (HH/H/N/L/LL) met kleuren
- Rapportages/Verpleegkundig: content + createdBy
- Risico's: riskLevel + rationale met severity kleuren

API Enrichment Logic:
- enrichWithSourceData() lookup in context (vitals, reports, risks)
- Source data toegevoegd aan aandachtspunten vóór response
- Type-safe matching op bron.id en bron.type
- Backwards compatible: werkt met/zonder sourceData

UI/UX Improvements:
- Color-coded interpretations: Red (HH/LL kritiek), Amber (H/L), Teal (N)
- Color-coded risk levels: Red (zeer hoog/hoog), Amber (gemiddeld), Teal (laag)
- Formatted text display met bg-slate-50 border
- Responsive popover met max-width 96 (384px)
- Fallback: geen sourceData = plain text zonder popover

Integration in OverdrachtBlock:
- AandachtspuntItem gebruikt LinkedEvidence component
- Replaced: "bron.label • bron.datum" plain text
- Now: LinkedEvidence met hover preview

Files Changed:
- lib/types/overdracht.ts: +12 lines (sourceData interface)
- app/api/overdracht/generate/route.ts: +58 lines (enrichWithSourceData)
- components/swift/blocks/overdracht-block.tsx: +1/-3 lines (LinkedEvidence import/usage)
- components/swift/shared/linked-evidence.tsx: +160 lines (NEW)

Technical Details:
- Popover from shadcn/ui (@/components/ui/popover)
- Icons from lucide-react (Activity, FileText, AlertTriangle, ExternalLink)
- Type guards voor safe property access (sourceData?.value)
- Underline decoration-dotted cursor-help voor accessibility

Testing:
- Build succesvol (pnpm build)
- /epd/swift: 143 kB (+24 kB door LinkedEvidence component)
- Geen nieuwe type errors
- Popover trigger werkt met keyboard (accessible)

Voortgang: 66 SP / 82 SP (80%) - E5.S2 compleet (3 SP)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 18:38:45 +01:00

121 lines
2.8 KiB
TypeScript

import { z } from 'zod';
import type { Json } from '@/lib/supabase/database.types';
// Patient overview for list view
export interface PatientOverzicht {
id: string;
name_given: string[];
name_family: string;
birth_date: string;
gender: string;
alerts: {
high_risk_count: number;
abnormal_vitals_count: number;
marked_logs_count: number;
incident_count: number;
total: number;
};
}
export interface PatientOverzichtResponse {
patients: PatientOverzicht[];
total: number;
date: string;
}
// Patient detail for detail view
export interface PatientDetail {
patient: {
id: string;
name_given: string[];
name_family: string;
name_prefix?: string;
birth_date: string;
gender: string;
};
vitals: VitalSign[];
reports: Report[];
risks: RiskAssessment[];
conditions: Condition[];
}
// Vital sign with interpretation
export interface VitalSign {
id: string;
code_display: string;
value_quantity_value: number | null;
value_quantity_unit: string | null;
interpretation_code?: string | null; // 'H' | 'L' | 'N'
effective_datetime: string;
}
// Report (rapportage) - now includes verpleegkundig type (was nursing_logs)
export interface Report {
id: string;
type: string;
content: string;
created_at: string;
created_by: string | null;
structured_data?: Json | null; // Contains category for verpleegkundig
include_in_handover?: boolean | null;
shift_date?: string | null;
}
// Risk assessment
export interface RiskAssessment {
id: string;
risk_type: string;
risk_level: string;
rationale?: string | null;
created_at: string | null;
}
// Condition (diagnose)
export interface Condition {
id: string;
code_display: string;
clinical_status: string;
onset_datetime?: string;
}
// AI Summary types
export interface AISamenvatting {
samenvatting: string;
aandachtspunten: Aandachtspunt[];
actiepunten: string[];
generatedAt: string;
durationMs: number;
}
export interface Aandachtspunt {
tekst: string;
urgent: boolean;
bron: {
type: 'observatie' | 'rapportage' | 'verpleegkundig' | 'risico';
id: string;
datum: string;
label: string;
};
sourceData?: {
// Voor observaties (vitals)
value?: string;
unit?: string;
interpretation?: string;
// Voor reports (rapportage, verpleegkundig)
content?: string;
createdBy?: string;
// Voor risico's
riskLevel?: string;
rationale?: string;
};
}
// Zod schema for generate request
export const GenerateOverdrachtSchema = z.object({
patientId: z.string().uuid('Patient ID moet een geldige UUID zijn'),
period: z.enum(['1d', '3d', '7d', '14d']).optional().default('1d'),
filterForRole: z.enum(['psychiater', 'verpleegkundige']).optional().default('verpleegkundige'),
});
export type GenerateOverdrachtInput = z.infer<typeof GenerateOverdrachtSchema>;