We bouwen aan twee systemen die samen één geheel moeten vormen: het GGZ‑ECD als eerste toepassing, TIP als het intent‑platform eronder. We hebben allebei dezelfde vraag op tafel — welke API’s hebben we nodig? — maar die is pas te beantwoorden als we samen de rolverdeling kiezen. Er leven nu twee verschillende beelden van hoe de systemen samenwerken, en die leiden tot verschillende API’s, verschillende datamodellen en een andere taakverdeling tussen de teams.
De kernvraag van dit stuk: hoe verdelen ECD en TIP het werk — TIP als beslisplatform dat het ECD voedt met gegevens, of TIP als intent‑laag die met het ECD meekijkt? Die keuze bepaalt óók het verhaal van het platform richting volgende domeinen. Een gezamenlijke productkeuze dus, geen techniekvraag van één van beide kanten.
Er komen drie sporen samen:
Het ECD wordt opnieuw opgebouwd. Het huidige prototype leunt op Supabase en FHIR‑conventies die eruit gaan. Er komt een eigen PostgreSQL‑datamodel onder, met voorbereiding op pgvector (semantisch zoeken) en Neo4j (ZPM‑relaties). Het moment om de architectuur goed te snijden is nú.
Het intent‑systeem komt uit TIP. De oorspronkelijke Cortex‑architectuur ging uit van een intent-motor als TypeScript‑bibliotheek ín de ECD‑app (lib/cortex/). TIP bestaat inmiddels als zelfstandig platform (Python‑services, eigen runtime) en is domein‑agnostisch opgezet: het GGZ‑ECD is de eerste toepassing, andere domeinen moeten volgen. Het ECD bewijst het platform; het platform draagt het ECD.
De gedeelde vraag: “welke API’s hebben we eigenlijk nodig?” Die vraag speelt aan beide kanten en is niet te beantwoorden zonder eerst samen de rolverdeling te kiezen. Bij het naast elkaar leggen van beide codebases bleek dat de twee beelden van die rolverdeling (§3) nu nog uiteenlopen — dat is geen probleem, maar wel iets om expliciet te maken vóór we contracten vastleggen.
Legenda: ECD klinische applicatie & dossier · TIP intent-platform.
TIP heeft geen eigen administratie. Trek je TIP eruit, dan werkt het ECD nog steeds — alleen zonder taalinterface. Dit is het model uit het oorspronkelijke Cortex‑architectuurdocument (vgl. “AI‑laag boven Chipsoft/Nexus”).
TIP werkt pas als het gevoed wordt: documenten, gebeurtenissen en gegevens moeten naar TIP gepusht worden. TIP houdt zelf bij waar elke casus staat. Trek je de datafeed eruit, dan is TIP blind.
Beide paden in TIP — het gestructureerde pad (intentregels over Information Elements) en het ongestructureerde pad (vrije tekst via /detect) — leveren dezelfde intent op. Maar alleen het ongestructureerde pad werkt zonder datafeed. De kracht van TIP — regels, scenario’s, zorgpaden — zit in het gestructureerde pad, en dat vereist Model B.
Deze opzet is een logische ontwerpkeuze. Elke beslislaag moet de data kunnen zien waarover hij beslist. De Information‑Element‑laag is precies wat TIP domein‑agnostisch maakt: het platform hoeft geen enkel bronsysteem te kennen, zolang bronsystemen hun gegevens als IE’s aanleveren. Er hoort alleen een consequentie bij die we samen moeten inplannen: een toepassing op TIP aansluiten betekent altijd een datafeed naar TIP bouwen — integratiewerk aan beide kanten, geen laag die je er los oplegt.
Hoe Model B er in de praktijk uitziet, stap voor stap. Let op waar de state terechtkomt.
Een verwijsbrief komt binnen (ZorgDomein, e-mail, upload). Het ECD slaat de brief op in het klinisch dossier en stuurt hem als artifact door naar TIP.
TIP maakt in zijn eigen database een workspace referral aan en extraheert Information Elements: verwijzer, verwijsreden, urgentie.
Een intentregel vuurt: “urgentie hoog én geen intake gepland → intent: intake inplannen”. Het scenario zet een menselijke taak klaar — TIP voert nooit zelf uit.
State in TIP: intent gevuurd · taak open · wacht op behandelaarHet ECD toont de taak. De behandelaar bevestigt (human‑in‑the‑loop) en de intake‑afspraak wordt in het ECD vastgelegd — het klinische feit leeft in het ECD.
Het ECD meldt de voltooiing terug aan TIP als event, zodat TIP weet dat de taak is afgerond en de procesfase verschuift.
State in TIP: fase verwijzing afgerond · intake gepland| ECD (klinische database) | TIP (platform-database) | |
|---|---|---|
| Bevat | Klinische feiten: rapportages, afspraken, diagnoses, de brief zelf | Proces-state: fase, workspaces, IE’s, gevuurde intents, open taken |
| Bron van waarheid voor | Het medisch dossier | “Waar staat het proces en wat moet er gebeuren” |
Zolang die scheiding scherp is — ECD = klinische feiten, TIP = proces- en beslislogica — is dit gezond. Het risico ontstaat waar hetzelfde feit op twee plekken leeft. “Intake gepland op 14 juli” bestaat als afspraak in het ECD én als IE in TIP. Wordt de afspraak in het ECD verzet, dan moet er een event naar TIP — anders beslist TIP op verouderde informatie. Per gegeven moet dus vastliggen wie eigenaar is; de ander kent het alleen als afgeleide kopie.
/detect — TIP als echte laagHet oorspronkelijke beeld: tekst in, intent uit, verder niets.
Het ECD roept alleen de intent‑detectieservice aan. Alle state, regels, nudges en procesbewaking worden in het ECD zelf gebouwd (zoals in het oorspronkelijke Cortex‑ontwerp).
Dun, stateless contract. Geen synchronisatievraagstuk. ECD blijft volledig autonoom; TIP‑uitval betekent alleen “geen taalinterface”.
We gebruiken ~10% van het platform en bouwen intentregels, scenario’s en taken dubbel in het ECD. Twee regelmotoren in twee talen die uit elkaar groeien.
TIP-kant vrijwel niets — /detect bestaat al. ECD-kant het meeste werk: alle beslislogica zelf bouwen. En de platformbelofte blijft onbeproefd.
Het ECD wordt registratie + UI; TIP doet alle beslislogica.
Elk relevant document en elke gebeurtenis gaat naar TIP. TIP bewaakt fases, evalueert regels, zet taken klaar. Het ECD toont en registreert.
TIP’s volle kracht: zorgpaden, intentregels, audit‑chain. Regels wijzigen zonder ECD‑deployment. Sterkste bewijs voor TIP’s platformbelofte.
ECD‑datamodel en TIP’s dossiermodel moeten sámen ontworpen worden — geen twee projecten meer, maar één systeem in twee repo’s. Eigenaarschap per gegeven en de eventfeed moeten vanaf dag één kloppen. Grote wederzijdse afhankelijkheid, nog vóór we het samenspel in het klein hebben beproefd.
ECD-kant: een volledige datafeed (artifacts, events) en taak-UI. TIP-kant: stabiele push‑API, GGZ‑workspace‑typen en beschikbaarheidsafspraken — het ECD leunt in dit model op het platform.
/detect + één gestructureerde flowKlein beginnen op het pad naar Model B, met een echte proef van de datafeed.
Fase 1: /detect voor de taalinterface. Fase 2: één flow gestructureerd via TIP — instroom (verwijsbrief → intake), precies de flow uit §4. Chat en entity resolution blijven bewust in het ECD. Pas daarna per flow uitbreiden.
Het dubbele‑administratie‑vraagstuk wordt in het klein beproefd vóór het hele ECD eraan hangt. Het API‑contract groeit mee met bewezen behoefte in plaats van vooraf gegokt. Beide teams houden tempo.
Tijdelijk hybride: sommige logica in het ECD, sommige in TIP. Vereist discipline om per flow expliciet te besluiten wáár die landt — anders ontstaat sluipenderwijs alsnog dubbeling.
TIP-kant: /detect (bestaat) + artifact‑ en event‑push voor één workspace‑type (referral) en een taken‑endpoint. ECD-kant: de feed voor die ene flow bouwen en taken tonen & afmelden in de UI. Samen: eigenaarschap vastleggen voor de gegevens in deze flow.
De snijlijn die in alle routes overeind blijft: TIP kent geen patiëntnamen en geen schermen; het ECD kent geen intentregels en geen scenario’s. Entity resolution (“jan” → patiënt #427) vereist toegang tot het patiëntenbestand en hoort daarmee aan de ECD‑kant — of het ECD stuurt kandidaten mee in de request.
Afgeleid uit de bestaande gebruikersflows van het ECD, gemapt op de huidige TIP‑API. Dit is de feitelijke basis onder onze gedeelde API‑vraag — per regel: wat de flow nodig heeft en waar dat vandaag staat.
| ECD-flow | Nodig van TIP | Status in TIP |
|---|---|---|
| Commando typen/inspreken → intent + prefill | POST /detect |
✓ bestaat |
| Verwijsbrief/document binnen → gegevens eruit | Artifact-push + IE-extractie in workspace | ✓ bestaat (data layer) |
| Na actie → vervolgsuggestie (nudge) | Event-push → intentregels → taak terug | △ model bestaat; push-API vanuit het ECD moet in het contract |
| Bevestiging behandelaar (human-in-the-loop) | /human-gates, taken ophalen & afmelden |
✓ bestaat |
| Beheer: intents, regels, scenario’s configureren | /intents, /rules, /contexts, /scenarios |
✓ bestaat |
| Audit-inzage | /audit/events, /audit/chain |
✓ bestaat |
| Chat (streaming, conversationeel) | — | ✗ nog nergens belegd — samen kiezen: ECD-kant of platform-roadmap (ai-engine) |
| Entity resolution (“jan” → patiënt #427) | — | ✗ hoort ECD-kant: vereist patiëntendata |
| Kennisbank / RAG (bronverwijzing bij suggestie) | — | ✗ nog niet zichtbaar in TIP |
Sluiten toepassingen aan op TIP (Model B), of legt TIP zich als laag op toepassingen (Model A)? Deze keuze maken we samen: hij bepaalt het verhaal richting álle toekomstige domeinen, niet alleen dit ECD.
Voorstel in dit stuk: route 3 — /detect plus de instroomflow als proef. Akkoord, of zien we het anders?
Per gegeven vastleggen: leidend in het ECD of in TIP, en hoe de ander de kopie actueel houdt (events). Startpunt: de gegevens uit de instroomflow.
Het ontbrekende stuk contract voor route 3: hoe levert het ECD documenten en gebeurtenissen aan, en hoe haalt het taken op en meldt het ze af?
Drie behoeftes die nu nergens belegd zijn. Bewust ECD-kant houden, of op de platform-roadmap (bijv. de ai-engine-service)? Per stuk samen besluiten.