Cortex handelt een no-show af vanuit één chatcommando: afspraak annuleren (declarabiliteits-nudge), en de openstaande concept- huisartsbrief wordt via LLM herschreven en ter review aangeboden in een document artifact (human-in-the-loop, PATCH dispatch zet status op verzendklaar). - API-routes: context, rescript, cancel, dispatch - NoShowDocumentBlock: review/edit UI met origineel-vergelijk - Mock-data voor concept huisartsbrief - PRD, FO, bouwplan en epics in docs/intent/noshow-case/ Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
10 KiB
NS.E5 — Integration & Demo Polish
Casus: Cortex No Show Afhandeling Epic doel: De volledige end-to-end flow werkend krijgen, edge cases afvangen, en de demo valideren aan de succescriteria uit het PRD. Geschatte tijd: ~2 uur Afhankelijkheden: NS.E1 t/m NS.E4 volledig afgerond
Context
Na NS.E1–NS.E4 zijn alle individuele onderdelen gebouwd:
- Intent wordt herkend (E1)
- Nudges triggeren en lopen sequentieel (E2)
- API routes werken (E3)
- Artifact component toont de brief (E4)
Dit epic zorgt dat alles correct samenwerkt, fouten netjes worden afgevangen, en de demo vloeiend loopt.
NS.E5.S1 — Volledige chat-panel.tsx integratie valideren
Bestand: components/cortex/chat/chat-panel.tsx
Checklist: zijn alle functies aanwezig en correct verbonden?
Na NS.E2 en NS.E4 moeten de volgende functies bestaan in ChatPanel:
| Functie | Aangemaakt in | Doet |
|---|---|---|
handleNoShowCancelStep |
NS.E2.S3 | Cancel API → context check → nudge 2 of done |
handleNoShowRescriptStep |
NS.E4.S3 | Rescript API → openArtifact |
handleAcceptNudge (uitgebreid) |
NS.E2.S3 | Brancht op trigger.intent en suggestion.rationale |
Verbinding handleAcceptNudge → handleNoShowRescriptStep
Controleer dat de stap-5 check correct is geïmplementeerd:
const handleAcceptNudge = useCallback(async (
suggestionId: string,
suggestion: ChatMessageType['nudge']
) => {
acceptSuggestion(suggestionId);
if (!suggestion) return;
// Stap 2→3: declarabiliteitscheck geaccepteerd → annuleer + check brief
if (suggestion.trigger.intent === 'register_no_show') {
await handleNoShowCancelStep(suggestion);
return;
}
// Stap 4→5: brief-check geaccepteerd → herschrijf brief
if (suggestion.suggestion.rationale === 'noshow-brief-check') {
await handleNoShowRescriptStep();
return;
}
// Generieke flow voor alle andere nudges
const artifact = routeIntentToArtifact(
suggestion.suggestion.intent,
suggestion.suggestion.entities,
0.9
);
if (artifact) {
openArtifact({ type: artifact.type, prefill: artifact.prefill, title: artifact.title });
}
}, [
acceptSuggestion,
openArtifact,
handleNoShowCancelStep,
handleNoShowRescriptStep,
]);
Belangrijk: handleNoShowCancelStep en handleNoShowRescriptStep moeten in de useCallback dependency array staan. Als ze er niet in staan, kan je stale closures krijgen.
onSend handler: no-show nudge trigger
Controleer dat de onDone callback de no-show nudge triggert. Dit blok moet aanwezig zijn in de onDone:
// No-show nudge trigger na register_no_show classificatie
if (parsed.action?.intent === 'register_no_show' && isFeatureEnabled('CORTEX_NUDGE')) {
const suggestions = evaluateNudge({
intent: 'register_no_show',
actionId: crypto.randomUUID(),
entities: parsed.action.entities,
content: message,
});
suggestions.forEach((suggestion) => {
addChatMessage({
type: 'nudge',
content: suggestion.suggestion.message,
nudge: suggestion,
});
});
}
Done criteria
- Volledige flow doorloopbaar zonder errors in de browser console
[ChatPanel]log berichten verschijnen op de juiste momenten- Geen
TypeErrorofundefined is not a functionerrors
NS.E5.S2 — Loading states en dubbele submits voorkomen
Bestand: components/cortex/chat/chat-panel.tsx + stores/cortex-store.ts
Probleem
Tussen de API calls (cancel → context → rescript) zit latentie. Als de gebruiker snel klikt, kunnen er dubbele calls ontstaan. Ook moet de UI duidelijk maken dat er iets "bezig" is.
Oplossing A — isNoShowProcessing flag in store
Voeg toe aan store (in CortexStore interface, initialState, en actions):
// In interface:
isNoShowProcessing: boolean;
// In initialState:
isNoShowProcessing: false,
// Actions:
setNoShowProcessing: (processing: boolean) => void;
Implementatie:
setNoShowProcessing: (processing) =>
set({ isNoShowProcessing: processing }, false, 'setNoShowProcessing'),
Oplossing B — Gebruik in handleNoShowCancelStep en handleNoShowRescriptStep
Wrap elke async functie:
const handleNoShowCancelStep = useCallback(async (...) => {
const { isNoShowProcessing } = useCortexStore.getState();
if (isNoShowProcessing) return; // Dubbele klik preventie
setNoShowProcessing(true);
try {
// ... bestaande logica
} finally {
setNoShowProcessing(false);
}
}, [..., setNoShowProcessing]);
Oplossing C — Nudge knop disablen tijdens processing
In NudgeChatMessage is de accept/dismiss knop al aanwezig. We moeten de accept knop disablen tijdens isNoShowProcessing:
Bestand: components/cortex/chat/nudge-chat-message.tsx
Voeg toe:
const isNoShowProcessing = useCortexStore((s) => s.isNoShowProcessing);
Voeg disabled={isNoShowProcessing} toe aan de accept-knop als de nudge een no-show nudge is (suggestion.trigger.intent === 'register_no_show' of suggestion.suggestion.rationale === 'noshow-brief-check').
Done criteria
- Snel twee keer klikken op
[Ja, annuleer]triggert de API maar één keer - Knop is visueel disabled tijdens verwerking
- Na voltooiing is de knop weer actief (relevant voor de "Nee" knop)
NS.E5.S3 — Cleanup bij unmount
Bestand: components/cortex/chat/chat-panel.tsx
Als de gebruiker weg navigeert tijdens een lopende no-show flow, moet de state worden opgeruimd.
Voeg toe in ChatPanel:
const resetNoShowFlow = useCortexStore((s) => s.resetNoShowFlow);
// Cleanup bij unmount
useEffect(() => {
return () => {
// Reset no-show flow als component unmount tijdens actieve flow
const { noShowFlow } = useCortexStore.getState();
if (noShowFlow.step !== 'idle' && noShowFlow.step !== 'done') {
resetNoShowFlow();
}
};
}, [resetNoShowFlow]);
Done criteria
- Navigeren weg van het dashboard tijdens een actieve no-show flow reset de state
- Bij terugkeren: flow begint opnieuw (geen "stuck" state)
NS.E5.S4 — Demo Validatie Checklist
Doorloop de volledige flow handmatig en vink elk punt af:
Classificatie
- Input
"patiënt is niet verschenen"→register_no_showintent herkend (zichtbaar in console) - Input
"no show vandaag"→register_no_showintent herkend - Input
"cliënt was er niet"→ AI classificeert alsregister_no_show - Input
"patiënt niet verschenen volgende week"→ escaleert naar AI (relative_time)
Nudge 1 — Declarabiliteitscheck
- Na no-show input: nudge bubble verschijnt met declarabiliteits-waarschuwing
- Nudge heeft prioriteit badge
high(rode kleur) [Nee]klik: nudge verdwijnt, geen verdere actie, flow eindigt[Ja, annuleer]klik: loading state actief (knop disabled)
Stap 3 — Annulering
- Cancel API aangeroepen:
POST /api/cortex/noshow/cancel→ 200 response - Context API aangeroepen:
GET /api/cortex/noshow/context→hasConceptBrief: true - Chat toont "Bezig met annuleren..." tijdens verwerking
- Na voltooiing: nudge 2 verschijnt met brief-vraag
Nudge 2 — Brief check
- Nudge 2 toont correcte message over conceptbrief
[Nee]klik: nudge verdwijnt, chat bevestigt annulering[Ja, pas brief aan]klik: rescript API aangeroepen
Stap 4 — Rescript
- Rescript API aangeroepen:
POST /api/cortex/noshow/rescript→ herschreven inhoud - Artifact paneel opent met
NoShowDocumentBlock - Chat toont "Huisartsbrief is aangepast. Kijk of je hiermee akkoord bent."
- Herschreven brief is NIET alleen de originele tekst met "no show" erachter geplakt
Stap 5 — Accordering
- Textarea is bewerkbaar — gebruiker kan aanpassingen maken
- "Originele brief bekijken" toggle werkt
[Akkoord & Verzendklaar]roept dispatch API aan- Na dispatch: knop verandert naar "✓ Verzendklaar"
- Chat ontvangt bevestigingsbericht
Technische criteria
- Volledige flow doorloopbaar in < 30 seconden (excl. LLM latency ~3-5s)
- Geen schermwissels nodig gedurende de hele flow
pnpm buildslaagt zonder errorspnpm lintslaagt zonder errors- Geen rode console errors in de browser
Edge cases
- Offline/netwerk fout tijdens cancel → error message in chat, flow herstelbaar
- LLM fout in rescript → originele brief getoond + gele waarschuwingsbalk
- Dubbele klik op
[Ja, annuleer]→ slechts één API call
NS.E5.S5 — Commit strategie
Commitvolgorde die logisch werkt voor code review:
feat(cortex): NS.E1 — register_no_show intent type + reflex patterns
feat(cortex): NS.E2.S1 — no-show flow state in cortex store
feat(cortex): NS.E2.S2 — nudge rule: declarabiliteitscheck
feat(cortex): NS.E2.S3 — chat panel: no-show nudge trigger + handlers
feat(cortex): NS.E3 — no-show API routes (cancel, context, rescript, dispatch)
feat(cortex): NS.E4.S1 — NoShowDocumentBlock component
feat(cortex): NS.E4.S2 — artifact-container: register_no_show case
feat(cortex): NS.E4.S3 — chat panel: rescript step + artifact koppeling
feat(cortex): NS.E5 — loading states, cleanup, demo polish
Elke commit moet pnpm build laten slagen.
Overzicht gewijzigde bestanden (totaal)
| Bestand | Wijziging |
|---|---|
lib/cortex/types.ts |
register_no_show in union + BLOCK_CONFIGS |
lib/cortex/reflex-classifier.ts |
Patronen voor register_no_show |
app/api/cortex/chat/route.ts |
System prompt uitgebreid |
lib/cortex/nudge.ts |
Nudge rule 1 toegevoegd |
stores/cortex-store.ts |
NoShowFlowState + actions + isNoShowProcessing |
lib/cortex/mock-data/noshow.ts |
Nieuw |
app/api/cortex/noshow/cancel/route.ts |
Nieuw |
app/api/cortex/noshow/context/route.ts |
Nieuw |
app/api/cortex/noshow/rescript/route.ts |
Nieuw |
app/api/cortex/noshow/dispatch/route.ts |
Nieuw |
components/cortex/blocks/noshow-document-block.tsx |
Nieuw |
components/cortex/artifacts/artifact-container.tsx |
Case + import + getArtifactTitle |
components/cortex/chat/chat-panel.tsx |
Nudge trigger + handlers + cleanup |
components/cortex/chat/nudge-chat-message.tsx |
isNoShowProcessing check |
Totaal: 14 bestanden — 5 nieuw, 9 aangepast