docs: add architecture and intake intent documentation
- Add architecture overview, implementation plan, and intent overview - Add intake intent process specs (gap analyse, bouwplan, testplan) - Add swift architecture specs and visualization prompts - Remove obsolete aispeedrun-manifesto template Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
894
docs/intent/intake-intent-proces/block-template-pattern.md
Normal file
894
docs/intent/intake-intent-proces/block-template-pattern.md
Normal file
@@ -0,0 +1,894 @@
|
||||
# Cortex Block Template & Patterns
|
||||
|
||||
**Datum:** 03-02-2026
|
||||
**Status:** Ontwerp
|
||||
**Doel:** Herbruikbaar patroon voor alle intake-gerelateerde Cortex blocks
|
||||
|
||||
---
|
||||
|
||||
## 1. Anatomie van een Cortex Block
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ [Icon] Titel [Close] │ ← Header (via BlockContainer)
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ Loading State │ │ ← State: Loading
|
||||
│ │ [Spinner] Data laden... │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ Error State │ │ ← State: Error
|
||||
│ │ [!] Foutmelding + [Retry] │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ Empty State │ │ ← State: Empty
|
||||
│ │ [Icon] Geen data + [Actie] │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ Data State │ │ ← State: Data
|
||||
│ │ │ │
|
||||
│ │ Section 1: [Icon] Label │ │
|
||||
│ │ ├── Item 1 │ │
|
||||
│ │ └── Item 2 │ │
|
||||
│ │ │ │
|
||||
│ │ Section 2: [Icon] Label │ │
|
||||
│ │ └── Content │ │
|
||||
│ │ │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ───────────────────────────────────────────────────────── │
|
||||
│ [Secondary Action] [Primary Action] │ ← Footer Actions
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Block Types
|
||||
|
||||
### 2.1 Query Block (Read-only)
|
||||
|
||||
**Doel:** Data tonen, navigeren naar EPD voor bewerken
|
||||
|
||||
```typescript
|
||||
// Voorbeeld: RisicoQueryBlock
|
||||
// Input: "Wat zijn de risico's?"
|
||||
// Output: Lijst risico's met levels
|
||||
|
||||
interface QueryBlockPattern {
|
||||
// Data ophalen
|
||||
fetch: () => Promise<Data>;
|
||||
|
||||
// Tonen
|
||||
render: (data: Data) => JSX.Element;
|
||||
|
||||
// Navigatie
|
||||
onViewInEPD: () => void; // "Bekijk in dossier"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 Action Block (Create/Update)
|
||||
|
||||
**Doel:** Snelle invoer, bevestiging, opslaan
|
||||
|
||||
```typescript
|
||||
// Voorbeeld: RisicoToevoegenBlock
|
||||
// Input: "Risico suïcidaliteit matig"
|
||||
// Output: Prefilled form, confirm, save
|
||||
|
||||
interface ActionBlockPattern {
|
||||
// Prefill van intent entities
|
||||
prefill: ExtractedEntities;
|
||||
|
||||
// Form state
|
||||
form: FormState;
|
||||
|
||||
// Opslaan
|
||||
onSubmit: () => Promise<void>;
|
||||
|
||||
// Bevestiging
|
||||
confirmationRequired: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 Status Block (Progress/Checklist)
|
||||
|
||||
**Doel:** Voortgang tonen, navigeren naar onvolledige items
|
||||
|
||||
```typescript
|
||||
// Voorbeeld: IntakeStatusBlock
|
||||
// Input: "Wat moet ik nog doen?"
|
||||
// Output: Checklist met links
|
||||
|
||||
interface StatusBlockPattern {
|
||||
// Status per onderdeel
|
||||
status: Record<string, boolean>;
|
||||
|
||||
// Navigatie naar onderdeel
|
||||
onNavigate: (section: string) => void;
|
||||
}
|
||||
```
|
||||
|
||||
### 2.4 Navigation Block (Route)
|
||||
|
||||
**Doel:** Direct navigeren naar EPD pagina
|
||||
|
||||
```typescript
|
||||
// Voorbeeld: IntakeNavigatieBlock
|
||||
// Input: "Ga naar diagnose"
|
||||
// Output: Router.push() of openArtifact()
|
||||
|
||||
interface NavigationBlockPattern {
|
||||
// Doel bepalen
|
||||
destination: string;
|
||||
|
||||
// Navigeren
|
||||
onNavigate: () => void;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Shared Components
|
||||
|
||||
### 3.1 Block States
|
||||
|
||||
```typescript
|
||||
// components/cortex/shared/block-states.tsx
|
||||
|
||||
interface BlockLoadingProps {
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export function BlockLoading({ message = 'Laden...' }: BlockLoadingProps) {
|
||||
return (
|
||||
<div className="flex items-center justify-center py-12">
|
||||
<Loader2 className="h-6 w-6 animate-spin text-slate-400 mr-2" />
|
||||
<span className="text-sm text-slate-500">{message}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface BlockErrorProps {
|
||||
message: string;
|
||||
onRetry?: () => void;
|
||||
}
|
||||
|
||||
export function BlockError({ message, onRetry }: BlockErrorProps) {
|
||||
return (
|
||||
<div className="text-center py-8">
|
||||
<AlertCircle className="h-8 w-8 text-red-500 mx-auto mb-2" />
|
||||
<p className="text-sm text-red-700 mb-3">{message}</p>
|
||||
{onRetry && (
|
||||
<Button variant="outline" size="sm" onClick={onRetry}>
|
||||
<RefreshCw className="h-4 w-4 mr-1.5" />
|
||||
Opnieuw proberen
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface BlockEmptyProps {
|
||||
icon: LucideIcon;
|
||||
message: string;
|
||||
action?: {
|
||||
label: string;
|
||||
onClick: () => void;
|
||||
};
|
||||
}
|
||||
|
||||
export function BlockEmpty({ icon: Icon, message, action }: BlockEmptyProps) {
|
||||
return (
|
||||
<div className="text-center py-8 text-slate-400">
|
||||
<Icon className="h-8 w-8 mx-auto mb-2 opacity-50" />
|
||||
<p className="text-sm">{message}</p>
|
||||
{action && (
|
||||
<Button variant="outline" size="sm" onClick={action.onClick} className="mt-3">
|
||||
{action.label}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 Block Section
|
||||
|
||||
```typescript
|
||||
// components/cortex/shared/block-section.tsx
|
||||
|
||||
interface BlockSectionProps {
|
||||
icon: LucideIcon;
|
||||
iconColor?: string;
|
||||
title: string;
|
||||
count?: number;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export function BlockSection({
|
||||
icon: Icon,
|
||||
iconColor = 'text-slate-600',
|
||||
title,
|
||||
count,
|
||||
children
|
||||
}: BlockSectionProps) {
|
||||
return (
|
||||
<section className="bg-white rounded-lg border border-slate-200 p-4">
|
||||
<div className="flex items-center gap-2 mb-3">
|
||||
<Icon className={cn('h-4 w-4', iconColor)} />
|
||||
<h3 className="text-sm font-medium text-slate-700">{title}</h3>
|
||||
{count !== undefined && (
|
||||
<span className="text-xs text-slate-500">({count})</span>
|
||||
)}
|
||||
</div>
|
||||
{children}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 Block Item (List Row)
|
||||
|
||||
```typescript
|
||||
// components/cortex/shared/block-item.tsx
|
||||
|
||||
interface BlockItemProps {
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
badge?: {
|
||||
label: string;
|
||||
variant: 'default' | 'success' | 'warning' | 'danger';
|
||||
};
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
const BADGE_STYLES = {
|
||||
default: 'bg-slate-100 text-slate-700',
|
||||
success: 'bg-green-50 text-green-700',
|
||||
warning: 'bg-amber-50 text-amber-700',
|
||||
danger: 'bg-red-50 text-red-700',
|
||||
};
|
||||
|
||||
export function BlockItem({ title, subtitle, badge, onClick }: BlockItemProps) {
|
||||
const Wrapper = onClick ? 'button' : 'div';
|
||||
|
||||
return (
|
||||
<Wrapper
|
||||
onClick={onClick}
|
||||
className={cn(
|
||||
'flex items-center justify-between p-3 rounded-lg bg-slate-50 border border-slate-200 w-full text-left',
|
||||
onClick && 'hover:bg-slate-100 cursor-pointer transition-colors'
|
||||
)}
|
||||
>
|
||||
<div>
|
||||
<p className="text-sm font-medium text-slate-900">{title}</p>
|
||||
{subtitle && (
|
||||
<p className="text-xs text-slate-500 mt-0.5">{subtitle}</p>
|
||||
)}
|
||||
</div>
|
||||
{badge && (
|
||||
<span className={cn(
|
||||
'px-2 py-0.5 rounded-full text-xs font-medium',
|
||||
BADGE_STYLES[badge.variant]
|
||||
)}>
|
||||
{badge.label}
|
||||
</span>
|
||||
)}
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 3.4 Block Footer
|
||||
|
||||
```typescript
|
||||
// components/cortex/shared/block-footer.tsx
|
||||
|
||||
interface BlockFooterProps {
|
||||
secondaryAction?: {
|
||||
label: string;
|
||||
icon?: LucideIcon;
|
||||
onClick: () => void;
|
||||
};
|
||||
primaryAction?: {
|
||||
label: string;
|
||||
icon?: LucideIcon;
|
||||
onClick: () => void;
|
||||
loading?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export function BlockFooter({ secondaryAction, primaryAction }: BlockFooterProps) {
|
||||
return (
|
||||
<div className="flex items-center justify-between pt-4 border-t border-slate-200 mt-4">
|
||||
{secondaryAction ? (
|
||||
<Button variant="ghost" size="sm" onClick={secondaryAction.onClick}>
|
||||
{secondaryAction.icon && <secondaryAction.icon className="h-4 w-4 mr-1.5" />}
|
||||
{secondaryAction.label}
|
||||
</Button>
|
||||
) : <div />}
|
||||
|
||||
{primaryAction && (
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={primaryAction.onClick}
|
||||
disabled={primaryAction.loading}
|
||||
>
|
||||
{primaryAction.loading ? (
|
||||
<Loader2 className="h-4 w-4 mr-1.5 animate-spin" />
|
||||
) : primaryAction.icon ? (
|
||||
<primaryAction.icon className="h-4 w-4 mr-1.5" />
|
||||
) : null}
|
||||
{primaryAction.label}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Custom Hook Pattern
|
||||
|
||||
### 4.1 useBlockData (Generic Data Fetching)
|
||||
|
||||
```typescript
|
||||
// lib/cortex/hooks/use-block-data.ts
|
||||
|
||||
interface UseBlockDataOptions<T> {
|
||||
endpoint: string;
|
||||
params?: Record<string, string>;
|
||||
enabled?: boolean;
|
||||
onError?: (error: Error) => void;
|
||||
}
|
||||
|
||||
interface UseBlockDataResult<T> {
|
||||
data: T | null;
|
||||
isLoading: boolean;
|
||||
error: string | null;
|
||||
refetch: () => Promise<void>;
|
||||
}
|
||||
|
||||
export function useBlockData<T>({
|
||||
endpoint,
|
||||
params,
|
||||
enabled = true,
|
||||
onError,
|
||||
}: UseBlockDataOptions<T>): UseBlockDataResult<T> {
|
||||
const [data, setData] = useState<T | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(enabled);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const { toast } = useToast();
|
||||
|
||||
const fetchData = useCallback(async () => {
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const url = new URL(endpoint, window.location.origin);
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
url.searchParams.set(key, value);
|
||||
});
|
||||
}
|
||||
|
||||
const response = await safeFetch(url.toString());
|
||||
const result = await response.json();
|
||||
setData(result);
|
||||
} catch (err) {
|
||||
const errorInfo = getErrorInfo(err);
|
||||
setError(errorInfo.description);
|
||||
onError?.(err as Error);
|
||||
toast({
|
||||
variant: 'destructive',
|
||||
title: errorInfo.title,
|
||||
description: errorInfo.description,
|
||||
});
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [endpoint, params, onError, toast]);
|
||||
|
||||
useEffect(() => {
|
||||
if (enabled) {
|
||||
fetchData();
|
||||
}
|
||||
}, [enabled, fetchData]);
|
||||
|
||||
return { data, isLoading, error, refetch: fetchData };
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 useIntakeContext (Intake-specific)
|
||||
|
||||
```typescript
|
||||
// lib/cortex/hooks/use-intake-context.ts
|
||||
|
||||
interface UseIntakeContextResult {
|
||||
patientId: string | null;
|
||||
intakeId: string | null;
|
||||
patientName: string | null;
|
||||
hasContext: boolean;
|
||||
}
|
||||
|
||||
export function useIntakeContext(prefill?: BlockPrefillData): UseIntakeContextResult {
|
||||
const { activePatient } = useCortexStore();
|
||||
|
||||
// TODO: Add activeIntake to cortex-store
|
||||
// For now, we need intakeId from prefill or URL
|
||||
|
||||
const patientId = prefill?.patientId || activePatient?.id || null;
|
||||
const patientName = prefill?.patientName ||
|
||||
(activePatient ? formatPatientName(activePatient) : null);
|
||||
const intakeId = prefill?.intakeId || null;
|
||||
|
||||
return {
|
||||
patientId,
|
||||
intakeId,
|
||||
patientName,
|
||||
hasContext: Boolean(patientId),
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Template: Query Block
|
||||
|
||||
```typescript
|
||||
// components/cortex/blocks/[name]-query-block.tsx
|
||||
|
||||
'use client';
|
||||
|
||||
/**
|
||||
* [Name] Query Block
|
||||
*
|
||||
* Block voor het tonen van [beschrijving].
|
||||
* Intent: [intent_name]
|
||||
*/
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import { useCortexStore } from '@/stores/cortex-store';
|
||||
import { useToast } from '@/hooks/use-toast';
|
||||
import { BlockContainer } from './block-container';
|
||||
import { BlockLoading, BlockError, BlockEmpty } from '../shared/block-states';
|
||||
import { BlockSection } from '../shared/block-section';
|
||||
import { BlockItem } from '../shared/block-item';
|
||||
import { BlockFooter } from '../shared/block-footer';
|
||||
import { useBlockData } from '@/lib/cortex/hooks/use-block-data';
|
||||
import { useIntakeContext } from '@/lib/cortex/hooks/use-intake-context';
|
||||
import type { BlockPrefillData } from '@/stores/cortex-store';
|
||||
import { BLOCK_CONFIGS } from '@/lib/cortex/types';
|
||||
import { [Icon], ExternalLink } from 'lucide-react';
|
||||
|
||||
// ============================================================================
|
||||
// Types
|
||||
// ============================================================================
|
||||
|
||||
interface [Name]QueryBlockProps {
|
||||
prefill?: BlockPrefillData;
|
||||
}
|
||||
|
||||
interface [Name]Data {
|
||||
items: Array<{
|
||||
id: string;
|
||||
// ... fields
|
||||
}>;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Component
|
||||
// ============================================================================
|
||||
|
||||
export function [Name]QueryBlock({ prefill }: [Name]QueryBlockProps) {
|
||||
const config = BLOCK_CONFIGS['[block-type]'];
|
||||
const { closeBlock } = useCortexStore();
|
||||
const { patientId, intakeId, patientName, hasContext } = useIntakeContext(prefill);
|
||||
|
||||
// Fetch data
|
||||
const { data, isLoading, error, refetch } = useBlockData<[Name]Data>({
|
||||
endpoint: `/api/cortex/intake/${intakeId}/[endpoint]`,
|
||||
enabled: Boolean(intakeId),
|
||||
});
|
||||
|
||||
// Handle no context
|
||||
if (!hasContext) {
|
||||
return (
|
||||
<BlockContainer title={config.title} size={config.size}>
|
||||
<BlockEmpty
|
||||
icon={[Icon]}
|
||||
message="Selecteer eerst een patiënt"
|
||||
/>
|
||||
</BlockContainer>
|
||||
);
|
||||
}
|
||||
|
||||
// Handle loading
|
||||
if (isLoading) {
|
||||
return (
|
||||
<BlockContainer title={config.title} size={config.size}>
|
||||
<BlockLoading message="[Name] laden..." />
|
||||
</BlockContainer>
|
||||
);
|
||||
}
|
||||
|
||||
// Handle error
|
||||
if (error) {
|
||||
return (
|
||||
<BlockContainer title={config.title} size={config.size}>
|
||||
<BlockError message={error} onRetry={refetch} />
|
||||
</BlockContainer>
|
||||
);
|
||||
}
|
||||
|
||||
// Handle empty
|
||||
if (!data?.items?.length) {
|
||||
return (
|
||||
<BlockContainer title={config.title} size={config.size}>
|
||||
<BlockEmpty
|
||||
icon={[Icon]}
|
||||
message="Geen [items] gevonden"
|
||||
action={{
|
||||
label: 'Toevoegen in dossier',
|
||||
onClick: () => {
|
||||
// Navigate to EPD
|
||||
window.location.href = `/epd/patients/${patientId}/intakes/${intakeId}/[tab]`;
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</BlockContainer>
|
||||
);
|
||||
}
|
||||
|
||||
// Render data
|
||||
return (
|
||||
<BlockContainer title={config.title} size={config.size}>
|
||||
<div className="space-y-4">
|
||||
<BlockSection icon={[Icon]} iconColor="text-[color]-600" title="[Section Title]" count={data.items.length}>
|
||||
<div className="space-y-2">
|
||||
{data.items.map((item) => (
|
||||
<BlockItem
|
||||
key={item.id}
|
||||
title={item.title}
|
||||
subtitle={item.subtitle}
|
||||
badge={{
|
||||
label: item.status,
|
||||
variant: getBadgeVariant(item.status),
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</BlockSection>
|
||||
|
||||
<BlockFooter
|
||||
secondaryAction={{
|
||||
label: 'Bekijk in dossier',
|
||||
icon: ExternalLink,
|
||||
onClick: () => {
|
||||
window.location.href = `/epd/patients/${patientId}/intakes/${intakeId}/[tab]`;
|
||||
},
|
||||
}}
|
||||
primaryAction={{
|
||||
label: 'Toevoegen',
|
||||
onClick: () => {
|
||||
// Open action block or navigate
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</BlockContainer>
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Helpers
|
||||
// ============================================================================
|
||||
|
||||
function getBadgeVariant(status: string): 'default' | 'success' | 'warning' | 'danger' {
|
||||
switch (status) {
|
||||
case 'laag': return 'success';
|
||||
case 'gemiddeld': return 'warning';
|
||||
case 'hoog':
|
||||
case 'zeer_hoog': return 'danger';
|
||||
default: return 'default';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Template: Status Block
|
||||
|
||||
```typescript
|
||||
// components/cortex/blocks/intake-status-block.tsx
|
||||
|
||||
'use client';
|
||||
|
||||
/**
|
||||
* Intake Status Block
|
||||
*
|
||||
* Block voor het tonen van intake voortgang/checklist.
|
||||
* Intent: intake_status
|
||||
*/
|
||||
|
||||
import { useCortexStore } from '@/stores/cortex-store';
|
||||
import { BlockContainer } from './block-container';
|
||||
import { BlockLoading, BlockError, BlockEmpty } from '../shared/block-states';
|
||||
import { useBlockData } from '@/lib/cortex/hooks/use-block-data';
|
||||
import { useIntakeContext } from '@/lib/cortex/hooks/use-intake-context';
|
||||
import type { BlockPrefillData } from '@/stores/cortex-store';
|
||||
import { BLOCK_CONFIGS } from '@/lib/cortex/types';
|
||||
import {
|
||||
CheckCircle2,
|
||||
Circle,
|
||||
ClipboardList,
|
||||
ChevronRight,
|
||||
} from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
// ============================================================================
|
||||
// Types
|
||||
// ============================================================================
|
||||
|
||||
interface IntakeStatusBlockProps {
|
||||
prefill?: BlockPrefillData;
|
||||
}
|
||||
|
||||
interface IntakeStatusData {
|
||||
intakeId: string;
|
||||
intakeTitle: string;
|
||||
completedCount: number;
|
||||
totalCount: number;
|
||||
sections: Array<{
|
||||
key: string;
|
||||
label: string;
|
||||
completed: boolean;
|
||||
required: boolean;
|
||||
path: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Constants
|
||||
// ============================================================================
|
||||
|
||||
const SECTION_ORDER = [
|
||||
{ key: 'algemeen', label: 'Algemeen', required: true },
|
||||
{ key: 'contactmomenten', label: 'Contactmomenten', required: false },
|
||||
{ key: 'kindcheck', label: 'Kindcheck', required: true },
|
||||
{ key: 'risicotaxatie', label: 'Risicotaxatie', required: true },
|
||||
{ key: 'anamnese', label: 'Anamnese', required: true },
|
||||
{ key: 'onderzoeken', label: 'Onderzoeken', required: false },
|
||||
{ key: 'rom', label: 'ROM', required: false },
|
||||
{ key: 'diagnose', label: 'Diagnose', required: true },
|
||||
{ key: 'behandeladvies', label: 'Behandeladvies', required: true },
|
||||
];
|
||||
|
||||
// ============================================================================
|
||||
// Component
|
||||
// ============================================================================
|
||||
|
||||
export function IntakeStatusBlock({ prefill }: IntakeStatusBlockProps) {
|
||||
const config = BLOCK_CONFIGS['intake-status']; // Need to add this
|
||||
const { patientId, intakeId, hasContext } = useIntakeContext(prefill);
|
||||
|
||||
const { data, isLoading, error, refetch } = useBlockData<IntakeStatusData>({
|
||||
endpoint: `/api/cortex/intake/${intakeId}/status`,
|
||||
enabled: Boolean(intakeId),
|
||||
});
|
||||
|
||||
if (!hasContext) {
|
||||
return (
|
||||
<BlockContainer title="Intake Status" size="md">
|
||||
<BlockEmpty
|
||||
icon={ClipboardList}
|
||||
message="Selecteer eerst een patiënt met een actieve intake"
|
||||
/>
|
||||
</BlockContainer>
|
||||
);
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<BlockContainer title="Intake Status" size="md">
|
||||
<BlockLoading message="Status laden..." />
|
||||
</BlockContainer>
|
||||
);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<BlockContainer title="Intake Status" size="md">
|
||||
<BlockError message={error} onRetry={refetch} />
|
||||
</BlockContainer>
|
||||
);
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return (
|
||||
<BlockContainer title="Intake Status" size="md">
|
||||
<BlockEmpty
|
||||
icon={ClipboardList}
|
||||
message="Geen actieve intake gevonden"
|
||||
/>
|
||||
</BlockContainer>
|
||||
);
|
||||
}
|
||||
|
||||
const progress = Math.round((data.completedCount / data.totalCount) * 100);
|
||||
const incompleteSections = data.sections.filter(s => !s.completed && s.required);
|
||||
|
||||
return (
|
||||
<BlockContainer title={`Intake Status - ${data.intakeTitle}`} size="md">
|
||||
<div className="space-y-4">
|
||||
{/* Progress Bar */}
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center justify-between text-sm">
|
||||
<span className="text-slate-600">Voortgang</span>
|
||||
<span className="font-medium text-slate-900">
|
||||
{data.completedCount}/{data.totalCount} ({progress}%)
|
||||
</span>
|
||||
</div>
|
||||
<div className="h-2 bg-slate-100 rounded-full overflow-hidden">
|
||||
<div
|
||||
className={cn(
|
||||
'h-full rounded-full transition-all',
|
||||
progress === 100 ? 'bg-green-500' : 'bg-teal-500'
|
||||
)}
|
||||
style={{ width: `${progress}%` }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Incomplete Items (priority) */}
|
||||
{incompleteSections.length > 0 && (
|
||||
<div className="p-3 bg-amber-50 border border-amber-200 rounded-lg">
|
||||
<p className="text-sm font-medium text-amber-800 mb-2">
|
||||
Nog te voltooien ({incompleteSections.length})
|
||||
</p>
|
||||
<div className="space-y-1">
|
||||
{incompleteSections.map((section) => (
|
||||
<button
|
||||
key={section.key}
|
||||
onClick={() => {
|
||||
window.location.href = `/epd/patients/${patientId}/intakes/${intakeId}/${section.path}`;
|
||||
}}
|
||||
className="flex items-center justify-between w-full p-2 rounded hover:bg-amber-100 transition-colors text-left"
|
||||
>
|
||||
<span className="text-sm text-amber-900">{section.label}</span>
|
||||
<ChevronRight className="h-4 w-4 text-amber-600" />
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* All Sections */}
|
||||
<div className="space-y-1">
|
||||
{data.sections.map((section) => (
|
||||
<button
|
||||
key={section.key}
|
||||
onClick={() => {
|
||||
window.location.href = `/epd/patients/${patientId}/intakes/${intakeId}/${section.path}`;
|
||||
}}
|
||||
className={cn(
|
||||
'flex items-center justify-between w-full p-3 rounded-lg border transition-colors text-left',
|
||||
section.completed
|
||||
? 'bg-green-50 border-green-200 hover:bg-green-100'
|
||||
: 'bg-slate-50 border-slate-200 hover:bg-slate-100'
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
{section.completed ? (
|
||||
<CheckCircle2 className="h-5 w-5 text-green-600" />
|
||||
) : (
|
||||
<Circle className="h-5 w-5 text-slate-400" />
|
||||
)}
|
||||
<span className={cn(
|
||||
'text-sm',
|
||||
section.completed ? 'text-green-900' : 'text-slate-700'
|
||||
)}>
|
||||
{section.label}
|
||||
</span>
|
||||
{section.required && !section.completed && (
|
||||
<span className="text-xs px-1.5 py-0.5 bg-red-100 text-red-700 rounded">
|
||||
Verplicht
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<ChevronRight className={cn(
|
||||
'h-4 w-4',
|
||||
section.completed ? 'text-green-600' : 'text-slate-400'
|
||||
)} />
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Complete Message */}
|
||||
{progress === 100 && (
|
||||
<div className="p-3 bg-green-50 border border-green-200 rounded-lg text-center">
|
||||
<CheckCircle2 className="h-6 w-6 text-green-600 mx-auto mb-2" />
|
||||
<p className="text-sm font-medium text-green-800">
|
||||
Intake is compleet!
|
||||
</p>
|
||||
<p className="text-xs text-green-600 mt-1">
|
||||
Je kunt de intake nu afsluiten
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</BlockContainer>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Checklist voor nieuwe Block
|
||||
|
||||
Bij het bouwen van een nieuwe block:
|
||||
|
||||
- [ ] **Types definiëren** - Props interface, Data interface
|
||||
- [ ] **Intent toevoegen** aan `lib/cortex/types.ts`
|
||||
- [ ] **Patterns toevoegen** aan `lib/cortex/reflex-classifier.ts`
|
||||
- [ ] **Block config toevoegen** aan `BLOCK_CONFIGS`
|
||||
- [ ] **API route maken** (indien nodig) in `app/api/cortex/`
|
||||
- [ ] **Block component bouwen** met shared components
|
||||
- [ ] **Canvas-area updaten** om block te renderen
|
||||
- [ ] **Testen** met voice input en prefill
|
||||
|
||||
---
|
||||
|
||||
## 8. Bestandsstructuur
|
||||
|
||||
```
|
||||
components/cortex/
|
||||
├── blocks/
|
||||
│ ├── block-container.tsx # Wrapper (bestaat)
|
||||
│ ├── dagnotitie-block.tsx # Bestaat
|
||||
│ ├── zoeken-block.tsx # Bestaat
|
||||
│ ├── overdracht-block.tsx # Bestaat
|
||||
│ ├── patient-dashboard-block.tsx # Bestaat
|
||||
│ │
|
||||
│ ├── # NIEUW - Intake Blocks
|
||||
│ ├── intake-status-block.tsx # Checklist
|
||||
│ ├── risico-query-block.tsx # Risico's tonen
|
||||
│ ├── diagnose-query-block.tsx # Diagnoses tonen
|
||||
│ ├── kindcheck-query-block.tsx # Kindcheck status
|
||||
│ └── screening-query-block.tsx # Screening overzicht
|
||||
│
|
||||
├── shared/
|
||||
│ ├── patient-list-item.tsx # Bestaat
|
||||
│ ├── linked-evidence.tsx # Bestaat
|
||||
│ │
|
||||
│ ├── # NIEUW - Shared Block Components
|
||||
│ ├── block-states.tsx # Loading/Error/Empty
|
||||
│ ├── block-section.tsx # Section wrapper
|
||||
│ ├── block-item.tsx # List item
|
||||
│ └── block-footer.tsx # Footer actions
|
||||
│
|
||||
lib/cortex/
|
||||
├── hooks/
|
||||
│ ├── use-patient-search.ts # Bestaat
|
||||
│ ├── use-patient-selection.ts # Bestaat
|
||||
│ │
|
||||
│ ├── # NIEUW
|
||||
│ ├── use-block-data.ts # Generic data fetching
|
||||
│ └── use-intake-context.ts # Intake context
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Volgende Stappen
|
||||
|
||||
1. **Shared components bouwen** (`block-states.tsx`, etc.)
|
||||
2. **Hooks bouwen** (`use-block-data.ts`, `use-intake-context.ts`)
|
||||
3. **Eerste block:** `IntakeStatusBlock` (meest waardevolle quick win)
|
||||
4. **API route:** `/api/cortex/intake/[id]/status`
|
||||
5. **Intent + patterns** toevoegen voor `intake_status`
|
||||
@@ -0,0 +1,365 @@
|
||||
# 🚀 Mission Control — Bouwplan Cortex Shared Components
|
||||
|
||||
**Projectnaam:** Cortex Intake Intent System - Shared Components
|
||||
**Versie:** v1.0
|
||||
**Datum:** 03-02-2026
|
||||
**Auteur:** Colin Lit
|
||||
|
||||
---
|
||||
|
||||
## 1. Doel en Context
|
||||
|
||||
🎯 **Doel:**
|
||||
Bouwen van herbruikbare shared components en hooks voor alle Cortex Intake Blocks. Deze componenten vormen de foundation voor de intake-gerelateerde intents.
|
||||
|
||||
📘 **Context:**
|
||||
De Cortex Command Center heeft momenteel 7 werkende intents, maar geen van de 26 intake-gerelateerde intents is geïmplementeerd. De shared components zijn de eerste stap om dit te realiseren. Ze worden hergebruikt door alle nieuwe intake blocks.
|
||||
|
||||
**Relatie met andere documenten:**
|
||||
| Document | Relatie |
|
||||
|----------|---------|
|
||||
| `fo-to-cortex-shared-components.md` | Functionele en technische specificaties |
|
||||
| `intake-process-intents.md` | Intent definities die deze components gebruiken |
|
||||
| `gap-analyse-intake-cortex.md` | Identificeert de behoefte aan deze components |
|
||||
|
||||
---
|
||||
|
||||
## 2. Uitgangspunten
|
||||
|
||||
### 2.1 Technische Stack
|
||||
|
||||
| Component | Technologie | Reden |
|
||||
|-----------|-------------|-------|
|
||||
| **Framework** | Next.js 14 (App Router) | Bestaande stack |
|
||||
| **UI Library** | React 18 + TypeScript | Type safety, DX |
|
||||
| **Styling** | Tailwind CSS | Utility-first, consistent met project |
|
||||
| **Icons** | Lucide React | Bestaande icon library |
|
||||
| **Components** | shadcn/ui | Button, etc. al in gebruik |
|
||||
| **State** | Zustand (cortex-store) | Bestaande state management |
|
||||
| **Animations** | Framer Motion | Optioneel, al in project |
|
||||
|
||||
### 2.2 Projectkaders
|
||||
|
||||
| Kader | Waarde |
|
||||
|-------|--------|
|
||||
| **Tijd** | 1 dag bouwtijd |
|
||||
| **Scope** | 4 components + 2 hooks |
|
||||
| **Team** | 1 developer |
|
||||
| **Data** | Geen nieuwe data, alleen UI |
|
||||
| **Doel** | Foundation voor intake blocks |
|
||||
|
||||
### 2.3 Programmeer Uitgangspunten
|
||||
|
||||
**Code Quality Principles:**
|
||||
- **DRY** - Herbruikbare components en utility functions
|
||||
- **KISS** - Eenvoudige oplossingen, geen premature optimization
|
||||
- **SOC** - UI gescheiden van business logic, hooks voor data
|
||||
- **YAGNI** - Alleen bouwen wat nu nodig is
|
||||
|
||||
**Development Practices:**
|
||||
- TypeScript strict mode
|
||||
- Props interfaces geëxporteerd voor hergebruik
|
||||
- Consistente naamgeving (`Block*` prefix)
|
||||
- JSDoc comments voor public API
|
||||
- Tree-shakeable exports via index.ts
|
||||
|
||||
---
|
||||
|
||||
## 3. Epics & Stories Overzicht
|
||||
|
||||
| Epic ID | Titel | Doel | Status | Stories | Geschat |
|
||||
|---------|-------|------|--------|---------|---------|
|
||||
| E0 | Block States | Loading/Error/Empty states | ⏳ To Do | 3 | 2 uur |
|
||||
| E1 | Block Layout | Section/Item/Footer components | ⏳ To Do | 3 | 2 uur |
|
||||
| E2 | Custom Hooks | Data fetching en context hooks | ⏳ To Do | 2 | 2 uur |
|
||||
| E3 | Integration | Exports en documentatie | ⏳ To Do | 2 | 1 uur |
|
||||
|
||||
**Totaal geschat:** ~7 uur (1 werkdag)
|
||||
|
||||
---
|
||||
|
||||
## 4. Epics & Stories (Uitwerking)
|
||||
|
||||
### Epic 0 — Block States
|
||||
|
||||
**Epic Doel:** Consistente states voor alle blocks (loading, error, empty).
|
||||
|
||||
| Story ID | Beschrijving | Acceptatiecriteria | Status | Afhankelijkheden | SP |
|
||||
|----------|--------------|---------------------|--------|------------------|----|
|
||||
| E0.S1 | `BlockLoading` component | Spinner + message, centered, animatie | ⏳ | — | 1 |
|
||||
| E0.S2 | `BlockError` component | Error icon + message + retry button | ⏳ | — | 1 |
|
||||
| E0.S3 | `BlockEmpty` component | Custom icon + message + action button | ⏳ | — | 1 |
|
||||
|
||||
**Technical Notes:**
|
||||
```typescript
|
||||
// Verwachte exports
|
||||
export { BlockLoading } from './block-states';
|
||||
export { BlockError } from './block-states';
|
||||
export { BlockEmpty } from './block-states';
|
||||
```
|
||||
|
||||
**Acceptatiecriteria E0:**
|
||||
- [ ] Alle 3 states renderen correct
|
||||
- [ ] Props zijn fully typed met interfaces
|
||||
- [ ] Responsive op alle block sizes (sm/md/lg)
|
||||
- [ ] Consistent met bestaande design (slate colors, tailwind)
|
||||
|
||||
---
|
||||
|
||||
### Epic 1 — Block Layout
|
||||
|
||||
**Epic Doel:** Herbruikbare layout components voor block content.
|
||||
|
||||
| Story ID | Beschrijving | Acceptatiecriteria | Status | Afhankelijkheden | SP |
|
||||
|----------|--------------|---------------------|--------|------------------|----|
|
||||
| E1.S1 | `BlockSection` component | Icon + title + count + children wrapper | ⏳ | — | 1 |
|
||||
| E1.S2 | `BlockItem` component | Title + subtitle + badge, clickable optie | ⏳ | — | 2 |
|
||||
| E1.S3 | `BlockFooter` component | Secondary + primary action buttons | ⏳ | E1.S2 | 1 |
|
||||
|
||||
**Technical Notes:**
|
||||
```typescript
|
||||
// Badge variants voor BlockItem
|
||||
type BadgeVariant = 'default' | 'success' | 'warning' | 'danger';
|
||||
|
||||
// Helper functie
|
||||
export function getRiskBadgeVariant(level: string): BadgeVariant;
|
||||
```
|
||||
|
||||
**Acceptatiecriteria E1:**
|
||||
- [ ] Section toont icon met configureerbare kleur
|
||||
- [ ] Item is klikbaar wanneer onClick meegegeven
|
||||
- [ ] Item hover state alleen bij klikbaar
|
||||
- [ ] Footer acties correct aligned (left/right)
|
||||
- [ ] Footer toont loading spinner op primary action
|
||||
|
||||
---
|
||||
|
||||
### Epic 2 — Custom Hooks
|
||||
|
||||
**Epic Doel:** Hooks voor data fetching en context management.
|
||||
|
||||
| Story ID | Beschrijving | Acceptatiecriteria | Status | Afhankelijkheden | SP |
|
||||
|----------|--------------|---------------------|--------|------------------|----|
|
||||
| E2.S1 | `useBlockData` hook | Generic fetch met loading/error states, refetch | ⏳ | error-handler.ts | 3 |
|
||||
| E2.S2 | `useIntakeContext` hook | Patient + Intake context van store/prefill | ⏳ | cortex-store | 2 |
|
||||
|
||||
**Technical Notes:**
|
||||
```typescript
|
||||
// useBlockData interface
|
||||
interface UseBlockDataResult<T> {
|
||||
data: T | null;
|
||||
isLoading: boolean;
|
||||
error: string | null;
|
||||
refetch: () => Promise<void>;
|
||||
}
|
||||
|
||||
// useIntakeContext interface
|
||||
interface UseIntakeContextResult {
|
||||
patientId: string | null;
|
||||
intakeId: string | null;
|
||||
patientName: string | null;
|
||||
hasPatientContext: boolean;
|
||||
hasIntakeContext: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
**Acceptatiecriteria E2:**
|
||||
- [ ] useBlockData handelt errors via bestaande error-handler
|
||||
- [ ] useBlockData toont toast bij error
|
||||
- [ ] useBlockData supported enabled flag voor conditional fetching
|
||||
- [ ] useIntakeContext valt terug op activePatient uit store
|
||||
- [ ] useIntakeContext is memoized om re-renders te voorkomen
|
||||
|
||||
---
|
||||
|
||||
### Epic 3 — Integration
|
||||
|
||||
**Epic Doel:** Exports, documentatie en integratie met bestaande code.
|
||||
|
||||
| Story ID | Beschrijving | Acceptatiecriteria | Status | Afhankelijkheden | SP |
|
||||
|----------|--------------|---------------------|--------|------------------|----|
|
||||
| E3.S1 | Index exports | Barrel file met alle exports | ⏳ | E0, E1, E2 | 1 |
|
||||
| E3.S2 | Update bestaande blocks | Refactor ZoekenBlock naar shared components | ⏳ | E3.S1 | 2 |
|
||||
|
||||
**Technical Notes:**
|
||||
```typescript
|
||||
// components/cortex/shared/index.ts
|
||||
// Block States
|
||||
export { BlockLoading, BlockError, BlockEmpty } from './block-states';
|
||||
|
||||
// Block Layout
|
||||
export { BlockSection } from './block-section';
|
||||
export { BlockItem, getRiskBadgeVariant, type BadgeVariant } from './block-item';
|
||||
export { BlockFooter } from './block-footer';
|
||||
|
||||
// Existing (unchanged)
|
||||
export { PatientListItem, PatientListEmpty, PatientListLoading } from './patient-list-item';
|
||||
export { LinkedEvidence } from './linked-evidence';
|
||||
```
|
||||
|
||||
**Acceptatiecriteria E3:**
|
||||
- [ ] Alle components importeerbaar via `@/components/cortex/shared`
|
||||
- [ ] Hooks importeerbaar via `@/lib/cortex/hooks`
|
||||
- [ ] Geen breaking changes voor bestaande code
|
||||
- [ ] ZoekenBlock werkt nog na refactor (smoke test)
|
||||
|
||||
---
|
||||
|
||||
## 5. Implementatie Volgorde
|
||||
|
||||
```
|
||||
E0.S1 BlockLoading ──┐
|
||||
E0.S2 BlockError ──┼──▶ E0 Complete
|
||||
E0.S3 BlockEmpty ──┘
|
||||
│
|
||||
E1.S1 BlockSection ──┐ │
|
||||
E1.S2 BlockItem ──┼──▶ E1 Complete
|
||||
E1.S3 BlockFooter ──┘ │
|
||||
│
|
||||
E2.S1 useBlockData ──┬──▶ E2 Complete
|
||||
E2.S2 useIntakeContext ──┘ │
|
||||
│
|
||||
E3.S1 Index exports ──┬──▶ E3 Complete ──▶ ✅ DONE
|
||||
E3.S2 Refactor test ──┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Bestandsstructuur (Deliverables)
|
||||
|
||||
```
|
||||
components/cortex/shared/
|
||||
├── block-states.tsx 🆕 E0.S1-S3
|
||||
├── block-section.tsx 🆕 E1.S1
|
||||
├── block-item.tsx 🆕 E1.S2
|
||||
├── block-footer.tsx 🆕 E1.S3
|
||||
├── index.ts 🆕 E3.S1 (update)
|
||||
├── patient-list-item.tsx ✅ Bestaat
|
||||
└── linked-evidence.tsx ✅ Bestaat
|
||||
|
||||
lib/cortex/hooks/
|
||||
├── use-block-data.ts 🆕 E2.S1
|
||||
├── use-intake-context.ts 🆕 E2.S2
|
||||
├── use-patient-search.ts ✅ Bestaat
|
||||
└── use-patient-selection.ts ✅ Bestaat
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Kwaliteit & Testplan
|
||||
|
||||
### Test Types
|
||||
|
||||
| Test Type | Scope | Hoe | Status |
|
||||
|-----------|-------|-----|--------|
|
||||
| Type Check | Alle files | `pnpm types:check` | ⏳ |
|
||||
| Lint | Alle files | `pnpm lint` | ⏳ |
|
||||
| Visual | Components | Browser inspection | ⏳ |
|
||||
| Integration | ZoekenBlock | Manual smoke test | ⏳ |
|
||||
|
||||
### Manual Test Checklist
|
||||
|
||||
**Block States:**
|
||||
- [ ] BlockLoading toont spinner + tekst
|
||||
- [ ] BlockError toont error + retry knop werkt
|
||||
- [ ] BlockEmpty toont icon + message + action werkt
|
||||
|
||||
**Block Layout:**
|
||||
- [ ] BlockSection toont icon in juiste kleur
|
||||
- [ ] BlockSection toont count badge
|
||||
- [ ] BlockItem is klikbaar met hover state
|
||||
- [ ] BlockItem toont badge in juiste kleur
|
||||
- [ ] BlockFooter toont beide acties
|
||||
- [ ] BlockFooter primary loading state werkt
|
||||
|
||||
**Hooks:**
|
||||
- [ ] useBlockData fetcht data correct
|
||||
- [ ] useBlockData toont loading state
|
||||
- [ ] useBlockData toont error bij failure
|
||||
- [ ] useBlockData refetch werkt
|
||||
- [ ] useIntakeContext leest activePatient
|
||||
- [ ] useIntakeContext leest prefill data
|
||||
|
||||
**Integration:**
|
||||
- [ ] Alle exports werken via index.ts
|
||||
- [ ] ZoekenBlock werkt nog na changes
|
||||
- [ ] Geen TypeScript errors
|
||||
- [ ] Geen console errors
|
||||
|
||||
---
|
||||
|
||||
## 8. Definition of Done
|
||||
|
||||
Een story is **DONE** wanneer:
|
||||
- [ ] Code is geschreven volgens FO/TO spec
|
||||
- [ ] TypeScript compileert zonder errors
|
||||
- [ ] ESLint toont geen errors
|
||||
- [ ] Component/hook werkt in browser
|
||||
- [ ] Props zijn gedocumenteerd met JSDoc
|
||||
- [ ] Export is toegevoegd aan index.ts
|
||||
|
||||
Het **project** is **DONE** wanneer:
|
||||
- [ ] Alle 10 stories zijn DONE
|
||||
- [ ] Manual test checklist is 100% ✅
|
||||
- [ ] ZoekenBlock smoke test passed
|
||||
- [ ] `pnpm build` slaagt
|
||||
|
||||
---
|
||||
|
||||
## 9. Risico's & Mitigatie
|
||||
|
||||
| Risico | Kans | Impact | Mitigatie |
|
||||
|--------|------|--------|-----------|
|
||||
| Breaking changes bestaande blocks | Middel | Hoog | Backward compatible exports, smoke test |
|
||||
| Performance issues hooks | Laag | Middel | useMemo, useCallback waar nodig |
|
||||
| Inconsistente styling | Laag | Laag | Tailwind design tokens hergebruiken |
|
||||
| Scope creep (extra features) | Middel | Middel | Strict aan FO/TO houden, YAGNI |
|
||||
|
||||
---
|
||||
|
||||
## 10. Dependencies Check
|
||||
|
||||
**Bestaande dependencies (geen installatie nodig):**
|
||||
- ✅ `lucide-react` - Icons
|
||||
- ✅ `@/components/ui/button` - shadcn Button
|
||||
- ✅ `@/lib/utils` - cn() helper
|
||||
- ✅ `@/lib/cortex/error-handler` - safeFetch, getErrorInfo
|
||||
- ✅ `@/stores/cortex-store` - useCortexStore
|
||||
- ✅ `@/hooks/use-toast` - Toast notifications
|
||||
|
||||
**Geen nieuwe dependencies nodig** ✅
|
||||
|
||||
---
|
||||
|
||||
## 11. Referenties
|
||||
|
||||
**Project Documents:**
|
||||
- `docs/intent/intake-intent-proces/fo-to-cortex-shared-components.md` - FO/TO
|
||||
- `docs/intent/intake-intent-proces/intake-process-intents.md` - Intents
|
||||
- `docs/intent/intake-intent-proces/gap-analyse-intake-cortex.md` - Gap analyse
|
||||
- `docs/intent/intake-intent-proces/block-template-pattern.md` - Patterns
|
||||
|
||||
**Bestaande Code (referentie):**
|
||||
- `components/cortex/shared/patient-list-item.tsx` - Pattern voorbeeld
|
||||
- `components/cortex/blocks/zoeken-block.tsx` - Block voorbeeld
|
||||
- `lib/cortex/hooks/use-patient-search.ts` - Hook voorbeeld
|
||||
|
||||
---
|
||||
|
||||
## 12. Glossary
|
||||
|
||||
| Term | Betekenis |
|
||||
|------|-----------|
|
||||
| Block | UI component in Cortex canvas-area |
|
||||
| Shared Component | Herbruikbare UI component voor blocks |
|
||||
| Hook | React custom hook voor logic/state |
|
||||
| Prefill | Data meegegeven aan block bij openen |
|
||||
| Intent | Gebruikers intentie (spraak/tekst) |
|
||||
|
||||
---
|
||||
|
||||
**Versiehistorie:**
|
||||
|
||||
| Versie | Datum | Auteur | Wijziging |
|
||||
|--------|-------|--------|-----------|
|
||||
| v1.0 | 03-02-2026 | Colin Lit | Initiële versie |
|
||||
1087
docs/intent/intake-intent-proces/fo-to-cortex-shared-components.md
Normal file
1087
docs/intent/intake-intent-proces/fo-to-cortex-shared-components.md
Normal file
File diff suppressed because it is too large
Load Diff
379
docs/intent/intake-intent-proces/gap-analyse-intake-cortex.md
Normal file
379
docs/intent/intake-intent-proces/gap-analyse-intake-cortex.md
Normal file
@@ -0,0 +1,379 @@
|
||||
# Gap Analyse: Intake Proces × Cortex
|
||||
|
||||
**Datum:** 03-02-2026
|
||||
**Status:** Analyse
|
||||
**Bron:** `docs/intent/intake-process-intents.md`
|
||||
|
||||
---
|
||||
|
||||
## 1. Executive Summary
|
||||
|
||||
| Laag | Status | Conclusie |
|
||||
|------|--------|-----------|
|
||||
| **EPD Backend** | ✅ 90% compleet | Server actions, database, API's zijn uitgebreid aanwezig |
|
||||
| **EPD UI** | ✅ 95% compleet | Alle 9 intake tabs + screening hebben werkende componenten |
|
||||
| **Cortex Intents** | ❌ 0% | Geen van de 26 intake intents bestaat |
|
||||
| **Cortex Blocks** | ❌ 0% | Geen intake-specifieke blocks |
|
||||
| **Cortex API** | ❌ 0% | Geen /api/cortex/intake/* routes |
|
||||
|
||||
**Conclusie:** De EPD-functionaliteit is robuust gebouwd. De koppeling met Cortex ontbreekt volledig.
|
||||
|
||||
---
|
||||
|
||||
## 2. Wat Bestaat (✅)
|
||||
|
||||
### 2.1 Cortex Core (7 intents)
|
||||
|
||||
```typescript
|
||||
// lib/cortex/types.ts
|
||||
type CortexIntent =
|
||||
| 'dagnotitie' // ✅ Block + patterns
|
||||
| 'zoeken' // ✅ Block + patterns
|
||||
| 'overdracht' // ✅ Block + patterns
|
||||
| 'agenda_query' // ✅ Patterns (geen dedicated block)
|
||||
| 'create_appointment' // ✅ Patterns
|
||||
| 'cancel_appointment' // ✅ Patterns
|
||||
| 'reschedule_appointment'// ✅ Patterns
|
||||
| 'unknown';
|
||||
```
|
||||
|
||||
### 2.2 Cortex Blocks (6 stuks)
|
||||
|
||||
| Block | Pad | Functie |
|
||||
|-------|-----|---------|
|
||||
| `dagnotitie-block.tsx` | `components/cortex/blocks/` | Notitie invoer |
|
||||
| `zoeken-block.tsx` | `components/cortex/blocks/` | Patiënt zoeken |
|
||||
| `overdracht-block.tsx` | `components/cortex/blocks/` | Overdracht samenvatting |
|
||||
| `patient-dashboard-block.tsx` | `components/cortex/blocks/` | Patiënt overzicht |
|
||||
| `patient-context-card.tsx` | `components/cortex/blocks/` | Context weergave |
|
||||
| `fallback-picker.tsx` | `components/cortex/blocks/` | Unknown intent handler |
|
||||
|
||||
### 2.3 Cortex API Routes
|
||||
|
||||
| Route | Methode | Functie |
|
||||
|-------|---------|---------|
|
||||
| `/api/cortex/classify` | POST | Intent classificatie |
|
||||
| `/api/cortex/chat` | POST | Streaming chat |
|
||||
| `/api/cortex/context` | GET | Context ophalen |
|
||||
| `/api/cortex/agenda` | GET | Agenda query |
|
||||
| `/api/cortex/agenda/create` | POST | Afspraak maken |
|
||||
| `/api/cortex/agenda/cancel` | POST | Afspraak annuleren |
|
||||
| `/api/cortex/agenda/reschedule` | POST | Afspraak verzetten |
|
||||
| `/api/cortex/patients/search` | GET | Patiënt zoeken |
|
||||
|
||||
### 2.4 EPD Screening (Volledig)
|
||||
|
||||
**UI Componenten:**
|
||||
| Component | Status | Functie |
|
||||
|-----------|--------|---------|
|
||||
| `HelpRequestCard` | ✅ | Hulpvraag invoer (textarea) |
|
||||
| `DecisionCard` | ✅ | Besluit: geschikt/niet_geschikt |
|
||||
| `DocumentCard` | ✅ | Document upload |
|
||||
| `ActivityLog` | ✅ | Activiteiten timeline |
|
||||
|
||||
**Server Actions:**
|
||||
| Action | Status | Functie |
|
||||
|--------|--------|---------|
|
||||
| `getScreeningSummary()` | ✅ | Screening data ophalen |
|
||||
| `saveHelpRequest()` | ✅ | Hulpvraag opslaan |
|
||||
| `saveScreeningDecision()` | ✅ | Besluit opslaan |
|
||||
| `addScreeningActivity()` | ✅ | Activiteit toevoegen |
|
||||
|
||||
### 2.5 EPD Intake (Volledig)
|
||||
|
||||
**9 Tabs met UI + Actions:**
|
||||
|
||||
| Tab | UI Component | GET Action | CREATE Action |
|
||||
|-----|--------------|------------|---------------|
|
||||
| Algemeen | `IntakePage` | `getIntakeById()` | `createIntake()` |
|
||||
| Contactmomenten | `ContactManager` | `getContactMoments()` | `createContactMoment()` |
|
||||
| Kindcheck | `KindcheckForm` | `getKindcheck()` | `saveKindcheck()` |
|
||||
| Risicotaxatie | `RiskManager` | `getRiskAssessments()` | `createRiskAssessment()` |
|
||||
| Anamnese | `AnamneseManager` | `getAnamneses()` | `createAnamnese()` |
|
||||
| Onderzoeken | `ExaminationManager` | `getExaminations()` | `createExamination()` |
|
||||
| ROM | `ExaminationManager` | `getExaminations()` | `createExamination()` |
|
||||
| Diagnose | `DiagnosisManager` | `getDiagnoses()` | `createDiagnosis()` |
|
||||
| Behandeladvies | `TreatmentAdviceForm` | `getTreatmentAdvice()` | `saveTreatmentAdvice()` |
|
||||
|
||||
---
|
||||
|
||||
## 3. Wat Ontbreekt (❌)
|
||||
|
||||
### 3.1 Intents (26 ontbreken)
|
||||
|
||||
Geen van de intake-gerelateerde intents uit `intake-process-intents.md` bestaat:
|
||||
|
||||
#### Screening Intents (4)
|
||||
| Intent | Type | Patterns nodig |
|
||||
|--------|------|----------------|
|
||||
| `screening_query` | Query | `^(toon\s+)?screening`, `wat is de hulpvraag` |
|
||||
| `hulpvraag_invoer` | Actie | `hulpvraag:`, `noteer hulpvraag` |
|
||||
| `screening_besluit` | Actie | `geschikt voor behandeling`, `niet geschikt` |
|
||||
| `screening_activiteit` | Actie | `gebeld met`, `verwijsbrief ontvangen` |
|
||||
|
||||
#### Intake Start Intents (2)
|
||||
| Intent | Type | Patterns nodig |
|
||||
|--------|------|----------------|
|
||||
| `intake_starten` | Actie | `start intake`, `nieuwe intake` |
|
||||
| `intake_lijst` | Query | `toon intakes`, `welke intakes` |
|
||||
|
||||
#### Intake Navigatie (3)
|
||||
| Intent | Type | Patterns nodig |
|
||||
|--------|------|----------------|
|
||||
| `intake_navigeer` | Navigatie | `ga naar risico`, `open kindcheck` |
|
||||
| `intake_volgende` | Navigatie | `volgende stap`, `ga verder` |
|
||||
| `intake_vorige` | Navigatie | `vorige`, `terug` |
|
||||
|
||||
#### Intake Tab Intents (14)
|
||||
| Intent | Type | Tab |
|
||||
|--------|------|-----|
|
||||
| `contact_toevoegen` | Actie | Contactmomenten |
|
||||
| `contacten_query` | Query | Contactmomenten |
|
||||
| `kindcheck_invullen` | Actie | Kindcheck |
|
||||
| `kindcheck_query` | Query | Kindcheck |
|
||||
| `risico_toevoegen` | Actie | Risicotaxatie |
|
||||
| `risico_query` | Query | Risicotaxatie |
|
||||
| `anamnese_toevoegen` | Actie | Anamnese |
|
||||
| `anamnese_query` | Query | Anamnese |
|
||||
| `onderzoek_toevoegen` | Actie | Onderzoeken |
|
||||
| `onderzoeken_query` | Query | Onderzoeken |
|
||||
| `rom_toevoegen` | Actie | ROM |
|
||||
| `rom_query` | Query | ROM |
|
||||
| `diagnose_toevoegen` | Actie | Diagnose |
|
||||
| `diagnose_query` | Query | Diagnose |
|
||||
| `behandeladvies_invoer` | Actie | Behandeladvies |
|
||||
| `behandeladvies_query` | Query | Behandeladvies |
|
||||
|
||||
#### Intake Afsluiten (3)
|
||||
| Intent | Type | Patterns nodig |
|
||||
|--------|------|----------------|
|
||||
| `intake_afsluiten` | Actie | `sluit intake af`, `intake afronden` |
|
||||
| `intake_samenvatting` | Query | `samenvatting intake` |
|
||||
| `intake_checklist` | Query | `wat moet ik nog doen`, `is intake compleet` |
|
||||
|
||||
### 3.2 Cortex Blocks (9 ontbreken)
|
||||
|
||||
| Block | Doel | Data bron |
|
||||
|-------|------|-----------|
|
||||
| `ScreeningBlock` | Screening overzicht | `getScreeningSummary()` |
|
||||
| `IntakeListBlock` | Lijst intakes van patiënt | `getIntakesByPatientId()` |
|
||||
| `IntakeStatusBlock` | Voortgang/checklist | Nieuwe functie nodig |
|
||||
| `KindcheckBlock` | Kindcheck samenvatting | `getKindcheck()` |
|
||||
| `RisicoBlock` | Risico's met levels | `getRiskAssessments()` |
|
||||
| `AnamneseBlock` | Anamnese samenvatting | `getAnamneses()` |
|
||||
| `DiagnoseBlock` | Diagnoses lijst | `getDiagnoses()` |
|
||||
| `BehandeladviesBlock` | Behandeladvies tonen | `getTreatmentAdvice()` |
|
||||
| `IntakeSamenvattingBlock` | AI samenvatting | Nieuwe AI functie nodig |
|
||||
|
||||
### 3.3 Cortex API Routes (ontbreken)
|
||||
|
||||
| Route | Methode | Functie |
|
||||
|-------|---------|---------|
|
||||
| `/api/cortex/screening` | GET | Screening data voor Cortex |
|
||||
| `/api/cortex/intake` | GET | Intake lijst |
|
||||
| `/api/cortex/intake/[id]` | GET | Intake details |
|
||||
| `/api/cortex/intake/[id]/status` | GET | Intake voortgang/checklist |
|
||||
| `/api/cortex/intake/[id]/risks` | GET | Risico's van intake |
|
||||
| `/api/cortex/intake/[id]/diagnoses` | GET | Diagnoses van intake |
|
||||
| `/api/cortex/intake/[id]/summary` | GET | AI samenvatting |
|
||||
|
||||
### 3.4 Reflex Patterns (ontbreken)
|
||||
|
||||
In `lib/cortex/reflex-classifier.ts` moeten patterns worden toegevoegd voor alle 26 intents.
|
||||
|
||||
---
|
||||
|
||||
## 4. Architectuur Gap
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ HUIDIGE SITUATIE │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ CORTEX EPD │
|
||||
│ ┌─────────────────┐ ┌─────────────────┐ │
|
||||
│ │ 7 Intents │ │ Screening UI │ │
|
||||
│ │ 6 Blocks │ ❌ │ Intake UI (9) │ │
|
||||
│ │ 8 API routes │ ─ ─ ─ ─ ─ ─ │ Server Actions │ │
|
||||
│ └─────────────────┘ GEEN LINK └─────────────────┘ │
|
||||
│ │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ GEWENSTE SITUATIE │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ CORTEX EPD │
|
||||
│ ┌─────────────────┐ ┌─────────────────┐ │
|
||||
│ │ 7 + 26 Intents │ │ Screening UI │ │
|
||||
│ │ 6 + 9 Blocks │ ✅ │ Intake UI (9) │ │
|
||||
│ │ 8 + 7 API routes│ ◀──────────▶ │ Server Actions │ │
|
||||
│ └─────────────────┘ GEKOPPELD └─────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Implementatie Roadmap
|
||||
|
||||
### Fase 1: Foundation (Query Intents)
|
||||
|
||||
**Doel:** Informatie opvragen via spraak
|
||||
|
||||
| # | Taak | Effort | Prioriteit |
|
||||
|---|------|--------|------------|
|
||||
| 1.1 | Intent types toevoegen aan `types.ts` | S | 🔴 |
|
||||
| 1.2 | Patterns toevoegen aan `reflex-classifier.ts` | M | 🔴 |
|
||||
| 1.3 | `IntakeStatusBlock` bouwen | M | 🔴 |
|
||||
| 1.4 | `RisicoBlock` bouwen | S | 🔴 |
|
||||
| 1.5 | `DiagnoseBlock` bouwen | S | 🟡 |
|
||||
| 1.6 | `/api/cortex/intake/*` routes | M | 🔴 |
|
||||
|
||||
**Resultaat:** "Wat zijn de risico's?", "Is de intake compleet?" werken
|
||||
|
||||
### Fase 2: Navigation (Navigatie Intents)
|
||||
|
||||
**Doel:** Navigeren via spraak
|
||||
|
||||
| # | Taak | Effort | Prioriteit |
|
||||
|---|------|--------|------------|
|
||||
| 2.1 | `intake_navigeer` patterns | S | 🔴 |
|
||||
| 2.2 | Navigation handler in orchestrator | M | 🔴 |
|
||||
| 2.3 | Router integratie | M | 🟡 |
|
||||
|
||||
**Resultaat:** "Ga naar diagnose", "Open kindcheck" werken
|
||||
|
||||
### Fase 3: Actions (Actie Intents)
|
||||
|
||||
**Doel:** Data invoeren via spraak
|
||||
|
||||
| # | Taak | Effort | Prioriteit |
|
||||
|---|------|--------|------------|
|
||||
| 3.1 | `intake_starten` intent + handler | M | 🟡 |
|
||||
| 3.2 | `risico_toevoegen` intent + handler | L | 🟡 |
|
||||
| 3.3 | `diagnose_toevoegen` intent + handler | L | 🟡 |
|
||||
| 3.4 | Confirmatie dialogen | M | 🟡 |
|
||||
|
||||
**Resultaat:** "Start intake", "Risico suïcidaliteit matig" werken
|
||||
|
||||
### Fase 4: Intelligence (AI Features)
|
||||
|
||||
**Doel:** Slimme AI functionaliteit
|
||||
|
||||
| # | Taak | Effort | Prioriteit |
|
||||
|---|------|--------|------------|
|
||||
| 4.1 | `IntakeSamenvattingBlock` met AI | L | 🔵 |
|
||||
| 4.2 | Intake-gerelateerde nudges | M | 🔵 |
|
||||
| 4.3 | Context-aware suggestions | L | 🔵 |
|
||||
|
||||
**Resultaat:** "Samenvatting intake", proactieve suggesties werken
|
||||
|
||||
---
|
||||
|
||||
## 6. Effort Schatting
|
||||
|
||||
| Fase | Items | Effort |
|
||||
|------|-------|--------|
|
||||
| Fase 1: Foundation | 6 taken | ~3-4 dagen |
|
||||
| Fase 2: Navigation | 3 taken | ~1-2 dagen |
|
||||
| Fase 3: Actions | 4 taken | ~3-4 dagen |
|
||||
| Fase 4: Intelligence | 3 taken | ~2-3 dagen |
|
||||
| **Totaal** | **16 taken** | **~10-13 dagen** |
|
||||
|
||||
---
|
||||
|
||||
## 7. Quick Wins
|
||||
|
||||
Snel te implementeren met hoge waarde:
|
||||
|
||||
### 7.1 `intake_status` Query (1 dag)
|
||||
|
||||
```typescript
|
||||
// Input: "Wat moet ik nog doen?" / "Is de intake compleet?"
|
||||
// Output: Checklist met voltooide/openstaande tabs
|
||||
|
||||
// Nieuwe functie nodig:
|
||||
async function getIntakeCompletionStatus(intakeId: string) {
|
||||
const intake = await getIntakeById(intakeId);
|
||||
const kindcheck = await getKindcheck(intakeId);
|
||||
const risks = await getRiskAssessments(intakeId);
|
||||
const diagnoses = await getDiagnoses(intakeId);
|
||||
// etc...
|
||||
|
||||
return {
|
||||
algemeen: !!intake,
|
||||
kindcheck: !!kindcheck.hasChildren !== undefined,
|
||||
risicotaxatie: risks.length > 0,
|
||||
diagnose: diagnoses.length > 0,
|
||||
// ...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### 7.2 `risico_query` (0.5 dag)
|
||||
|
||||
```typescript
|
||||
// Input: "Wat zijn de risico's?"
|
||||
// Output: RisicoBlock met bestaande getRiskAssessments()
|
||||
|
||||
// Block template:
|
||||
<RisicoBlock
|
||||
risks={[
|
||||
{ type: 'suicidaliteit', level: 'matig', rationale: '...' },
|
||||
{ type: 'agressie', level: 'laag', rationale: '...' }
|
||||
]}
|
||||
/>
|
||||
```
|
||||
|
||||
### 7.3 `intake_navigeer` (0.5 dag)
|
||||
|
||||
```typescript
|
||||
// Input: "Ga naar diagnose"
|
||||
// Output: router.push() naar juiste tab
|
||||
|
||||
// Pattern matching:
|
||||
{ pattern: /^ga\s+naar\s+(risico|diagnose|kindcheck|anamnese)/i, weight: 1.0 }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Dependencies
|
||||
|
||||
```
|
||||
types.ts (intent definitions)
|
||||
↓
|
||||
reflex-classifier.ts (patterns)
|
||||
↓
|
||||
/api/cortex/intake/* (data routes)
|
||||
↓
|
||||
blocks/*.tsx (UI components)
|
||||
↓
|
||||
canvas-area.tsx (block rendering)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Risico's
|
||||
|
||||
| Risico | Impact | Mitigatie |
|
||||
|--------|--------|-----------|
|
||||
| Intake context niet beschikbaar | Hoog | ActiveIntake store toevoegen |
|
||||
| Meerdere intakes per patiënt | Middel | Intent clarification bij ambiguïteit |
|
||||
| Performance bij grote datasets | Laag | Pagination in queries |
|
||||
| Pattern overlap met bestaande intents | Middel | Goede escalation logic |
|
||||
|
||||
---
|
||||
|
||||
## 10. Aanbeveling
|
||||
|
||||
**Start met Fase 1 (Query Intents)** omdat:
|
||||
1. Hergebruikt bestaande server actions
|
||||
2. Geen destructieve acties (veilig)
|
||||
3. Direct waarde voor gebruiker
|
||||
4. Legt foundation voor actie intents
|
||||
|
||||
**Eerste implementatie:**
|
||||
1. `intake_status` - "Wat moet ik nog doen?"
|
||||
2. `risico_query` - "Wat zijn de risico's?"
|
||||
3. `intake_navigeer` - "Ga naar diagnose"
|
||||
|
||||
Deze 3 intents dekken de belangrijkste use case: snel navigeren en informatie opvragen tijdens een intake sessie.
|
||||
234
docs/intent/intake-intent-proces/intake-process-image-prompts.md
Normal file
234
docs/intent/intake-intent-proces/intake-process-image-prompts.md
Normal file
@@ -0,0 +1,234 @@
|
||||
# Text-to-Image Prompts: Intake Proces Visualisatie
|
||||
|
||||
**Doel:** Prompts voor het genereren van visualisaties van het Cortex intake proces
|
||||
|
||||
---
|
||||
|
||||
## 1. Overzichtsprompt (Hero Image)
|
||||
|
||||
### Voor: Midjourney / DALL-E 3
|
||||
|
||||
```
|
||||
A clean, modern healthcare software interface showing an AI-powered patient intake workflow.
|
||||
|
||||
The image displays a split view:
|
||||
- Left side: A vertical process flow with connected nodes showing stages: "Screening" → "Intake Start" → "Assessment" → "Diagnosis" → "Treatment Plan", each node glowing softly in teal/cyan
|
||||
- Right side: A sleek dashboard interface with a voice input bar at the top showing a waveform, and card-based UI components below displaying patient information
|
||||
|
||||
The design aesthetic is minimal, professional healthcare software with a white background, subtle shadows, and accent colors in teal (#0d9488) and slate gray. Small microphone icon indicates voice control.
|
||||
|
||||
Style: Clean UI mockup, flat design, healthcare technology, professional, minimalist
|
||||
Aspect ratio: 16:9
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Process Flow Diagram
|
||||
|
||||
### Voor: Midjourney / Ideogram
|
||||
|
||||
```
|
||||
A horizontal workflow diagram for a medical intake process, infographic style.
|
||||
|
||||
Four connected phases flowing left to right:
|
||||
1. "SCREENING" - icon of clipboard with checkmark, showing "Hulpvraag" and "Besluit"
|
||||
2. "INTAKE" - icon of folder opening, showing 9 small tab icons stacked
|
||||
3. "ASSESSMENT" - icon of stethoscope and brain, showing "Risico", "Diagnose", "Anamnese"
|
||||
4. "BEHANDELPLAN" - icon of document with heart, showing "Doelen" and "Interventies"
|
||||
|
||||
Arrows connect each phase. Below each phase, small cards show the key data points.
|
||||
|
||||
Color scheme: Teal (#0d9488) for primary, soft grays for backgrounds, white cards with subtle shadows. Modern healthcare aesthetic, clean lines, professional.
|
||||
|
||||
Style: Process infographic, flat icons, medical software, flowchart
|
||||
Aspect ratio: 21:9 (ultrawide)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Voice Intent Interactie
|
||||
|
||||
### Voor: DALL-E 3 / Midjourney
|
||||
|
||||
```
|
||||
A modern healthcare software interface demonstrating voice-controlled AI assistant interaction.
|
||||
|
||||
Center focus: A floating command bar with a glowing microphone icon and the Dutch text "Wat zijn de risico's van Jan?" displayed as voice input with a subtle sound waveform.
|
||||
|
||||
Below the command bar: Three response cards appearing in a staggered layout:
|
||||
- Card 1: "Suïcidaliteit - Matig" with orange indicator
|
||||
- Card 2: "Agressie - Laag" with green indicator
|
||||
- Card 3: "Zelfverwaarlozing - Laag" with green indicator
|
||||
|
||||
The interface has a soft blur effect on the background showing a patient dashboard. A small AI assistant avatar or brain icon indicates the system is processing.
|
||||
|
||||
Style: Voice UI, conversational interface, healthcare app, glassmorphism, modern
|
||||
Aspect ratio: 4:3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Intake Tabs UI
|
||||
|
||||
### Voor: Midjourney / Stable Diffusion
|
||||
|
||||
```
|
||||
A detailed healthcare software interface showing a patient intake workflow with 9 horizontal tabs.
|
||||
|
||||
The tab bar displays: "Algemeen | Contacten | Kindcheck | Risico | Anamnese | Onderzoek | ROM | Diagnose | Behandeladvies"
|
||||
|
||||
The "Risico" tab is highlighted/active in teal. Below shows a risk assessment form with:
|
||||
- Risk type dropdown showing "Suïcidaliteit"
|
||||
- Severity scale: Laag / Matig / Hoog / Zeer hoog (Matig selected)
|
||||
- Notes textarea
|
||||
- Action items checklist
|
||||
|
||||
Left sidebar shows patient info card with name, age, photo placeholder.
|
||||
|
||||
Clean, professional medical software aesthetic. White background, teal accents, clear typography, organized layout.
|
||||
|
||||
Style: Healthcare EHR interface, medical software UI, dashboard design, professional
|
||||
Aspect ratio: 16:10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Cortex Command Center
|
||||
|
||||
### Voor: DALL-E 3
|
||||
|
||||
```
|
||||
A futuristic but professional healthcare AI command center interface called "Cortex".
|
||||
|
||||
Top section: A prominent voice/text input bar with placeholder "Vraag iets of geef een opdracht..." and a microphone button, subtle glow effect.
|
||||
|
||||
Main area shows three "action blocks" in a grid:
|
||||
1. "Intake Status" card - circular progress indicator showing 6/9 complete, checklist of remaining items
|
||||
2. "Risicotaxatie" card - risk assessment summary with colored severity badges
|
||||
3. "Volgende Actie" card - AI suggestion "Kindcheck invullen?" with accept/dismiss buttons
|
||||
|
||||
Bottom: Recent actions timeline showing "Diagnose toegevoegd", "Risico bijgewerkt" with timestamps.
|
||||
|
||||
Right sidebar: Active patient context showing "Jan de Vries" with key info.
|
||||
|
||||
Color palette: Teal primary (#0d9488), white backgrounds, slate text, subtle gradients. Modern healthcare technology feel.
|
||||
|
||||
Style: AI dashboard, healthcare technology, command center UI, modern minimal
|
||||
Aspect ratio: 16:9
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Intent Classification Diagram
|
||||
|
||||
### Voor: Ideogram / Midjourney
|
||||
|
||||
```
|
||||
A technical diagram showing AI intent classification for healthcare voice commands.
|
||||
|
||||
Center: A brain/neural network icon labeled "Cortex AI"
|
||||
|
||||
Three incoming arrows from the left showing voice inputs:
|
||||
- "Start intake voor Jan"
|
||||
- "Wat zijn de risico's?"
|
||||
- "Ga naar diagnose"
|
||||
|
||||
Three outgoing arrows to the right showing classified intents with icons:
|
||||
- "intake_starten" → folder icon → "Actie"
|
||||
- "risico_query" → search icon → "Query"
|
||||
- "intake_navigeer" → arrow icon → "Navigatie"
|
||||
|
||||
Below: A confidence meter showing "Reflex: 0.9" and "AI Fallback" path for low confidence.
|
||||
|
||||
Style: Technical flowchart, AI/ML diagram, clean infographic, developer documentation
|
||||
Aspect ratio: 16:9
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Mobile Voice Assistant
|
||||
|
||||
### Voor: DALL-E 3 / Midjourney
|
||||
|
||||
```
|
||||
A healthcare professional's hand holding a tablet device showing a voice-activated patient intake assistant.
|
||||
|
||||
The tablet screen displays:
|
||||
- Top: Patient header "Marie Jansen - Intake #2024-0042"
|
||||
- Center: Large circular voice activation button with pulsing animation rings
|
||||
- Below: Recent voice command "Kindcheck: geen kinderen" with checkmark
|
||||
- Bottom: Suggested next actions as pill-shaped buttons: "Risicotaxatie", "Anamnese", "Diagnose"
|
||||
|
||||
Background: Soft-focus hospital/clinic environment with warm lighting.
|
||||
|
||||
The overall feel is modern healthcare technology that's approachable and easy to use.
|
||||
|
||||
Style: Healthcare technology, tablet UI, medical app, professional photography composite
|
||||
Aspect ratio: 3:4 (portrait)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Before/After Comparison
|
||||
|
||||
### Voor: Midjourney
|
||||
|
||||
```
|
||||
A split-screen comparison image showing healthcare workflow transformation.
|
||||
|
||||
LEFT SIDE labeled "Traditioneel":
|
||||
- Cluttered desktop with multiple windows open
|
||||
- Paper forms scattered
|
||||
- Mouse clicking through endless menus
|
||||
- Stressed healthcare worker
|
||||
- Gray, busy, overwhelming
|
||||
|
||||
RIGHT SIDE labeled "Met Cortex":
|
||||
- Clean single interface
|
||||
- Voice waveform indicating speech input
|
||||
- Organized card-based results
|
||||
- Calm, focused healthcare worker
|
||||
- Bright, organized, efficient
|
||||
|
||||
A diagonal dividing line separates the two sides. The contrast emphasizes simplicity vs complexity.
|
||||
|
||||
Style: Comparison infographic, before/after, healthcare technology marketing
|
||||
Aspect ratio: 2:1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Prompt Tips
|
||||
|
||||
### Stijl Keywords
|
||||
- Healthcare software / Medical EHR / Clinical interface
|
||||
- Clean UI / Minimal design / Professional
|
||||
- Voice interface / AI assistant / Conversational UI
|
||||
- Dashboard / Card-based layout / Modern web app
|
||||
|
||||
### Kleurenpalet
|
||||
- Primary: Teal `#0d9488`
|
||||
- Background: White `#ffffff`, Slate `#f1f5f9`
|
||||
- Text: Slate `#1e293b`
|
||||
- Accents: Amber (warning), Red (high risk), Green (success)
|
||||
|
||||
### Vermijden
|
||||
- Geen stockfoto-achtige healthcare beelden (stethoscopen, witte jassen)
|
||||
- Geen te futuristische sci-fi elementen
|
||||
- Geen drukke, overladen interfaces
|
||||
- Geen generieke "AI brain" clichés
|
||||
|
||||
---
|
||||
|
||||
## Aanbevolen Model per Prompt
|
||||
|
||||
| Prompt | Best Model | Reden |
|
||||
|--------|------------|-------|
|
||||
| 1. Hero Image | DALL-E 3 | Beste voor UI mockups |
|
||||
| 2. Process Flow | Ideogram | Sterk in diagrammen |
|
||||
| 3. Voice Intent | DALL-E 3 | Goed met tekst in beeld |
|
||||
| 4. Tabs UI | Midjourney | Gedetailleerde interfaces |
|
||||
| 5. Command Center | DALL-E 3 | Complexe UI compositie |
|
||||
| 6. Intent Diagram | Ideogram | Technische diagrammen |
|
||||
| 7. Mobile | Midjourney | Realistische composities |
|
||||
| 8. Before/After | Midjourney | Conceptuele vergelijkingen |
|
||||
330
docs/intent/intake-intent-proces/intake-process-intents.md
Normal file
330
docs/intent/intake-intent-proces/intake-process-intents.md
Normal file
@@ -0,0 +1,330 @@
|
||||
# Intake Proces: Flow, Intents & UI
|
||||
|
||||
**Datum:** 03-02-2026
|
||||
**Status:** Ontwerp
|
||||
**Doel:** Documentatie van het intake proces met bijbehorende Cortex intents en UI componenten
|
||||
|
||||
---
|
||||
|
||||
## 1. Procesoverzicht
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ INTAKE PROCES │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────────┐ │
|
||||
│ │ SCREENING │ ──▶ │ INTAKE START │ ──▶ │ INTAKE UITVOERING │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ • Hulpvraag │ │ • Titel │ │ ┌────────────────────┐ │ │
|
||||
│ │ • Documenten │ │ • Afdeling │ │ │ 1. Algemeen │ │ │
|
||||
│ │ • Activiteit │ │ • Startdatum │ │ │ 2. Contactmomenten │ │ │
|
||||
│ │ • Besluit │ │ │ │ │ 3. Kindcheck │ │ │
|
||||
│ └──────────────┘ └──────────────┘ │ │ 4. Risicotaxatie │ │ │
|
||||
│ │ │ │ │ 5. Anamnese │ │ │
|
||||
│ ▼ │ │ │ 6. Onderzoeken │ │ │
|
||||
│ geschikt? ───▶ NEE ───▶ STOP │ │ 7. ROM │ │ │
|
||||
│ │ │ │ 8. Diagnose │ │ │
|
||||
│ JA │ │ 9. Behandeladvies │ │ │
|
||||
│ └────────────────────┘ │ └────────────────────┘ │ │
|
||||
│ │ │ │ │
|
||||
│ └─────────────┼────────────┘ │
|
||||
│ ▼ │
|
||||
│ ┌──────────────────────────┐ │
|
||||
│ │ INTAKE AFSLUITEN │ │
|
||||
│ │ │ │
|
||||
│ │ • Status: afgerond │ │
|
||||
│ │ • Einddatum │ │
|
||||
│ │ → Start Behandelplan │ │
|
||||
│ └──────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Fase 1: Screening
|
||||
|
||||
### 2.1 Procesbeschrijving
|
||||
|
||||
De screening is de eerste beoordeling of een patiënt geschikt is voor behandeling. Hier wordt de hulpvraag vastgelegd, documenten verzameld (verwijsbrief), en een besluit genomen.
|
||||
|
||||
### 2.2 UI Componenten
|
||||
|
||||
| Component | Pad | Beschrijving |
|
||||
|-----------|-----|--------------|
|
||||
| `ScreeningPage` | `app/epd/patients/[id]/screening/page.tsx` | Container pagina |
|
||||
| `HelpRequestCard` | `screening/components/help-request-card.tsx` | Hulpvraag invoer (textarea) |
|
||||
| `DecisionCard` | `screening/components/decision-card.tsx` | Besluit: geschikt/niet_geschikt + afdeling |
|
||||
| `DocumentCard` | `screening/components/document-card.tsx` | Upload verwijsbrief en documenten |
|
||||
| `ActivityLog` | `screening/components/activity-log.tsx` | Chronologisch activiteitenlog |
|
||||
|
||||
### 2.3 Intents & Queries
|
||||
|
||||
| Intent | Type | Input Voorbeelden | Output/Actie |
|
||||
|--------|------|-------------------|--------------|
|
||||
| `screening_query` | Query | "Toon screening van Jan"<br>"Wat is de hulpvraag?" | `ScreeningBlock` - overzicht hulpvraag, besluit, status |
|
||||
| `hulpvraag_invoer` | Actie | "Hulpvraag: angstklachten en slaapproblemen"<br>"Noteer hulpvraag: depressieve klachten" | Vult `HelpRequestCard` in |
|
||||
| `screening_besluit` | Actie | "Jan is geschikt voor behandeling"<br>"Niet geschikt, doorverwijzen" | Vult `DecisionCard` in |
|
||||
| `screening_activiteit` | Actie | "Gebeld met huisarts over verwijzing"<br>"Verwijsbrief ontvangen" | Voegt toe aan `ActivityLog` |
|
||||
|
||||
### 2.4 Nudges
|
||||
|
||||
| Trigger | Nudge | Priority |
|
||||
|---------|-------|----------|
|
||||
| Hulpvraag ingevuld, geen verwijsbrief | "Verwijsbrief uploaden?" | medium |
|
||||
| Verwijsbrief + hulpvraag compleet | "Screeningsbesluit nemen?" | medium |
|
||||
| Besluit = geschikt | "Intake starten voor deze patiënt?" | low |
|
||||
|
||||
---
|
||||
|
||||
## 3. Fase 2: Intake Starten
|
||||
|
||||
### 3.1 Procesbeschrijving
|
||||
|
||||
Na een positief screeningsbesluit wordt een nieuwe intake aangemaakt met basisgegevens.
|
||||
|
||||
### 3.2 UI Componenten
|
||||
|
||||
| Component | Pad | Beschrijving |
|
||||
|-----------|-----|--------------|
|
||||
| `NewIntakePage` | `intakes/new/page.tsx` | Formulier voor nieuwe intake |
|
||||
| `NewIntakeForm` | `intakes/components/new-intake-form.tsx` | Titel, afdeling, startdatum |
|
||||
| `IntakeList` | `intakes/components/intake-list.tsx` | Overzicht alle intakes van patiënt |
|
||||
|
||||
### 3.3 Intents & Queries
|
||||
|
||||
| Intent | Type | Input Voorbeelden | Output/Actie |
|
||||
|--------|------|-------------------|--------------|
|
||||
| `intake_starten` | Actie | "Start intake voor Jan"<br>"Nieuwe intake afdeling Volwassenen" | Opent `NewIntakeForm` met prefill |
|
||||
| `intake_lijst` | Query | "Toon intakes van Jan"<br>"Welke intakes heeft Marie?" | `IntakeListBlock` - lijst met status |
|
||||
|
||||
---
|
||||
|
||||
## 4. Fase 3: Intake Uitvoering
|
||||
|
||||
### 4.1 Overzicht Tabs
|
||||
|
||||
| # | Tab | Verplicht | Component | Beschrijving |
|
||||
|---|-----|-----------|-----------|--------------|
|
||||
| 1 | Algemeen | ✅ | `IntakePage` | Basisgegevens intake |
|
||||
| 2 | Contactmomenten | ❌ | `ContactManager` | Gesprekken, telefoontjes |
|
||||
| 3 | Kindcheck | ⚠️* | `KindcheckForm` | Kinderen in beeld, zorgen, acties |
|
||||
| 4 | Risicotaxatie | ✅ | `RiskManager` | Suïcidaliteit, agressie, etc. |
|
||||
| 5 | Anamnese | ✅ | `AnamneseManager` | Psychiatrisch, sociaal, somatisch |
|
||||
| 6 | Onderzoeken | ❌ | `ExaminationManager` | Lichamelijk, psychologisch onderzoek |
|
||||
| 7 | ROM | ❌ | `ExaminationManager` (isRom) | Vragenlijsten (OQ-45, etc.) |
|
||||
| 8 | Diagnose | ✅ | `DiagnosisManager` | ICD-10 classificaties |
|
||||
| 9 | Behandeladvies | ✅ | `TreatmentAdviceForm` | Advies, programma, behandelaar |
|
||||
|
||||
*Kindcheck is wettelijk verplicht bij patiënten met kinderen
|
||||
|
||||
### 4.2 Tab-specifieke Intents
|
||||
|
||||
#### 4.2.1 Algemeen
|
||||
|
||||
| Intent | Type | Input | Output |
|
||||
|--------|------|-------|--------|
|
||||
| `intake_algemeen` | Query | "Toon intake gegevens"<br>"Wanneer is de intake gestart?" | Toont algemene info |
|
||||
| `intake_status` | Query | "Wat is de status van de intake?"<br>"Is de intake compleet?" | Status + checklist onvolledige secties |
|
||||
|
||||
#### 4.2.2 Contactmomenten
|
||||
|
||||
| Intent | Type | Input | Output |
|
||||
|--------|------|-------|--------|
|
||||
| `contact_toevoegen` | Actie | "Intakegesprek gehad met Jan"<br>"Telefonisch contact: besproken wachttijd" | Voegt contactmoment toe |
|
||||
| `contacten_query` | Query | "Welke contactmomenten zijn er geweest?" | Lijst contactmomenten |
|
||||
|
||||
#### 4.2.3 Kindcheck
|
||||
|
||||
| Intent | Type | Input | Output |
|
||||
|--------|------|-------|--------|
|
||||
| `kindcheck_invullen` | Actie | "Kindcheck: 2 kinderen, geen zorgen"<br>"Geen kinderen in beeld" | Vult kindcheck formulier |
|
||||
| `kindcheck_query` | Query | "Is de kindcheck gedaan?"<br>"Hoeveel kinderen heeft Jan?" | Status + samenvatting |
|
||||
|
||||
#### 4.2.4 Risicotaxatie
|
||||
|
||||
| Intent | Type | Input | Output |
|
||||
|--------|------|-------|--------|
|
||||
| `risico_toevoegen` | Actie | "Risico suïcidaliteit: matig"<br>"Agressierisico laag" | Voegt risico toe aan `RiskManager` |
|
||||
| `risico_query` | Query | "Wat zijn de risico's van Jan?"<br>"Toon risicotaxatie" | Risico overzicht met levels |
|
||||
|
||||
#### 4.2.5 Anamnese
|
||||
|
||||
| Intent | Type | Input | Output |
|
||||
|--------|------|-------|--------|
|
||||
| `anamnese_toevoegen` | Actie | "Psychiatrische anamnese: eerste depressie 2019"<br>"Sociale anamnese: woont alleen" | Voegt anamnese sectie toe |
|
||||
| `anamnese_query` | Query | "Wat is de voorgeschiedenis?"<br>"Toon anamnese" | Anamnese overzicht |
|
||||
|
||||
#### 4.2.6 Onderzoeken
|
||||
|
||||
| Intent | Type | Input | Output |
|
||||
|--------|------|-------|--------|
|
||||
| `onderzoek_toevoegen` | Actie | "Psychologisch onderzoek aangevraagd"<br>"Lab: bloedonderzoek normaal" | Voegt onderzoek toe |
|
||||
| `onderzoeken_query` | Query | "Welke onderzoeken zijn gedaan?" | Lijst onderzoeken + resultaten |
|
||||
|
||||
#### 4.2.7 ROM
|
||||
|
||||
| Intent | Type | Input | Output |
|
||||
|--------|------|-------|--------|
|
||||
| `rom_toevoegen` | Actie | "ROM: OQ-45 score 82"<br>"PHQ-9 afgenomen, score 14" | Voegt ROM-meting toe |
|
||||
| `rom_query` | Query | "Wat zijn de ROM scores?"<br>"Toon vragenlijsten" | ROM overzicht met scores |
|
||||
|
||||
#### 4.2.8 Diagnose
|
||||
|
||||
| Intent | Type | Input | Output |
|
||||
|--------|------|-------|--------|
|
||||
| `diagnose_toevoegen` | Actie | "Diagnose: depressieve stoornis"<br>"Hoofddiagnose F32.1" | Opent ICD-10 zoeken + voegt toe |
|
||||
| `diagnose_query` | Query | "Wat zijn de diagnoses?"<br>"Welke diagnose heeft Jan?" | Diagnose overzicht |
|
||||
|
||||
#### 4.2.9 Behandeladvies
|
||||
|
||||
| Intent | Type | Input | Output |
|
||||
|--------|------|-------|--------|
|
||||
| `behandeladvies_invoer` | Actie | "Behandeladvies: CGT bij angst"<br>"Advies: EMDR voor trauma" | Vult behandeladvies formulier |
|
||||
| `behandeladvies_query` | Query | "Wat is het behandeladvies?"<br>"Toon advies" | Behandeladvies overzicht |
|
||||
|
||||
### 4.3 Navigatie Intents
|
||||
|
||||
| Intent | Type | Input | Output |
|
||||
|--------|------|-------|--------|
|
||||
| `intake_navigeer` | Navigatie | "Ga naar risicotaxatie"<br>"Open kindcheck"<br>"Naar diagnose" | Navigeert naar specifieke tab |
|
||||
| `intake_volgende` | Navigatie | "Volgende stap"<br>"Ga verder" | Navigeert naar volgende tab |
|
||||
| `intake_vorige` | Navigatie | "Vorige"<br>"Terug" | Navigeert naar vorige tab |
|
||||
|
||||
---
|
||||
|
||||
## 5. Fase 4: Intake Afsluiten
|
||||
|
||||
### 5.1 Procesbeschrijving
|
||||
|
||||
Wanneer alle verplichte secties zijn ingevuld, kan de intake worden afgesloten.
|
||||
|
||||
### 5.2 Intents
|
||||
|
||||
| Intent | Type | Input | Output |
|
||||
|--------|------|-------|--------|
|
||||
| `intake_afsluiten` | Actie | "Sluit intake af"<br>"Intake afronden" | Zet status op 'afgerond' + einddatum |
|
||||
| `intake_samenvatting` | Query | "Samenvatting intake"<br>"Geef overzicht van de intake" | AI-gegenereerde samenvatting |
|
||||
| `intake_checklist` | Query | "Wat moet ik nog doen?"<br>"Is de intake compleet?" | Checklist onvolledige secties |
|
||||
|
||||
### 5.3 Nudges
|
||||
|
||||
| Trigger | Nudge | Priority |
|
||||
|---------|-------|----------|
|
||||
| Alle verplichte secties ingevuld | "Intake afsluiten?" | medium |
|
||||
| Intake afgesloten | "Behandelplan opstellen?" | low |
|
||||
| Intake > 4 weken open | "Intake nog actueel? Afsluiten of voortzetten?" | low |
|
||||
|
||||
---
|
||||
|
||||
## 6. Intent Matrix (Totaaloverzicht)
|
||||
|
||||
### 6.1 Alle Intents
|
||||
|
||||
| # | Intent ID | Type | Fase | Priority |
|
||||
|---|-----------|------|------|----------|
|
||||
| 1 | `screening_query` | Query | Screening | 🔴 Hoog |
|
||||
| 2 | `hulpvraag_invoer` | Actie | Screening | 🟡 Middel |
|
||||
| 3 | `screening_besluit` | Actie | Screening | 🟡 Middel |
|
||||
| 4 | `screening_activiteit` | Actie | Screening | 🔵 Laag |
|
||||
| 5 | `intake_starten` | Actie | Start | 🔴 Hoog |
|
||||
| 6 | `intake_lijst` | Query | Start | 🟡 Middel |
|
||||
| 7 | `intake_navigeer` | Navigatie | Uitvoering | 🔴 Hoog |
|
||||
| 8 | `intake_status` | Query | Uitvoering | 🔴 Hoog |
|
||||
| 9 | `contact_toevoegen` | Actie | Uitvoering | 🟡 Middel |
|
||||
| 10 | `kindcheck_invullen` | Actie | Uitvoering | 🟡 Middel |
|
||||
| 11 | `kindcheck_query` | Query | Uitvoering | 🟡 Middel |
|
||||
| 12 | `risico_toevoegen` | Actie | Uitvoering | 🔴 Hoog |
|
||||
| 13 | `risico_query` | Query | Uitvoering | 🔴 Hoog |
|
||||
| 14 | `anamnese_toevoegen` | Actie | Uitvoering | 🟡 Middel |
|
||||
| 15 | `anamnese_query` | Query | Uitvoering | 🟡 Middel |
|
||||
| 16 | `onderzoek_toevoegen` | Actie | Uitvoering | 🔵 Laag |
|
||||
| 17 | `onderzoeken_query` | Query | Uitvoering | 🔵 Laag |
|
||||
| 18 | `rom_toevoegen` | Actie | Uitvoering | 🟡 Middel |
|
||||
| 19 | `rom_query` | Query | Uitvoering | 🟡 Middel |
|
||||
| 20 | `diagnose_toevoegen` | Actie | Uitvoering | 🔴 Hoog |
|
||||
| 21 | `diagnose_query` | Query | Uitvoering | 🔴 Hoog |
|
||||
| 22 | `behandeladvies_invoer` | Actie | Uitvoering | 🔴 Hoog |
|
||||
| 23 | `behandeladvies_query` | Query | Uitvoering | 🔴 Hoog |
|
||||
| 24 | `intake_afsluiten` | Actie | Afsluiten | 🟡 Middel |
|
||||
| 25 | `intake_samenvatting` | Query | Afsluiten | 🟡 Middel |
|
||||
| 26 | `intake_checklist` | Query | Afsluiten | 🟡 Middel |
|
||||
|
||||
### 6.2 Verdeling
|
||||
|
||||
| Type | Aantal |
|
||||
|------|--------|
|
||||
| Query | 13 |
|
||||
| Actie | 11 |
|
||||
| Navigatie | 2 |
|
||||
| **Totaal** | **26** |
|
||||
|
||||
| Priority | Aantal |
|
||||
|----------|--------|
|
||||
| 🔴 Hoog | 10 |
|
||||
| 🟡 Middel | 13 |
|
||||
| 🔵 Laag | 3 |
|
||||
|
||||
---
|
||||
|
||||
## 7. UI Blocks (Nieuw te bouwen)
|
||||
|
||||
Voor Cortex moeten we nieuwe blocks bouwen die de intent resultaten tonen:
|
||||
|
||||
| Block | Toont | Bron Data |
|
||||
|-------|-------|-----------|
|
||||
| `ScreeningBlock` | Hulpvraag, besluit, status | `getScreeningSummary()` |
|
||||
| `IntakeStatusBlock` | Checklist tabs, voortgang | Nieuwe functie nodig |
|
||||
| `IntakeListBlock` | Lijst intakes van patiënt | `getIntakesByPatient()` |
|
||||
| `KindcheckBlock` | Samenvatting kindcheck | `getKindcheck()` |
|
||||
| `RisicoBlock` | Risico's met levels | `getRiskAssessments()` |
|
||||
| `AnamneseBlock` | Anamnese samenvatting | `getAnamneses()` |
|
||||
| `DiagnoseBlock` | Diagnoses lijst | `getDiagnoses()` |
|
||||
| `BehandeladviesBlock` | Behandeladvies | `getTreatmentAdvice()` |
|
||||
| `IntakeSamenvattingBlock` | AI-samenvatting hele intake | Nieuwe AI functie nodig |
|
||||
|
||||
---
|
||||
|
||||
## 8. Implementatie Prioriteit
|
||||
|
||||
### 8.1 MVP (Fase 1)
|
||||
|
||||
Focus op de meest waardevolle intents:
|
||||
|
||||
1. **`intake_status`** - "Wat moet ik nog doen?" → Checklist
|
||||
2. **`intake_navigeer`** - "Ga naar risicotaxatie" → Direct navigeren
|
||||
3. **`risico_query`** - "Wat zijn de risico's?" → Risico overzicht
|
||||
4. **`diagnose_query`** - "Welke diagnoses?" → Diagnose overzicht
|
||||
5. **`intake_samenvatting`** - "Samenvatting intake" → AI samenvatting
|
||||
|
||||
### 8.2 Fase 2
|
||||
|
||||
6. **`screening_query`** - Screening overzicht
|
||||
7. **`kindcheck_query`** - Kindcheck status
|
||||
8. **`behandeladvies_query`** - Behandeladvies tonen
|
||||
9. **`intake_starten`** - Nieuwe intake via spraak
|
||||
|
||||
### 8.3 Fase 3 (Actie intents)
|
||||
|
||||
10. **`risico_toevoegen`** - Risico toevoegen via spraak
|
||||
11. **`diagnose_toevoegen`** - Diagnose toevoegen
|
||||
12. **`kindcheck_invullen`** - Kindcheck invullen
|
||||
13. Overige actie intents...
|
||||
|
||||
---
|
||||
|
||||
## 9. Open Vragen
|
||||
|
||||
1. **Contextbeheer**: Hoe weet Cortex welke intake actief is als een patiënt meerdere intakes heeft?
|
||||
2. **Navigatie vs Blocks**: Navigeren we naar bestaande pagina's of tonen we data in Cortex blocks?
|
||||
3. **Actie confirmatie**: Welke acties vereisen bevestiging voordat ze uitgevoerd worden?
|
||||
4. **Integratie behandelplan**: Hoe koppelen we intake-afsluiting aan behandelplan-start?
|
||||
|
||||
---
|
||||
|
||||
## Versiehistorie
|
||||
|
||||
| Versie | Datum | Auteur | Wijziging |
|
||||
|--------|-------|--------|-----------|
|
||||
| v0.1 | 03-02-2026 | Colin Lit | Initieel ontwerp |
|
||||
@@ -0,0 +1,221 @@
|
||||
# Text-to-Image Prompt: Intake Procesflow met Intents
|
||||
|
||||
**Doel:** Visualisatie van het complete intake proces met spraak-intents en EPD schermen
|
||||
|
||||
---
|
||||
|
||||
## Prompt (DALL-E 3 / Ideogram)
|
||||
|
||||
```
|
||||
A detailed horizontal process flow diagram for a Dutch healthcare EPD (Electronic Patient Dossier) system showing voice intents triggering UI screens.
|
||||
|
||||
The diagram flows LEFT to RIGHT through 4 main phases, each in a distinct colored zone:
|
||||
|
||||
PHASE 1 - "SCREENING" (light blue zone):
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Voice intents (speech bubbles): │
|
||||
│ • "Wat is de hulpvraag?" │
|
||||
│ • "Jan is geschikt voor behandeling" │
|
||||
│ ↓ │
|
||||
│ EPD Screens (UI cards): │
|
||||
│ [HelpRequestCard] [DecisionCard] │
|
||||
│ [DocumentCard] [ActivityLog] │
|
||||
└─────────────────────────────────────────┘
|
||||
|
||||
Arrow → to next phase
|
||||
|
||||
PHASE 2 - "INTAKE START" (light green zone):
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Voice intents: │
|
||||
│ • "Start intake voor Jan" │
|
||||
│ • "Nieuwe intake Volwassenen" │
|
||||
│ ↓ │
|
||||
│ EPD Screens: │
|
||||
│ [NewIntakeForm] │
|
||||
│ - Titel │
|
||||
│ - Afdeling │
|
||||
│ - Startdatum │
|
||||
└─────────────────────────────────────────┘
|
||||
|
||||
Arrow → to next phase
|
||||
|
||||
PHASE 3 - "INTAKE UITVOERING" (light teal zone, largest section):
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 9 TABS displayed as a horizontal tab bar: │
|
||||
│ [Algemeen|Contact|Kindcheck|Risico|Anamnese|Onderzoek|ROM|Diagnose|Advies] │
|
||||
│ │
|
||||
│ Below: 3 columns of intent→screen mappings: │
|
||||
│ │
|
||||
│ Column 1: Column 2: Column 3: │
|
||||
│ "Ga naar risico" "Wat zijn de risico's?" "Diagnose: depressie" │
|
||||
│ ↓ ↓ ↓ │
|
||||
│ [RiskManager] [RisicoBlock] [DiagnosisManager] │
|
||||
│ │
|
||||
│ "Kindcheck: geen kinderen" "Is intake compleet?" "Behandeladvies CGT" │
|
||||
│ ↓ ↓ ↓ │
|
||||
│ [KindcheckForm] [IntakeStatusBlock] [TreatmentAdviceForm] │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
Arrow → to next phase
|
||||
|
||||
PHASE 4 - "AFSLUITEN" (light purple zone):
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Voice intents: │
|
||||
│ • "Sluit intake af" │
|
||||
│ • "Samenvatting intake" │
|
||||
│ ↓ │
|
||||
│ EPD Screens: │
|
||||
│ [IntakeSummaryBlock] │
|
||||
│ [Status: Afgerond ✓] │
|
||||
│ ↓ │
|
||||
│ "Start behandelplan" → │
|
||||
└─────────────────────────────────────────┘
|
||||
|
||||
LEGEND at bottom:
|
||||
🎤 = Voice Intent (input)
|
||||
📱 = EPD Screen/Component (output)
|
||||
→ = Process flow
|
||||
↓ = Intent triggers screen
|
||||
|
||||
Design style: Clean technical flowchart, software architecture diagram, white background with subtle colored zones for each phase. Speech bubbles for intents, rounded rectangles for UI components. Arrows showing relationships. Professional documentation style.
|
||||
|
||||
Typography: Sans-serif, clear hierarchy, Dutch language labels.
|
||||
Colors: Screening=#e0f2fe, Start=#dcfce7, Uitvoering=#ccfbf1, Afsluiten=#f3e8ff, Arrows=#0d9488
|
||||
Aspect ratio: 21:9 (ultrawide) or 3:1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Alternatief: Verticale Flow (voor A4/portrait)
|
||||
|
||||
```
|
||||
A vertical process flow diagram for a Dutch healthcare intake system showing voice commands and their corresponding EPD screens.
|
||||
|
||||
TOP TO BOTTOM layout with 4 stacked sections:
|
||||
|
||||
SECTION 1 - SCREENING
|
||||
├── Intent bubble: "Wat is de hulpvraag van Jan?"
|
||||
├── Arrow down
|
||||
└── Screen cards: [HelpRequestCard] [DecisionCard]
|
||||
|
||||
SECTION 2 - INTAKE START
|
||||
├── Intent bubble: "Start intake voor Jan"
|
||||
├── Arrow down
|
||||
└── Screen card: [NewIntakeForm]
|
||||
|
||||
SECTION 3 - INTAKE TABS (expanded section)
|
||||
├── Tab bar showing 9 tabs
|
||||
├── Three example flows side by side:
|
||||
│ ├── "Ga naar risico" → [RiskManager]
|
||||
│ ├── "Wat zijn diagnoses?" → [DiagnoseBlock]
|
||||
│ └── "Kindcheck geen kinderen" → [KindcheckForm]
|
||||
|
||||
SECTION 4 - AFSLUITEN
|
||||
├── Intent bubble: "Sluit intake af"
|
||||
├── Arrow down
|
||||
└── Screen cards: [IntakeSummaryBlock] → Behandelplan
|
||||
|
||||
Visual style: Technical documentation, swim lane diagram, clear sections with subtle background colors, speech bubbles for voice input, device frames for screens.
|
||||
|
||||
Aspect ratio: 9:16 or A4 portrait
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Simpele Versie (voor snelle generatie)
|
||||
|
||||
```
|
||||
A software flowchart showing voice commands triggering healthcare screens.
|
||||
|
||||
Four colored columns left to right:
|
||||
1. SCREENING (blue): "Hulpvraag?" → HelpRequestCard
|
||||
2. INTAKE START (green): "Start intake" → NewIntakeForm
|
||||
3. UITVOERING (teal): "Risico's?" → RiskManager, "Diagnose?" → DiagnosisManager
|
||||
4. AFSLUITEN (purple): "Samenvatting" → IntakeSummaryBlock
|
||||
|
||||
Speech bubbles connect to UI component boxes with arrows.
|
||||
Clean, minimal, technical diagram style.
|
||||
White background, colored section headers.
|
||||
|
||||
Aspect ratio: 16:9
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mermaid Diagram (voor technische docs)
|
||||
|
||||
Als je liever een exacte diagram wilt die je zelf kunt renderen:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph SCREENING["🔵 SCREENING"]
|
||||
I1["🎤 Wat is de hulpvraag?"]
|
||||
I2["🎤 Jan is geschikt"]
|
||||
S1["📱 HelpRequestCard"]
|
||||
S2["📱 DecisionCard"]
|
||||
I1 --> S1
|
||||
I2 --> S2
|
||||
end
|
||||
|
||||
subgraph START["🟢 INTAKE START"]
|
||||
I3["🎤 Start intake voor Jan"]
|
||||
S3["📱 NewIntakeForm"]
|
||||
I3 --> S3
|
||||
end
|
||||
|
||||
subgraph UITVOERING["🔷 INTAKE UITVOERING"]
|
||||
direction TB
|
||||
TABS["9 Tabs: Algemeen | Contact | Kindcheck | Risico | Anamnese | Onderzoek | ROM | Diagnose | Advies"]
|
||||
|
||||
I4["🎤 Ga naar risico"]
|
||||
I5["🎤 Wat zijn de risico's?"]
|
||||
I6["🎤 Diagnose: depressie"]
|
||||
I7["🎤 Kindcheck: geen kinderen"]
|
||||
|
||||
S4["📱 RiskManager"]
|
||||
S5["📱 RisicoBlock"]
|
||||
S6["📱 DiagnosisManager"]
|
||||
S7["📱 KindcheckForm"]
|
||||
|
||||
I4 --> S4
|
||||
I5 --> S5
|
||||
I6 --> S6
|
||||
I7 --> S7
|
||||
end
|
||||
|
||||
subgraph AFSLUITEN["🟣 AFSLUITEN"]
|
||||
I8["🎤 Sluit intake af"]
|
||||
I9["🎤 Samenvatting intake"]
|
||||
S8["📱 IntakeSummaryBlock"]
|
||||
S9["📱 Status: Afgerond ✓"]
|
||||
I8 --> S9
|
||||
I9 --> S8
|
||||
end
|
||||
|
||||
SCREENING --> START
|
||||
START --> UITVOERING
|
||||
UITVOERING --> AFSLUITEN
|
||||
AFSLUITEN -->|"Start behandelplan"| BP["📱 BehandelplanView"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Prompt Parameters
|
||||
|
||||
| Parameter | Waarde |
|
||||
|-----------|--------|
|
||||
| **Model** | DALL-E 3, Ideogram, of Midjourney |
|
||||
| **Style** | Technical diagram / Software flowchart |
|
||||
| **Aspect** | 21:9 (ultrawide) voor horizontaal, 9:16 voor verticaal |
|
||||
| **Kleuren** | Fase-gebonden: blauw→groen→teal→paars |
|
||||
| **Taal** | Nederlands (intent teksten) |
|
||||
|
||||
---
|
||||
|
||||
## Tips voor beste resultaat
|
||||
|
||||
1. **DALL-E 3**: Beste voor tekst in afbeeldingen, maar kan moeite hebben met complexe diagrammen
|
||||
2. **Ideogram**: Zeer sterk in diagrammen en flowcharts met tekst
|
||||
3. **Midjourney**: Mooi visueel maar minder nauwkeurig met tekst
|
||||
|
||||
**Aanbeveling**: Gebruik Ideogram voor dit type technische procesflow, of maak het diagram in Figma/Miro en gebruik AI alleen voor styling.
|
||||
Reference in New Issue
Block a user