Getting started

CONFIGURATION-CONTRACT

W01 — gezamenlijk configuratiecontract en compatibele leesloader

Datum: 20 oktober 2026. Basis: de volledige dashboardintegratie, geïntegreerd bouwplan W01/W03 en de aangevulde veld-tot-gedragmatrix. Geen nieuwe brede audit uitgevoerd. origin/main is bijgewerkt tot 3073f3c en in deze geïsoleerde branch opgenomen.

Wat nu daadwerkelijk werkt

  • Eén browserveilig Zod/TypeScript-contract in src/contracts/configuration, gebruikt door backend en frontend. Alle 42 veldgroepen hebben een mapping, afgeleide betekenis of expliciete ontbrekende ondersteuning.
  • De gegenereerde contractmatrix beschrijft 190 opslagvelden: opslagbron, type, eenheid, enum waar begrensd, betekenis van null/leeg/ontbrekend, bestaande runtimeconsument, afhankelijkheden en testbewijs. Oorspronkelijke acceptatietests uit het onderzoek zijn expliciet toekomstige runtimeacceptatie en worden niet als voltooid aangemerkt.
  • GET /company/configuration/snapshot leest de configuratie met de bestaande companyAuth en requireCompany. Bedrijf en gebruiker komen uitsluitend uit de geverifieerde sessie. Queryparameters voor tenantselectie worden geweigerd.
  • Een expliciete databasekolommenlijst sluit providercredentials, auth-ID’s, betaalidentifiers, gespreksinhoud en willekeurige extra kolommen uit. Kindrecords en bevoegdheidsrelaties moeten naar geladen records van hetzelfde bedrijf verwijzen.
  • De loader leest ook voorbij de Supabase-paginagrens, accepteert geen gedeeltelijk succesvolle bronlezing en onderscheidt een echte lege verzameling van een bronfout. De grens van 20.000 rijen per bron geeft een fout, geen afgekapt succes.
  • Formulieren en configuratieassistent gebruiken dezelfde snapshottypen en waarden. De leescontext van de assistent toont opgeslagen instellingen. Het premium interactieve chatontwerp blijft volledig beschikbaar in de demo; echte AI-opdrachten en schrijfhandelingen zijn nog niet aangesloten.
  • Assistent, bedrijf, diensten/detail, rijke intake/prijzen, werkgebied, uitzonderingsdagen, routeringscontacten, boekingsbeleid, kennis en medewerkers lezen het contract. Account, facturatie, actuele providerstatus en gesprekken houden hun bestaande afzonderlijke GET-grens.
  • De expliciete demo-adapter bewaart alle oorspronkelijke configuratievelden verliesvrij, ook rijkere/UI-specifieke waarden. Klantgesprekken en transcripties komen niet in het configuratiecontract. Demo-opslag blijft organisatie-onafhankelijk en tabgebonden.

De 37-functiestatus is bijgewerkt. De status vóór W01 blijft apart staan, met de eerder uitgevoerde route-, flow- en screenshotcontroles.

Bestaande klantregels behouden

De loader vervangt geen bestaande runtime. Hij hergebruikt resolveEffectiveServices, buildCompanyCallPolicy en de bestaande dienstvalidatie. De oorspronkelijke geselecteerde configuratiewaarden blijven daarnaast in compatibility.sources staan.

| Geval | Contractgedrag | |---|---| | false, 0, null, lege tekst/lijst, ontbrekend | Blijven verschillende waarden. Geen demo-default bij ontbrekende data. | | Onbekende enum | Waarde blijft behouden; issue unknown_enum. | | Afwijkend opgeslagen type | Ruwe waarde blijft behouden; canonical veld ontbreekt met een zichtbaar issue. Een niet leesbare bestaande policy wordt null, geen verzonnen standaardpolicy. | | Gemigreerde maar lege dienstenlijst | Blijft leeg; oude diensten worden niet teruggezet. | | Legacydienst zonder rij | id: null; geen verzonnen klant-ID of afhandeling. | | Intake | Legacy required én rijke requirement/condition/options/requiredBefore blijven behouden. | | Prijzen | Integer centen en valuta, staffels, beslisregels, prijsvoorwaarden en verboden toezeggingen blijven apart. Algemene legacytarieven blijven in euro’s. | | Boeking | Buffers vóór en na blijven apart; de enkelvoudige prototypebuffer wordt niet automatisch gesplitst. Null op dienstoverrides blijft overerving. | | Medewerkerbevoegdheid | Geen regels = niet geconfigureerd, zoals de bestaande runtime; expliciete maar allemaal inactieve regels = niemand bevoegd. | | Identificatie/bevestiging | Bestaande company policy, typed unidentified-issue policy, vrije context en runtimebevestigingsregels blijven leidend. | | Stem/taal/audio | Opgeslagen voice-ID blijft behouden. Null/fallback, taalwisselbeleid en ontbrekende audioverwijzing worden niet als bewezen nieuwe instellingen voorgesteld. | | Werkgebied | Brontekst, plaatsen/postcodes, coördinaten, straal en dienstoverride-tekst blijven apart. Geen automatische geocoding of nieuwe actieve gebiedsbeslissing. |

Voorgestelde F27-prioriteit voor W04: harde uitsluiting → expliciete dienstuitzondering → bedrijfsgebied. Binnen een gekozen regelscope gaat uitsluiten vóór op-aanvraag vóór bedienen. Een dienstuitzondering mag een harde uitsluiting niet opheffen; onopgeloste vrije tekst vraagt beoordeling. Deze ontwerpprioriteit is nog geen gedeelde evaluator en is niet stil op de huidige demokaart of legacy-runtime toegepast.

Versies, consistentie en de mutatiegrens

schemaVersion, compilerVersion, een SHA-256-inhoudsrevisie, versionId, herkomst per veld en F01–F42-coverage reizen samen. Een inhouds- of compilerwijziging maakt eerder versiegebonden testbewijs ongeldig. Capturetijd, abonnement en importvoortgang veranderen de configuratie-inhoudsrevisie niet.

Er is geen nieuwe databasearchitectuur of migratie. De huidige tabellen hebben geen gezamenlijk transactioneel versienummer. Daarom vereist de loader twee gelijke volledige lezingen, met maximaal één extra observatie bij wijziging; voortdurende wijziging geeft 409 CONFIG_CHANGED_DURING_READ. Dit is geen MVCC-snapshot en geen publiceerbare release. Ieder snapshot heeft publishable: false.

Het contract bevat interfaces voor readDraft, patchDraft, validateDraft, proposePatch, confirmProposal en undoAsNewPatch. De pure guards controleren actor/bedrijf, concept en revisie, vervaldatum, voorstelstatus, exacte opgeslagen diffhash, toegestane schema-paden, oude veldwaarde en nieuwe waardevorm. Er is nog geen persistente uitvoerder. canEdit moet straks uit serverautorisatie komen, nooit uit vrije clientinvoer. Een gewijzigde prijs op N+1 blokkeert het chatvoorstel voor N.

Uitgevoerde controles

| Controle | Resultaat | |---|---| | Backend build/typecontrole | Geslaagd | | Backend lint | Geslaagd, geen waarschuwingen | | Volledige backendsuite | 319 bestanden; 4.336 tests geslaagd, 1 bestaande skip | | Aanvullende bronkolom-/matrixcontrole | 2 tests geslaagd; geselecteerde kolommen bestaan in de bestaande DB-rowtypen | | Nieuwe contract-/loader-/API-/conflicttests | 32 gerichte tests; netwerkloze synthetische fixtures | | release:p0 | 102 bestanden; 1.569 tests geslaagd, 1 bestaande skip | | golden:check | Geslaagd; bestaande voice-runtimevingerafdruk behouden | | Frontend build en typecontrole | Geslaagd; gedeeld contract wordt meegebundeld | | Frontendtests | 28 bestanden; 180 tests geslaagd | | Frontendlint | Geen fouten; dezelfde 6 bestaande waarschuwingen | | Compatibiliteit met resterend lokaal voicewerk | 122 gerichte tests geslaagd met tijdelijke overlay; kandidaatbestanden daarna bytegelijk hersteld | | Gerichte browserregressie | 8 desktop-/mobiele pagina- en refreshcases geslaagd; geen overflow, browserfouten of externe requests |

Vier nieuwe beelden en het browserresultaat staan in configuration-smoke: assistent desktop, chat desktop, assistent mobiel, chat mobiel. Dit zijn expliciet synthetische previews; ze bewijzen geen ingelogde klantintegratie.

De drie synthetische onderzoeksprofielen (informatie, menselijke beoordeling en afspraken) behouden na serialisatie/herladen hun bestaande policy, planningsbeslissingen en identificatie-instructies. Starter/Growth/Enterprise behouden alle prototypeconfiguratie en de configuratiescopes uit de studio. Er staan geen echte klantfixtures in Git.

Van de negen nieuwere runtimebestanden zijn zes gelijk aan het bijgewerkte origin/main. Nog afwijkend in de oorspronkelijke werkboom: GeminiVoiceService.ts (stilte na afscheid), unidentifiedIssuePolicy.ts (duidelijker WhatsApp-verwijzing) en confirmationDecision.ts (Nederlandse instemmingen). Deze drie plus bijbehorende tests zijn tijdelijk over de kandidaat gelegd voor compatibiliteitstests. De oorspronkelijke werkboom is alleen gelezen; dat afzonderlijke ongecommitte werk is niet ongemerkt in deze configuratiecommit opgenomen.

Ruwe commandologs staan lokaal in output/dashboard-integratie-20261020/, met de namen backend-contract-full-tests.txt, contract-release-p0.txt, contract-matrix-tests.txt, contract-primary-overlay-tests.txt, frontend-contract-tests.txt, frontend-contract-build.txt en de twee lintlogs.

Niet uitgevoerd: een ingelogde proef tegen een echte backend/tenant, actuele providers, een outbound testcall, berichten, betalingen, migraties of productie-uitrol. De geselecteerde kolommen zijn tegen repositorytypen gecontroleerd; een ontwikkelomgeving met ontbrekende migraties geeft een zichtbare bronfout. Een echte bronfout wordt nooit een leeg of fictief succes.

Lokaal gebruiken

Op een verse checkout zijn beide dependencysets nodig; frontend en backend delen de browserveilige contractbron.

cd C:\Users\mausv\Documents\Beller\worktrees\dashboard-integratie-20261020
npm ci
npm --prefix frontend ci
npm --prefix frontend run dev:dashboard

Volledige demo: http://127.0.0.1:3211/preview/dashboard.

Met de bestaande toegestane ontwikkelsessie en API-configuratie:

  • /dashboard/nieuw/assistent?data=live
  • /dashboard/nieuw/configuratie-assistent?data=live
  • /dashboard/nieuw/diensten?data=live

Zet uitsluitend op de te testen ontwikkelbackend BELLER_CONFIG_SNAPSHOT_ENABLED=1. Standaard is de nieuwe route uitgeschakeld (404). De frontendpreview start geen backend. Bij niet beschikbare snapshot-API verschijnt foutfeedback met opnieuw laden; er is geen terugval naar demodata. Een lokale link is niet toegankelijk via mobiele data.

Matrix opnieuw genereren: npx tsx scripts/configuration-matrix.ts. De frontendbron blijft één contractbestand delen; de repositorygrens is ingesteld volgens de Next.js-documentatie voor Turbopack-roots.

Concrete volgende bouwopdracht: W03

Implementeer duurzame concepten en één mutatie-executor achter het bestaande contract:

  1. Draft en immutable kandidaat opslaan met bedrijf, actor, basisversie en monotone revisie. Teruglezen/hervatten geeft hetzelfde volledige contract, ook voor verborgen of nog niet bewerkbare legacyvelden.
  2. Formulieren en de echte configuratieassistent gebruiken dezelfde patchDraft met expectedRevision. Laat beide gelijktijdig dezelfde draft lezen; voer compare-and-swap atomair uit in de database.
  3. Laat voorstellen exact binden aan draft/revisie, servergegenereerde hash van de volledige diff, actor, scope en vervaldatum. Bij conflict toont de UI oude, voorgestelde en huidige waarden.
  4. Voer structurele, semantische en bestaande klant-/dienstvalidatie uit vóór opslaan. Unsupported velden blijven expliciet geblokkeerd; geen onbedoeld defaulten, planverhoging, provideractie of betaling.
  5. Bouw undo als een nieuwe, opnieuw gevalideerde patch. Het mag latere wijzigingen of een andere actor niet overschrijven. Test ook dubbele bevestiging, herhaalde requests, onzekere netwerkuitkomst en idempotency.
  6. Koppel de bestaande formulieren en premium chat met laadstatus, tussentijds opslaan, hervatten, veldfeedback en menselijke bevestiging. Sla geen echte draft in de demo-sessionStorage op.
  7. Houd draft, geteste kandidaat en actieve release gescheiden. Wijziging maakt testbewijs ongeldig. Outbound testcall blijft de beoogde menselijke hoofdtest in de latere testketen.
  8. Bewijs opnieuw F01–F42-roundtrip, drie klantprofielen, tenantisolatie en CQ23-concurrency. Voeg fout-/hersteltests voor transacties en duurzame opslag toe. Actieve klantconfiguratie blijft ongemoeid totdat de afzonderlijke activatiegrens is geïmplementeerd en goedgekeurd.

W04 volgt met één gebiedsevaluator voor UI en runtime. Providerwrites, testcalls en activatie blijven aparte bouwstappen.

Main en productie

De CI-workflow vermeldt Railway als automatische productie-deployautoriteit bij remote main. Daarom kan deze gecontroleerde kandidaat lokaal naar main worden overgenomen, maar wordt remote main niet gepusht binnen deze opdracht. Geen deployment of productieaanpassing.