Gravety — Volledige architectuur
Elk systeem, elke dataflow, elke beslissing — uitgewerkt tot op tabelniveau. Dit document is de technische basis voor de bouw. Alle keuzes zijn onderbouwd.
Alles wat met zorg te maken heeft. Cliënten, begeleiders, gesprekken, check-ins, signalen, profielen. De app praat uitsluitend met Supabase. Row-level security zorgt voor isolatie tussen organisaties.
| Tabel / gebied | Inhoud | Versleuteld |
|---|---|---|
organizations | Naam, type, zorgpad, instellingen, SF Account ID | — |
org_ai_profiles | Methodieken, waarden, communicatiestandaard, grenzen, AI-prompt preview | — |
users | Naam, e-mail, rol, taal, beroepsgeheimbevestiging | ✓ naam + e-mail |
counselor_ai_profiles | Werkstijlsamenvatting (AI), persoonlijkheidsassessment, voorkeursaanpakken | — |
client_profiles | Stressbronnen, strategieën, dynamisch profiel, AI-suggesties | — |
consent_records | Welke toestemmingen zijn gegeven, wanneer, versie | — |
conversations | Metadata, zichtbaarheid voor begeleider, AI-samenvatting | ✓ ai_summary |
messages | Gespreksberichten — cliënt en AI | ✓ content (per-cliënt sleutel) |
check_ins | Dagelijkse en wekelijkse check-in antwoorden | — |
signals | Waarschuwingen + vooruitgang, redenering, betrouwbaarheidsscore, AI-zin | ✓ ai_sentence |
direct_messages | Berichten tussen begeleider en cliënt, crisisberichten | ✓ content |
goals | Doelen van cliënt, voortgang | — |
interventions | Uitgevoerde interventies, uitkomst, notities | ✓ notes |
zrm_assessments | ZRM-domeinscores, periode | ✓ notes |
org_knowledge_patterns | Organisatie-eigen kennislaag — anoniem, opt-in | — |
knowledge_patterns | Platform blackbox — anoniem, alle orgs die bijdragen | — |
pattern_nominations | Wachtrij voor platform-review door Gravety | — |
audit_log | Elke actie, door wie, wanneer — append-only | — |
| Bucket | Inhoud | Bewaartermijn | Toegang |
|---|---|---|---|
voice-memos | Spraakmemo's van cliënten (audio) | 30 dagen na transcriptie → auto-delete | Cliënt alleen |
voice-transcriptions | Whisper-transcripties (tekst) | 2 jaar (= berichten) | Cliënt + begeleider indien gedeeld |
exports | AVG-gegevensexports op cliëntverzoek | 48u na download → auto-delete | Cliënt alleen, tijdelijke URL |
| Object | Inhoud | Bron |
|---|---|---|
Account | Organisatienaam, type, status, Postgres UUID als External ID | Gesynchroniseerd vanuit Postgres |
Contact | Org-admin naam + e-mail, gekoppeld aan Account | Gesynchroniseerd vanuit Postgres |
Subscription__c | Seats, prijs, startdatum, verlengingsdatum | Handmatig of via Stripe webhook |
Task / Activity | Follow-ups, belafspraken, onboarding checkpoints | Handmatig door Gravety-team |
Campaign | Onboarding e-mailflows, renewal-campagnes, upsell | SF-native |
Health_Score__c | Anonieme score: % actieve cliënten, check-in score (geen persoonsdata) | Nachtelijk batch vanuit Postgres |
| ❌ Cliëntnamen | Nooit in Salesforce. Technisch geblokkeerd in sync-service. | |
| ❌ Gesprekken / check-ins | Nooit in Salesforce. | |
| Gebruik | Model | Wanneer | Data die OpenAI ziet |
|---|---|---|---|
| Companion chat | GPT-5.4 mini (stream) | Per bericht, real-time | Context stack (lagen 0–4) + huidig bericht. Nooit rauwe namen. |
| Moderatie | /v1/moderations | Elk bericht in + uit | Berichtinhoud (pseudoniem) |
| Sessie-samenvatting | GPT-5.4 mini | Na gesprek (async) | Gespreksberichten van die sessie |
| Signaal-analyse | GPT-5.4 mini | Async, na check-in of gesprek | Recente check-ins + gesprekssamenvattingen |
| Spraakmemo transcriptie | Whisper | Async na upload | Audiobestand (pseudoniem bestandsnaam) |
| Nominatie-analyse | GPT-5.4 nano | Batch, nachtelijk | Geanonimiseerde patroondata — geen persoonsdata |
Elke keer dat een cliënt een bericht stuurt, worden vijf lagen context samengesteld en als systeem-prompt naar OpenAI gestuurd. De org-laag staat bovenaan — die vormt alles daaronder.
Drie verwerkingsbanen: synchroon voor crisis (veiligheid vóór alles), async voor taalanalyse, nachtelijk batch voor patronen. Elk bericht doorloopt ze in deze volgorde.
Per bericht (elke keer dat de cliënt iets stuurt)
Na gesprek (triggered door 30 min inactiviteit of cliënt sluit af)
Nachtelijk batch (02:00 elke nacht)
De platform blackbox is Gravety's eigen kennislaag. Anonieme patronen van alle bijdragende organisaties. Nooit persoonlijk, nooit herleidbaar. De nominatie-flow heeft een menselijke reviewstap — initieel om de AI te trainen, later geautomatiseerd.
Nominatie → Review → Blackbox
→ source_intervention_id uit nomination gewist (definitief anoniem)
→ Beschikbaar voor AI-suggesties (min. 5 cases vereist)
→ Audit trail bewaart wie goedkeurde
→ Reden gaat in rejection_reasons tabel
→ AI traint op afwijzingen: patronen die X keer zijn afgewezen met zelfde reden worden niet meer genomineerd
→ Self-learning loop: hoe meer reviews, hoe beter de nominaties
Cliënten kunnen in plaats van typen een spraakmemo inspreken. De AI verwerkt dit als tekst. Het audio-bestand wordt na 30 dagen automatisch verwijderd — alleen de transcriptie blijft.
voice-memos. Bestandsnaam = UUID (geen herleidbare naam).messages tabel met type = 'voice_transcription'. Zelfde versleuteling als tekstberichten.Begeleiders kunnen instellen bij welk signaalniveau ze een pushmelding ontvangen. Kritieke signalen gaan altijd door. De app wordt als PWA (Progressive Web App) gebouwd — geen aparte native app nodig voor notificaties.
| Signaalniveau | Default | Instelbaar | Nacht (00:00–07:00) |
|---|---|---|---|
| Kritiek (zelfschade / crisis) | ✓ Aan | Niet uitschakelbaar | ✓ Altijd doorsturen |
| Hoog (terugval risico, agressie) | ✓ Aan | ✓ Uit te zetten | Alleen als begeleider 24/7 aan heeft |
| Laag / Monitor | ✗ Uit | ✓ Aan te zetten | Nooit |
| Vooruitgang | ✗ Uit | ✓ Aan te zetten | Nooit |
Alle organisaties zitten in dezelfde Supabase-instantie. Isolatie via Row Level Security (RLS) — goedkoper dan aparte instanties, veilig genoeg voor AVG op pilot-schaal. Encryptie per cliënt voegt een tweede isolatielaag toe.
| Rol | RLS-conditie | Ziet |
|---|---|---|
client | client_id = auth.uid() | Alleen eigen rijen in alle tabellen |
counselor | org_id = eigen org AND counselor_id = auth.uid() | Eigen cliënten (niet die van collega's) |
org_admin | org_id = eigen org | Alle begeleiders + cliënten in eigen org |
gravety_admin | target_table IN (organizations, knowledge_patterns) | Alleen org-metadata + platform kennislaag. Nooit cliëntinhoud. |
Eén-richtingssync. Postgres is altijd de bron. Salesforce volgt. Als de sync faalt, blijft de app gewoon werken.
| Data | Richting | Trigger | Velden |
|---|---|---|---|
| Nieuwe organisatie | Postgres → SF | Webhook bij INSERT op organizations | name, type, contact_email, postgres_uuid (als External ID) |
| SF Account ID terug | SF → Postgres | Sync-service schrijft terug na upsert | organizations.sf_account_id |
| Org-update (naam, type) | Postgres → SF | Webhook bij UPDATE op organizations | name, type (upsert op External ID) |
| Org health score | Postgres → SF | Nachtelijk batch | active_client_pct, checkin_score_7d (anoniem, geen persoonsdata) |
| Cliëntdata | Nooit | — | Technisch geblokkeerd in sync-service |
| Gesprekken / check-ins | Nooit | — | Technisch geblokkeerd |
| Signalen | Nooit | — | Technisch geblokkeerd |
Elke gebruiker heeft het recht zijn data te laten verwijderen. Dit is de exacte volgorde en wat er gebeurt bij elk niveau. Anonieme data in de kennislaag valt buiten het verwijderingsrecht (AVG Overweging 26).
Pascal begint fresh. Hier is de stapsgewijze opbouw — van gratis development-omgeving tot productie-CRM.
| Fase | Salesforce editie | Kosten | Wanneer |
|---|---|---|---|
| Development | Developer Edition | Gratis | Nu — Pascal bouwt datamodel en automaties |
| Pilot | Developer Edition of Starter ($25/user) | $0–75/maand | Bij eerste betalende klant — mogelijk Starter voor productie-features |
| Early growth | Starter Suite ($25/user) of Professional ($80/user) | $75–240/maand | Bij 5–20 org-klanten |
| Scale | Enterprise ($165/user) | Onderhandeld | Bij 50+ orgs en complexe automaties |
| Object | Type | Doel | Key velden |
|---|---|---|---|
Account | Standaard | Gravety-organisatie (zorginst.) | Name, Type, Postgres_UUID__c (External ID), Status__c |
Contact | Standaard | Org-admin contactpersoon | FirstName, LastName, Email, Role__c, AccountId |
Subscription__c | Custom object | Abonnement + seats | Account__c, Seats__c, Price__c, Start_Date__c, Renewal_Date__c, Status__c |
Health_Score__c | Custom object | Anonieme platform health metrics | Account__c, Active_Client_Pct__c, Checkin_Score__c, Date__c |
Campaign | Standaard | Onboarding flows, renewals | Name, Type, Status, StartDate |
De architectuur in één zin
Supabase/Postgres bewaart alles wat met zorg te maken heeft — versleuteld, in de EU, met row-level security per organisatie. Salesforce beheert de zakelijke kant. Ze communiceren via een één-richtingssync waarbij Postgres altijd de baas is. De platform blackbox groeit zichzelf slim via een human-in-the-loop nominatieproces dat afwijzingen terugkoppelt naar de AI.