Files
triqura-ecd/docs/intent/noshow-case/epics/NS-E5-integration.md
colinislit 924988dd15 feat(cortex): no-show casus — intent flow, brief-rescript en document artifact
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>
2026-07-09 23:14:55 +02:00

10 KiB
Raw Blame History

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.E1NS.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 handleAcceptNudgehandleNoShowRescriptStep

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 TypeError of undefined is not a function errors

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_show intent herkend (zichtbaar in console)
  • Input "no show vandaag"register_no_show intent herkend
  • Input "cliënt was er niet" → AI classificeert als register_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/contexthasConceptBrief: 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 build slaagt zonder errors
  • pnpm lint slaagt 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