De tellers hierboven zijn machinaal hergeteld uit de opgemaakte inhoud van deze
pagina, met dezelfde methode als de vorige keer: elk <article class="req"> met een
E--id is één eis, en de status komt uit de eerste statusmarkering in die kaart. Uitkomst:
115 eiskaarten (100 besloten, 15 afgeleid, 0 open) en 16 items onder "bewust niet gekozen",
waarvan er één — N-02 — alsnog gekozen is en dus niet meetelt: 15 afgewezen.
Alle interne ankers zijn gevalideerd; er is geen enkele verwijzing naar een id dat niet bestaat.
Laatste hertelling: 6 augustus 2026, ná de doorloop van het domeinen- en startstandenstuk.
Bijgewerkt 6 augustus 2026 — herziene besluiten, en géén open vraag meer
Terugkomen op een besluit hoort zichtbaar te gebeuren, dus staat het hier en niet alleen in de
eiskaarten. E-NAV-10 is omgedraaid: de gesplitste centrale pil was
afgewezen en is nu gekozen, omdat het doorslaggevende bezwaar op een aanname rustte die
E-NAV-12 heeft achterhaald. Daarmee vervalt ook de variant uit
E-NAV-09 (AI als actie in de kop) en is
N-02 geen afgewezen optie meer. En E-NAV-13 heeft een
nieuwe vorm: drie vaste tabposities en een vierde die een module draagt.
Later op 6 augustus: de balkvolgorde is besloten (E-NAV-20 —
Vandaag · Dashboard · Modules · Taken), waardoor E-NAV-01 en
E-NAV-05 op de volgorde zijn bijgewerkt en Taken bewust van plek 2 naar plek 4
verhuist. En E-VDG-11 is van open vraag naar besluit gegaan: de keuze bij het
aanmaken luidt "moet je hier zijn" tegenover "moet je dit doen", ná de twee
randvoorwaarden die daar staan.
Doorloopsessie 6 augustus — tien besluiten, en drie ADR's aanvaard. De vijf openstaande
Plus-eisen zijn beslecht: E-PLUS-15 (statusregel in Instellingen — ja),
E-PLUS-16 (nee, met uitzondering — géén bericht vooraf, alleen een
afteller ná een opzegging; het dag-11-moment is geschrapt), E-PLUS-17
(bevestiging ná de omzetting — ja, en dáármee het enige moment waarop de app iets zegt over de eerste
afschrijving), E-PLUS-19 (een eerlijk upgrade-aanbod bij Solo) en
E-PLUS-22 (Solo niet aanbieden bij meer dan één account). Tegelijk zijn
ADR-0021, ADR-0022 en ADR-0023 geaccepteerd; daaruit volgt de herziening bij
E-WID-15 op twee punten — het vinkje gaat over voltooien in plaats van over
bewerken, en orderHint vervalt niet.
En de dringendheidsschaal is beslist, het punt dat ADR-0021 als "niet stilzwijgend in te vullen"
had gemarkeerd. Hij staat nu als E-VDG-12 in dit register: een vaste rangorde in
vier lagen, met als onderliggende regel hoe minder omkeerbaar het gemis, hoe hoger. Daarmee is
ook beantwoord dat een aankondiging een signaal is (laag 3, met een ontsnapping voor dringende
gevallen) en een uitnodiging ook (laag 1). ADR-0021 is dus geen leeg raamwerk meer.
Avond 6 augustus — acht besluiten die de laatste openstaande vragen in de implementatieplannen
sluiten. Geen van de acht verandert de status van een eis: het zijn punten die bínnen een
besloten eis of in een ADR open stonden. Ze staan hier omdat ze bepalen wat er gebouwd kan worden.
(1) De derde stand: de oppervlaktegate krijgt drie uitkomsten — toegestaan, geweigerd en
nog onbekend; bij onbekend toont de app de vorige bekende stand of een rustige laadweergave, geen
etalage en geen lege balk (ADR-0022; raakt E-PLUS-02,
E-PLUS-03, E-PLUS-04, E-NAV-19).
(2) De suggestiebron splitst per item op vervaldatum — laag 2 mét, laag 4 zonder
(E-VDG-12). (3) Chroom is een eigen laag buiten de vier banden: het
Vandaag-menu, de gezinsstrook, de quote en de stappenteller houden hun plek en vallen buiten het plafond
(E-VDG-01, E-VDG-02). (4) Agenda is beschikbaar als
widget maar staat niet standaard op het dashboard — dat lost de tegenspraak tussen
E-WID-10 en het widgetonderzoek op. (5) Deeplink-landing: de herkomst
bepaalt de terugweg; zonder historie is Mijn modules de terugval (E-NAV-12).
(6) Een module van je beginscherm halen onthoudt zijn plek — inclusief de map waar hij in zat
(E-MOD-10). (7) Het tablabel wordt "Modules"; het scherm mag "Mijn
modules" heten (E-NAV-04). (8) De tabkeuze krijgt een eigen opslagrij voor
navigatie, naast springboard, dashboards en Vandaag (E-OPS-01,
E-OPS-04). En de tegenspraak
E-NAV-03 ↔ E-NAV-14 is beslecht: instelbaarheid
wint, maar niet vóór fase 4 — tot dan staat Taken vast op positie 4. Er is dus geen tegenspraak, alleen
een volgorde.
Avond 6 augustus, tweede ronde — acht besluiten, en twee daarvan draaien een eerder voorstel
om. Deze ronde sluit de laatste openstaande punten in de drie implementatieplannen; ná deze ronde
staat er nul open vragen in dit register.
(1) Domeinen blijven bestaan als de vaste categorieën van de catalogus (onboarding,
modulebeheer, meldingen, AI); mappen ordenen het beginscherm. Alleen /domein/:id
verviel — E-MOD-06 is daarop herschreven, want zijn oude zin ("geen enkel
scherm ordent nog op domein") las als "domeinen verdwijnen". Uitgevoerd nog diezelfde dag: de
route en domain_screen.dart zijn verwijderd met F1-9 (merge
20f1b910); test/core/router/domein_route_verwijderd_test.dart bewaakt het.
(2) "Map opheffen" komt er, met de modules op de plek van de map
(E-MOD-11, nieuw).
(3) Verborgen lijst: verbergen wint — de widget toont zijn lege staat. Dit draait het
voorstel in ADR-0022 om ("de expliciete widgetkeuze wint"); dat voorstel staat nu als afgewezen
optie N-12.
(4) De favorietenbalk volgt de inhoud — leeg is weg, en de schakelaar uit
E-NAV-16 blijft daarnaast bestaan.
(5) Poort 4 mag op Vandaag, met een veilige startwaarde: tot de eerste geslaagde verversing
geldt tonen (E-PLUS-02, ADR-0022).
(6) De maatnamen zijn akkoord — Klein · Hoog · Breed · Groot
(E-WID-18, van open vraag naar besluit; dit was de laatste).
(7) De Vandaag-schakelaars krijgen een eigen sleutel, óók voor kernmodules, en de kern-set
krimpt naar Agenda · Taken · Lijstjes met een uit te leggen regel eronder — Boodschappen wordt een
gewone gratis module (E-VDG-08 aangevuld,
E-MOD-12 nieuw, afgewezen alternatieven in N-13).
(8) Geen sessie: vorige bekende stand, laadweergave alleen bij een echte eerste start — met één
uitzondering die niet cosmetisch is: wat achter een toegangsslot zit blijft verborgen zolang niet
bekend is wie er kijkt (ADR-0022).
Doorloop van het domeinen- en startstandenstuk, 6 augustus 2026 — zeven besluiten, en drie ervan
keren een eerdere stand om. Deze ronde beantwoordt de zes open punten uit
dat stuk en levert vier nieuwe eisen op plus twee
bijstellingen.
(1) De domeinen worden opnieuw gesneden tot zes — Eten · Gezin · Huis · Geld · Gezondheid ·
Bewaren — met Boodschappen in eten (E-MOD-13, nieuw).
Dit draait de telling in E-MOD-06 om: de conversie maakt zes mappen, niet
tien. En het sluit het detail dat E-MOD-12 uitdrukkelijk openhield, waarmee
F1-2 ontstopt is.
(2) De startstand van het Modules-scherm ligt vast op vier losse tegels en zes mappen
(E-MOD-14, nieuw). Ook dat is een omkering: de staart van
E-MOD-12 telde drie losse kernoppervlakken; het zijn er vier, want Lijstjes
ontbrak in die telling.
(3) De startstand van het Dashboard ligt vast op één bord van zes widgets voor iedereen, met
twee uitgeschakelde voorbeeldwidgets voor wie aantoonbaar geen Plus heeft
(E-WID-19, nieuw).
(4) Die zes wijken bewust af van de letter van E-WID-10, die er acht
oplevert; die eis is daarop bijgewerkt zodat eis en seed elkaar niet meer tegenspreken.
(5) De gratis modules zijn er tien, niet negen — Lijstjes ontbrak in het freemium-besluit
(E-PLUS-36, nieuw). Een correctie van een telling, geen herverdeling van
tiers.
(6) Quote wordt een instelling van Vandaag in plaats van een module
(E-MOD-15, nieuw) — en dat keert het voorstel in het bronstuk om, dat
met Quote als module in Gezondheid rekende. Mét de voorwaarde van de eigenaar dat er dan ook écht
instellingen voor moeten zijn; zonder dat vervolgpakket is de eis niet uitgevoerd.
(7) De gebieden krijgen nieuwe id's, mét omzetting van de AI-toestemmingen
(E-MOD-16, nieuw). Dat is de duurste van de zeven: vijftien van de negentien
losse domainId-snaren moeten mee, en een hernoeming zonder eenmalige remap van de gesyncte
opt-in-set zet iemands AI-toestemming stilletjes uit. Daarin zit ook de geaccordeerde versoepeling:
Garanties en Wagenpark verlaten het gevoelige gebied. De afgewezen alternatieven staan in
N-14, N-15 en N-16.
En één herziening van diezelfde middag, zichtbaar gehouden: de grens tussen Solo en Gezin ligt
bij het aantal accounts, niet bij het aantal leden. E-PLUS-20,
E-PLUS-21 en E-PLUS-22 zijn daarop bijgesteld —
een alleenstaande ouder met twee kinderen zonder account blijft Solo, en de poort valt samen met
uitnodigen. E-PLUS-35 is nieuw en bevestigt dat: co-ouderschap is standaard
niet gedeeld met de andere ouder en maakt dus geen tweede account.
Gebied 1
Navigatiemodel
Wat er op de vier tabposities staat, in welke volgorde het gebouwd wordt, en waar AI
woont. Dit is het gebied waar de meeste discussie in is gaan zitten, dus ook waar het register het
hardst nodig is.
Het model
Wat er op de vier posities komt te staan.
Bouw het navigatiemodel volgens concept E: vier tabposities — Vandaag · Dashboard · Mijn modules · Taken.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek, na het afwegen van vijf concepten in
../archive/implemented/design/navigatie-ontwerpconcepten.html.
- Waarom
- Springboard en widget-board waren tot dat moment concurrenten om
één positie. Concept E maakt er twee antwoorden op twee verschillende vragen van: "waar is
het?" (Mijn modules) en "hoe staat het ervoor?" (Dashboards). Daardoor hoeft Vandaag
geen tweede rol te dragen en hoeft geen van beide oppervlakken zich te verantwoorden tegenover de
ander.
- Raakt
- TEN-165 (koepel) · alle vier de fasen · vraagt een eigen ADR.
Volgorde bijgewerkt 6 augustus 2026. Hier stond
Vandaag · Taken · Mijn modules · Dashboards. De eigenaar heeft de balkvolgorde vastgelegd in
E-NAV-20: Dashboard staat op plek 2 en Taken op plek 4. Het model zelf
verandert daar niet van — het blijven dezelfde vier oppervlakken met dezelfde rollen.
Houd Vandaag een gecureerd dagoverzicht; geef het geen tweede rol als widget-oppervlak.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek. Maakt concept D (Vandaag wordt zélf het
board) overbodig.
- Waarom
- Zonder deze eis moest Vandaag zijn chronologie inleveren en die
terugkopen met een verplichte "Je dag"-widget — een dure ruil die niets oplevert. Met een eigen
Dashboards-tab vervalt de ruil. Praktisch gevolg: het beleid dat in fase 2 op Vandaag wordt
vastgelegd, blijft daarna staan en hoeft niet nog eens omgegooid te worden.
- Raakt
- TEN-162 · fase 2 · gebied 2 in dit register.
Laat Taken zijn eigen tabpositie houden.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek. Dit is de verfijning die de eigenaar zelf
aanbracht op het oorspronkelijke voorstel.
- Waarom
- Taken is het drukst gebruikte oppervlak van de app. Het van de
tabbalk halen kost élke gebruiker een tik per bezoek, elke dag, permanent — en levert alleen ruimte
op voor iets waarvan nog bewezen moet worden dat het een tabpositie waard is. De vrijgekomen positie
komt van de Assistent, niet van Taken.
- Raakt
- TEN-165 · fase 3 · beantwoordt de openstaande vraag W5 ·
E-NAV-20 (wáár op de balk).
De tegenspraak met E-NAV-14 is beslecht — 6 augustus
2026: instelbaarheid wint, maar niet vóór fase 4. De vraag was: mag Taken van de balk als de
gebruiker positie 4 met een andere module vult? Beide lezingen leverden werkende code op, dus dit is
precies het soort punt dat een fixer stilzwijgend zou invullen. Het antwoord: deze eis gaat
over de standaardstand — Taken is de standaardbezetting én de terugval van positie 4
(E-NAV-19), en wie hem zelf wegkiest doet dat bewust, met
E-NAV-06 als vangnet (drie wegen naar Taken). De harde lezing — Taken kan er
nooit af — is afgewezen, want dan is E-NAV-14 in zijn huidige vorm niet
bouwbaar. Maar het geldt pas vanaf fase 4. In fase 1 t/m 3 ligt positie 4 vast op Taken en is er
geen keuzelijst — dat is precies wat E-NAV-13 zelf al beschrijft. Er is dus
geen tegenspraak, alleen een volgorde: een agent die vóór fase 4 aan de balk werkt, bouwt hier niets
instelbaars.
Deze eis gaat over de tab, niet over de plek. Met
E-NAV-20 staat Taken op plek 4 in plaats van plek 2. Dat raakt het argument
hierboven niet: de prijs die hier vermeden wordt is een extra tik per bezoek, en die betaalt
niemand — Taken houdt zijn tabpositie. Het prototype toonde die plek 4 trouwens al; wat daar als
"oude stand" stond, is de besloten stand geworden.
Vervang de tab "Mijn leven" door het springboard "Mijn modules".
- Herkomst
- Ontwerpstuk §2 (concept B) · onderzoek, bevestigd door de eigenaar op
5 augustus 2026.
- Waarom
- Het huidige scherm toont 35 tegels van 136 px in 11 secties, in een
volgorde die de gebruiker niet kan veranderen. Bij 29 modules is dat geen overzicht meer maar een
catalogus. Een springboard met eigen volgorde, mappen en opruimen beantwoordt de vraag "waar is het?"
en schaalt mee als er modules bij komen.
- Raakt
- TEN-163 · fase 1 · gebied 4 in dit register.
Het tablabel is beslist — 6 augustus 2026: het wordt "Modules". ADR-0024 liet
de woordkeuze open en zei erbij dat hij vóór fase 1 vast moest staan. "Modules" vraagt ongeveer
41 px in plaats van 60, dus ruime marge in een tab van 64 px op een 360 px-scherm — ook bij
grotere lettergrootte, waar "Mijn modules" bij textScaler 1.5 afkapte.
Het scherm zelf mag wél "Mijn modules" heten: een tablabel is een wegwijzer, geen titel, en de
twee hoeven niet gelijk te zijn. Concreet: l.tabsMyLife wordt "Modules",
l.mijnLevenTitle blijft "Mijn modules". Dat verschil hoort expliciet in de brief, anders
trekt een uitvoerder ze uit netheid gelijk.
Geef het widget-board een eigen Dashboard-tab in de tabpositie die de Assistent achterlaat; op de balk landt hij op plek 2.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek.
- Waarom
- Het board heeft een eigen oppervlak nodig, en de enige positie die
zonder verlies vrijkomt is die van de Assistent — want AI verhuist toch al naar een permanente eigen
plek (E-NAV-09). Geen enkel bestaand oppervlak levert dus iets in.
- Raakt
- Fase 3 · nieuw ticket "Dashboards-tab + widgetcontract" ·
gebied 5 · E-NAV-20 (wáár op de balk).
Bijgesteld 6 augustus 2026 — "de positie die de Assistent achterlaat" is een
telling, geen plek. Wat vrijkomt is één van de vier tabposities; welk oppervlak waar op de balk
staat, is met E-NAV-20 apart besloten. Uitkomst: Dashboard staat op
plek 2 en Taken schuift naar plek 4 — dus naar de plek waar de Assistent vandaag staat. De
onderbouwing hierboven blijft ongewijzigd: geen enkel bestaand oppervlak levert een tab in. Het
prototype bouwt deze stand al.
Houd Taken bereikbaar via drie wegen: de band op Vandaag, een tegel op het springboard en een widget op het dashboard.
- Waarom
- Dit staat hier zodat niemand het later als kost opschrijft.
Dat Taken op drie plekken opduikt is geen dubbeling die opgeruimd moet worden — het is precies wat
concept E belooft: hetzelfde ding benaderbaar vanuit "wat gebeurt er vandaag", "waar is het" en
"hoe staat het ervoor". Wie dit als redundantie behandelt, sloopt de winst van het model.
- Raakt
- Fases 1–3 · reviews van elk van de drie oppervlakken.
De volgorde
Hoe het programma in stukken uiteenvalt, en waarom in deze volgorde.
Voer concept E uit in vier fasen: 1 Mijn modules · 2 Vandaag · 3 AI krijgt een eigen plek → board bouwen en beoordelen → Dashboards in de vrijgekomen positie · 4 vierde tab instelbaar en favorietenbalk optioneel.
- Herkomst
- Ontwerpstuk §8 · onderzoek, bevestigd en verfijnd door de eigenaar op
5 augustus 2026.
- Waarom
- De volgorde is geen planning maar een risicovolgorde. Fase 1
en 2 raken de tabbalk niet en leveren op zichzelf al winst. Fase 3 is de dure fase, en die begint
bewust met de AI-plek: zolang AI geen eigen plek heeft, komt de vierde positie niet vrij en kan
Dashboards er niet in. Binnen fase 3 wordt het board eerst gebouwd en beoordeeld vóórdat het
een tabpositie krijgt — blijkt het voor een gratis gebruiker te dun, dan stopt E bij fase 2 zonder
dat er iets half blijft staan.
- Raakt
- TEN-165 · drie nieuwe tickets (Dashboards-tab, AI-plek, instelbare vierde
positie) · het implementatieplan.
Bijgesteld 6 augustus 2026 — fase 4 heeft er een voorwaarde bij gekregen.
Sinds E-NAV-13 in zijn nieuwe vorm draagt de vierde positie een module.
Moduleroutes zijn vandaag top-level en geen shell-branch, dus zonder
E-NAV-12 bestaat de keuzelijst uit één regel (Taken) en is "instelbaar" een
instelling zonder keuze — zie E-NAV-14. Fase 4 hangt daarmee aan E-NAV-12, en
dat stond hier niet. De risicovolgorde blijft ongewijzigd: fase 1 t/m 3 raken dit niet, en
E-NAV-08 staat nog steeds toe dat fase 4 wegblijft — dan blijft de balk staan
zoals fase 3 hem achterlaat.
Lever elke fase op als een op zichzelf staand afgerond product; fase 4 mag wegblijven.
- Waarom
- Als een fase alleen af is samen met de volgende, is de fasering een
illusie en zit je vast zodra er iets tegenvalt. Fase 4 is bovendien de enige fase waarna de app per
gebruiker verschilt en de enige die je niet stil terugdraait — daarom staat hij achteraan, en daarom
mag hij ook overgeslagen worden.
- Raakt
- Werkpakket-indeling · elke fase-oplevering.
De plek van AI
De enige vraag die fase 3 blokkeerde. Hij is beantwoord.
Geef AI een vaste actie in de kop (variant 3); in fase 3 alléén in de shell-AppBar.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek, op basis van de driewegvergelijking in
../archive/implemented/design/navigatie-ontwerpconcepten.html.
- Waarom
- Eén ingreep op één plek in de code bedient alle vier de
shell-schermen; er hoeft in fase 3 geen enkel modulescherm aangeraakt te worden. Het patroon is al
bewezen: TEN-164 zette op precies deze manier een instellingen-ingang op 29 moduleschermen zonder
per scherm iets te configureren. De AI-knop is daar een tweeling van.
- Raakt
- Fase 3, stap 1 · nieuw ticket "AI krijgt een eigen plek" · beantwoordt de
blokkerende vraag W7 · blokkeerde de Dashboards-tab.
Geverifieerd. AppIcons.ai bestaat al; de shell-AppBar draagt vandaag
twee acties (agenda, inbox) en wordt op één plek gedefinieerd in
lib/features/shell/app_shell.dart. Uitbreiden naar drie is één wijziging.
Herzien 6 augustus 2026 — de kern blijft, de variant vervalt. Wat overeind
staat is de eis: AI krijgt een vaste, permanente eigen plek buiten de tabbalk, zodat de
Assistent-tab vrij kan komen zonder dat de assistent iets inlevert. Wat vervalt is de uitwerking
— "variant 3, een actie in de kop". Per E-NAV-10 woont AI in de rechterhelft
van de centrale pil, op elk scherm. Lees deze eis dus als het besluit dát AI een eigen plek krijgt;
E-NAV-10 zegt wélke. De hier genoemde route ("één ingreep in de shell-AppBar bedient alle vier de
shell-schermen, geen modulescherm hoeft aangeraakt te worden") geldt niet meer: de pil vraagt juist
dat de balk op álle schermen komt, en dat is een groter werkpakket. Dat staat eerlijk uitgeschreven
bij E-NAV-10.
Splits de centrale knop in een pil met twee helften — vastleggen en AI — plaats hem laag (variant C), en toon de balk mét pil op álle schermen.
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek. Begon als heropening
("De AI-knop zit nu ook altijd onder in de pil als we hem daar houden") en eindigde
als besluit. Herziet zijn eigen uitspraak van 5 augustus, die de pil juist afwees.
- Waarom
- Eén gebaar geeft toegang tot de twee dingen die je onderweg wilt:
iets vastleggen en iets vragen. Ze staan permanent op dezelfde plek, op elk scherm, en concurreren
niet met de kop. En het houdt het Plus-pad prominent: voor wie geen Plus heeft is de AI-helft de
zichtbaarste plek waar Plus zich laat zien, elke dag, zonder dat er een banner voor nodig
is.
- Raakt
- Fase 3 ·
lib/features/shell/pa_fab.dart ·
lib/features/shell/pa_tab_bar.dart · lib/features/shell/app_shell.dart ·
E-NAV-09 (variant 3 vervalt) · E-NAV-12
(voorwaarde) · E-NAV-11 · E-MOD-09 ·
N-02 · ADR-0024.
Statuswijziging — waarom een besloten eis is omgedraaid
Het doorslaggevende bezwaar rustte op een aanname, en die is achterhaald
Tot 5 augustus luidde E-NAV-10: "Laat de centrale knop één knop met één betekenis blijven;
splits hem niet op in vastleggen en AI" — besloten, op gezag van de eigenaar. Het zwaarste
argument daaronder was het contextargument: de centrale knop bestaat alleen op de vier
shell-schermen, en juist dáár geeft moduleIdForLocation null terug — een
AI-knop in het midden zou dus overal staan wáár de route niets zegt, en nergens wáár die wél iets
zegt.
Dat argument rustte op een aanname die inmiddels niet meer geldt: dat de balk alleen op de
vier basisschermen bestaat. Met E-NAV-12 staat de tabbalk óók in
moduleschermen, en met dit besluit staat hij op alle schermen. Binnen een module is de
route een moduleroute, dus de assistent weet dan precies waar hij vandaan wordt aangeroepen — het
bezwaar keert zelfs om: de pil is dan de enige AI-ingang die altijd weet waar je staat.
Dit hoort zichtbaar te gebeuren en niet stil bijgewerkt te worden: een besloten eis is hier
omgedraaid omdat de feiten eronder veranderden, niet omdat iemand van gedachten wisselde over
smaak. N-02 — de gesplitste pil als "bewust niet gekozen" — vervalt daarmee
als afwijzing.
Geverifieerd — de maten komen uit het prototype en uit de widgets. Vandaag:
PaTabBar.height = 64, fabGap = 72, fabOverlap = 28
(pa_tab_bar.dart:31,34,38), en :51 asserteert vier tabs in een
2 + FAB + 2-opmaak (:77-88). Het langste label onder concept E is "Mijn modules",
60 px tekst. Op 360 px krijgt elke tab nu (360 − 72) / 4 = 72 px. De drie pilvarianten
staan als CSS-variabelen in ../archive/implemented/design/prototype-concept-e.html, blok "Balk- en pilgeometrie".
Aanbeveling — variant C
C is de enige variant die alle drie de randvoorwaarden haalt
1 · Het label. Alleen bij C blijft "Mijn modules" heel op 360 px: de middenruimte is daar
104 en niet 108 of meer, juist zodat elke tab 64 px krijgt tegen 60 px tekst. In A en B is de tab
59 respectievelijk 61 px en kapt het label af — en dat is het label van een vaste positie, dus dat
zou permanent zijn.
2 · De raakvlakken. C geeft twee helften van 48 × 48 px: precies de 48 px van Material en
ruim boven de 44 pt van Apple. B haalt dat ook (52 × 48). Wat het niet haalt is een pil
die binnen de huidige 72 px past — dat zou twee helften van 36 px geven, onder beide normen. Die
weg is dus dicht, en de middenruimte moet hoe dan ook groeien.
3 · "Lager geplaatst", zoals gevraagd. C tilt de pil 10 px van de schermrand tegen 36 in A,
en steekt 0 px boven de balkrand uit. Dat is niet alleen rustiger, het scheelt ook werk: de
onderruimte die elke scrollende lijst nodig heeft wordt dan balkhoogte + safe area, en
de hele fabOverlap-correctie van 28 px vervalt. De balk wordt 4 px hoger (68 in plaats
van 64), wat die winst deels terugneemt maar niet opheft.
Wat het kost — eerlijk, want dit is de duurste van de drie besluiten
1 · E-NAV-12 is geen wens meer maar een voorwaarde
"De balk op álle schermen" betekent dat de 29 moduleschermen die balk moeten dragen, en dat is
precies E-NAV-12. Die eis stond als een op zichzelf staande verbetering van
de oriëntatie, in te plannen wanneer het uitkwam; vanaf nu kan E-NAV-10 niet zonder. De twee zijn
onlosmakelijk: zonder E-NAV-12 heeft de pil op 29 van de 33 schermen geen bestaan, en precies
daar zit de context waarvoor hij gekozen is.
Nuance die werk scheelt, en die je expliciet moet maken: voor het contextargument volstaat
de goedkope vorm van E-NAV-12 — een gedeelde scaffold die dezelfde balk onderaan een
modulescherm tekent. De router hoeft daarvoor niet om: een modulescherm heeft ook als top-level
push-route de locatie /module/…, dus moduleIdForLocation geeft daar
gewoon het module-id terug. De dure vorm (29 routes de shell in) is alleen nodig voor
bewaarde stapels per tab en voor de groei van E-NAV-14. Reken dus niet de
verkeerde prijs af op dit besluit — maar reken ook de goedkope vorm niet gratis: 33 schermen hebben
een eigen floatingActionButton die met de pil botst, en 34 bestanden staan op
AppSpacing.fabClearance en moeten naar het balk-patroon.
2 · De fasering schuift
Fase 3 begon met "AI krijgt een eigen plek" als de goedkoopste eerste stap: één icoon in één
AppBar. Die stap bestaat niet meer. De nieuwe stap (a) is de balk met pil op alle schermen,
en die heeft E-NAV-12 in de goedkope vorm als voorwerk. Fase 3 wordt daarmee zwaarder aan de
voorkant. Zie de bijstelling bij E-NAV-07.
3 · Twee dingen die je accepteert
De + verlaat het exacte midden en schuift ~24 px naar links; hij blijft de primaire
toevoegactie maar niet meer de enige knop in het midden. En bij grote systeemletters kapt "Mijn
modules" af: app.dart:342-345 klemt textScaler op 1.0–1.5, en bij 1,5×
vraagt dat label ~90 px in een tab van 64. Dat gebeurt vandaag ook al (90 in 72), maar C maakt de
marge kleiner. Het antwoord is een korter label — "Modules" — of de afkapping bewust accepteren;
niet een andere balkgeometrie.
Twee zorgen die hiermee juist vervállen. (1) De dubbele ingang. Zolang AI
zowel in de pil als in de kop zou staan, waren er twee permanent zichtbare wegen naar dezelfde
assistent — de dubbeling waar ADR-0024 voor waarschuwt. Met dit besluit is er één ingang, en
die staat overal. (2) De kopdrukte. Omdat AI niet meer in de AppBar hoeft, worden de vaste
kopacties er twee in plaats van drie; zie E-MOD-09 en
E-NAV-18. De grens van vier uit E-NAV-11 blijft
gelden en knelt daarna nog op precies één scherm.
Draag maximaal vier acties in een modulekop; de AI-actie komt erbij zolang er hooguit drie andere staan, en anders niet.
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek: "Daarbovenin mag hij erbij komen als
er maximaal drie andere icoontjes zijn, zodat er tot vier icoontjes zijn. Een vijfde icoon wordt,
denk ik, te veel." Beantwoordt vraag W11 uit het ontwerpstuk §7, blootgelegd door TEN-164.
- Waarom
- Niet omdat vijf onmogelijk is — het past fysiek — maar omdat vijf
een ruil tegen de moduletitel is, en die ruil wil je niet 29 keer hoeven maken. Zie de
rekensom hieronder. Vier redt het zonder afweging; vanaf vijf moet je per scherm gaan wegen of de
naam nog past, en dat is precies het soort per-scherm-oordeel dat
E-MOD-09 wil opruimen. De grens is bovendien hard en geen
richtlijn: zonder plafond groeit elke kop mee met elke nieuwe app-brede ingang, en dat is precies
hoe de Afvalkalender ongemerkt op vier kwam.
Geverifieerd — de telling klopt, en hier is hij volledig. Alle 29 moduleschermen
bouwen hun eigen AppBar; TEN-164 leverde geen gedeelde kop maar een gedeelde
actie (ModuleSettingsAction,
lib/features/modules_beheer/presentation/module_settings_action.dart), met de afspraak:
scherm-eigen acties eerst, dan het tandwiel, dan de ster
(ShortcutMenuAction) als laatste. De acties zijn niet tier- of
vlag-afhankelijk — op de landingsroute is het maximum gelijk aan het gewone aantal.
De grens bijt vandaag al, op één scherm. De Afvalkalender zit op vier en zijn
kop is dus vol: de AI-actie komt daar niet bij, tenzij er iets anders wijkt. Op de vijf
schermen met drie past AI er precies bij. Op de 23 schermen met twee of één past hij ruim. In de
eindstand van deze eis alléén — dus zonder E-MOD-09 erbij — krijgt 28 van de
29 schermen een AI-knop en één niet.
Past er niet gewoon een vijfde? — de rekensom
Vijf past, maar de moduletitel betaalt ervoor
De maten zijn framework-constanten, geen schattingen. Een IconButton in de app heeft
geen eigen maat gekregen (app_theme.dart:183-185 zet alleen een kleur), dus geldt de
standaard: een raakvlak van 48 px breed. De terugknop links neemt 56 px, en tussen
de terugknop en de titel zit 16 px vaste ruimte. Wat er op 360 px voor de titel overblijft
is dus 360 − 56 − 16 − (n × 48):
De titelbreedtes zijn geschat op de werkelijke stijl (titleLarge = 18 px,
gewicht 500, app_typography.dart:75) bij ongeveer 0,55 em per teken; de kolom
"acties" is exact. Conclusie: vijf is geen muur maar een titel die verdwijnt, en zelfs vier
kost de lange namen al iets. Dat maakt de grens van vier geen fysieke waarheid maar een
afspraak — en de echte oplossing zit dan ook niet in de grens maar in wat er in de kop
hoort te staan. Zie E-NAV-18.
Besloten — twee vervolgvragen die de eigenaar stelde
1 · Wie beslist wat er wijkt: een vaste regel, niet per scherm
Per scherm beslissen is 29 losse oordelen, en dat is exact de toestand die
E-MOD-09 wil opruimen — "per module opnieuw leren waar iets zit". Een vaste
regel is één maatstaf die overal hetzelfde uitpakt, en hij is te toetsen. Die regel staat in
E-NAV-18: de kop is voor wat je vaak doet, de instellingen zijn voor wat
je één keer instelt. Dat is een inhoudelijke toets en geen rangorde — hij haalt de drukte weg
in plaats van hem te verdelen.
2 · Een overloopmenu is niet de uitweg
Een ⋯-menu haalt het icoonaantal formeel onder vier — maar het besluit hierboven gaat
over drukte, en drie iconen plus een menu waar de rest in zit is dezelfde drukte met een extra tik
eromheen. Zwaarder weegt dat het de voorspelbaarheid sloopt: wat er in het menu zit verschilt dan
per scherm, en de gebruiker weet nooit of een actie er niet is of alleen verstopt zit.
Geverifieerd: er is ook geen patroon om op voort te bouwen. Van de 42 keer dat
PopupMenuButton in lib/ voorkomt staan er precies twee in een
AppBar: Vaste kosten (één item — "toon betaald",
vaste_kosten_screen.dart:60) en Agenda (één item — agenda koppelen,
agenda_screen.dart:63). Beide zijn eenpitters, geen verzamelbak. Een overloopmenu
invoeren is dus een nieuw app-breed patroon introduceren om een grens te omzeilen die net is
gesteld.
Wat wél mag: een scherm-eigen actie die een menu ís (zoals Vaste kosten) telt gewoon als
één actie. Verboden is het menu als vergaarbak voor de acties die niet pasten.
De kop is voor wat je vaak doet; de instellingen zijn voor wat je één keer instelt.
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek. Ontstond als vraag of er niet gewoon
vijf iconen passen, en werd beantwoord met een betere vraag: hoort het importeren van een
kalender niet gewoon in de instellingen van de afvalkalender?
- Waarom
- De grens van E-NAV-11 zegt hoevéél er in
een kop mag; deze eis zegt wát erin hoort — en dat is de eigenlijke oplossing. Een kop die
alleen dagelijkse handelingen draagt, komt vanzelf niet aan vier toe. Een kop waar ook de
eenmalige instellingen in staan, loopt bij elke nieuwe module opnieuw vol, en dan zit je te
onderhandelen over welk icoon mag blijven. De toets is bovendien te stellen zonder de code te
kennen: doe je dit wekelijks, of deed je dit één keer toen je de module in gebruik nam?
De bestemming hoeft niet gebouwd te worden. TEN-164 zette met
ModuleSettingsAction
(lib/features/modules_beheer/presentation/module_settings_action.dart) een
instellingen-ingang op alle 29 moduleschermen, die zichzelf uit de route afleidt. Wat naar "de
instellingen" verhuist, verhuist dus naar een blad dat vanuit elk modulescherm al één tik weg is.
Deze eis kost daarom vooral verplaatswerk, geen nieuw oppervlak.
Zonder deze eis blijft het knellen — met, past alles. Sinds
E-NAV-10 zit AI in de pil en niet in de kop, dus het vaste blok is
zoeken + instellingen + favorietenster = drie. Dat laat precies één plek over voor een
scherm-eigen actie binnen de grens van vier. Zes schermen hebben er vandaag één of twee — de
Afvalkalender twee, en die zou met zoeken erbij op vijf komen. Na de toets hieronder houdt geen enkel
scherm er meer dan één over, en past de grens van vier overal.
Uitkomst
Vier verhuizingen, en daarna past de grens van vier overal
Na deze pas houdt geen enkel modulescherm meer dan één eigen actie over. Met het vaste blok van
drie (zoeken · instellingen · ster) komt het maximum op vier — de grens van
E-NAV-11 — en dat maximum wordt gehaald door drie schermen:
Afvalkalender, Vaste kosten en Sportkalender. De overige 26 zitten op drie of minder. Er hoeft dus
niets naar een overloopmenu, en de weigering van dat menu bij
E-NAV-11 blijft houdbaar.
Let op de volgorde van oorzaken: dit werkt alleen omdat AI met
E-NAV-10 uit de kop verdween. Zou AI daar wél staan, dan was het vaste blok
vier en had geen enkel scherm nog ruimte voor iets eigens — dan waren deze verhuizingen niet genoeg
geweest.
Waar de toets níét beslist — bewust gemarkeerd, niet geforceerd
Twee acties vallen ertussenin
Pauzeren (Afvalkalender). Je gebruikt hem misschien twee keer per jaar, dus de toets zegt
"instellingen" — maar je gebruikt hem op een moment dat je hem meteen wilt kunnen vinden, en dat
pleit voor de kop. De toets geeft hier geen uitsluitsel, en dat hoeft ook niet: met de
ICS-import weg zakt het scherm naar drie eigen plus vast, dus er is geen ruimte-argument dat de
knoop doorhakt. Hij blijft staan tot iemand een reden heeft die niet over ruimte gaat.
Team toevoegen (Sportkalender). Aanmaken hoort bij de kop, frequentie pleit voor de
instellingen. Ook hier is er geen ruimtenood, dus ook hier blijft hij. Wordt de Sportkalender ooit
uitgebreid met een tweede eigen actie, dan is dit de eerste kandidaat om te verhuizen.
Dat er twee gevallen zijn waarin de regel niet beslist, is geen zwakte van de regel — het is de
reden om ze te markeren in plaats van er een uitspraak in te lezen die de eigenaar niet gedaan
heeft.
Chrome en vrijheid
Wat er om de schermen heen staat, en wat de gebruiker daaraan mag veranderen.
Houd de tabbalk zichtbaar in moduleschermen.
- Herkomst
- Prototype-feedback, 5 augustus 2026 · bevestigd als eigenschap van concept E.
- Waarom
- Vandaag verdwijnt bij het openen van een module de hele oriëntatie:
geen tabbalk, geen favorietenbalk, alleen een terugknop. Van een module naar de instellingen van
diezelfde module kostte daardoor zes handelingen. Met een blijvende tabbalk is een module een
plek in de app in plaats van een uitstapje eruit.
- Raakt
- Router ·
lib/core/router/app_router.dart · fase 3/4 ·
eigen werkpakket.
Kostenwaarschuwing — geverifieerd. Dit is géén vlaggetje. De
registry-moduleroutes staan vandaag in de top-level routes:-lijst, als broer van
de StatefulShellRoute.indexedStack, niet erin. Ze de shell in trekken betekent: elke
module een genest pad geven, per tab een eigen navigatiestapel bijhouden, en beslissen wat er gebeurt
als je vanuit Vandaag een module opent en dan op tab 3 tikt. Reken op een navigatie-verbouwing en
plan hem als zodanig in.
Deze eis is zwaarder gaan wegen — 6 augustus 2026. Hij stond hier als een op
zichzelf staande verbetering van de oriëntatie. Sinds E-NAV-13 draagt hij ook
fase 4: de vierde tabpositie wordt een module, en modules kunnen daar alleen komen te staan als
hun routes shell-branches worden — precies wat deze eis doet. Zie
E-NAV-14. En hij versterkt daarnaast
E-NAV-10: zodra de tabbalk in moduleschermen staat, staat de centrale knop
daar óók, en heeft die knop wél een moduleroute onder zich — het argument waarop de gesplitste pil op
5 augustus sneuvelde.
De deeplink-vraag is beantwoord — 6 augustus 2026: de herkomst bepaalt de
terugweg. De kostenwaarschuwing hierboven noemt als productbesluit: "in welke branch landt een
koud geopende deeplink naar /module/garanties, en wat gebeurt er als je vanuit Vandaag een
module opent en dan op tab 3 tikt?" Antwoord: kwam je ergens vandaan — Vandaag, Modules, of
zelfs een andere module — dan is dát je terugnavigatie: de module landt in díe branch en de
terugweg voert daarheen terug. Is er geen historie, zoals bij een melding of een echte deeplink
van buiten, dan is Mijn modules de terugval.
Let op: dit is een combinatie van de twee opties die op tafel lagen, dus beide helften
moeten uitgewerkt worden. Wie alleen de terugval bouwt ("een module landt altijd in de
Modules-branch") levert precies de helft die de gebruiker binnen de app nooit merkt — en breekt het
gewone geval, want dan verlaat elke module-opening vanuit Vandaag stilzwijgend je Vandaag-stack. De
herkomst-tak is het gewone geval; de terugval is het randgeval.
Zet drie vaste posities — Vandaag · Dashboard · Mijn modules — en maak alleen de vierde instelbaar, met een module als keuze.
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek. Vervangt zijn eigen vorm van
5 augustus ("de vierde positie per lid instelbaar, met Dashboards als standaard").
- Waarom
- De drie basisschermen staan altijd en kunnen nóóit gekozen of
uitgezet worden. De vierde positie is de keuze, en die keuze is een module — niet een van de
basisschermen. In fase 1 t/m 3 staat daar alleen Taken; vanaf fase 4 kunnen er andere modules
bij. Het argument van de eigenaar: "Doordat we daar niet een van de drie basisschermen in
mogelijk maken die dan kan uitzetten, hebben we dit probleem helemaal niet." Een basisscherm
kan zo per constructie niet onbereikbaar worden, en de open vraag daarover
(E-NAV-17) verdampt in plaats van beantwoord te worden.
De opsomming ís de balkvolgorde — sinds 6 augustus 2026 besloten. Dat de eigenaar
de drie vaste posities in déze volgorde noemde, liet twee lezingen toe; hij heeft de eerste bevestigd
in E-NAV-20. De balk wordt Vandaag · Dashboard · Modules · Taken, dus
de "vierde positie" uit deze eis is ook letterlijk de vierde plek.
Gevolg dat je moet uitspreken: de Assistent verliest zijn tab definitief.
In de vorm van 5 augustus was de Assistent nog een van de keuzes voor positie 4. Nu de vierde positie
een module draagt en de Assistent geen module is, is er geen weg terug naar de tabbalk. Dat
is consistent met de verhuizing van AI naar de kop of de pil
(E-NAV-09/E-NAV-10) — maar het maakt die verhuizing
wel tot de énige ingang naar de assistent, en dus tot een besluit dat je niet halverwege kunt laten
staan. /assistent blijft als branch bestaan; alleen de tab verdwijnt.
Correctie op het argument — het is sterk, maar het lost niet álles op. De
blokkerende vorm van het geen-tab-actief-probleem is inderdaad weg: geen enkel basisscherm kan
zijn tab nog kwijtraken, dus er is geen oppervlak dat onbereikbaar wordt. Dat is precies wat het panel
en ADR-0024 als blokkerend markeerden, en dat vervalt. Maar de weergave "geen tab in
accentkleur" moet er alsnog komen, en niet zuinig ook: met E-NAV-12 staat de
tabbalk straks op 29 moduleschermen, waarvan er hooguit één de module op positie 4 is. Op de andere 28
is er dus geen actieve tab. Wat eerst een randgeval was, wordt de gewone stand — maar het is een
renderregel van een paar regels, geen productbesluit meer.
De volgorde erbij, uitgesproken op 6 augustus 2026. "In fase 1 t/m 3 staat
daar alleen Taken" stond hier als beschrijving; het is nu ook een instructie. Tot fase 4 ligt
positie 4 vast op Taken: geen keuzelijst, geen voorkeur-lezing, geen halve aanleg daarvan.
Zo is de spanning met E-NAV-03 geen tegenspraak maar een volgorde — zie de
toelichting daar.
Beperk de keuzelijst voor tabpositie 4 tot wat de router kan dragen: tot E-NAV-12 af is, is dat alleen Taken.
- Herkomst
- Afgeleid uit E-NAV-13 (nieuwe vorm, 6 augustus 2026)
· onderzoek in
app_router.dart. Vervangt de eerdere vorm, die de lijst beperkte
tot "oppervlakken die een shell-branch zijn en blijven" en Dashboards, Assistent, Agenda en
Boodschappen voorstelde.
- Waarom
- Een shell-branch houdt zijn navigatie- en scrollstaat vast en
heeft binnenin de tabbalk; een gewone push-route begint elke keer opnieuw en dekt de balk af. Een
module op de tabbalk zetten terwijl haar route top-level is, levert dus een tab die je kunt
aantikken maar die nooit actief kan oplichten — je duwt een scherm over de balk heen die je net
hebt aangetikt. Daarom groeit deze lijst pas mee met
E-NAV-12.
De koppeling die hier het belangrijkst is
E-NAV-13 en E-NAV-12 dragen elkaar — fase 4 hangt vanaf nu aan E-NAV-12
"Vanaf fase 4 kunnen er andere modules bij" kán alleen als moduleroutes shell-branches worden, en
dát is precies wat E-NAV-12 doet. Zonder E-NAV-12 is de vierde positie
beperkt tot wat vandaag al branch is — en dat is alleen Taken. Mét E-NAV-12 kan elke module
erin. De twee besluiten zijn daarmee geen buren meer maar een paar: E-NAV-12 levert de vrijheid die
E-NAV-13 belooft.
Dat staat nog niet in de fasering. E-NAV-07 beschrijft fase 4 als
"vierde tab instelbaar en favorietenbalk optioneel", zonder afhankelijkheid. Vanaf nu geldt: fase 4
levert met alleen Taken in de lijst geen instelbaarheid op die iets voorstelt, dus E-NAV-12 hoort
in of vóór fase 4 ingepland te worden — als eigen werkpakket, met de kostenwaarschuwing die er bij
E-NAV-12 al staat.
Geverifieerd — waarom Taken wél kan en de andere 29 niet.
lib/core/router/app_router.dart:146-183 definieert precies vier
StatefulShellBranches: /vandaag, /taken,
/mijn-leven, /assistent. /taken is er één van, dus Taken kán
vandaag op de tabbalk staan zonder één regel router. De 29 registry-moduleroutes staan als
...registryRoutes op :262 in de top-level lijst, buiten de shell —
die kunnen het dus niet.
Nuance bij "de keuze is een module": Taken ís technisch geen registry-module.
Er is geen ModuleDescriptor voor Taken; het id 'taken' staat in
kCoreSurfaceModuleIds (lib/core/modules/module_registry.dart:15) — de set
kernoppervlakken die voor ieder lid altijd aan staat, zónder persoonlijke activatie-toggle, zónder
gezinsset-default en zónder beheerder-blokkade. In fase 1 t/m 3 wordt de vierde positie dus gevuld
door een kernoppervlak dat toevallig ook een branch is. Dat is geen bezwaar — het is de
reden dat E-NAV-19 Taken als terugval kan aanwijzen — maar noem het zo in
het implementatieplan, anders gaat een fixer een ModuleDescriptor voor Taken zoeken die
er niet is.
De spanning met E-NAV-03 is beslecht — 6 augustus 2026.
Deze eis laat elke module positie 4 innemen, wat betekent dat Taken van de balk kan. Instelbaarheid
wint — E-NAV-03 gaat over de standaardstand, en E-NAV-06 draagt de rest —
maar pas vanaf fase 4. Tot dan is de lijst niet "één regel lang omdat de router het niet
aankan", maar afwezig: positie 4 ligt vast. Dat maakt het verschil voor een uitvoerder in
fase 1 t/m 3, die dus geen keuzemechanisme aanlegt waarvan de enige keuze Taken is.
Waarom de oude lijst vervalt. Dashboards is nu een vaste positie en
staat dus niet meer in een keuzelijst; de Assistent verliest zijn tab definitief
(E-NAV-13). Van de vier voorgestelde oppervlakken blijven er nul over. De
prijskaartjes die ADR-0024 aan Agenda en Boodschappen hing — /agenda van push-route naar
branch promoveren, en eerst een stabiel /boodschappen-pad maken — vervallen daarmee ook
als fase-4-werk: onder het nieuwe model is de vraag niet "welke oppervlakken promoveren we" maar
"wanneer doen we E-NAV-12".
Ontkoppel de tab-index van de branch-index vóór de Dashboards-tab landt.
- Waarom
- Vandaag is de tab-index letterlijk de branch-index: de shell geeft
hem rechtstreeks door. Zodra Dashboards een eigen branch krijgt terwijl
/assistent als
branch blijft bestaan, zijn het vijf branches en vier tabs en klopt de gelijkstelling niet
meer. De afbeelding is klein (een constante lijst), maar hij verhuist daarmee van fase 4 naar
fase 3 — en de hidden-module-redirect en de deeplinks mogen de oude aanname dan evenmin nog maken.
- Raakt
- Fase 3 ·
lib/features/shell/app_shell.dart ·
hiddenModuleRedirect · deeplinks.
Maak de favorietenbalk uitschakelbaar (fase 4).
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek.
- Waarom
- De balk kostte tot nu toe 52 px die niemand kon terugkrijgen. In een
eerder voorstel was die ruimte nodig als AI-plek; met E-NAV-09 is dat niet
langer zo. Daarmee is dit geen ruil meer maar een schone opruimkeuze: wie de balk niet gebruikt,
hoort hem uit te kunnen zetten.
- Raakt
- Fase 4 ·
lib/features/shell/quick_actions/ ·
E-OPS-01.
Correctie na verificatie. De balk bestaat (ShellQuickActionsBar,
vast 52 px in de shell-AppBar) en de inhoud ervan is al per lid instelbaar en gesynct via de
_shell-rij. Maar de balk zelf kan vandaag niet uit: hij hangt onvoorwaardelijk in
de AppBar en claimt zijn 52 px altijd, ook leeg (dan toont hij een "Beheren"-knop). Deze eis is dus
nieuw werk, geen instelling die alleen nog ontsloten hoeft te worden.
Aangevuld avond 6 augustus 2026 — wat de startstand is
De balk volgt de inhoud: leeg is weg, en de schakelaar blijft daarnaast bestaan
Het besluit. Staat er geen enkele favoriet in, dan is er geen balk — die 52 px komt niet
in beeld. Zet iemand zijn eerste favoriet, dan verschijnt de balk vanzelf. En de expliciete
schakelaar uit deze eis blijft bestaan, voor wie de balk óók met favorieten erin weg wil. Twee
mechanismen die elkaar niet in de weg zitten: de inhoud bepaalt de startstand, de
schakelaar overrulet.
De nuance die het goedkoop maakt — en die makkelijk verkeerd gelezen wordt. De startstand
is niet een opgeslagen voorkeur met de waarde "uit"; hij is afgeleid uit de
inhoud. Daarmee vervalt de vraag die hier open stond ("staat de balk voor nieuwe accounts standaard
uit?") én de vraag die erachteraan zou komen ("en voor bestaande accounts dan?"). Er is dus geen
migratie en geen eenmalige keuze voor bestaande gebruikers. Wie vandaag favorieten heeft, ziet
niets veranderen: zijn lijst is niet leeg, dus zijn balk staat er nog. Wie er nooit een heeft
gezet, krijgt 52 px terug zonder er iets voor te doen — en het rijtje met alleen een
"Beheren"-knop, dat vandaag de enige inhoud van een lege balk is
(shell_quick_actions_bar.dart:34-43), verdwijnt.
Eén val, en die is geverifieerd. "Leeg is weg" mag niet naïef op de
huidige provider worden gelegd. QuickActionSelection.build() geeft const []
terug zolang de gesynchroniseerde favorieten nog laden
(module_quick_action_providers.dart:197-198, met het commentaar "laadt nog; geen
selectie tonen") én bij een lege sessie (:189-192). Wie "leeg" één op één als
"geen balk" leest, laat de AppBar bij élke koude start eerst 52 px inklappen en daarna weer
uitklappen — precies het geknipper dat E-NAV-19 en de derde stand uit
ADR-0022 wegnemen. De regel is dus: leeg is weg zodra de lijst bekend is; zolang hij laadt,
geldt de vorige bekende stand. Dán is het waar dat iemand met favorieten geen verschil ziet.
Dashboards kan zijn tab niet kwijtraken: het is een vaste positie.
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek — beantwoord door
E-NAV-13, niet los besloten. Stond als vraag W10 uit ontwerpstuk §7.
- Waarom
- De vraag luidde: "wat gebeurt er met Dashboards als iemand
tabpositie 4 aan iets anders geeft?" Onder het nieuwe model kán dat niet — Dashboard is een van
de drie vaste posities en de vierde positie draagt een module. Het board is dus altijd één tik weg,
en de vraag of het "een gewone bestemming of een tab-gebonden oppervlak" is, hoeft niet meer
beantwoord te worden: het is een tab-gebonden oppervlak, permanent.
- Raakt
- Fase 4 · E-NAV-13 ·
nieuw ticket "instelbare vierde positie + balk" · ADR-0024.
Dit is een vraag die vervalt, geen vraag die beantwoord is. Het verschil doet
ertoe voor wie later terugleest: er is geen afweging gemaakt tussen "board bereikbaar via Mijn
modules" en "board als tab" — het model maakt de tweede variant de enige mogelijke. Wordt
E-NAV-13 ooit herzien, dan komt deze vraag in volle omvang terug.
Blijft desondanks waar en waardevol: de tegel op Mijn modules waarmee het board in
fase 3b beoordeeld wordt, mag blijven staan. Hij kost niets, hij bestaat al in die fase, en hij is
de tweede weg die E-NAV-06 voor Taken óók vanzelfsprekend vindt.
Val terug op Taken als de module op tabpositie 4 wegvalt, en bewaar de keuze zodat de tab vanzelf terugkomt.
- Herkomst
- Afgeleid uit E-NAV-13 · het randgeval dat het nieuwe
model overhoudt, uitgewerkt op 6 augustus 2026.
- Waarom
- Er is één gat dat het nieuwe model niet dicht: de gebruiker zet
positie 4 op een module en zet die module daarna uit — of kiest een Plus-module en verliest Plus.
Dan wijst de tab naar iets dat er niet meer is. Het gat is klein, maar zonder uitspraak vindt een
fixer het pas als een tester erop stuit, en dan staat er een tab die crasht of leeg blijft.
Waarom uitgerekend Taken, en waarom dit geen nieuw mechanisme is. Taken is het
enige oppervlak dat zélf nooit kan wegvallen: 'taken' staat in
kCoreSurfaceModuleIds (module_registry.dart:15) — altijd aan voor ieder lid,
geen persoonlijke toggle, geen beheerder-blokkade, en gratis. Een terugval op iets dat zelf
uitgezet kan worden, verplaatst het probleem alleen. En de vorm is bekend:
hiddenModuleRedirect stuurt een verboden of Plus-gesloten moduleroute al naar een vaste
bestemming (app_router.dart:287 en :298), en
module_settings_action.dart:38 doet hetzelfde als je de module uitzet waar je in staat.
Het enige nieuwe is welke bestemming.
Wegvallen en nog-niet-weten zijn twee verschillende dingen — 6 augustus 2026.
De terugval hierboven mag niet ook bij elke koude start gebeuren. De entitlement wordt bij het
opstarten opgehaald en geldt zolang als "geen Plus"; zonder maatregel zou de tab van een betalende
gebruiker bij élke start eerst terugvallen op Taken en daarna terugspringen — en een tabbalk die tijdens
het opstarten van bezetting wisselt leest als een defect. Besluit: de oppervlaktegate kent een
derde uitkomst, nog onbekend; zolang die geldt houdt de balk zijn vorige bekende
bezetting (en zonder vorige stand een rustige laadweergave). De terugval geldt pas als het verdict
daadwerkelijk geweigerd is. Zie ADR-0022.
De keuze wordt niet gewist, alleen niet gehonoreerd — en ze staat in een eigen
rij. De voorkeur blijft als id opgeslagen; de terugval gebeurt bij het lezen. Bijgesteld
6 augustus 2026: hier stond "in de _shell-rij". De tabkeuze krijgt een eigen rij
voor navigatie, naast springboard, dashboards en Vandaag (zie E-OPS-04) —
zodat je tabvoorkeur niet sneuvelt doordat je op een ander toestel je springboard herordent. Zet de
gebruiker
de module weer aan of komt zijn Plus terug, dan staat zijn tab er vanzelf weer — zonder dat hij hem
opnieuw moet kiezen. Dat is exact de redenering van E-OPS-03 ("het item blijft
in de lijst staan en rendert simpelweg niet") toegepast op de tabbalk, en het vraagt geen migratie en
geen extra sleutel. Wat je ervoor accepteert: bij het aflopen van Plus verandert de tabbalk
zonder aankondiging. Dat hoort mee in de tekst van het Plus-afloopscherm, niet in een eigen melding.
Zet de balk in de volgorde Vandaag · Dashboard · Modules · Taken; de vierde positie is ook de vierde plek, en Taken verhuist daarheen.
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek. Beantwoordt de vraag die bij het
vastleggen van E-NAV-13 ontstond en die twee kanten op kon: de opsomming
Vandaag · Dashboard · Mijn modules was balkvolgorde, niet alleen een opsomming.
Vervangt het voorstel dat hier stond (Taken op plek 2 houden, Dashboard op plek 4) — een
eigenaar-uitspraak overrulet een advies.
- Waarom
- Dat Taken van plek 2 naar plek 4 schuift is bewust, geen
bijvangst van de nummering. De drie vaste posities staan in de volgorde waarin je ze op een dag
gebruikt — wat gebeurt er vandaag, hoe staat het ervoor, waar is het — en
de instelbare plek staat achteraan, waar hij ook van bezetting mag wisselen zonder dat de rest
verschuift. Daarmee is "de vierde positie" uit E-NAV-13,
E-NAV-14 en E-NAV-19 letterlijk de vierde plek: één
begrip in de code, in de instellingen en op het scherm, in plaats van een nummer dat iets anders
betekent dan wat de gebruiker ziet.
Plek 4 is de rechteronderhoek, en die is voor een duim juist góéd bereikbaar.
pa_tab_bar.dart:77-88 legt de rij hard uit als
tab(0) · tab(1) · fabGap · tab(2) · tab(3): plek 2 ligt links van de centrale pil, plek 4
uiterst rechts. Hier stond eerder dat het drukst gebruikte oppervlak daarmee "naar de verste hoek"
zou verhuizen. Dat argument gaat niet op. Op een telefoon in één hand ligt de duim in rust bij
de onderrand aan de kant waarmee je vasthoudt; de rechteronderhoek is voor de rechterduim het
gemákkelijkste doel van de hele balk, niet het verste — ver zijn de bovenhoeken. De prijs
die E-NAV-03 wilde vermijden was een extra tik per bezoek, en die
prijs betaalt niemand: Taken houdt zijn tab, alleen op een andere plek.
Wat er wél verandert, en voor wie. Bestaande gebruikers zien Taken één plek
opschuiven — spiergeheugen dat één keer bijgesteld moet worden, en dat is de hele kost. Er verandert
niets aan bereikbaarheid (elk oppervlak blijft één tik weg), niets aan de router (welke branch op
welke index staat is een constante lijst, zie E-NAV-15) en niets aan de
opmaak van de balk: het blijven vier tabs in de 2 + pil + 2-vorm. Wat mee moet: de golden
test/features/shell/goldens/tab_bar_4.png en de labelvolgorde in
app_shell.dart:26-34.
Het prototype houdt deze volgorde al aan.
../archive/implemented/design/prototype-concept-e.html definieert TABS als
Vandaag · Dashboards · Mijn modules · Taken. Wat tot nu toe als "het prototype loopt achter
op de tabvolgorde" in de leeswijzer stond, klopt daarmee niet meer: op dit punt liep het vooruit.
Er komt hier dus geen corpuswerk-item bij — anders dan bij
E-MOD-05, waar het prototype wél moet worden bijgewerkt.
Gebied 2
Vandaag
Vandaag blijft wat het is, maar wordt gezuiverd: vier banden met een plafond in plaats
van vijftien losse secties met hardgecodeerde volgordegetallen.
Deel Vandaag in vier banden: Je dag · Nog te doen · Signalen · Klaar.
- Herkomst
- Ontwerpstuk §3 (variant T4) · onderzoek, bevestigd door de eigenaar op
5 augustus 2026.
- Waarom
- Vandaag bestaat nu uit vijftien secties uit elf bronnen, elk op een
hardgecodeerd volgordegetal, elk met een eigen plafond of geen plafond. Elke nieuwe module vraagt
opnieuw "op welk getal?" en niemand kan die vraag beantwoorden. Met vier banden kiest een nieuwe
sectie een band, en de band bepaalt het plafond. De vraag verdwijnt in plaats van dat hij
elke keer opnieuw beslecht wordt.
- Raakt
- TEN-162 · fase 2 ·
lib/features/today/ ·
TodaySection.orderHint.
Naast de vier banden staat een vijfde laag: chroom — besloten 6 augustus 2026.
Vier secties passen in geen enkele band en hoefden dat ook niet: het Vandaag-menu, de
gezinsstrook "wie doet wat", de quote en de stappenteller. Ze houden hun huidige
plek en volgorde en vallen buiten het plafond van E-VDG-02. (De
header stond al als chroom vastgelegd.)
Chroom is een eigen laag, geen vijfde band en geen restbak — en dat verschil is de hele
instructie. Bandblokken renderen als blok; chroom-secties sorteren op hun eigen
volgordegetal tussen die blokken door. Wie chroom als blok groepeert, schuift "wie doet wat" en
het Vandaag-menu naar boven, naast de header — een zichtbare regressie. De toets op de uitvoering is één
zin: de pagina blijft er exact hetzelfde uitzien. Wat het besluit óók vastlegt: het Vandaag-menu
gaat dus niet naar "Je dag", en TEN-42 wordt niet teruggedraaid.
Toon maximaal één signaalkaart tegelijk; berg de rest op achter "en X meer…".
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek (besluit D1 in het ontwerpstuk).
- Waarom
- De aanspreekkaarten hebben vandaag drie losse budgetten van drie
zonder gedeeld plafond, en discovery-kaarten staan bovendien boven de dagstroom. Op een vers
account zie je daardoor vier kaarten vóór je eigen dag. Eén kaart dwingt de app om te kiezen in
plaats van alles te tonen.
- Raakt
- TEN-162 · TEN-137 (suggestielaag) · TEN-150 (discovery) · fase 2.
Gevolg dat je moet accepteren. Met een budget van drie mocht de rangschikking
middelmatig zijn. Met één kaart is de rangschikking het hele product van die band: kiest hij
verkeerd, dan is dat de enige die de gebruiker die dag ziet. En "en X meer…" is daarmee geen restbak
maar een tweede oppervlak dat doorzoekbaar moet zijn.
Die rangschikking is inmiddels vastgelegd. Op 6 augustus 2026 is de
dringendheidsschaal beslist: een vaste rangorde in vier lagen, zie E-VDG-12.
Daarmee is deze eis niet langer een belofte zonder mechanisme. Het plafond zelf wordt afgedwongen door
een signaal-collector op de band en niet door een rijbudget per sectie — zie ADR-0021 en de
herziening bij E-WID-15.
Herzien 6 augustus 2026 — de rest klapt inline uit, en het zoeken vervalt.
Na het bekijken van build 1420 stelde de eigenaar vast dat "en X meer…" hoort te doen wat het zegt:
de overige signaalkaarten verschijnen ónder de eerste, op het scherm zelf, en dezelfde knop klapt ze
weer in. Er is dus geen tweede oppervlak meer — het bodemblad vervalt. Daarmee vervalt ook
het zoekveld dat aan dat oppervlak hing: het gaat om hooguit een handvol signalen, en zoeken
in vijf kaarten die je al ziet lost een probleem op dat er niet is. Lees de zin hierboven — "en X
meer… is daarmee geen restbak maar een tweede oppervlak dat doorzoekbaar moet zijn" — dus als
vervallen; wat eruit overeind blijft is dat het géén restbak is. Wat niet verandert: het
plafond. Ingeklapt, de stand waarin het scherm opent, staat er nog steeds precies één kaart; alleen
de weg naar de rest is korter. En de rangschikking blijft het hele product van deze band, want die
ene kaart is nog altijd wat je zonder handeling ziet. Het veld TodaySignal.searchText
blijft bestaan — het voedt de app-brede zoekfunctie, niet deze band.
Plaats de signaalkaart in band 3, nooit boven band 1.
- Waarom
- Eén kaart die bovenaan staat is nog steeds een kaart die vóór je
dag komt. Vandaag begint met je dag; wat de app zélf opmerkt komt daarna. Zonder deze eis lost het
plafond het probleem maar half op.
- Raakt
- TEN-162 · fase 2.
Laat een verstreken afspraak de hele dag staan; vink hem nooit automatisch af binnen de dag.
- Herkomst
- Eigenaar · besluit D3, gebouwd als TEN-144.
- Waarom
- "Voorbij" en "klaar" zijn twee verschillende dingen. Een afspraak
die om 14:00 begon is om 15:00 voorbij, maar of hij klaar is, weet alleen de gebruiker.
Hem automatisch wegzetten haalt informatie weg die iemand die dag nog nodig heeft — en verbergt
precies datgene waarvan je wilt onthouden of het gelukt is.
- Raakt
- TEN-144 (gemerged) ·
lib/features/today/domain/today_schedule.dart ·
test/features/today/agenda_past_row_test.dart.
Geverifieerd — gebouwd. Een verstreken agendarij blijft in de dagstroom staan,
gedimd en afvinkbaar. De semantiek "voorbij ≠ klaar" is expliciet in de code vastgelegd.
Schuif een verstreken afspraak 24 uur na de eindtijd automatisch door naar Klaar.
- Herkomst
- Eigenaar · tweede helft van besluit D3, gebouwd als TEN-175.
- Waarom
- Zonder deze helft blijft een niet-afgevinkte afspraak eeuwig in de
dagstroom hangen en groeit Vandaag dicht met gisteren. 24 uur is lang genoeg dat de gebruiker de
kans heeft gehad hem zelf af te vinken, en kort genoeg dat de dagstroom schoon blijft.
- Raakt
- TEN-175 (gemerged) ·
kAgendaAutoDoneGrace ·
test/features/today/agenda_auto_done_test.dart.
Correctie na verificatie. De grens loopt 24 uur vanaf de effectieve
eindtijd van de afspraak, niet vanaf het einde van de kalenderdag — "de afspraak is wat de
gebruiker onthoudt, niet de datum". Een afspraak zonder eindtijd krijgt één aangenomen uur; een
hele-dag-afspraak eindigt om middernacht ná zijn eigen dag. De overgang wordt geschreven als een
gewone dismissal, zodat ongedaan maken blijft werken, en vuurt hooguit één keer per item per dag.
Laat gebeurtenissen met hun dag verlopen; laat verplichtingen staan tot ze gedaan of weggelegd zijn.
- Herkomst
- Ontstaan als vraag bij TEN-175 ("hoe lang blijft iets op Vandaag staan?") ·
beslecht door de eigenaar op 6 augustus 2026.
- Waarom
- Het antwoord is geen nieuwe instelling maar een eigenschap
van het soort item. Een verjaardag, een afvalbak, een afspraak — die hebben de volgende dag geen
betekenis meer; ze horen te verlopen. Een taak, een boodschap, een openstaande betaling — die zijn
morgen nog steeds verschuldigd; die horen te blijven. Een schuifknop "hoe lang blijft dit staan"
zou de gebruiker laten instellen wat de app zelf hoort te weten, en zou bovendien op elke bron
hetzelfde getal opdringen terwijl de bronnen wezenlijk verschillen.
- Raakt
- TEN-175 · fase 2 ·
TodayLane ·
lib/features/today/domain/today_schedule.dart ·
lib/features/today/domain/today_horizons.dart ·
E-VDG-09 · E-VDG-10.
Gebeurtenissen verlopen met hun dag. Verplichtingen blijven tot ze gedaan of weggelegd zijn.
— eigenaar, 6 augustus 2026
Geverifieerd — dit regelt de achterkant, niet de voorkant. Er bestaat al een
vooruitkijk-venster per module (todayHorizonDefaults, instelbaar in het
instellingenblad): hoe ver vooruit een item opduikt. Dat venster blijft precies zoals het is.
De registry codeert de nieuwe regel bovendien al gedeeltelijk: verjaardagen: 0 (alleen
de dag zelf), de afvalkalender staat er bewust niet in ("buitenzetten is a same-day action"), en
taken: 7 vooruit — met achterstallige taken altijd zichtbaar, want het filter is
dagen ≤ venster en dat getal is negatief zodra iets over tijd is (idem voor
onderhoud). Deze eis gaat over de achterkant: wat er gebeurt nadat de dag voorbij
is. Vooruit is een instelling; achteruit is een eigenschap van het soort.
Grace: 24 uur na de eindtijd — hergebruikt uit TEN-175, geen nieuwe keuze. De
eigenaar wil geen harde middernacht-grens, en die bestaat al:
kAgendaAutoDoneGrace = Duration(hours: 24), geteld vanaf
agendaItemEffectiveEnd. TEN-175 heeft de twee lastige gevallen al beslecht en die keuzes
gelden nu voor élke gebeurtenis: een gebeurtenis zonder eindtijd krijgt één aangenomen uur
(kAssumedAppointmentDuration, zodat iets dat net begonnen is niet meteen "voorbij" heet),
en een hele dag loopt tot middernacht ná zijn eigen dag — niet tot 00:00 van de dag zelf. Een
heledaggebeurtenis van maandag verlaat de dagstroom dus dinsdagnacht om 00:00, niet maandagnacht.
Zo valt er niets onder iemands handen weg terwijl hij nog wakker is.
Laad de dag van gisteren mee zolang de uitloop van 24 uur nog loopt.
- Herkomst
- Afgeleid uit E-VDG-06 · gemeld door de fixer van
TEN-175 en geverifieerd in de code op 5 augustus 2026.
- Waarom
- Vandaag laadt precies één kalenderdag: de agendaprovider
mergt van
now tot now, en de doorschuiflus loopt alleen over díe lijst.
Een gebeurtenis van gisteren is dus alleen nog zichtbaar voor de regel zolang de merge van gisteren
in het geheugen staat — alleen als de app over middernacht heen open blijft. Na een herstart
is er niets meer om door te schuiven. Zolang dat zo is, is de uitloop uit
E-VDG-06 een belofte die de app meestal niet waarmaakt: de gebeurtenis is
na middernacht niet netjes doorgeschoven maar gewoon weg — precies wat de uitloop moest
voorkomen. Daarom is dit geen losse afweging meer maar een gevolg: laad gisteren mee en filter, of
de grace-periode bestaat alleen op papier. Dit is nadrukkelijk geen bug in TEN-175 maar een
grens van het datamodel eronder.
- Raakt
- TEN-175 (vervolg) ·
todayEventsProvider en
_todayEvents in lib/features/agenda/presentation/agenda_providers.dart ·
fase 2.
Twee dingen om in de begroting mee te nemen. De bestaande tests injecteren
de agendalijst rechtstreeks en omzeilen daarmee de eendaagse merge — het herstartpad is dus niet
gedekt en vraagt een eigen test. En Vandaag berekent now per build zonder ticker, dus er
is ook geen timer die de regel opnieuw beoordeelt terwijl het scherm openstaat.
Deel elke Vandaag-bron expliciet in bij gebeurtenis of verplichting, en houd die indeling gelijk aan de baan.
- Herkomst
- Afgeleid uit E-VDG-06 · nagelopen tegen alle elf
geregistreerde rijbronnen op 6 augustus 2026.
- Waarom
- Een regel die per soort verschilt, moet per bron te beantwoorden
zijn — anders wordt het bij elke nieuwe module opnieuw een discussie. Het goede nieuws is dat de
indeling al bestaat: elke rij draagt een
TodayLane, en de vier banden dragen
hem al zichtbaar — "Je dag" is de baan flow, "Nog te doen" is de baan
todo. Deze eis maakt dat wat het nu impliciet is: flow = gebeurtenis,
todo = verplichting. Een nieuwe bron kiest daarmee geen baan meer maar beantwoordt één
vraag — verloopt dit met zijn dag? — en de baan volgt.
- Raakt
- Fase 2 ·
TodayLane in lib/core/today/today_item.dart ·
alle elf TodayRowSource-registraties · E-VDG-01.
Wat "weggelegd" betekent, verschilt per soort — en dat is precies goed. De
dismissal-tabel is op (item, dag) gesleuteld. Voor een gebeurtenis is dat het einde: hij komt
toch niet terug. Voor een verplichting is het "vandaag even niet" — hij staat er morgen weer, want de
verplichting is niet verdwenen. Eén mechanisme, twee betekenissen, allebei de bedoelde.
Let op bij het bouwen: die dismissals zijn local-only in PowerSync en dragen geen
lid-id — ze synchroniseren dus niet en volgen je niet naar een tweede toestel. Voor gebeurtenissen is
dat verdedigbaar; voor alles wat als verplichting telt, is het een bekend gat (zie
E-VDG-11).
Geef agenda-items géén instelling "wil je dit afvinken" — stel bij het aanmaken één vraag: een afspraak is "moet je hier zijn", een taak is "moet je dit doen".
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek — bevestigt de aanbeveling uit
docs/design/agenda-of-taak.html. Begon als vraag, hardop gedacht: "misschien is het
verschil een taak met datum en tijd versus een echt agenda-item".
- Waarom
- Een schakelaar per agenda-item maakt van dat item een
schaduwtaak: iets dat je afvinkt maar dat nergens meetelt. Het onderscheid dat de eigenaar
zoekt bestaat al — taken, routines en afspraken zijn drie dingen in de app. Wat ontbreekt is niet
een schakelaar achteraf maar een keuze bij het aanmaken. Die keuze wordt in gewone taal
gesteld en de twee antwoorden staan hieronder letterlijk: het zijn de woorden die in de interface
komen te staan. Het eerste antwoord wordt een afspraak — verloopt met zijn dag, geen vinkje. Het
tweede wordt een taak met een tijd — afvinkbaar met een staat die synchroniseert, toewijsbaar met
gevolg, telt mee, en blijft tot hij gedaan is. Dat is E-VDG-06 toegepast op
het invoerscherm in plaats van op de weergave.
- Raakt
- Fase 2 · TEN-185 (randvoorwaarde) ·
lib/features/agenda/presentation/add_appointment_sheet.dart ·
lib/features/tasks/presentation/add_task_sheet.dart ·
docs/design/agenda-of-taak.html.
De twee formuleringen — letterlijk, want ze komen in de interface
Een afspraak is "moet je hier zijn".
Een taak is "moet je dit doen".
Citeer ze zo. Wie ze onderweg herschrijft naar "agenda-item" en "taak met deadline", geeft de
gebruiker het datamodel terug in plaats van de vraag waarvan hij het antwoord al weet.
Twee randvoorwaarden — eerst die, dan pas de vraag
De volgorde is niet vrij: andersom straft de keuze mensen voor het juiste antwoord
1 · Taken missen vier velden die afspraken wél hebben — notitie, locatie, eindtijd of duur,
en een per-item-herinnering die net zo vindbaar is (TEN-185). Dit is waargenomen, geen
vermoeden: een tester maakte een terugkerende taak aan als agenda-item omdat taken geen notitieveld
hebben. Zolang het antwoord "moet je dit doen" een veld kost dat iemand nodig heeft, kiest zij
alsnog de afspraak.
2 · Een taak met een tijd verschijnt vandaag niet in de agenda. Het agendascherm leest
alleen agendarijen plus de externe agenda van het toestel; geen enkele taakprovider zit erin. Wie
"moet je dit doen" antwoordt, raakt zijn item dus kwijt uit het overzicht waar hij het verwachtte.
De goedkope weg is samenvoegen bij het lezen — geen schemawijziging, 4 tot 7 bestanden — met de
vier voorafgaande keuzes uit agenda-of-taak.html §5.
Pas als beide dicht zijn, is de keuzevraag eerlijk. Ervóór is het een extra stap vóór
dezelfde vergissing, en erger: dan bestraft de app het juiste antwoord met minder velden en een
verdwenen rij. Plan ze in die volgorde in.
Het schaduwtaak-argument houdt stand — op twee van de drie punten, en het echte
argument is sterker dan het derde. Geverifieerd: een als afspraak bewaard item telt niet mee
in openstaande taken (de tellingen lezen alleen de takenlijst; de agenda staat er als los veld
naast) en verschijnt niet in Taken. Maar "niet toewijsbaar" klopt niet letterlijk: een afspraak
kent wél leden — er is een "Voor wie?"-kiezer — alleen is dat betrokkenheid, een ander veld
dan de toewijzing van een taak, en er telt niets op. Wat het argument mist en wat zwaarder weegt: het
vinkje op een agendarij is een local-only dismissal — die synchroniseert niet, draagt geen
lid-id en volgt je niet naar een tweede toestel. Een afgevinkte afspraak is dus voor niemand anders
afgevinkt en op je tablet niet gebeurd; een afgevinkte taak wél. Dát is de bodem onder de
aanbeveling.
De randvoorwaarden zijn eigen werk, niet dat van deze eis. De volledige
kolom-voor-kolom-vergelijking van de twee tabellen staat in
docs/design/agenda-of-taak.html §4; de twee wegen om een taak met een tijd in de agenda
te krijgen, met kosten, in §5. TEN-185 is de ingang voor de ontbrekende velden.
Drie punten waarover de eigenaar zich niet heeft uitgesproken — advies, geen besluit
Ze staan hier zodat ze terugvindbaar zijn zonder dat ze als beslist tellen. Een fixer vult ze
niet stilzwijgend in; ze horen bij het werk dat uit de twee randvoorwaarden voortkomt.
- Taken met een tijd horen níét naar de dagstroom te verhuizen. De banden dragen
betekenis: "Je dag" is wat er gebeurt, "Nog te doen" is wat jij nog moet
(E-VDG-10). Een taak chronologisch tussen de afspraken zetten laat hem
lijken op iets dat vanzelf gebeurt. Maar het onderliggende verlangen is terecht — je wilt zien
wanneer het moet. Advies: chronologie is een sorteervolgorde, geen band. Toon de tijd in
"Nog te doen" en sorteer die band erop.
- De wegleg-markering mag lokaal blijven — maar een vinkje mag nooit een wegleg-markering
zijn. Wegleggen is van nature persoonlijk en hoeft niet te synchroniseren; daar zit het
probleem niet. Het probleem is dat het vinkje op een agendarij een wegleg-markering ís:
het ziet eruit als afvinken en gedraagt zich als persoonlijk verbergen. Advies als regel: een
vinkje betekent gedaan en synchroniseert; alleen-voor-jezelf wegleggen is een andere handeling
— wegvegen of een menu-item.
- Een weg terug is nodig, maar één kant op: van afspraak naar taak. Daar zit de behoefte —
bestaande items die taken hadden moeten zijn (precies het geval uit TEN-185). Andersom, een taak
die een afspraak had moeten zijn, komt vrijwel niet voor; bouw die richting niet
vooruitlopend.
Geef de band "Nog te doen" een vaste voet "Alle taken ›", ook wanneer de band leeg is.
- Herkomst
- Ontwerpstuk §3 · onderzoek, versterkt door E-NAV-01.
- Waarom
- Onder concept E is deze band niet alleen een lijstje maar ook een
navigatieroute naar Taken — een van de drie wegen uit E-NAV-06. Vandaag
verdwijnt de hele sectie zodra er geen taken zijn, en daarmee verdwijnt ook de route. Een lege band
hoort één regel te tonen ("Geen taken vandaag — Alle taken ›"), niet niets.
- Raakt
- TEN-162 · fase 2 ·
lib/features/today/…/todo_section.dart.
Geef een module twee schakelaars voor Vandaag: één voor items en één voor signalen.
- Herkomst
- Ontwerpstuk §7, vraag D6 · onderzoek, beslecht door de eigenaar op
6 augustus 2026: "Mogen er 2 zijn."
- Waarom
- Eén schakelaar is te grof: wie de suggesties van een module niet
wil, wil de items vaak nog wél. Een app-brede knop geeft geen keuze per module. De twee schakelaars
vallen samen met een grens die er al ligt: items dekt band 1+2 (rijbronnen — wat er van jou
in de dag staat), signalen dekt band 3 (gaten en suggesties — wat de app zélf opmerkt).
Dat is dezelfde scheiding als de vier-paden-grens, dus de schakelaars volgen de architectuur in
plaats van er een tweede indeling overheen te leggen. Gelaagd zoals voorgesteld: persoonlijk,
anders gezin, anders de standaard van de module.
- Raakt
- TEN-161 · TEN-162 · fase 2 ·
TodaySection.moduleId ·
TodaySection.band.
De blokkade op fase 2 vervalt. Deze vraag stond als blokkerend voor fase 2
genoteerd omdat TEN-161 er niet zonder gebouwd kon worden. Met dit besluit kunnen TEN-161 en TEN-162
in één beweging. Band 4 (Klaar) krijgt géén eigen schakelaar: die band toont wat de gebruiker zelf
heeft afgehandeld en volgt dus de schakelaar van de band waar het item vandaan kwam.
Aangevuld avond 6 augustus 2026 — anders is de schakelaar een lege huls
De twee schakelaars krijgen een eigen sleutel, die óók voor kernmodules geldt
Het probleem, gevonden door de sectie-audit (bevinding A-OB-1). De schakelaars zouden
aangrijpen op de bestaande zichtbaarheidspoort. Maar
moduleVisibleForMemberProvider geeft onvoorwaardelijk true terug
voor elke id in kCoreSurfaceModuleIds (module_providers.dart:396), en
modulebeheer weigert voor zo'n module überhaupt een modulestate te schrijven
(modules_beheer_providers.dart:34 en :62,
module_settings_action.dart:78). Er bestaat vandaag dus geen bereikbare toestand
"dit lid heeft Taken van zijn Vandaag gehaald" — en dan doet de schakelaar op precies de
modules waar de meeste dagrijen vandaan komen niets.
Het besluit: uitweg (a). De twee schakelaars krijgen een eigen sleutel in de
prefs-bag per (lid, module), los van de aan/uit van de module zelf, en die sleutel
geldt ook voor kernmodules. De module blijft altijd aan en altijd bereikbaar — via zijn tab,
zijn route en modulebeheer; alleen zijn bijdrage aan Vandaag gaat uit. De twee afgewezen
uitwegen: (b) de kernuitzondering beperken tot route en springboard — dat maakt van één
begrip twee met een uitzonderingslijst ertussen; en (c) het taakgat ongepoort laten — dan
blijft de schakelaar op dat gat een dode knop.
Waarom dit geen uitholling van "altijd aan" is: "staat dit op mijn Vandaag" is een
andere vraag dan "gebruik ik deze module". De kernuitzondering bestaat om te voorkomen dat
iemand een tabblad kwijtraakt dat de app nodig heeft; hij bestaat niet om te bepalen hoe iemands
dagoverzicht eruitziet. Wie zijn taken in Taken beheert en zijn Vandaag voor afspraken gebruikt,
vraagt niets onredelijks. De harde grens blijft: de module zelf kan niet uit.
Waar de sleutel niet hoort: niet in de _shell-rij. Deze twee schakelaars staan
in de rij per (lid, module) — de granulariteit waarvoor last-write-wins aanvaardbaar
is. In _shell zou een schakelaar op je telefoon je springboard op je tablet kunnen
overschrijven.
Hangt samen met E-MOD-12. Dat besluit krimpt de kern-set naar
Agenda, Taken en Lijstjes. Deze eis maakt de schakelaars onafhankelijk van die set — ze werken dus
ongeacht hoe de kern-set er in de toekomst uitziet, en dat is precies de bedoeling.
Rangschik de signaalband op een vaste rangorde in vier lagen; laat de laag volgen uit de aard van het signaal en niet uit wat een module zelf vindt.
- Herkomst
- Eigenaar, 6 augustus 2026 · beantwoordt de vraag die ADR-0021 als
"niet stilzwijgend in te vullen" had gemarkeerd: waarop weegt een uitnodiging tegen een
aankondiging tegen een ongepland avondeten?
- Waarom
- E-VDG-02 zegt het zelf: met één zichtbare
kaart is de rangschikking het hele product van die band. Een cijfer per signaal of "de
meest recente wint" lost dat niet op — het eerste laat elke module zijn eigen belang inschatten, het
tweede beloont wie het vaakst iets stuurt. De onderliggende regel is: hoe minder omkeerbaar het
gemis, hoe hoger. Aan die regel wordt een nieuw soort signaal getoetst, niet aan gelijkenis met
een bestaand voorbeeld. Dat de laag uit de aard volgt en niet uit een instelling is
dezelfde keuze als bij gebeurtenis-versus-verplichting: zo kan een nieuwe module zichzelf niet
vooraan zetten.
- Raakt
- TEN-162 · fase 2 · ADR-0021 (besluit 3, de signaal-collector) ·
E-VDG-01 · E-VDG-02 ·
public.announcements (nieuwe ernstkolom).
Binnen een laag wint de dichtstbijzijnde deadline; heeft geen van beide er een, dan
het jongste signaal. Geverifieerd op 6 augustus 2026 welke bronnen dat vandaag kunnen leveren:
suggesties heeft een echte vervaldatum (VandaagSuggestion.dueDate),
announcement heeft startsAt/endsAt, share-hint
heeft alleen recency (updatedAt), gaps heeft geen datum maar wel
GapTone als ernstproxy, en discovery en invite hebben niets
sorteerbaars. Uitnodigingen dragen zelfs geen tijdstempel, dus bij meer dan één uitnodiging is
"het jongste" pas uit te rekenen als die bron een aanmaakmoment meelevert. Dit zijn de zes
signaalbronnen die er zijn — de overige negen Vandaag-secties leveren dagrijen of chroom.
Aankondigingen kennen twee ernstniveaus. Een gewone aankondiging (nieuwe
functie, tip) volgt de rangorde en kan dus achter "en X meer…" belanden. Een dringende (storing,
gegevensverlies, iets dat actie vraagt) staat boven het plafond en verschijnt altijd — buiten de
collector om, niet als laag 0 erbinnen, zodat hij niet met een uitnodiging om voorrang concurreert.
Dat kost één vlag bij het versturen, gezet door de exploitant; technisch is dat een nieuwe kolom op de
server-only tabel public.announcements, die vandaag geen ernstveld heeft
(segment is doelgroep, geen ernst). Die vlag moet spaarzaam gebruikt worden, en dat
hoort bij de knop te staan: een dringende aankondiging die niet dringend is, leert mensen de kaart te
negeren — en dan werkt hij ook niet op de dag dat er écht iets aan de hand is. Dit is het enige
mechanisme dat het plafond van E-VDG-02 mag doorbreken.
De spanning bij laag 2 is beslecht — 6 augustus 2026: de suggestiebron splitst per
item. Het voorbeeld bij laag 2 — "een verlopende verzekering" — landt in de code op de
suggestiebron, en die stond als bron in laag 4. Gekozen: lezing (a). Een suggestie
mét een naderende vervaldatum valt in laag 2; de rest blijft laag 4. De bron
bepaalt de laag dus per item in plaats van één keer voor alles. Lezing (b) — laag 2
reserveren voor bronnen die er nog niet zijn — is afgewezen.
Waarom, en wat het zichtbaar verandert. De aanwezigheid van een deadline is een
eigenschap van het item, geen oordeel van de module — precies de onderliggende regel van deze
eis, en het houdt overeind dat een module zichzelf niet vooraan kan zetten: hij kan alleen een datum
melden die er is. Gevolg op het scherm: "verloopt over drie dagen" staat vanaf nu boven een
aankondiging van de exploitant. Met een plafond van één kaart
(E-VDG-02) is dat het verschil tussen die kaart wel of niet zien, en dat is de
bedoeling. Voor de bouwer: de laag is een waarde per signaal, nooit een constante op de
bron — anders staat de laag op twee plekken.
Gebied 4
Mijn modules
Het springboard. Fase 1, en het enige gebied dat op zichzelf al een afgeronde
verbetering is.
Mappen
De reden dat het springboard schaalt — en dus geen aardigheidje.
Bied een zichtbare knop "Nieuwe map" als primaire weg om een map te maken.
- Herkomst
- Prototype-feedback, 5 augustus 2026 · bevestigd door de eigenaar.
- Waarom
- Mappen zijn in dit ontwerp een randvoorwaarde, niet een
extraatje: zonder mappen schaalt het springboard niet mee met 29 modules. Iets noodzakelijks mag
niet afhangen van een gebaar dat je moet kennen, gericht moet uitvoeren, én alleen werkt in een
stand die je ook al moet ontdekken. Dat is een te dun fundament.
- Raakt
- TEN-163 · fase 1.
Bied het sleepgebaar (tegel op tegel) als tweede weg naar een map — nooit als de enige.
- Herkomst
- Prototype-feedback, 5 augustus 2026 · bevestigd door de eigenaar.
- Waarom
- Het gebaar is snel en vertrouwd voor wie het kent, dus het verdient
een plek. Maar de knop is de weg en het gebaar is de snelweg. Praktisch gevolg dat je in de
planning mag gebruiken: valt het bouwen van het sleepgebaar duur uit, dan is dit het eerste dat
sneuvelt zonder dat er functionaliteit verdwijnt. Bij een omgekeerde keuze zou het schrappen
van het gebaar de functie zelf onbereikbaar maken.
Maak een module uit een map sleepbaar, met daarnaast een niet-sleep-weg via het lang-indrukmenu.
- Herkomst
- Prototype-feedback, 5 augustus 2026 · eigenaar.
- Waarom
- Dezelfde redenering als E-MOD-01, maar dan
voor de omgekeerde beweging. Een map in kunnen zonder eruit te kunnen is een val. En omdat het
lang-indrukmenu er toch al is (verplaatsen, van beginscherm halen, op Vandaag tonen, instellingen),
kost de tweede weg hier bijna niets.
- Raakt
- TEN-163 · fase 1 · TEN-164 (het menu bestaat al).
Laat een map die leeg raakt vanzelf verdwijnen.
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek. Sleept de gebruiker de laatste module
eruit, dan is de map weg.
- Waarom
- Het is het gedrag dat iedereen van iOS kent — daar hoeft niemand
iets voor te leren, en afwijken van een bekend patroon kost meer dan het oplevert. En een lege map
is een lege huls: hij vertegenwoordigt niets meer, neemt wel een plek in het raster in, en levert
alleen opruimwerk op dat de gebruiker later zelf moet doen.
Geverifieerd — het prototype bouwt dit al zo; schets en besluit lopen gelijk.
ejectFromFolder() in docs/archive/implemented/design/prototype-concept-e.html doet
if(f.items.length===0){ S.board.splice(fi,1); … dissolved=true; }, en de hint in het
mappaneel zegt letterlijk: "Haal je de laatste eruit, dan verdwijnt de lege map vanzelf." Er
hoeft dus niets herbouwd te worden — dit besluit bevestigt wat er staat.
Correctie op dit register. Bij deze eis stond tot vandaag als herkomst: "het
prototype laat een lege map gewoon staan". Dat klopt niet en heeft de vraag zwaarder doen lijken dan
hij was; de regel hierboven is er sinds de tweede prototyperonde.
Twee gevolgen die vastgelegd moeten worden
1 · Een map met één module blijft wél staan
Alleen leeg betekent weg. Een map met één module is geen restant maar een keuze: iemand
heeft die map gemaakt, hem een naam gegeven en is misschien nog bezig hem te vullen. Een map bij één
module alvast opheffen zou de gebruiker in zijn eigen indeling tegenwerken en zijn naam weggooien
terwijl hij hem nog gebruikt. Dit bevestigt wat het prototype doet, en het is dezelfde grens die
iOS trekt.
2 · Ongedaan maken herstelt de map, mét zijn naam en op zijn oude plek
Dit is de voorwaarde waaronder gevolg 1 acceptabel is. Zonder herstel zou één sleepbeweging genoeg
zijn om een zelfbedachte mapnaam te verliezen — precies het soort onzichtbare vernietiging waar
E-OPS-03 zich tegen keert, en de reden dat deze vraag überhaupt open stond.
Terugdraaien zet de map terug op de index waar hij stond, met dezelfde naam en met de module er weer
in.
Geverifieerd — ook dit staat al in het prototype: de terugdraai-tak doet
S.board.splice(Math.min(fi,S.board.length),0,{k:'f',name:name,items:[id]}), dus
oorspronkelijke index, oorspronkelijke naam. De melding die het aanbiedt is er ook, inclusief de
tekst "· de lege map is verdwenen" — de gebruiker wordt dus verteld wat er gebeurde vóór hij het kan
terugdraaien. Neem dat mee als eis, niet als detail: automatisch opruimen zonder melding
mét ongedaan-maken is niet hetzelfde besluit.
Laat een tegel die uit een map wordt gehaald achteraan op het springboard landen.
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek: "aangezien je vanuit een drawer
sleept die over icons heen gaat is het precies neerzetten sowieso niet echt handig."
- Waarom
- Je mikt op een beginscherm dat op dat moment achter het mappaneel
ligt — je ziet niet waar je loslaat. Doen alsof de losplek betekenis heeft is dus schijnprecisie:
de gebruiker krijgt een uitkomst die van toeval afhangt en die hij niet kon sturen. Achteraan is
altijd dezelfde plek, ongeacht waar je loslaat, en het is bovendien het enige antwoord dat óók klopt
voor de menu-weg uit E-MOD-03, waar helemaal geen losplek bestaat. Daarmee
geven de twee wegen hetzelfde resultaat — wat de eigenlijke vraag was.
Wijkt af van het prototype — het prototype moet hierop aangepast worden.
ejectFromFolder() zet de tegel vandaag direct naast de map (var at=fi+1),
met in de toelichting exact dezelfde onderbouwing over het niet kunnen mikken, maar met een andere
uitkomst: "Achteraan zetten is wél voorspelbaar, maar dan moet je hem gaan zoeken in een raster
van 29 modules. Naast de map is allebei." De eigenaar kiest anders, en een eigenaar-uitspraak
overrulet een ontwerpstuk. Het besluit hierboven geldt; het prototype loopt achter en staat als los
punt op de corpuswerk-lijst.
De kanttekening — bewust geaccepteerd, niet vergeten
"Achteraan" kan twee schermen naar beneden zijn
Op een springboard met 35 tegels in de beginstand betekent achteraan: buiten beeld. De gebruiker
trekt iets uit een map en het verdwijnt. Zodra iemand zijn springboard heeft opgeruimd werkt dit
prima — maar de beginstand is nu juist vol, en dat is precies de stand waarin mensen gaan
opruimen. Dit is het bezwaar dat het prototype deed kiezen voor "naast de map"; het besluit neemt
het voor lief, en dan moet er iets tegenover staan.
Aanbeveling — hoe de gebruiker ziet wáár de tegel bleef
Een melding die de module noemt en "ongedaan maken" aanbiedt
Zonder zo'n mechanisme is dit de enige handeling in het springboard waarvan het resultaat
onzichtbaar is, en dat is geen kleinigheid: onzichtbare uitkomsten maken dat mensen de handeling
niet meer durven te doen. Van de drie mogelijkheden is de melding de enige die het werk doet.
- Meescrollen naar de nieuwe plek — werkt alleen bij slepen; na de menu-weg uit
E-MOD-03 sta je in het mappaneel en zou het scherm onder je vandaan
springen. Het toont bovendien wél waar iets is, maar niet wat er gebeurde.
- Een korte markering op de tegel — is per definitie onzichtbaar in het geval dat het moet
oplossen: de tegel staat buiten beeld. Prima als aanvulling voor wie er daarna heen scrolt, geen
antwoord op zichzelf.
- Een melding met "ongedaan maken" gekozen — zichtbaar
ongeacht de scrollpositie, noemt de module bij naam, werkt identiek voor de sleep- en de menu-weg,
en beantwoordt de vraag die de gebruiker écht heeft ("is hij weg?") in plaats van alleen "waar is
hij?".
Het is bovendien het goedkoopste antwoord: het prototype heeft de melding met terugdraaien
al (toastUndo, gebruikt bij precies deze handeling), en
E-MOD-04 heeft hem sowieso nodig voor het herstellen van een verdwenen map.
Eén mechanisme bedient beide eisen.
Gebruik de domeinen als startpunt in de vorm van mappen; op het beginscherm van de gebruiker
vervangt de map het domein. In de catalogus blijft het domein de vaste categorie.
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek. Neemt het voorstel uit ontwerpstuk §7
(vraag E1) over. Herformuleerd op de avond van 6 augustus 2026, toen de eigenaar de grens
uitsprak: domeinen ordenen wat de app te bieden heeft, mappen ordenen wat de gebruiker ervan
gemaakt heeft.
- Waarom
- Eén ordeningsbegrip per gebied, niet twee door elkaar.
Bij de overgang worden de bestaande domeinen eenmalig omgezet naar mappen, zodat niemand op een
leeg raster start; vanaf dat moment is op het springboard en het dashboard de map de
waarheid. Twee begrippen dóór elkaar op hetzelfde scherm zou betekenen dat de gebruiker moet
snappen waarom zijn eigen map niet hetzelfde is als een domein — en dat is een uitleg die je nooit
meer kwijtraakt. Maar in de catalogus — onboarding, modulebeheer, meldingeninstellingen,
AI-instellingen — heeft de gebruiker nog niets ingericht; daar is een map leeg begrip en het domein
juist de enige beschikbare ordening.
- Raakt
- TEN-163 · fase 1 ·
/domein/:id (vervallen — verwijderd met F1-9, merge 20f1b910, 6 augustus 2026) ·
E-MOD-04 · E-OPS-03. Niet modulebeheer,
onboarding, meldingeninstellingen of AI-instellingen — die blijven op domein ordenen.
Correctie op de telling: het zijn er tien, niet elf. Er bestaan precies tien
DomainDescriptors, elk gedeclareerd in zijn eigen feature-module en samengevoegd in
module_registry.dart:43-45: gezin, planning,
financieel, huis, gezondheid, vastgoed,
voorraad, documenten, bewaarlijsten en welzijn.
De elfde sectie op Mijn leven is geen domein maar de gecureerde "Populair"-strook
(mijn_leven_screen.dart:66-102). Er worden dus tien mappen aangemaakt bij de
conversie, niet elf.
En op 6 augustus 2026 werden het er zes — deze telling is achterhaald. De
correctie hierboven beschrijft de registry zoals die tot 6 augustus 2026 was; sinds merge
0ea70a81 staan de zes domeinen op één plek in
lib/features/app_domains.dart:81-120 en zijn de tien domein-id's hierboven verdwenen
(financieel heet nu geld). Met E-MOD-13 zijn de tien domeinen opnieuw gesneden
tot zes — Eten · Gezin · Huis · Geld · Gezondheid · Bewaren — en maakt de conversie dus
zes mappen. Deze eis zelf verandert niet: domeinen worden mappen, en de map is daarna de
waarheid van de gebruiker. Alleen het getal eronder verandert, en de reden staat in
E-MOD-13: vier van de tien domeinen heetten precies zoals hun enige module,
en zes van de tien droegen er maar één. Dat er zes mappen zijn en niet tien is dus geen bijstelling
van deze eis maar het gevolg van een besluit erboven.
Correctie — de overlapzorg vervalt níét
De "Populair"-strook bevat wél registry-modules: twee stuks
De aanname dat de strook alleen kernoppervlakken bevat, klopt voor de eerste vier tegels — Vandaag,
Taken, Agenda en Boodschappen — maar niet voor de strook als geheel. Direct daarna staan er twee
gecureerde registry-modules in:
for (final id in const ['maaltijden', 'recepten'])
(mijn_leven_screen.dart:143-145, met de opmerking "Curated picks surfaced in the pinned
row: Maaltijden (free) en Recepten (a Plus upsell)"). Allebei hebben ze
domainId: 'planning' (planning_module.dart:109-110 en
:119-120), en de domeinsecties eronder tonen álle ingeschakelde modules van hun domein.
Die twee tegels staan vandaag dus twee keer op Mijn leven, en na de conversie zouden ze zowel
in de map "Planning" als in de strook staan.
Wat er moet gebeuren: de twee gecureerde picks vervallen bij de conversie. Onder deze eis is
het springboard de indeling van de gebruiker; een tegel die de app er ongevraagd dubbel in zet, is
precies wat "de map is de waarheid" uitsluit. Maaltijden en Recepten landen in hun map Planning, één
keer. Wil de app Recepten als Plus-verleiding tonen, dan hoort dat op een Plus-oppervlak en niet als
tweede exemplaar van een tegel die er al staat.
Nog een detail dat bij de conversie opvalt: de gecureerde picks worden opgehaald met
registry.moduleById(id) en niet door de isEnabled-filter geleid die de
domeinsecties wél gebruiken. Een uitgezette Maaltijden-module staat vandaag dus alsnog in de
strook. Dat verdwijnt mee met de picks.
De vier gevolgen, uitgewerkt
1 · De kernoppervlakken blijven los en prominent bovenaan
Vandaag, Taken, Agenda en Lijstjes zitten in geen enkel domein en worden dus ook geen
mapinhoud. Ze blijven staan waar ze staan: los, bovenaan, vóór de mappen. Dat is consistent met het
eerdere besluit dat kernoppervlakken verplaatst, verborgen of alsnog in een map gestopt mogen
worden, maar standaard prominent staan. De conversie verandert daar niets aan — hij raakt alleen de
tien domeinen.
Bijgesteld op de avond van 6 augustus 2026 — en er zat een tweede fout in.
Hier stond "Vandaag, Taken, Agenda en Boodschappen". Met E-MOD-12 is
Boodschappen geen kernmodule meer: hij krijgt een domein, landt bij de conversie gewoon in díé map
en is daarna te verplaatsen als elke andere module. En Lijstjes ontbrak — die was en blijft
kern. Dat kwam doordat deze zin de "Populair"-strook beschreef en niet de kern-set: de
strook toont Vandaag, Taken, Agenda en Boodschappen
(mijn_leven_screen.dart:66-100), terwijl kCoreSurfaceModuleIds Taken,
Agenda, Lijstjes en Boodschappen bevat (module_registry.dart:14-19). Vandaag staat wel
in de strook en niet in de set (het is een tab, geen module); Lijstjes staat wel in de set en niet
in de strook. Los daarvan blijft de conclusie staan voor de drie die kern blijven plus
Vandaag: geen van hen is een registry-module met een domainId, dus geen van hen wordt
door de conversie mapinhoud. Boodschappen is vanaf E-MOD-12 de enige die
dat wél wordt.
2 · Lege domeinen worden geen lege map
Hier vangen twee besluiten elkaar netjes op, en dat is het waard om uit te schrijven.
Geverifieerd: de weergave laat vandaag al lege domeinen weg —
].where((s) => s.modules.isNotEmpty) (mijn_leven_screen.dart:113), met
in de code de reden erbij ("dropping domains that have none enabled so the grid mirrors the module
choices"). Bij de conversie ontstaan er dus geen mappen zonder inhoud. En zou er later één leeg
raken, dan verdwijnt hij vanzelf op grond van E-MOD-04. Er is geen derde
regel nodig: de startstand kan geen lege map opleveren, en de eindstand houdt er geen.
3 · De conversie is eenmalig, en daarna landt nieuw werk in "Nieuw"
Een module die ná de conversie aan de app wordt toegevoegd landt niet in de map van zijn
oude domein, maar in een aparte "Nieuw"-bak. De reden is de kern van deze eis: vanaf de
conversie zijn de mappen van de gebruiker. Daar ongevraagd iets in zetten is aanmatigend — het is
de app die de indeling van iemand anders bijwerkt, in een map die die persoon zelf een naam heeft
gegeven en misschien allang anders gebruikt dan het oude domein suggereert. In een aparte bak is
het bovendien zichtbaar dát er iets nieuws is, en verplaatst de gebruiker het zelf naar de plek
waar het volgens hém hoort. Dat is dezelfde redenering als bij
E-MOD-05: als de app niet weet waar iets hoort, zet ze het niet ergens
neer alsof ze het wel wist.
4 · Wat er met /domein/:id is gebeurd — en wat er níét is vervallen
Het domein blijft in de code bestaan als eigenschap van een module — het is de bron voor de
eenmalige conversie en voor de "Nieuw"-bak-afweging hierboven. Wat verviel is precies één
weergave: de route /domein/:id met zijn scherm. Dat onderscheid
hoort in het implementatieplan te staan, anders wordt DomainDescriptor weggehaald en
is de conversie niet meer herhaalbaar voor een account dat hem nog niet heeft gehad.
Uitgevoerd op 6 augustus 2026 met F1-9 (merge 20f1b910), en precies
zo afgebakend. Weg zijn de GoRoute en
lib/features/shell/screens/domain_screen.dart — die map bevat nu alleen nog
mijn_leven_screen.dart, en de router-doc benoemt de uitfasering zelf
(lib/core/router/app_router.dart:7-9).
test/core/router/domein_route_verwijderd_test.dart bewaakt dat de route niet
terugkomt. Gebleven zijn DomainDescriptor, ModuleDescriptor.domainId en
modulesForDomain (lib/core/modules/module_registry.dart:66-67), plus alle
vier de catalogusschermen die op domein ordenen. (De regelverwijzingen
app_router.dart:256-260 en domain_screen.dart:18-31 stonden hier tot deze
herziening; ze wijzen nergens meer naar en zijn daarom verwijderd in plaats van bijgewerkt.)
De grens, uitgesproken door de eigenaar — avond 6 augustus 2026
Domeinen ordenen de catalogus; mappen ordenen het beginscherm
Dit vervangt een eerdere formulering die te ver ging. Deze eis zei tot vandaag: "na de
conversie ordent geen enkel scherm nog op domein." Letterlijk gelezen betekent dat "domeinen
verdwijnen", en dat ís het besluit niet — het trok bovendien vier schermen fase 1 in die er niets
te zoeken hebben. De eigenaar heeft de grens anders gelegd, en zo geldt hij:
- Domeinen blijven de vaste categorieën van de catalogus — de standaardindeling waarmee
de app ordent wat hij te bieden heeft. Vier schermen, en alle vier blijven ze op domein
ordenen: onboarding-modulekeuze (
modules_step.dart:30,32,53),
modulebeheer (modules_beheer_screen.dart:212-230),
meldingeninstellingen (meldingen_screen.dart:139,148,152) en
AI-instellingen (ai_settings_section.dart:47-48).
- Mappen ordenen wat de gebruiker er zelf van gemaakt heeft — springboard en dashboard.
Daar, en alleen daar, vervangt de map het domein.
Waarom de catalogus geen mappen kan gebruiken. Een catalogus toont álles wat er is, óók
wat je nog niet hebt aangezet — daar heeft de gebruiker per definitie nog geen indeling van
gemaakt. Mappen zijn per lid en zelfbenoemd; een catalogus op mappen zou per lid anders zijn, en
een module die in géén map zit zou nergens meer opduiken. Bij de AI-instellingen is het niet eens
een keuze: daar hangt de gevoeligheid aan het domein (domain.sensitive,
ai_settings_section.dart:47-48) en niet aan de gebruikersindeling.
Twee begrippen, twee gebieden — en dat is geen dubbeling. De uitleg die deze eis wilde
vermijden ("waarom is mijn map niet hetzelfde als een domein") komt alleen op als de twee op
hetzelfde scherm staan. Dat gebeurt na deze grens nergens meer.
Geef het mappaneel een "Map opheffen"; de modules komen terug op het springboard op de plek
waar de map stond, in hun onderlinge volgorde.
- Herkomst
- Eigenaar, avond 6 augustus 2026 · beantwoordt de vraag die het
fase-0/1-plan als §6 open vraag 4 had genoteerd ("bestaat map opheffen?"). Het prototype had de
knop al zonder dat er een eis over ging.
- Waarom
- Zonder deze handeling is een map met acht modules alleen
ontbindbaar door acht keer uit te halen — en dan staan ze alle acht achteraan, in een volgorde die
van je tempo afhing. Dat is geen opruimhandeling maar een straf op het proberen. En dat de plek
van de map behouden blijft, is hier wél te verantwoorden: een map ís een groep die bij elkaar
hoort en die de gebruiker zelf op die plek heeft gezet. De plek draagt betekenis die hij zelf
heeft aangebracht.
Wijkt bewust af van E-MOD-05 — en dat verschil moet uitgelegd blijven
Eén tegel landt achteraan; een hele map landt waar de map stond
E-MOD-05 zegt: een tegel die je uit een map haalt, landt
achteraan. Deze eis zegt: de modules van een map die je opheft, landen op de
plek van de map. Dat lijkt een tegenspraak en is het niet, want de twee handelingen verschillen
op precies het punt waar de regel van afhangt: weet de app waar de gebruiker het wilde
hebben?
- Uit de map halen — je sleept over een paneel dat het beginscherm afdekt, of je gebruikt
het menu, waar helemaal geen losplek bestaat. De app weet de bedoelde plek niet. Achteraan is
dan het eerlijke antwoord: dezelfde uitkomst, ongeacht waar je loslaat.
- Map opheffen — de gebruiker wijst geen plek aan, maar hij heeft er al één: de map staat
ergens, en die plek heeft hij zelf gekozen. De app hoeft niets te raden; ze hoeft alleen niet
weg te gooien wat er al was. Het gaat bovendien om een groep die bij elkaar hoort — die
uit elkaar trekken naar de staart van een raster van 29 tegels is precies het verlies dat de
handeling zou moeten voorkomen.
De onderliggende regel, en zo hoort hij in het plan: weet de app een plek, dan
gebruikt ze die; weet ze er geen, dan verzint ze er geen. Dat is dezelfde regel die
E-MOD-05 naar "achteraan" leidt en E-MOD-10 naar
"onthoud de plek" — drie eisen, één beginsel.
Geverifieerd — het prototype doet dit hier al goed, in tegenstelling tot
ejectFromFolder. dissolvefolder in
docs/archive/implemented/design/prototype-concept-e.html:2420-2425 vervangt de map-entry door zijn items op
dezelfde index: S.board.splice.apply(S.board,[fi,1].concat(items)), met een melding
"Map … opgeheven". Dat is exact deze eis. Bij deze knop loopt het prototype dus niet achter
en mag hij als referentie dienen — anders dan bij ejectFromFolder en
rmtile/rmbyid, waar hij dat wél doet
(E-MOD-05, E-MOD-10).
Twee dingen die hierbij horen en niet vergeten mogen worden. Eén:
opheffen krijgt dezelfde melding met "ongedaan maken" als E-MOD-04 en
E-MOD-05 — terugdraaien zet de map terug op zijn index, met zijn naam en
zijn hele inhoud. Eén mechanisme bedient nu drie eisen. Twee: opheffen is een
handeling van de gebruiker en verwijdert de map dus echt, ook als er nog niet-renderende
id's in staan — dat is de grens uit E-MOD-10, en die id's verhuizen mee naar
het springboard in plaats van te verdwijnen.
Vinden en openen
Toon bij een zoekresultaat de naam van de map waar de module in zit.
- Herkomst
- Prototype-feedback, 5 augustus 2026 · door de eigenaar expliciet als
waardevol bevestigd.
- Waarom
- Mappen maken dingen vindbaar én verstoppen ze. Zoeken kijkt dwars
door mappen heen, maar zonder de mapnaam leert de gebruiker nooit wáár iets staat en blijft hij
zoeken in plaats van navigeren. De mapnaam maakt van elk zoekresultaat een kleine les in de eigen
indeling.
- Raakt
- TEN-163 · fase 1.
Geef het springboard een zoekveld bovenaan.
- Herkomst
- Ontwerpstuk §2 · onderzoek, daar aangeduid als harde randvoorwaarde.
- Waarom
- Zodra de gebruiker mag ordenen, verbergen en in mappen stoppen,
is er geen vaste plek meer waar iets "hoort" te staan. Zoeken is de ontsnapping die dat mogelijk
maakt. Zonder zoekveld is elke opruimhandeling ook een risico.
Geef elke module bovenin dezelfde kop, met zoeken en instellingen.
- Herkomst
- Prototype-feedback, 5 augustus 2026 · door de eigenaar expliciet als
waardevol bevestigd, en gevraagd consequent over de hele app. Bijgesteld 6 augustus 2026: de
derde vaste actie (AI) vervalt.
- Waarom
- Vandaag verschilt elke modulekop en moet je per module opnieuw
leren waar iets zit. Dezelfde vaste acties op dezelfde plek maakt van 29 losse schermen één app.
De instellingen-ingang is met TEN-164 al zo gebouwd — die leidt zichzelf af uit de route en werkt
daardoor op alle moduleschermen zonder per scherm iets te configureren. Zoeken volgt dat
patroon.
- Raakt
- TEN-164 (gemerged, levert het patroon) · E-NAV-10 ·
E-NAV-18 · begrensd door E-NAV-11 (hoeveel acties
past een kop).
Waarom AI hier verdwenen is. Deze eis vroeg drie vaste acties: zoeken, AI en
instellingen. Sinds E-NAV-10 zit de AI-ingang in de centrale pil, en die pil
staat op álle schermen — dus ook op elk modulescherm. Een tweede AI-knop in de kop zou daar direct
boven staan: twee ingangen naar dezelfde assistent, in één beeld. Hij vervalt dus niet omdat AI minder
belangrijk werd, maar omdat hij er al staat.
Wat dat oplevert, en wat het niet oplevert. Het vaste blok is nu zoeken +
instellingen — plus de favorietenster, die deze eis nooit noemde maar die op 28 van de 29
moduleschermen staat. Vast blok = drie, dus binnen de grens van vier
(E-NAV-11) blijft er één plek over voor een scherm-eigen actie.
Dat is niet vanzelf genoeg: de Afvalkalender heeft er twee en zou op vijf uitkomen. Wat daar
gebeurt staat in E-NAV-18 — de ICS-import verhuist naar de
module-instellingen, en dan past het.
Onthoud de plek van een module die uitgezet wordt: het id blijft in de map staan en rendert niet.
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek — akkoord met het voorstel uit
ontwerpstuk §7 (vraag C2) zoals het hier stond.
- Waarom
- Vergeet de app de plek, dan komt de module bij heraanzetten ergens
anders terug en is de indeling van de gebruiker stiekem veranderd — een verandering die hij niet
heeft aangebracht en niet kan terugdraaien, omdat hij niet weet dat het gebeurd is. Onthouden
betekent dat uitzetten en weer aanzetten samen niets doen, en dat is de enige uitkomst waarbij een
gebruiker zijn ordening durft te vertrouwen.
Geen gevolg voor het opslagformaat — dat is al besloten.
E-OPS-03 legt vast dat posities als id's worden opgeslagen en niet
als indexposities, met exact deze motivering: "met id's blijft het item in de lijst staan en rendert
het simpelweg niet — precies wat de favorietenbalk vandaag al doet met onbekende id's". Deze eis is
dus de toepassing van E-OPS-03 op mapinhoud, geen nieuwe vorm. Er is geen extra veld, geen
migratie en geen tweede lijst met "onthouden plekken" nodig.
De koppeling die expliciet moet — anders botst dit met E-MOD-04
Een handeling van de gebruiker verwijdert; een toestand van het systeem verbergt alleen
Zonder deze regel spreken twee besluiten elkaar tegen. E-MOD-04 zegt: een
lege map verdwijnt vanzelf. Deze eis zegt: een uitgezette module blijft als id in zijn map staan.
Wat gebeurt er met een map waarvan de laatste module wordt uitgezet — is die map leeg of
niet?
Hij is niet leeg, en hij verdwijnt dus niet. Hij bevat nog een id; er is alleen niets te
tonen. Zo'n map wordt daarom verborgen zolang hij niets rendert, en komt met naam en
inhoud terug zodra een van zijn modules weer aan gaat. Dat is precies hetzelfde mechanisme dat de
weergave vandaag al toepast op lege domeinen (mijn_leven_screen.dart:113), en het is
dezelfde leesregel als bij E-NAV-19: de voorkeur blijft staan, de
weergave valt terug.
De grens is daarmee scherp te formuleren, en zo hoort hij in het implementatieplan te staan:
alleen een handeling van de gebruiker verwijdert een map — de laatste tegel eruit slepen. Een
toestand van het systeem (module uit, Plus verlopen, module verwijderd uit de registry) verbergt
hem hooguit. De gebruiker verliest zijn mapnaam dus nooit door iets dat hij niet zelf deed.
"Van beginscherm halen" valt hier óók onder — besloten 6 augustus 2026. Het
prototype heeft twee wegen om een tegel van het springboard te halen: het minus-knopje in de
bewerkstand en "Van beginscherm halen" in het lang-indrukmenu. Of dat een andere handeling was
dan uitzetten — met een eigen opslageffect — stond open. Antwoord: het onthoudt zijn plek. De
positie blijft opgeslagen maar rendert niet; zet je de module weer aan, dan staat hij terug wáár hij
stond, inclusief in de map waar hij in zat. Dat is exact het patroon dat de favorietenbalk al
gebruikt met onbekende id's, en dus deze eis toegepast op een tweede handeling — geen nieuw begrip.
Wat daarmee is afgewezen: een aparte "niet op mijn springboard"-staat naast uitzetten. Die zou een
vijfde poort toevoegen aan een zichtbaarheidsgate die er al vier heeft, met tegengestelde
faalrichtingen.
Het prototype doet dit verkeerd, en dat is corpuswerk.
../archive/implemented/design/prototype-concept-e.html haalt bij beide wegen het item uit de indeling. Dat is
het tegenovergestelde van dit besluit en het is de gevaarlijkste van de plekken waar het prototype
achterloopt: een uitvoerder die het als referentie neemt, bouwt een eenrichtingsdeur. Het prototype
moet worden bijgewerkt of van een zichtbare notitie voorzien.
Bepaal de kern uit een regel, niet uit een lijst: kern is een module waar andere modules op
voortbouwen. Dat zijn er drie — Agenda, Taken en Lijstjes.
- Herkomst
- Eigenaar, avond 6 augustus 2026 · gesprek, naar aanleiding van bevinding
A-OB-1 uit de sectie-audit (V1) in het fase-2-plan.
- Waarom
- De kern-set was een historische lijst: vier id's die ooit de
eerste tabbladen waren. Zo'n lijst kan geen enkele volgende vraag beantwoorden — bij elke nieuwe
module begint dezelfde discussie opnieuw, en er is geen argument om hem mee te winnen of te
verliezen. De regel is: kern is wat een hoofdentiteit levert waar andere modules op
voortbouwen. Een afspraak (Agenda), een taak (Taken) en een lijst (Lijstjes) zijn de drie
dingen waar de rest van de app in praat: modules maken taken aan, hangen dingen in de agenda en
leggen lijsten aan. Zet je die uit, dan valt er meer om dan die ene module. Dát is wat
"altijd aan" rechtvaardigt, en niets anders.
- Raakt
- TEN-163 · fase 1 · fase 2 (V8, V10) ·
kCoreSurfaceModuleIds (module_registry.dart:14-19) ·
module_providers.dart:396 · modulebeheer
(modules_beheer_screen.dart:120-151, modules_beheer_providers.dart:34,:62,
module_settings_action.dart:78) · E-VDG-08 ·
E-MOD-06.
Het gevolg: Boodschappen verlaat de kern
Nog steeds gratis, maar uitzetbaar en van je beginscherm af te halen
Boodschappen levert geen entiteit waar iets anders op voortbouwt — het is één canonieke
gezinslijst (share_policy.dart:136, "altijd heel gezin, bewust niet configureerbaar")
en verder een consument van de lijsten-primitive. Onder de regel hierboven hoort hij dus niet in de
kern. Wat er verandert: hij wordt een gewone module — uit te zetten in modulebeheer, van het
springboard te halen, in een map te stoppen. Wat er niet verandert: hij blijft
gratis. Dit is geen tier-wijziging; de vrije modules uit het freemium-besluit blijven vrij.
Vier plekken waar dat vandaag hard vastzit, alle vier geverifieerd.
kCoreSurfaceModuleIds bevat 'boodschappen'
(module_registry.dart:14-19); moduleVisibleForMemberProvider geeft er
daardoor onvoorwaardelijk true voor terug (module_providers.dart:396);
modulebeheer weigert er een modulestate voor te schrijven — persoonlijk én als gezinsstandaard
(modules_beheer_providers.dart:34 en :62) — en het instellingenblad
onderdrukt zijn schakelaar (module_settings_action.dart:78). In het scherm staat hij
bovendien als vierde _CoreSurface in de groep "Basis"
(modules_beheer_screen.dart:145-151), die bewust geen schakelaar toont.
En één ding dat het corpus nergens zegt en dat de omvang bepaalt: core-surfaces zijn
geen registry-modules (module_registry.dart:9-13). Er bestaat vandaag géén
ModuleDescriptor voor Boodschappen — ModuleRegistry.moduleById('boodschappen')
levert null. "Een gewone module worden" is dus niet één id uit een set halen: hij moet
een descriptor krijgen (met naam, icoon, route, tier gratis en een domein). Wie alleen de
set aanpast, houdt een module over die nergens in modulebeheer, onboarding of de conversie
opduikt.
Dit detail is beantwoord — 6 augustus 2026
Boodschappen landt in eten, de map "Eten"
Wat hier stond: "Het domein bepaalt in welke map hij bij de eenmalige conversie
terechtkomt (E-MOD-06) en onder welke kop hij in modulebeheer, onboarding en
de meldingeninstellingen staat. Er is vandaag geen antwoord in de code, want er is geen descriptor.
Dit is één woord van de eigenaar en geen bouwkeuze — vul het niet stilzwijgend in."
Het woord is er. Boodschappen krijgt domainId: 'eten' en landt bij de conversie
in de map Eten, naast Maaltijden, Recepten en Voorraad — de ketting menu → lijstje → kast.
Zie E-MOD-13 voor de nieuwe domeinindeling en
E-MOD-14 voor de conversieseed waarin hij staat. Daarmee is
F1-2 ontstopt: dat pakket wachtte alleen hierop.
En één bouwdetail dat hierbij hoort en dat het corpus nergens noemde: Boodschappen heeft
vandaag geen route. Hij leeft op /lijstjes/<deterministisch id> en de tegel
valt terug op /lijstjes zolang het lijst-id nog niet bekend is. Maar
routePath is verplicht op ModuleDescriptor en de descriptors staan in
const-lijsten — en uit datzelfde routePath wordt de scherm-snelkoppeling
afgeleid. Er moet dus een nieuwe stabiele route komen. Zonder route geen descriptor, zonder
descriptor geen domainId, geen plek in modulebeheer en geen conversie-item.
Wat er meebeweegt, en wat expliciet níet. Zijn Vandaag-rijbron draagt al
moduleId: 'boodschappen' (shopping_today_source.dart:50-52) en zijn
assistent-bijdrage staat al achter een zichtbaarheidscheck
(assistant_providers.dart:390); die twee gaan vanzelf werken zodra de poort niet meer
onvoorwaardelijk true geeft — dat is het hele punt. Niet mee verandert het
deelbeleid: Boodschappen blijft één gezinslijst en wordt niet ineens naar privé configureerbaar
(share_policy.dart:134-136, TEN-55).
Bijgesteld 6 augustus 2026 — de staart van deze eis telde verkeerd. Hier
stond: "en E-MOD-06 gevolg 1 telt voortaan drie losse
kernoppervlakken boven de mappen in plaats van vier". Dat klopt half. Boodschappen gaat er
terecht uit, maar Lijstjes hoort er wél in — en die stond niet in de "Populair"-strook waar
die zin op geënt was. Het zijn er dus weer vier: Vandaag · Taken · Agenda · Lijstjes
(E-MOD-14). Dat Vandaag geen registry-module is en Lijstjes wel, verandert
daar niets aan: geen van de vier heeft een domainId, dus geen van de vier wordt
mapinhoud.
Geverifieerd — de code liep hier al vooruit en staat inmiddels goed.
kSpringboardCoreSurfaceIds (lib/core/modules/springboard_layout.dart:116-121)
bevat Vandaag · Taken · Agenda · Lijstjes, precies deze eis; gerepareerd in c9fe4be3, met
vangrails op test/core/modules/springboard_layout_test.dart:311-327. Wat nog
achterloopt is kCoreSurfaceModuleIds
(lib/core/modules/module_registry.dart:14-19), dat nog 'boodschappen' bevat
en géén 'vandaag' — plus de doc-comment bij ModuleDescriptor.tier
(lib/core/modules/module_descriptor.dart:124-127), die de gratis kern nog als
"Agenda/Taken/Vandaag/Boodschappen" beschrijft. Allebei belegd bij het pakket dat Boodschappen zijn
descriptor geeft.
De domeinindeling en de startstand
Vier eisen uit de doorloop van ../archive/implemented/design/domeinen-en-startstanden.html op 6 augustus 2026.
Snijd de domeinen opnieuw tot zes: Eten · Gezin · Huis · Geld · Gezondheid · Bewaren. Een
gebied draagt minstens twee modules.
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek. Doorloop van
het domeinen- en startstandenstuk, variant
A3 gekozen boven A1, A2 en A4. Sluit OV-1 van dat
stuk: Boodschappen landt in
eten.
- Waarom
- De domeinindeling van vandaag is geen indeling van de app maar
een afdruk van
lib/features/: elke feature-map declareerde één domein, ook als er maar
één module in zat. Dat verklaart in één keer waarom zes van de tien domeinen precies één
module dragen en waarom er vier domeinen zijn die heten zoals hun enige inhoud
(Bewaarlijsten bevat Bewaarlijsten, Vastgoed bevat Vastgoed, Voorraad bevat Voorraad, Documenten
bevat Documenten). Zolang dat alleen een kop in modulebeheer was, kostte het weinig. Vanaf
E-MOD-06 wordt het de startindeling van het beginscherm van iedere
gebruiker, en vanaf dat moment mag de app er niet meer aan zitten — een map is een belofte dat
er meerdere dingen in zitten, en vier mappen die je opent voor één ding is een omweg die je nooit
meer weghaalt. Dit is het laatste moment waarop de indeling gratis te herzien is. Aan de
andere kant stond financieel met negen modules: bijna een derde van de app in één map,
wat het ordeningsprobleem alleen een niveau dieper duwt.
- Raakt
- Fase 1 · E-MOD-06 (zes mappen in plaats van tien) ·
E-MOD-14 · E-MOD-16 ·
E-MOD-15 · modulebeheer, onboarding, meldingeninstellingen en
AI-instellingen (die blijven alle vier op domein ordenen).
Nageteld: 4 + 6 + 4 + 7 + 5 + 3 = 29. Dat zijn de 29 huidige
ModuleDescriptors min Quote (E-MOD-15) plus
Boodschappen. Kleinste gebied 3, grootste 7 — geen enkel gebied vraagt een sub-niveau, geen enkel
gebied draagt er één. De regel achter het minimum is twee: dat is de definitie van een groep.
Eén is geen groep; het is een tegel met een deurtje ervoor.
Het voorstel telde er 30 — dit is de bijgestelde telling. Het bronstuk zette
Quote als zesde module in Gezondheid, omdat een module schrappen geen bouwkeuze is en het stuk die
niet zelf mocht maken. Met E-MOD-15 is dat besloten en telt Gezondheid er
vijf.
Wat je hiervoor opgeeft, en waarom dat de goede kant op is
Een domein volgt niet langer een map onder lib/features/
Na deze eis wonen Wagenpark en Garanties in de map lib/features/financieel/ maar horen
ze bij het domein huis respectievelijk bewaren. Dat is verwarrend voor wie
de code leest, en het is de goede afweging: een domein is een gebruikersbegrip en een broncodemap
niet. Wie de indeling op de mappenstructuur laat volgen, bouwt de startindeling van iedere
gebruiker op de toevallige geschiedenis van het bestandssysteem.
Twee namen zijn bewust een compromis. "Gezin" klopt niet voor een Solo-abonnee, die per
E-PLUS-20 nadrukkelijk bestaat — maar "Mensen" of "Agenda's" leest
slechter voor de meerderheid, en de map is hoe dan ook hernoembaar
(E-MOD-06). "Bewaren" is een werkwoord, net als het afgekeurde "Planning";
het verschil is dat "bewaren" wél iets uitsluit — het gaat over dingen die je niet gebruikt maar
terugvindt — terwijl "plannen" niets uitsluit en dus niets sorteert.
Seed het springboard met vier losse tegels en zes mappen: Vandaag · Taken · Agenda ·
Lijstjes, daaronder de zes gebieden. Tien tegels, drie rijen, geen scroll.
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek. Variant
B2 gekozen boven B1 (alles in een map "Basis"),
B3 (gratis los, Plus in mappen) en B4 (plat raster zonder mappen).
- Waarom
- Een startstand heeft twee manieren om te falen. Nietszeggend
— zeven grijze deurtjes waarachter alles verstopt zit — leert niemand wat de tab is, en zet Taken
op twee tikken terwijl E-NAV-06 juist drie korte wegen belooft.
Slim op de verkeerde as is erger: sorteer je op tier, dan wordt de indeling bevroren op het
abonnement dat iemand op dag één had, en die bevriezing is onomkeerbaar omdat
E-MOD-10 terecht verbiedt dat de app een opgeslagen indeling herschrijft.
Tien tegels in drie rijen van vier is de enige stand die op één blik past, meteen uitlegt hoe het
scherm werkt — boven staat wat je doet, onder staat waar je het over hebt — en geen enkele
beslissing neemt die later omgedraaid moet worden.
De seed, en de vijf regels eromheen
Wat F1-2 letterlijk mag bouwen
Rij 1, los en bovenaan: Vandaag · Taken · Agenda · Lijstjes.
Rij 2 en 3, de mappen in deze volgorde: Eten (4) · Gezin (6) · Huis (4) · Geld (7) ·
Gezondheid (5) · Bewaren (3). Verder niets.
- De mapnaam is de
DomainDescriptor.name als startnaam en dus hernoembaar —
dat is E-MOD-06, niet een nieuwe regel.
- Map-ids worden deterministisch uit het domein-id afgeleid, zodat twee toestellen die
tegelijk converteren dezelfde indeling opleveren.
- Converteer op de volledige registry, niet op de ingeschakelde subset: de weergave
verbergt wat niet rendert, en "staat er niet in" leid je af uit de opgeslagen indeling — nooit
uit wat er rendert.
- De mapinhoud is "gratis eerst" gesorteerd. Een maptegel toont een minivoorbeeld van
maximaal vier iconen; op registervolgorde tonen Eten en Huis vier Plus-iconen en ziet de map er
dood uit voor wie geen Plus heeft. Met gratis-eerst tonen Eten, Gezin, Huis en Bewaren minstens
één icoon dat écht opengaat. Geld en Gezondheid zijn volledig Plus — daar valt niets te sorteren,
en dat is eerlijke informatie.
- De gecureerde picks vervallen. Maaltijden en Recepten staan vandaag zowel in de
"Populair"-strook als in hun domeinsectie; na de conversie precies één keer, in de map Eten.
Vier losse oppervlakken, niet drie — dit keert de staart van
E-MOD-12 om. Die eis sloot af met "voortaan drie losse kernoppervlakken
in plaats van vier", omdat Boodschappen de kern verlaat. Maar die zin was geënt op de
"Populair"-strook (Vandaag · Taken · Agenda · Boodschappen) en niet op de kern-set, en
Lijstjes ontbrak in allebei de tellingen. Het zijn er vier.
Wat je hiervoor opgeeft. Zichtbaarheid van individuele modules op dag één: een
nieuwe gebruiker ziet zes mapnamen en geen modulenamen. Dat is opgevangen door het zoekveld
(E-MOD-08) dat de mapnaam bij het resultaat toont
(E-MOD-07), en door de onboarding, die op domein blijft ordenen en dus
dezelfde zes koppen gebruikt.
Maak Quote een instelling van Vandaag in plaats van een module — en lever die instellingen
er dan ook echt bij.
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek. Sluit OV-2 van het domeinenstuk, waar
drie opties lagen: (i) Quote wordt module in Gezondheid, (ii) Quote blijft module in een
niet-gevoelig domein, (iii) Quote is geen module maar een instelling van Vandaag. Optie (iii)
gekozen, mét een voorwaarde.
- Waarom
- Quote is een dagelijkse spreuk die zichzelf al als
TodaySection op Vandaag zet, en waarvan de landings-favoriet al bewust was uitgezet
omdat het scherm niets toevoegt. Het is dus een tegel die niemand tikt, met een eigen route en —
tot E-MOD-13 — een eigen domein voor één spreuk. Als module in Gezondheid
zou hij bovendien de gevoeligheidsvlag van dat domein overnemen, wat voor een spreuk onzin is.
Er verdwijnt hier een tegel, een route en een domein tegelijk — en geen functionaliteit.
De quote-sectie op Vandaag blijft staan, in de laag chroom en buiten het
signaalplafond (E-VDG-01).
"Prima als instelling van vandaag, maar er moeten dan wel echt instellingen voor zijn (welke
thema's vind je leuk etc.)"
— eigenaar, 6 augustus 2026
De voorwaarde is niet decoratief — zonder pakket is dit functieverlies
Wat er vandaag aan dat scherm hangt, en dus mee moet
Geverifieerd, en het zit anders dan het bronstuk aannam. De instellingen staan níét op het
Quote-scherm maar in de generieke module-instellingensheet
(quote_settings_section.dart), bereikt via de ModuleSettingsAction() in de
kop (quote_screen.dart:39). Die sheet draagt drie dingen
(quote_settings_section.dart:40-71): thema-selectie met per thema een gewicht
(soms/normaal/vaker — quote_prefs.dart:25-43), meldingen aan/uit en het
meldingstijdstip. In de themakiezer zit daarnaast een taalkeuze nl/en/beide
(quote_prefs.dart:46-60, gerenderd op quote_theme_selector.dart:103). Op
het scherm zelf verschijnt de themakiezer alleen als lege-staat-terugval, zolang er nog geen thema
gekozen is (quote_screen.dart:49-50). Die themakeuze moet meeverhuizen — dat is
precies wat de eigenaar bedoelt met "er moeten dan wel echt instellingen voor zijn".
En er staat méér op dat scherm dan instellingen. Het draagt ook een favorietenlijst
en een archief van de laatste veertien dagen (quote_screen.dart:70-100). Dat
zijn geen instellingen; ze verhuizen niet vanzelf mee, en met de route verdwijnen ze. Dat is een
uitspraak die nog moet vallen — beleg ze elders of laat ze expliciet los, maar laat het niet
per ongeluk gebeuren.
Die uitspraak is gevallen — eigenaar, 6 augustus 2026 (avond): alles verhuist mee.
Thema's, favorieten én archief. Niemand raakt iets kwijt. De eigenaar accepteerde daarbij
expliciet dat de landingsplek daarmee eerder een klein scherm binnen de instellingen wordt dan
één schakelaar, en dat de winst dus vooral zit in het opruimen van een tegel die niemand tikt.
Alle voorkeuren zijn persoonlijk en device-lokaal (SharedPreferences,
quote_prefs.dart:4-11), niet gesynct. Wat er ook gebeurt: die eigenschap moet
overleven, want ze is een bewuste correctie op een eerdere gezinsbrede opslag.
Vervolgwerk — deze eis is pas af met een pakket. Dat pakket (a) brengt
thema-selectie, gewichten, taalkeuze en meldingstijdstip naar de Vandaag-instellingen, (b) registreert
de TodaySection ergens anders nu welzijn_module.dart vervalt, en (c) doet
een uitspraak over favorieten en archief. Zolang dat pakket er niet is, is deze eis niet
uitgevoerd door de module simpelweg te schrappen.
Dat pakket is er — W4 in het fase-2-plan, gebouwd op 6 augustus 2026. De
schakelaar is QuotePrefs.showOnToday (eigen sleutel, device-lokaal, standaard aan);
de sectie staat geregistreerd in quote_module.dart, onveranderd in chroom
op orderHint 10 en zonder moduleId; en /vandaag/quote draagt
de schakelaar, de thema's met gewichten, de taal, meldingen aan/uit, het meldingstijdstip, de
favorieten en het archief van veertien dagen. Twee ingangen: een vaste regel in Instellingen — die
er óók is als er nog geen thema gekozen is en er dus geen kaart op Vandaag staat — en het
ingedrukt-houden-menu van de quote-kaart zelf. Wat resteert is niet deze eis maar F1-2: de
map Welzijn uit de conversieseed van het Modules-scherm.
Geef de nieuwe gebieden nieuwe id's — en zet de AI-toestemmingen mee om, want die hangen aan
het domein-id.
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek. Sluit OV-6 (nieuwe id's of alleen
nieuwe labels) en OV-3 (Garanties en Wagenpark verlaten het gevoelige gebied) van het
domeinenstuk.
- Waarom
- Bestaande id's hergebruiken met een nieuw label is gratis
voor de tekstsnaren en voor de gesyncte opt-in-set, en duur voor iedereen die de code
later leest: een domein
voorraad dat "Eten" heet en Boodschappen bevat is een val die
je niet ziet aankomen. Nieuwe id's zijn eerlijk. Maar ze kosten iets echts, en dat is de kern van
deze eis: een hernoeming zonder omzetting van de opt-in-set zet iemands AI-toestemming
stilletjes uit — de poort weigert dan zonder melding, en de gebruiker ziet alleen dat AI
"het niet doet". Dat is geen cosmetische wijziging maar een gedragswijziging met een onzichtbare
faalrichting.
- Raakt
- Fase 1 · E-MOD-13 ·
E-OPS-01 · ADR-0022 · de AI-poort en de AI-instellingen.
De omzetting — dit hoort in de brief van het pakket, niet in de bouw
sensitive_opt_in_domains_json is een gesyncte set met domein-id's
De opslag: kolomdefinitie lib/core/ai/data/ai_settings_table.dart:31-32, sync-schema
lib/core/sync/powersync_schema.dart:98, schrijfpad
lib/core/ai/ai_providers.dart:120-128. Het leespad: de poort weigert een capability als
het meegegeven domein gevoelig is en het id níét in de opt-in-set staat
(lib/core/ai/ai_gate.dart:37-38), gevoed door de gevoelige domeinen uit de registry
(:54-57).
Eén remap is nodig en voldoende: financieel → geld.
gezondheid houdt zijn id, dus daar is niets te doen. De remap draait eenmalig en moet
idempotent zijn, want de kolom synct: twee toestellen kunnen hem allebei zien.
En vijftien van de negentien losse tekstsnaren moeten mee. Er is geen compile-time
koppeling met de registry — een gemiste snaar valt niet om, hij wordt genegeerd, en voor een
gevoelig domein valt de poort daarmee stil open.
7 + 6 + 1 + 1 = 15 moeten mee; 4 blijven staan. Van de tien domein-id's verdwijnen er
zeven (planning, financieel, vastgoed, voorraad,
documenten, bewaarlijsten, welzijn), houden er drie het hunne
(gezin, gezondheid, huis) en komen er drie nieuwe bij
(eten, geld, bewaren).
OV-3 · de versoepeling is bewust geaccordeerd
Garanties en Wagenpark verlaten het gevoelige gebied
Ze gaan van financieel (sensitive: true) naar bewaren en
huis, allebei niet gevoelig. Hun AI-standaard versoepelt daarmee van "vraagt eerst een
expliciete opt-in" naar "gewoon toegestaan". Dat is geen bijwerking die iemand later ontdekt —
het is bekeken en goedgekeurd. Een garantiebewijs scannen is geen financiële handeling.
Concreet raakt het één aanroep: add_warranty_sheet.dart:204. Wagenpark heeft vandaag
geen eigen domainId-snaar, dus daar verandert alleen de registratie.
Wat níét gekozen is: sensitive verplaatsen van DomainDescriptor
naar ModuleDescriptor. Dat is de nettere architectuur en meer werk, en het is geen
voorwaarde voor deze herindeling. Het staat genoteerd als overweging, niet als opdracht — zie ook
N-16.
Gebied 5
Widgets
Het duurste onderdeel van het programma, en het onderdeel waar de meeste eisen op
elkaar staan. Fase 3.
Maten
Benoem elke maat met breedte én hoogte ("halve breedte · laag"), nooit als "1×1" of "2×2".
- Herkomst
- Prototype-feedback, 5 augustus 2026 · eigenaar. De rasternotatie bleek
onbegrijpelijk.
- Waarom
- "1×1" zegt niemand iets: het veronderstelt dat je het raster kent
dat je juist niet ziet. "Klein / breed / groot" dekt de hoogte niet. Met eerst de breedte en dan de
hoogte — altijd in die volgorde — kun je de vier maten uit elkaar houden zonder ze te leren.
De vier namen zijn: halve breedte · laag, halve breedte · hoog, volle breedte ·
laag, volle breedte · hoog.
- Raakt
- Fase 3 · widgetgalerij · alle teksten rond widgets · vertaalsleutels.
Voer vier maten in, inclusief "halve breedte · hoog".
- Herkomst
- Prototype-feedback, 5 augustus 2026 · eigenaar.
- Waarom
- Volgt rechtstreeks uit E-WID-01: als "vol"
twee hoogtes kent en "half" maar één, is de naamgeving scheef en is het geen stelsel maar een
lijstje. Twee breedtes maal twee hoogtes is uitlegbaar; drie willekeurige maten niet.
- Raakt
- Fase 3 · widgetcontract · rasterindeling van het dashboard.
Correctie op het ontwerpstuk. ../archive/implemented/design/navigatie-ontwerpconcepten.html §6
kent nog drie maten (1×1, strook, 2×2) en zegt daar expliciet bij dat meer dan drie het raster
rommelig maakt. Deze eis vervangt dat: de vierde maat is toegevoegd omdat de benaming er anders niet
uitkomt. Wie §6 leest, leest op dit punt een achterhaalde stand.
Maak widgets interactief: een taak afvinken en een boodschap toevoegen moet vanaf het dashboard kunnen.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek. Alleen-lezende widgets zijn expliciet
afgekeurd.
- Waarom
- Een dashboard dat alleen kijkt, dwingt je bij elke handeling naar
een ander scherm — en dan had je net zo goed meteen daarheen kunnen gaan. De hele belofte van
"hoe staat het ervoor?" valt weg als je er niets aan kunt doen. Mensen gaan het bovendien tóch
proberen; een widget die niet reageert leest als kapot.
- Raakt
- Fase 3 · nieuw ticket "Dashboards-tab + widgetcontract" · beantwoordt de
blokkerende vraag W2 · TEN-138 (rij-swipe).
Overrulet het ontwerpstuk. §6 van
../archive/implemented/design/navigatie-ontwerpconcepten.html adviseert het tegenovergestelde — "widgets tonen, ze doen
niet" — met als argument dat read-only een fractie van het werk is en gebaarconflicten vermijdt. De
eigenaar heeft anders beslist. Neem de prijs mee in het plan: een rechten-check per rij, een
ongedaan-maken-verhaal per widget, en het vervallen van veeg-navigatie tussen dashboards
(E-WID-11).
Toevoegen en aanpassen
Laat een module die maar één maat biedt met één tik toevoegen.
- Herkomst
- Prototype-feedback, 5 augustus 2026 · eigenaar.
- Waarom
- Een keuzestap tonen waar niets te kiezen valt is pure vertraging.
Als er één maat is, is de module aantikken al de hele beslissing.
- Raakt
- Fase 3 · widgetgalerij.
Nog niet in het prototype. Daar kost toevoegen altijd twee tikken: eerst de
modulerij, dan de maatkaart — ook bij één beschikbare maat.
Maak de maat-indicatoren in de modulerij zelf aanklikbaar, als snelweg naar toevoegen.
- Herkomst
- Prototype-feedback, 5 augustus 2026 · eigenaar.
- Waarom
- De indicatoren tonen al precies wat je krijgt — de vorm, niet een
woord dat je moet lezen. Ze dan alleen decoratief laten zijn, betekent dat de gebruiker eerst de rij
moet openvouwen om dezelfde blokjes nog een keer te zien voordat hij mag kiezen. Wie weet wat hij
wil, hoort meteen te kunnen kiezen; wie het niet weet, opent de rij.
Nog niet in het prototype. Daar is de hele rij één trefvlak en zijn de
blokjes rechts niet afzonderlijk aanklikbaar.
Laat een geplaatste widget in de bewerkstand van maat wisselen, zonder verlies.
- Herkomst
- Prototype-feedback, 5 augustus 2026 · eigenaar.
- Waarom
- Je weet pas of een maat klopt als de widget op je board staat
tussen de andere. Is wisselen alleen mogelijk door verwijderen en opnieuw toevoegen, dan is elke
heroverweging een straf en blijft iedereen bij de eerste gok. Dit is de gebruikerskant van
E-OPS-02: los opslaan is de voorwaarde, verliesvrij wisselen is de
belofte.
- Raakt
- Fase 3 · E-OPS-02 · bewerkstand van het dashboard.
Nog niet in het prototype. Daar kun je een widget alleen verwijderen en
opnieuw toevoegen; geen van beide bronstukken beschrijft een maatwissel.
Gedrag en contract
Laat een tik op een rij ín een widget de module openen; uitklappen is daar niet de logische actie.
- Herkomst
- Prototype-feedback, 5 augustus 2026 · eigenaar.
- Waarom
- Een widget is een samenvatting. Wie op een regel tikt wil méér zien
dan de samenvatting geeft, en dat "meer" woont in de module — niet in een uitgeklapt regeltje binnen
een tegel van halve breedte, waar toch geen ruimte is. Dit botst niet met
E-WID-03: afvinken gebeurt via de checkbox in de rij
(E-INT-01), openen via de tekst.
Correctie op het prototype. Daar is de regeltekst in een widget zélf de
afvinkknop — een tik op de tekst vinkt af en opent de module dus níet. Dat wijkt af van deze eis én
van E-INT-01, en van de manier waarop de echte app het op Vandaag al doet.
Laat een module een bestaand, generiek widgettype vullen of uitbreiden; een volledig eigen widget is de uitzondering die verantwoord moet worden.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek.
- Waarom
- Met 29 modules maal vier maten loopt "elke module zijn eigen
widget" uit op een onhoudbare hoeveelheid eenmalige code, en op een dashboard dat er per tegel
anders uitziet. Herbruikbare typen houden het aantal te onderhouden onderdelen laag én zorgen dat
een nieuwe module een widget kan leveren zonder ontwerpronde. De uitzondering blijft toegestaan —
maar als uitzondering, met een reden.
- Raakt
- Fase 3 · widgetcontract · elke toekomstige module.
Laat elke module declareren welke maten hij aankan, en toon in de galerij waaróm een module er niet in staat.
- Waarom
- Zonder declaratie weet de galerij niet welke maatkaarten hij moet
tonen en kan E-WID-04 niet bestaan. En een module die ontbreekt zonder
uitleg leest als een fout: de gebruiker moet kunnen zien of de module uitstaat of gewoon geen
widget heeft.
- Raakt
- Fase 3 ·
ModuleDescriptor · widgetgalerij.
Start een verse installatie nooit met een leeg dashboard.
- Herkomst
- Ontwerpstuk §6 · onderzoek.
- Waarom
- Een leeg board is een gemaakte toestand, geen begintoestand. Wie op
dag één een lege tab opent, weet niet wat de tab is en komt niet terug — en dan wordt er nooit
gemeten of het board werkt. De startstand toont Taken, Agenda, Boodschappen en één widget per
aangezette gratis module.
- Raakt
- Fase 3 · E-PLUS-01 (het board moet ook gratis
gevuld zijn).
Bijgesteld 6 augustus 2026: Agenda hoort niet in de startstand. De zin
hierboven noemt "Taken, Agenda, Boodschappen"; het widgetonderzoek (TEN-179 §6) verbiedt in de
startstand juist elke tijdlijnkaart, en Agenda is daar als tijdlijnkaart geclassificeerd —
met als argument dat een dag-zware startstand het board "Vandaag in een ander jasje" maakt. Beide
stonden als besloten. Uitkomst: Agenda is beschikbaar als widget maar staat niet standaard op het
dashboard. Wie hem wil, heeft hem — hij staat gewoon in de galerij; wie het dashboard voor het
eerst ziet, krijgt hem niet.
Waarom dat geen compromis is maar de tegenspraak oplost. Deze eis ging over
beschikbaarheid (het board mag niet leeg zijn), het onderzoek over de startstand
(de eerste indruk mag geen tweede Vandaag zijn). Die twee kunnen tegelijk waar zijn zodra je ze uit
elkaar trekt.
Bijgesteld 6 augustus 2026, tweede keer: de startstand is zes widgets,
en de eis en de seed spreken elkaar niet meer tegen. Hierboven stond, en in de "waarom" hierboven
staat nog, "één widget per aangezette gratis module". Letterlijk uitgevoerd zijn dat
acht widgets — Taken, Boodschappen, Lijstjes, Bewaarlijsten, Maaltijden, Verjaardagen,
Schoolvakanties, Afvalkalender — en dat is de lezing die een uitvoerder overneemt. De eigenaar heeft
op 6 augustus 2026 expliciet als keuze bevestigd dat de seed er zes telt, met de lezing
"per gratis module is er een widget beschíkbaar". De startstand zelf staat in
E-WID-19.
Waarom acht de verkeerde uitkomst is. Drie van de acht zijn lijstkaarten van
dezelfde bouwsteen (Taken, Lijstjes, Bewaarlijsten — het widgetonderzoek zegt dat met zoveel woorden:
"Bewaarlijsten: dezelfde bouwsteen als Lijstjes"), en drie keer dezelfde kaartvorm onder elkaar leest
als een fout in plaats van als een keuze. Het is bovendien ruim twee schermen scrollen op dag één. En
bij Lijstjes komt er een keuze bij die op dag één niet te maken is: die widget vraagt welke
lijst hij toont, en op een verse installatie is er nog geen lijst om te kiezen.
Wat deze eis blijft zeggen, onverkort: start een verse installatie nooit
met een leeg dashboard, en zet er geen tijdlijnkaart in. Het aantal is met
E-WID-19 ingevuld; de eis zelf gaat over niet-leeg-starten en die staat.
Seed het dashboard met één bord van zes widgets voor iedereen; zonder Plus komen er twee
uitgeschakelde voorbeeldwidgets onder. Geen tweede startstand.
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek. Variant
C2 gekozen boven C1 (de letterlijke lezing van
E-WID-10), C3 (twee startstanden, gratis en Plus) en C4 (drie widgets).
Sluit OV-5 van het domeinenstuk.
- Waarom
- Een gratis dashboard dat halfleeg voelt verkoopt geen Plus, en een
dashboard vol met wat je niet hebt ergert. Die twee vangen elkaar op zodra je ze uit elkaar trekt
in bord en etalage. Het bord is voor iedereen hetzelfde en is uit gratis bronnen
volledig te vullen — zes werkende widgets, waarvan één groot en interactief. De etalage is twee
kaarten en staat onderaan, waar ze verleidt zonder in de weg te zitten. Daarmee is het verschil
tussen gratis en Plus op dag één zichtbaar zonder dat het pijn doet, en blijft er precies
één seed te onderhouden.
Vier regels die in de brief moeten, anders bouwt iemand het net verkeerd
De seed is niet alleen een lijst
1 · Seed alle zes, ook als de module uitstaat. Dezelfde regel als op het springboard
(E-MOD-10): de instantie blijft staan en rendert niet. Wie Schoolvakanties
later aanzet, krijgt zijn widget terug op de plek waar hij hoorde. De alternatieve implementatie
("seed alleen wat aanstaat") leest de renderbaarheid en levert een bord dat per lid anders is en
niet meer te herstellen.
2 · Een widget die niets rendert laat geen gat. Op het springboard is dat vanzelf zo; in een
raster niet. Laat verborgen instanties inklappen in plaats van een lege cel achter te laten.
3 · De etalage verschijnt pas als het vaststaat. Bij de derde stand "nog onbekend"
uit E-PLUS-02 toont het bord de zes gewone widgets en géén
voorbeeldkaarten — anders ziet een betalende klant bij elke koude start seconden lang
"Voorbeeld · Plus" onder zijn eigen bord staan. De voorbeeldkaarten dragen verplicht het label
"Voorbeeld" (E-PLUS-03).
4 · Eén seed, geen tweede. Wie later Plus koopt houdt zijn bord zoals het stond; de
opgeslagen indeling wordt niet herschreven. Dat is E-MOD-10 toegepast op het
dashboard, en het is precies waarom C3 (twee startstanden) is afgevallen — die werkt alleen voor wie
Plus koopt vóór hij de tab één keer opent.
Waarom Gewicht en Voorraad de twee etalagekaarten zijn, en niet twee willekeurige.
Het widgetonderzoek stelt vast dat het probleem van het gratis bord niet het aantal widgets
is maar welke soorten ontbreken: een gratis gebruiker ziet nooit een verloopkaart (een
grafiek) en bijna nooit een aandachtkaart. Dat zijn precies de twee soorten die het dashboard
onderscheiden van Vandaag. Zet je die twee als etalage neer, dan toont de app niet "je mist een
module" maar "je mist een manier van kijken" — en dat is het eerlijkste argument dat Plus
heeft.
De volgorde is niet willekeurig. Boven staat wat je aanraakt (Taken,
Boodschappen), in het midden wat je moet weten (Afval, Menu, Verjaardagen, Schoolvakantie), onder wat
je zou kunnen hebben. Geen tijdlijnkaart, dus geen tweede Vandaag —
E-WID-10 houdt daarmee stand, ook al wijkt het aantal af van de letter.
Navigeer niet met een veeg tussen dashboards.
- Herkomst
- Afgeleid uit E-WID-03 · gebaarconflict met TEN-138.
- Waarom
- Zodra widgets interactief zijn, komt de app-brede rij-swipe uit
TEN-138 ook binnen een widget terecht. Een horizontale veeg over een board zou dan twee dingen
tegelijk kunnen betekenen — sleep je de rij of de pagina? Dat is precies het conflict waarop
concept C is afgeketst. Komen er meerdere dashboards, dan navigeer je via de titel als keuzemenu.
Bouw één dashboard, en sla het op in een vorm die er later meer toestaat.
- Herkomst
- Ontwerpstuk §7, vraag W1 · onderzoek, beslecht door de eigenaar op
6 augustus 2026: één dashboard voor nu, later mogelijk meer.
- Waarom
- Het verschil tussen één en meer zit in navigatie en in benaming,
niet in opslag. Eén bord houdt fase 3 klein — geen kiezer, geen titelmenu, geen lege tweede pagina —
terwijl het opslagformaat de deur openhoudt. Precies de aanbeveling uit het widget-interfaceonderzoek:
bewaar een lijst in plaats van één kaart, in dezelfde
_shell-rij en met dezelfde
patch-codec (E-OPS-01).
De blokkade op fase 3 vervalt — en twee gevolgen die bepalen of "later meer"
straks écht gratis is.
1. Meervoud-klaar vanaf dag één: de opslag is een lijst van dashboards, elk met een
eigen id, een naam en een lijst widget-instanties — ook als er precies één in staat. Slaat fase 3 één
object op, dan is meervoud later een migratie in plaats van een schermwijziging.
2. De garantie "Taken staat standaard op je dashboard" geldt bij meervoud alleen op het eerste
bord. Een tweede bord begint leeg; anders zou elk nieuw bord dezelfde widget opdringen. Dit stond
al in het onderzoek en staat hier zodat het bij de uitbreiding niet opnieuw uitgezocht wordt.
Instanties en het modulecontract
Uitgewerkt in docs/archive/implemented/design/widget-interfaces-en-modulecontracten.html (TEN-179,
5 augustus 2026). Hieronder alleen wat het register moet dragen.
Behandel een geplaatste widget als een instantie, niet als een combinatie van module en maat.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek, op open vraag V5 uit het
widget-interfaceonderzoek (TEN-179).
- Waarom
- "Welke module" is niet wat een widget ís — het is één van zijn
eigenschappen. Vijf lijstwidgets met elk een andere lijst zijn vijf verschillende dingen op je
board, geen vijf keer hetzelfde. Zodra je een widget als instantie ziet, zijn maat wisselen,
verplaatsen en verwijderen handelingen op één object, en hoeft nergens uitgezocht te worden
"welke van de twee taken-widgets bedoel je".
Sta meerdere widgets van dezelfde soort op één dashboard toe; voorkom alleen de exacte dubbeling — zelfde module én zelfde maat én zelfde configuratie.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek, op open vraag V5 (TEN-179).
- Waarom
- Een gezin met een boodschappenlijst, een klusjeslijst en drie
bewaarlijsten wil die naast elkaar zien — dat is precies waar een dashboard voor is. Een
bovengrens per module zou die gebruiker uitleggen dat zijn eigen indeling verboden is, terwijl er
geen enkel technisch bezwaar tegen is. Wat wél tegengehouden hoort te worden is de exacte
dubbeling: twee widgets die letterlijk hetzelfde tonen, zijn altijd een vergissing en nooit een
keuze. Daarmee is de regel bovendien afdwingbaar zonder iemand te beperken.
Overrulet het voorstel in TEN-179, dat "hooguit twee widgets per module"
adviseerde met als argument dat drie "verzamelen" wordt. De eigenaar heeft die grens verworpen; alleen
de exacte dubbeling blijft over.
Neem de overige adviezen uit ../archive/implemented/design/widget-interfaces-en-modulecontracten.html over, inclusief de daar voorgestelde antwoorden op de open vragen.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek, na lezing van het stuk (TEN-179).
- Waarom
- Dit staat hier zodat niemand dat document nog leest als "een
voorstel dat nog openstaat". De adviezen zijn aangenomen en de daar gestelde open vragen zijn met
hun voorgestelde antwoord beslecht. Concreet betekent dat onder meer: acht generieke widgetsoorten
in plaats van een widget per module; één databron met een weergave per maat in plaats van drie
losse widgets; interactie uitsluitend via knoppen en nooit via een gebaar; een toevoeg-knop opent
het bestaande invoerblad in plaats van een eigen veld; rechten en ongedaan maken via de bestaande
voorzieningen; één meting-bouwsteen vóór de eerste verloopkaart; één herhaalberekening in de kern;
TodaySection krijgt moduleId, band en rijbudget
terwijl orderHint vervalt; en zichtbaarheid en Plus blijven van de app, niet van de
module.
Twee uitzonderingen. Deze eis geldt behalve waar dit register het
stuk expliciet overrulet: E-WID-14 (geen bovengrens per module),
E-OPS-06 (instanties met een eigen id) en
E-WID-16 (de lijstkaart krijgt wél een strook).
Statuswijziging — twee zinnen uit deze eis zijn herzien op 6 augustus 2026
Het vinkje gaat over voltooien, niet over bewerken · en orderHint vervalt niet
(1) Het vinkje — ADR-0022 (B1). Deze eis nam uit TEN-179 over dat rechten "via de bestaande
voorzieningen" lopen, met als regel: "mag je het item niet bewerken, dan toont de widget de regel
wél maar het vinkje niet". Die regel geldt niet meer. Een gedeeld alleen-lezen item is op
een widget wél afvinkbaar — gelijk aan Taken en gelijk aan de server. De aangehaalde helper was de
verkeerde: mutation_guard.dart:104-105 verbiedt in zijn eigen documentatie om
afvink-toggles op canEditSharedContent te baseren, en de server staat voltooien
uitdrukkelijk toe (private.guard_share_read_only, migratie 0044). Met de oude regel zou
dezelfde taak in Taken wél en op het dashboard níet afvinkbaar zijn: twee rechtenmodellen voor één
item. Wat de widget bij mayEditContent == false wél verbergt, is elke
bewerk-affordance. De bronzin is in
../archive/implemented/design/widget-interfaces-en-modulecontracten.html als herzien gemarkeerd.
(2) Het rijbudget en orderHint — ADR-0021. Hier stond dat
TodaySection moduleId, band en rijbudget krijgt
"terwijl orderHint vervalt", en dat het rijbudget het plafond van
E-VDG-02 voor het eerst afdwingbaar maakt. Beide zijn herzien. Een
budget per sectie kan een bandplafond niet afdwingen — de compositielaag ziet de kaarten binnen een
sectie-builder niet, en vijf secties met budget 1 geven vijf kaarten. Het plafond komt
daarom van een signaal-collector met een gedeelde dringendheidsschaal op de band. En
orderHint blijft, gedemoveerd tot positie binnen de band; dat redt de
aangrenzendheids-eis uit de TEN-75-hertest en maakt de omzetting in twee stappen mogelijk. Het doel
van E-VDG-01 en E-VDG-02 staat ongewijzigd overeind — alleen het mechanisme is een ander.
Bied de lijstkaart ook aan als strook — volle breedte, laag.
- Herkomst
- Eigenaar, 5 augustus 2026 · visuele beoordeling van de schetsen in TEN-179:
de voorbeelden hielden zichtbaar ruimte over.
- Waarom
- De lijstkaart is de meest gevraagde widget van allemaal — het is
de widget waarmee je afvinkt zonder de app in te gaan. Hem alleen in de twee grootste vormen
aanbieden dwingt iemand met vier lijsten om zijn halve board eraan te geven. En het argument dat
één laag "dan een telkaart" wordt, bleek in de schetsen niet te kloppen: er bleef ruimte over.
- Raakt
- Fase 3 · widgetcontract (matenlijst van de lijstkaart) ·
E-WID-17 · TEN-179.
Overrulet het ontwerpstuk. TEN-179 zet bij de lijstkaart uitdrukkelijk
"strook: nee", met als reden "één laag hoog past hooguit één regel — dan is het een telkaart en geen
lijst". Die redenering vervalt.
Houd "halve breedte · hoog" een volwaardige maat in het stelsel; een soort die breedte nodig heeft, stelt die maat als ondergrens en niet als omissie.
- Herkomst
- Eigenaar, 5 augustus 2026 · visuele beoordeling van TEN-179. Bevestigt
E-WID-02.
- Waarom
- Twee dingen tegelijk. Eén: de vierde maat is geen
bijverschijnsel van de lijstkaart maar een gelijkwaardig lid van het stelsel — anders klopt de
benaming niet (E-WID-01) en is het weer een lijstje in plaats van twee
breedtes maal twee hoogtes. Twee: dat niet elke soort hem aanbiedt, is geen gat.
Een grafiek of een tijdlijn met tijden in een kolom links heeft breedte nodig; die soorten hebben
dus een ondergrens, en dat is een eigenschap van het soort. "Deze maat ontbreekt bij de
verloopkaart" is geen bug die opgelost moet worden.
- Raakt
- Fase 3 · widgetcontract (maten per soort) · widgetgalerij ·
E-WID-02 · E-WID-09 · TEN-179.
Ruimt een inconsistentie op. In de eerste versie van TEN-179 kwam deze vorm
alleen informeel voor — als "tegel over twee lagen", uitsluitend binnen de lijstkaart — en kenden de
maatwisselaar en het opslagveld maar drie waarden. Dat is inmiddels rechtgezet: het stuk kent nu vier
volwaardige maten, sinds 6 augustus 2026 onder de namen uit E-WID-18
(Klein · Hoog · Breed · Groot — besloten, niet langer een voorstel). Met deze eis is de vierde
maat een gewoon lid van het stelsel en moeten wisselaar, matenlijst en opslag hem alle drie kennen.
In code is de vierde maat fullTall; de vierde naam is Groot.
Noem de vier maten Klein · Hoog · Breed · Groot, met één woordenlijst voor interface,
documentatie en code.
- Herkomst
- Geconstateerd bij het naast elkaar leggen van
E-WID-01 en TEN-179, 5 augustus 2026 · voorstel opgesteld op verzoek van de
eigenaar, 6 augustus 2026 · akkoord gegeven door de eigenaar op 6 augustus 2026; het
register liep daarop achter en is op de avond van dezelfde dag bijgewerkt.
- Waarom
- Er lopen twee stelsels naast elkaar. E-WID-01
eist namen die breedte én hoogte dragen ("volle breedte · laag"). TEN-179 gebruikt de korte namen
tegel · strook · paneel — die de hoogte juist níét dragen ("tegel" zegt niets over hoog of
laag). Dat is geen smaakverschil: het heeft al schade gedaan. Het onderzoeksstuk sprak van
drie maten terwijl het register er vier kende, precies omdat een naam zonder
hoogte-as de vierde maat niet kan benoemen (E-WID-17). Twee woordenlijsten
voor dezelfde vier dingen is hoe documentatie uit elkaar loopt.
- Raakt
- Fase 3 · widgetgalerij · vertaalsleutels · maatwisselaar · opslagveld
maat · E-WID-01 · E-WID-17 ·
TEN-179.
Besloten · dit is de woordenlijst
Vier korte namen die één stelsel vormen: Klein · Hoog · Breed · Groot
Vier korte woorden die allemaal over grootte gaan, en de paren kloppen: van Klein naar
Hoog is dezelfde breedte maar hoger, van Klein naar Breed dezelfde hoogte maar
breder, en Groot is allebei. Dat is een stelsel in plaats van een lijst — precies wat
tegel · strook · paneel niet was.
Het dragende argument: in de galerij staat naast elke naam al een maatvoorbeeld. Het
plaatje doet de uitleg; de naam hoeft alleen een handvat te zijn. Daarom mág hij kort —
"halve breedte · laag" beschrijft wat je er toch al naast ziet, en is als naam te lang en te weinig
zeggend.
- De vier woorden zijn de primaire, gebruikersgerichte namen — in de galerij, in de
bewerkstand en in alle documentatie. Eén woordenlijst.
- De lange beschrijving blijft toelichting, niet naam: als bijregel onder de naam waar er
ruimte is ("halve breedte, twee lagen hoog"), nooit als het label zelf.
- In code systematische afgeleiden van de twee assen:
halfLow,
halfTall, fullLow, fullTall — zodat de code-namen niet
meebewegen met een tekstwijziging en een vertaling nooit een opslagwaarde raakt.
De code-namen benoemen de assen, niet de maat. half tegenover
full is een paar dat de breedte-as uitdrukt, en Low tegenover
Tall doet hetzelfde voor de hoogte. Dat is precies wat deze eis van de code-namen
vraagt: twee assen, systematisch gecombineerd. Een naam als small tegenover
full zou dat juist bederven — dat is geen paar, want het mengt "hoe groot" met "hoe
breed", en dat is de fout die het hele stelsel moest wegnemen. Er staat nog geen regel code
— WidgetSize en de vier waarden komen nul keer voor in lib/ — dus de vier
namen zijn vandaag puur een afspraak in het corpus.
Zelf getoetst — één echt bezwaar, en het is oplosbaar.
Loopt "Hoog" door "Groot" heen? In een kale opsomming enigszins: beide klinken als "meer",
en niets in het woord "Hoog" verraadt dat het de smalle maat is. Naast het maatvoorbeeld in de
galerij valt dat weg — dáár is de naam een handvat, geen definitie. Het bezwaar geldt dus voor
lopende tekst, niet voor de galerij.
Het echte bezwaar is grammaticaal: dit zijn bijvoeglijke naamwoorden, terwijl
tegel · strook · paneel zelfstandige naamwoorden waren. "Op een paneel passen vijf regels" wordt
"op een Groot passen vijf regels" — dat leest niet. Aanbevolen oplossing: geef ze één vast
zelfstandig naamwoord om bij te horen — een kleine kaart · een hoge kaart · een brede kaart ·
een grote kaart. Het label in de interface blijft dan één woord (Klein · Hoog · Breed · Groot),
en lopende tekst krijgt zijn naamwoord terug zonder een tweede woordenlijst. Zonder die afspraak
verschijnt "de maat Groot" en "een Groot" door elkaar, en is het stelsel binnen een half document
weer scheef.
Wat de wissel kostte — en hij is al gedaan.
../archive/implemented/design/widget-interfaces-en-modulecontracten.html is omgezet: de oude korte namen stonden er
142 keer (tegel 78 · strook 31 · paneel 33), waarvan 133 vindplaatsen op ruim honderd
regels zijn omgezet — de negen die blijven staan zijn andere woorden (tegelijk,
actiestrook, knoppenstrook, weekstrook). De plekken waar de maatnaam
primair is, zijn allemaal meegegaan: de maattabel, de matrix soort-maal-maat (vier
kolomkoppen plus acht rijen celtekst), de maatwisselaars in de schetsen, de acht
Maten-regels in de modulecontracten, de capaciteitsregel, de startstand-tabel en het
opslagvoorbeeld — dat nu halfLow · halfTall · fullLow · fullTall toont in plaats van
'paneel', 'hogeTegel' en 'strook'. Lopende tekst kreeg de
kaart-vorm ("op een hoge kaart past…"). Er staat nog géén code, dus dit was een tekstuele herziening
van één document; kiest de eigenaar andere woorden, dan is het dezelfde ingreep nog een keer.
Gebied 7
Plus en het upgradepad
Uitgewerkt in docs/design/plus-presentatie-en-upgradepad.html. Hier staan
alleen de eisen die het E-programma raken, plus de harde cijfers waar een implementatieplan op moet
kunnen bouwen.
Het dashboard als etalage
Houd het dashboard bruikbaar in de gratis variant.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek.
- Waarom
- Een tabpositie die voor een gratis gebruiker leeg is, is een
tabpositie die je weggooit. En een Plus-muur om de functie heen zetten leert de gebruiker
niets over wat Plus is — het leert hem alleen dat een kwart van zijn navigatiebalk niet van hem is.
Meetpunt, niet vrijblijvend. Zonder Plus zijn er 4 kernoppervlakken plus 5 gratis
modules — ongeveer 8 tot 12 widgetbronnen tegenover ruim 30 mét Plus. Blijkt bij de beoordeling in
fase 3 dat het board voor een gratis gebruiker een tweede Vandaag wordt, dan is dat volgens de
fasering (E-NAV-07) reden om E bij fase 2 te stoppen.
Toon Plus-widgets zichtbaar maar uitgeschakeld, met hun echte vorm.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek. Uitgewerkt in het Plus-ontwerpstuk §4.
- Waarom
- Een gratis gebruiker mag goed zien wat hij mist, en dat is bewust
marketing. Een grijze tegel op het springboard toont een naam; een uitgeschakelde widget
toont de vorm van wat je zou krijgen. Dat maakt het dashboard het beste verkooppunt dat de
app heeft — winst tonen in plaats van een slot tonen.
Laden is niet hetzelfde als geen recht — besloten 6 augustus 2026. Deze eis
beschrijft wat een gebruiker zonder Plus ziet. Er was geen antwoord op de vraag wat een
gebruiker ziet zolang de app het nog niet weet: het Plus-recht wordt bij het opstarten
opgehaald en geldt zolang als "geen Plus". Zonder maatregel ziet een betalende gebruiker bij
elke koude start seconden lang zijn Plus-rijen verdwijnen en zijn Plus-widgets als "Voorbeeld" —
geen flikkering van één frame, maar de duur van een netwerkquery.
Besluit: de oppervlaktegate krijgt drie uitkomsten — toegestaan, geweigerd en nog
onbekend. Bij onbekend toont de app de vorige bekende stand, en zonder vorige stand een
rustige laadweergave. Geen etalage, geen lege balk. De etalage uit deze eis geldt dus pas als
vaststaat dát er geen Plus is. Zie ADR-0022; hetzelfde geldt voor
E-PLUS-03, E-PLUS-04 en de tabbalk onder
E-NAV-19.
En Vandaag mag die poort krijgen — met een veilige startwaarde, besloten avond
6 augustus 2026. Vandaag kende tot nu toe geen enkel tier-besef. Met de Plus-poort erin hangt de
zichtbaarheid van dagrijen af van effectiveTier
(module_tier_overrides.dart:44-47), die een tabel leest die bij het opstarten anoniem
wordt opgehaald en in SharedPreferences gecacht
(ModuleTierOverrides.build()/refresh(), :77-95).
De regel: tot de eerste geslaagde verversing geldt tonen. Een offline toestel of een
verse installatie verbergt dus nooit iets op grond van een gok; de faalrichting is altijd "te veel
tonen", nooit "stil iets weghalen". Dit is dezelfde derde stand als hierboven, toegepast op poort 4.
Wat dat in de bouw kost, en dat is geverifieerd: die stand bestaat vandaag niet.
_readCache() degradeert bij élke fout — en ook bij "nog nooit iets opgehaald" — naar
const {} (:97-116), wat niet te onderscheiden is van "opgehaald, en er zijn
geen overrides". Er moet dus een heb-ik-dit-ooit-geweten-stand bij; alleen dán kan de gate
"onbekend" antwoorden in plaats van te raden.
Label verzonnen vulling verplicht als "Voorbeeld".
- Herkomst
- Plus-ontwerpstuk §4 · onderzoek, als harde regel geformuleerd.
- Waarom
- Volgt op E-PLUS-02: als je de echte vorm
toont, toon je ook data — en een etalage die eruitziet als jouw gegevens maar het niet is, kost
precies één keer vertrouwen. Het label is de prijs voor het mogen tonen van de vorm.
- Raakt
- Fase 3 · TEN-149 · elke vergrendelde widget.
Toon de AI-knop zonder Plus zichtbaar maar uit; een tik opent het Plus-vlak met AI-context.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek, aangescherpt in het Plus-ontwerpstuk §4.
- Waarom
- AI verliest in fase 3 zijn tab en wordt een icoon in de kop
(E-NAV-09). Voor het zichtbaarste Plus-onderdeel van de app is dat weinig —
dus die ene knop moet zijn werk doen als trechter. Hij hoort er te staan zodat je weet dát hij
bestaat en wáár hij zit. En hij moet reageren: een knop die niets doet leest voor een gebruiker als
een bug, niet als een slot.
Proef en prijs
Geef twee weken gratis proef op alle vier de producten.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek. Vastgelegd in App Store Connect.
- Waarom
- 24 van de 29 modules zitten achter Plus. Zonder proef kan een
nieuwe gebruiker onmogelijk beoordelen of dat de moeite waard is, en beslist hij op basis van een
grijs raster. Twee weken is lang genoeg om een gezinsritme één keer rond te maken.
Hanteer de vastgestelde prijzen — Solo € 39,99 per jaar en € 5,99 per maand, Gezin € 59,99 per jaar en € 7,99 per maand — en lees ze uit de aanbieding in plaats van ze vast te zetten in code.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek. De vier producten bestaan sinds
5 augustus 2026 in App Store Connect.
- Waarom
- De prijzen zijn definitief — het woord "richtprijs" dat nu in de
app staat kan weg. Uitlezen in plaats van hardcoderen is geen nettigheid maar noodzaak: Apple past
bedragen per land aan, en een hardgecodeerd bedrag naast een afwijkend bedrag in de koopdialoog is
precies het soort tegenstrijdigheid dat een review afkeurt.
- Raakt
- TEN-157 · koopflow (B5) ·
_familyAnnualPrice in de huidige
upsell.
Nuance na verificatie. De vier abonnementen bestáán in App Store Connect,
maar zijn nog niet bruikbaar: er ontbreekt per product een reviewschermafbeelding en de
review zelf. Zonder goedgekeurde producten geeft de SDK een lege aanbieding terug — "de
producten bestaan" is dus niet hetzelfde als "de prijzen zijn op te halen".
Geef bij het gezinsabonnement élk lid Plus, ook tijdens de proefperiode.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek.
- Waarom
- Het product dat verkocht wordt is een gezinservaring. Wie
in de proefweken als enige Plus heeft, kan precies dat niet beoordelen — hij ziet een betere
solo-app, niet het gezin dat samenwerkt. De proef zou dan het verkeerde ding testen.
- Raakt
- TEN-157 ·
plus_entitlements · gezinsdeling ·
E-OPS-05.
Gevolg voor de teksten. Een scherm na aankoop krijgt hierdoor ook leden te zien
die zelf niets gekocht hebben. "Bedankt voor je aankoop" is dus geen bruikbare kop.
Maak de proefperiode zichtbaar op de plekken waar iemand tegen een grens loopt.
- Herkomst
- Eigenaar, 5 augustus 2026 · na het doorlopen van het prototype
("het valt niet echt op dat je een proefperiode kan doen").
- Waarom
- De proef wordt vandaag op één plek genoemd, en dan nog als
"binnenkort", tegenover meer dan vijftig plekken waar de grens gevoeld wordt. Een aanbieding die
alleen bestaat waar niemand hem zoekt, bestaat niet. Het moment van de grens is bovendien het enige
moment waarop de gebruiker zélf al bedacht heeft dat hij iets wil.
- Raakt
- TEN-150 ·
docs/design/plus-presentatie-en-upgradepad.html voor de
uitwerking (label-provider, Vandaag-regel, springboard-strip, onboarding).
Toon het label "14 dagen gratis" alleen wanneer de proef voor déze gebruiker echt beschikbaar is.
- Waarom
- Als het label overal komt te staan, komt het ook te staan bij wie
de proef al verbruikt heeft. De aanbieding geldt per Apple-account; anders lieg je. Val in dat geval
terug op "Plus".
- Raakt
plusTrialAvailableProvider · koopflow (B5) · TEN-150.
Zet geen knop in een echte build die niets doet.
- Herkomst
- Eigenaar, 5 augustus 2026 · gesprek. Als harde regel opgenomen in het
Plus-ontwerpstuk §7.
- Waarom
- De koopflow bestaat nog niet. Een knop met "Begin je 14 gratis
dagen" die vervolgens niets doet is de enige variant die gegarandeerd een bugmelding oplevert — en
hij kost het vertrouwen van precies de testers die je nodig hebt. Kies één van twee: de knop staat
er niet en het Plus-vlak legt alleen uit, óf de knop staat er wel maar alleen in een testbuild
achter een define.
Stand van zaken, geverifieerd. Handhaving staat áán
(plusEnforcementProvider = true; het commentaar "OFF until B5" ernaast is verouderd),
plusTrialAvailableProvider staat hard op false, _startTrial is
een lege pop met een TODO(B5), en er zit geen aankoop-SDK in
pubspec.yaml. Er is dus vandaag geen enkel scherm dat iets kan verkopen.
Wat de koopflow blokkeerde — alle drie beslecht
Laat het inloggen vóór de aankoop vallen; de koopknop staat achter de sessie.
- Herkomst
- Eigenaar, 6 augustus 2026 · beslecht in het voordeel van ADR-0023
(B1), ná de eerdere uitspraak op het voorstel in het Plus-ontwerpstuk §8, vraag 2.
- Waarom
- De volgorde is Plus-vlak → account maken of inloggen →
koopdialoog;
Purchases.logIn(<supabase user id>) gaat vooraf aan élke
koopaanroep, zodat app_user_id altijd onze user-id is en de bestaande webhook
ongewijzigd werkt. Drie redenen, alle drie tegen de code gecontroleerd. (1) Een Solo-recht
kan zonder begunstigd lid niet opgeslagen worden: 0042:25-26 eist
check (tier <> 'solo' or beneficiary_member_id is not null), en vóór het account
bestaat er geen lid; de tabel heeft bovendien alleen een select-policy (0042:31-35).
(2) De webhook accepteert geen anonieme RevenueCat-id en er is geen claim-pad:
revenuecat-webhook/index.ts:47 leest alleen event.app_user_id en
:63-66 geeft bij $RCAnonymousID een 200 met
skipped — geen retry, geen wachtrij, en nul treffers op claim/
pending in die function. (3) Cloud-sync is zélf de Plus-functie
(plus_entitlement.dart:3-7), dus een proef zonder account test het verkeerde
product.
- Raakt
- TEN-157 · koopflow (B5) ·
plusEntitlementProvider ·
ADR-0023 (B1).
De eerdere formulering van deze eis — "laat het inloggen ná de aankoop vallen" — is
ingetrokken. Die versie nam het voorstel uit ontwerpstuk §8 vraag 2 over ("laat de
App Store-koop eerst slagen en koppel het account daarna") en woog uitsluitend conversie op het
koopscherm; de drie blokkades hierboven bleven daarbij buiten beschouwing. Kom je dat oude advies nog
ergens tegen — in een ouder werkpakket, in een oude comment op TEN-157, of in een aangehaalde versie
van §8 — dan is het achterhaald. De tegenspraak met ADR-0023 is hiermee weg en dit punt houdt de
koopflow niet langer op.
Bewaar een module die zonder Plus wordt aangevinkt als wens, device-lokaal.
- Herkomst
- Eigenaar, 6 augustus 2026 · akkoord op het voorstel in het
Plus-ontwerpstuk §8, vraag 1. Niet langer blokkerend.
- Waarom
- In de onboarding mag iemand ook Plus-modules aantikken; die keuze
is de brug naar het proefaanbod een stap later. Blijft die keuze bewaard, dan staan de modules
klaar zodra Plus aangaat en voelt de proef als "wat ik zelf koos". Verdwijnt hij, dan moet de
gebruiker alles opnieuw doen op het moment dat hij net betaald heeft. De wens gaat
device-lokaal in
SharedPreferences in plaats van in de syncbare database; dat
maakt een migratie en de gezinsset/persoonlijk-vraag overbodig.
- Raakt
- TEN-149 · TEN-157 · onboarding · E-PLUS-11.
Houd de "bewaard"-groep permanent zichtbaar nadat Plus is weggevallen.
- Herkomst
- Eigenaar, 6 augustus 2026 · Plus-ontwerpstuk §8, vraag 7. De oorspronkelijke
vraag ging over "proefdata"; het antwoord is breder en valt uiteen in drie lagen.
- Waarom
- De belofte bij afloop is dat er nooit iets verwijderd wordt omdat
een abonnement stopt — "er is niets weg, er staat alleen wat op slot". De tellingen in die groep
komen uit de lokale database, en die blijft bestaan; er is dus geen reden ze ooit te laten
verdwijnen. Het oorspronkelijke voorstel ("permanent") klopt, maar om een andere reden dan er
stond.
Niet te verwarren met de bewaartermijn. Deze eis gaat over de lokale laag.
De cloudkopie heeft wél een termijn (E-PLUS-28) en de
bijlagen zijn de enige laag die daarna echt verloren gaat
(E-PLUS-29).
Wat er tijdens de proef zichtbaar is
Toon géén permanente proefteller op Vandaag.
- Herkomst
- Eigenaar, 6 augustus 2026 · afwijzing van het voorstel in het
Plus-ontwerpstuk §3 ("Nog 7 dagen Plus-proef · Regel het nu").
- Waarom
- Bij een automatisch verlengend abonnement met introductieaanbieding
is de gewenste uitkomst dat de proef omzet in betaald. Een dagelijkse teller met "regel het
nu" leest dan niet als service maar als een uitnodiging om op te zeggen — een churn-herinnering in
de vermomming van behulpzaamheid. Bovendien nodigt hij veertien dagen lang uit om over de kosten na
te denken, elke ochtend opnieuw, en juist in de periode waarin de gebruiker nog nauwelijks waarde
heeft opgebouwd. Je vraagt om de beslissing op het zwakste moment dat er is.
Waar het minimum wél ligt: bij de aankoop. Apple eist volledige informatie op het
aankoopmoment — titel, duur van het abonnement én van de proef, prijs, dat er bij bevestiging wordt
afgeschreven, dat het automatisch verlengt tenzij minimaal 24 uur vóór het einde van de periode wordt
opgezegd, dat de afschrijving binnen 24 uur vóór het einde plaatsvindt, waar de gebruiker het
abonnement beheert, en dat een ongebruikt deel van een proefperiode vervalt bij aankoop.
Er is geen enkele eis voor een permanente teller of een herinnering in de app tijdens de proef.
Onzeker en niet om op te bouwen: of Apple zélf waarschuwt vóórdat een proef omzet in betaald — de
bronnen spreken elkaar daarop tegen.
Zet de proefstatus als regel in Instellingen.
- Herkomst
- Eigenaar, 6 augustus 2026 · akkoord op voorstel 1 uit Plus-ontwerpstuk §3 ·
vervanger van E-PLUS-14. De eerdere aarzeling ("we zijn nog niet zeker of we
die herinneringen willen doen") is hiermee opgeheven voor dít voorstel.
- Waarom
- "Plus-proef · loopt tot 19 augustus · daarna € 59,99 per jaar":
status waar je hem zoekt, niet waar je hem niet kunt ontwijken. Vindbaar en eerlijk zonder dagelijkse
aandacht te vragen. Het is geen herinnering maar een statusregel — hij vraagt niets, onderbreekt
niets, en hij is de plek waarheen alle andere Plus-teksten wijzen. Dat is precies waarom dit het
minst omstreden van de drie vervangers was en waarom het als enige zonder voorbehoud doorgaat: het
kost bijna niets en het kan niets kapotmaken.
- Raakt
- TEN-150 · Instellingen ·
period_type en expires_at
uit ADR-0023 (B3) · E-PLUS-16 · E-PLUS-17.
Het bereik van deze regel is beperkt, en dat is nu belangrijker geworden. Een deel
van de gebruikers opent Instellingen nooit. Zolang E-PLUS-16 nog een moment
vooraf zou toevoegen, was dat een aanvaardbaar gat; met de afwijzing daarvan is deze regel het enige
wat er tíjdens een normale proef in de app over te vinden is. Wie hem niet zoekt, hoort pas iets ná de
afschrijving (E-PLUS-17). Dat is een bewuste uitkomst, geen omissie —
period_type is nodig om de regel niet boven een betaald jaarabonnement te laten
verschijnen.
Toon géén bericht vooraf tijdens een proef die gewoon doorloopt; toon alleen een afteller mét de gevolgen zodra iemand actief heeft opgezegd.
- Herkomst
- Eigenaar, 6 augustus 2026 · afwijzing van voorstel 2 uit
Plus-ontwerpstuk §3, mét één uitzondering. Het voorgestelde moment rond dag 11 of 12 is
geschrapt.
- Waarom
- Bij de normale gang van zaken is er niets aan de hand: de proef
gaat over in betaald, dat is de gewenste uitkomst, en een scherm dat daar aandacht op vestigt is —
hoe vriendelijk ook geformuleerd — een uitnodiging om op te zeggen. Een terugblik met cijfers
verandert daar niets aan; hij vraagt nog steeds om de beslissing op een moment dat de gebruiker er
niet om vroeg. De uitzondering is de spiegel daarvan: zodra iemand zélf heeft opgezegd, is er
wél iets aan de hand, en dan zwijgen is oneerlijk. Dán telt de app af en zegt er concreet bij wat er
verdwijnt — "je proef loopt over 3 dagen af; hierna verlies je toegang tot Budget, Auto en
Documenten". Dat is dezelfde regel als E-PLUS-24 en
E-PLUS-25, hier toegepast op de proef: de app reageert op een
gebeurtenis, nooit op een klok.
- Raakt
- TEN-150 · TEN-157 · ADR-0023 (B3) —
will_renew is de
trigger · E-PLUS-24 · E-PLUS-25 (dáár staat de
uitwerking van de afteller) · E-PLUS-17.
Wat hiermee vervalt. Het dag-11/12-moment, de terugblik met tellingen
("7 van je 24 modules in gebruik", "3 toestellen in huis"), de knoppen "Plus houden" / "Ik wil straks
stoppen", en de eis dat er een stopknop bij dat scherm hoort. Dat scherm bestaat niet meer, dus die
eis ook niet. De schets ervan is uit Plus-ontwerpstuk §3 verwijderd; wat daar overblijft zijn de
statusregel (E-PLUS-15) en de bevestiging achteraf
(E-PLUS-17).
Geen enkele Apple-eis staat hier tegenover. Het minimum ligt volledig op het
aankoopmoment (zie E-PLUS-14); er is geen verplichting tot een teller of een
herinnering tijdens de proef. Wat dit besluit wél verzwaart is E-PLUS-17: die
bevestiging is nu het enige moment waarop de app iets zegt over de eerste afschrijving, en dat is de
reden dat die eis niet geschrapt kan worden zonder dat de app in een normale proef volledig zwijgt
over het geld.
Toon één rustige bevestiging nadat de proef in een betaald abonnement is omgezet.
- Herkomst
- Eigenaar, 6 augustus 2026 · akkoord op voorstel 3 uit Plus-ontwerpstuk §3 ·
vervanger van E-PLUS-14.
- Waarom
- "Je Plus is actief", met wat er verandert en waar je het beheert.
Eén keer, direct na de eerste afschrijving, zonder knop die iets verkoopt. Dit voorkomt de
verrassingsafschrijving die eindigt in terugboekingen en recensies van één ster — het verschil tussen
"ik was het vergeten maar ik wist het" en "ze hebben me stilletjes afgeschreven". Het kost niets aan
conversie, want de afschrijving is dan al gedaan.
- Raakt
- TEN-157 · de entitlement-listener uit §5 · ADR-0023 (B3) —
de overgang
period_type TRIAL → NORMAL is het signaal ·
E-PLUS-16 · E-PLUS-07 ·
E-PLUS-18.
Samenhang met E-PLUS-16 — dit scherm is zwaarder geworden
Omdat er vooraf niets getoond wordt, is dit het enige moment waarop de app iets zegt over de eerste afschrijving
In het oorspronkelijke voorstel was dit de derde en lichtste van drie momenten: er ging een
terugblik rond dag 11 aan vooraf, dus wie hier iets las, wist het al. Met de afwijzing van E-PLUS-16
staat dat moment er niet meer. In het normale verloop van een proef zegt de app dus niets
tussen de aankoop en de afschrijving — behalve wat iemand zelf in Instellingen opzoekt
(E-PLUS-15). Dit scherm is daarmee van "vriendelijk extra" tot
de enige waarschuwing achteraf geworden, en het moet naar die rol uitgewerkt worden.
Wat dat concreet betekent voor de inhoud. Het bedrag en de datum staan er niet als
bijzin maar als hoofdzaak: "Vandaag is € 59,99 afgeschreven. Je abonnement loopt tot
19 augustus 2027." Het beheerpad naar de App Store staat er als volwaardige regel, niet als
voetnoot — dit is de plek waar iemand die het níet wilde, moet kunnen doorklikken zonder te zoeken.
En er staat bij dat er verder niets verandert aan de app, want dat is de vraag die iemand op dat
moment het eerst stelt.
Wat het níet wordt. Geen knop die iets verkoopt, geen upsell naar
een duurder plan, geen vraag. Het scherm is een bonnetje. De verleiding om er — nu het het enige
moment is — meer op te zetten, is precies de verleiding die het onbetrouwbaar maakt. Bij
tier = family geldt bovendien E-PLUS-07: leden die zelf niets
kochten mogen deze afschrijvingsbevestiging niet zien — daarvoor is
purchaser_member_id uit ADR-0023 (B2) nodig.
Dit gaat verder dan het Apple-minimum, en dat is bewust. Het strikte minimum is
informeren bij de aankoop en daarna zwijgen; dat converteert op korte termijn beter. Maar een stille
afschrijving die iemand pas op zijn bankafschrift ziet, kost een terugboeking, een recensie en een
gebruiker die niet terugkomt. Met E-PLUS-16 afgewezen is dit het enige scherm dat die uitkomst nog
tegenhoudt.
Het welkomstscherm en de afbakening van Solo
Laat het welkomstscherm per abonnement verschillen; toon de gezinsbelofte alleen bij Gezin.
- Herkomst
- Eigenaar, 6 augustus 2026 · na het lezen van het welkomstscherm in het
Plus-ontwerpstuk §5.
- Waarom
- De kaart "Nodig je gezin uit — iedereen krijgt Plus, zonder extra
kosten" is bij Solo niet overbodig maar onwaar. Een Solo-koper die op die kaart tikt en zijn
gezin uitnodigt, denkt ze Plus te hebben gegeven terwijl ze in de gratis variant landen. Een
verkeerde belofte op het moment dat iemand net betaald heeft is de duurste die er is: hij wordt pas
ontdekt als er iemand anders bij betrokken is die het ook niet begrijpt.
Technisch gratis. tier zit al in de rij die de listener leest
(plus_entitlement.dart:52-56); het is één conditie om de rij weg te laten.
Toon een Solo-koper op de plek van de uitnodigingskaart een eerlijk upgrade-aanbod: "wil je dat je gezin ook Plus heeft? Dat is Gezin, € 20 per jaar meer."
- Herkomst
- Eigenaar, 6 augustus 2026 · akkoord op Solo-variant B uit Plus-ontwerpstuk
§5 · volgt op E-PLUS-18, dat alleen het negatieve besluit vastlegde.
- Waarom
- Er stond twee antwoorden open: niets tonen, of één regel. Het is de
regel geworden, omdat het sinds E-PLUS-21 geen verkooppraatje meer is maar
relevante informatie: wie later iemand uitnodigt, móét op dat moment upgraden. Dat één keer
rustig zeggen op het moment dat iemand aandachtig is, is eerlijker dan het later als verrassing te
laten komen. Waar bij Gezin een belofte stond die klopt ("iedereen krijgt Plus"), staat hier dus een
aanbod dat óók klopt — inclusief de prijs.
Uitwerking — de toon is hier de eis, niet een detail
Eén regel onderaan, in de informatiestijl; geen kaart, geen accentkleur, geen pijl die duwt
Waar: onderaan het Solo-welkomstscherm, ná de regel "later regelen kan ook" en ná de twee
schakelaars — niet ertussen. Vorm: de rustige informatiestrook
(strip info), dezelfde als elders in de app voor mededelingen; níet de
accentkleur en níet de kaartvorm die bij Gezin gebruikt wordt. Een kaart tussen de schakelaars, met
pijl en accentkleur, is een verkoopvoorstel; dezelfde woorden onderaan in grijs zijn een
mededeling.
De tekst: "Wil je dat je gezin ook Plus heeft? Dat is Gezin, € 20 per jaar meer."
met als actie "Bekijken". Drie dingen daaraan zijn met opzet zo: het is een vraag
en geen aansporing; het noemt het verschil (€ 20) en niet het volle bedrag, want het verschil
is wat er werkelijk bij komt; en het woord "upgrade" komt er niet in voor. Het prijsverschil wordt
uit de aanbieding gelezen en niet als vaste tekst opgenomen
(E-PLUS-06) — Apple past bedragen per land aan, en een verkeerd verschil in
een verkoopregel is precies wat een review afkeurt.
Wat het risico is en hoe het afgedekt wordt. Dit is de enige plek in
het hele Plus-ontwerp waar een duurdere variant wordt genoemd aan iemand die zojuist betaald heeft.
Dat kán hebzuchtig overkomen, en dat risico is de reden dat "niets tonen" een serieus alternatief
was. Het verschil tussen hebzuchtig en behulpzaam zit volledig in plaatsing en toon, en die twee zijn
hierboven daarom als eis geformuleerd en niet als suggestie. Eén keer, en daarna nooit meer op dit
scherm — de regel keert niet terug bij een volgende start.
Positioneer Solo als het abonnement voor één account: één persoon logt in, met onbeperkt leden zónder account erbij.
- Herkomst
- Eigenaar, 6 augustus 2026 · beantwoordt de open vraag "Solo in een huishouden
van vier" uit het Plus-ontwerpstuk §8, vraag 10. Later diezelfde dag herzien: de grens ligt bij
het aantal accounts, niet bij het aantal leden — zie het blok hieronder.
- Waarom
- Volgens het freemium-besluit is cloud-sync zelf een Plus-functie.
Waar het misgaat is dus niet "iemand gebruikt gezinsfuncties" maar "er zijn twee mensen die inloggen
en er synchroniseert er één": dan werkt het gedeelde huishouden — de kern van het product — voor de
helft van de mensen niet. Zolang er één account is, speelt dat niet, hoeveel leden er ook in het
huishouden staan. Solo is dus "één persoon logt in", en Gezin is "twee of meer mensen loggen
in".
- Raakt
- TEN-157 · E-PLUS-21 · E-PLUS-22 ·
E-PLUS-35 · prijsvolgorde op het Plus-vlak · ADR-0023 (de
twee-Solo-botsing) · ADR-0020 (bevinding 7b).
Statuswijziging — de grens is verlegd van leden naar accounts
"Voor wie alleen woont" was te smal, en het scenario dat dat aantoont is niet zeldzaam
Deze eis luidde eerst: "Positioneer Solo als het abonnement voor wie géén gezinsfuncties
gebruikt", met als toelichting dat Solo feitelijk "voor wie alleen woont" is. Dat is op
6 augustus 2026 herzien. De aanleiding is een alleenstaande ouder met twee kinderen, gescheiden,
die juist wél gezinsfuncties wil — co-ouderschap en de sportkalender. Haar kinderen hebben geen
account. Onder de oude formulering zou zij € 59,99 voor Gezin betalen terwijl er één persoon inlogt,
één toestel synchroniseert en niemand anders Plus krijgt. Dat is geen randgeval en het is niet uit te
leggen.
Het schema kende dit onderscheid al. authUserId op de ledentabel is nullable,
met in de code de toelichting "null for non-auth (e.g. child) members"
(lib/core/database/tables/foundation_tables.dart:131-132). Leden zonder account bestaan
dus al bij ontwerp; dit besluit voegt geen functie toe, het benoemt een bestaande eigenschap en maakt
hem tot de grens.
En het sluit aan op ADR-0020. Dat ADR stelde vast dat "per lid" in de
praktijk "per lid mét account" is — de sync-query eist auth_user_id
(sync-config.yaml:121) — en markeerde dat als iets wat de eigenaar moest bevestigen. Dat
is hiermee bevestigd. Een lid zonder account heeft geen eigen gesynchroniseerde indeling, en dat is
consistent in plaats van een tekortkoming: zo iemand heeft ook geen toestel.
E-OPS-05 ("per lid, niet gedeeld") heeft daar niets te regelen omdat er niets
ís.
Feitelijke afwijking, geverifieerd op 6 augustus 2026. In de code zit cloud-sync
vandaag niet achter Plus: app_root.dart:115-117 schakelt cloud in op
hasCloudSync && session != null, zonder entitlement-check. Alleen de doc-comment in
plus_entitlement.dart:3-7 beweert dat het Plus is. Wat er nu gebeurt wijkt dus af van wat
er besloten is — dat bepaalt of dit vandaag al een probleem is (nee) of pas zodra de gate erin gaat
(ja). Zie ook E-PLUS-33.
Sta een Solo-abonnee niet toe iemand uit te nodigen zonder op dat moment te upgraden naar Gezin; een lid zónder account toevoegen raakt niets.
- Herkomst
- Eigenaar, 6 augustus 2026 · de handhaving bij
E-PLUS-20. Later diezelfde dag herzien van "een tweede lid toevoegen"
naar "iemand uitnodigen" — zie het blok hieronder.
- Waarom
- Je kunt als Solo geen tweede account opbouwen om daarna pas te
betalen: het uitnodigen ís het upgrade-moment. En uitnodigen is precies de handeling die een
tweede account maakt — daarmee valt de poort samen met de grens uit
E-PLUS-20 in plaats van er iets naast te zetten. De poort ligt bij het
uitnodigen en niet bij het gebruik achteraf: dat is de enige plek waar hij te begrijpen is en niet
als straf voelt.
- Raakt
- TEN-157 · Instellingen → Huishouden · uitnodigingen · kindprofielen ·
koopflow (B5) · E-PLUS-22.
Statuswijziging — de poort staat bij het uitnodigen, niet bij het toevoegen
Een kindprofiel aanmaken kost niets en vraagt geen upgrade
Deze eis luidde eerst "een tweede lid toevoegen". Met de herziening van
E-PLUS-20 — de grens ligt bij accounts — is dat te breed geworden: een
kindprofiel is een lid zonder account, dat niet inlogt en niet synchroniseert. Zo'n profiel
aanmaken raakt het abonnement dus niet, hoeveel het er ook zijn. De poort wordt daarmee één
regel: iemand uitnodigen vereist Gezin. Dat is scherper dan de oude formulering én makkelijker
te bouwen, want er is precies één handeling om af te vangen in plaats van twee soorten "toevoegen"
die uit elkaar gehouden moeten worden.
Het overgangsmoment: een kindprofiel dat later alsnog een account
krijgt. Het kind krijgt een telefoon en gaat zelf inloggen. Op dát moment ontstaat het tweede
account, en dus passeert het huishouden op dát moment dezelfde poort: Gezin is vereist voordat
het account er is, niet erna. Praktisch betekent dat dat het aanmaken van een inlog voor een
bestaand kindprofiel door dezelfde uitleg-met-prijs gaat als een uitnodiging, met dezelfde
afbreekregel — bij afbreken blijft het kindprofiel gewoon bestaan zoals het was, zonder account en
zonder halve toestand. Er is geen sluiproute waarin een profiel "stilletjes" een account wordt,
want er is geen pad dat een auth_user_id zet zonder dat iemand inlogt.
De flow. Waar: op elk scherm dat tot een uitnodiging leidt — één poort,
meerdere deuren. Wat de gebruiker ziet: geen foutmelding maar een uitleg met een prijs, mét de
naam van de persoon die hij net wilde uitnodigen. Bij doorgaan: de koopdialoog voor de upgrade,
en pas ná een geslaagde upgrade gaat de uitnodiging de deur uit. Bij afbreken: het lid wordt niet
toegevoegd en er blijft niets achter — geen half-toegevoegd lid, geen zwevende uitnodiging, geen
"pending"-toestand die later opgeruimd moet worden. Elke andere keuze creëert een huishouden met meer
accounts dan het abonnement toestaat, en dat is precies het probleem dat deze poort oplost.
Bied Solo niet aan zodra een huishouden meer dan één account heeft; toon dan alleen Gezin.
- Herkomst
- Eigenaar, 6 augustus 2026 · akkoord op het voorstel dat naast
E-PLUS-21 was opengehouden. Later diezelfde dag herzien: geteld
worden accounts, niet leden — zie het blok hieronder.
- Waarom
- De poort van E-PLUS-21 voorkomt nieuwe gemengde situaties,
maar er zijn vandaag al huishoudens met meerdere accounts en die zijn er niet doorheen gekomen — de
poort bestaat nog niet. Daarom wordt er bij het kopen gekeken hoeveel accounts het huishouden heeft;
zijn het er meer dan één, dan is alleen Gezin te koop, met de zin "voor jullie alle vier". Dan hoeft
er nergens iets geblokkeerd of teruggedraaid te worden en is de regel op elk moment uit te leggen.
Het alternatief — Solo toestaan met een uitleg erbij — levert precies de asymmetrie op die
E-PLUS-20 wilde wegnemen. Dit is bovendien consistent met E-PLUS-21: daar
vereist het maken van een tweede account een upgrade, hier is het bestáán ervan een reden om Solo
niet aan te bieden.
- Raakt
- TEN-157 · koopflow (B5) · het Plus-vlak (plankeuze) ·
E-PLUS-20 · E-PLUS-21 · ADR-0023 — de
twee-Solo-botsing wordt hierdoor zeldzamer maar verdwijnt niet.
Statuswijziging — geteld worden accounts, niet leden
"Meer dan één lid" zou een alleenstaande ouder met kinderen naar Gezin duwen
Deze eis luidde bij het besluit "zodra het huishouden meer dan één lid telt". Dat is
op 6 augustus 2026 herzien naar accounts, om dezelfde reden als bij
E-PLUS-20: een huishouden met een ouder en twee kindprofielen telt drie
leden en één account. Onder de oude formulering was Solo daar niet te koop, terwijl er precies één
persoon inlogt. De teleenheid is dus "leden mét een auth_user_id" — hetzelfde
predicaat dat de sync-laag toch al hanteert.
Praktisch gevolg voor de koopflow: het Plus-vlak kent twee vormen. Bij één
account staan Solo en Gezin naast elkaar; bij twee of meer accounts staat alleen Gezin er, met een
zin die uitlegt waaróm ("jullie zijn met z'n vieren"). Er is geen derde vorm en geen uitzondering.
Wie vandaag al Solo heeft in zo'n huishouden houdt dat, ongemoeid. Dit is een regel
over kopen, niet over hebben: een bestaand Solo-recht wordt niet ingetrokken, niet
gedegradeerd en niet geblokkeerd zodra er een tweede account in het huishouden blijkt te staan. Er
wordt niets teruggedraaid en niemand raakt iets kwijt. Wat zo iemand merkt is alleen dit: de andere
accounts in dat huishouden krijgen géén Plus (dat is wat Solo is), en op het Plus-vlak wordt hem bij
een volgende aankoop of verlenging alleen Gezin aangeboden. Er komt geen dwingende melding en geen
afteller — dat zou een gebruiker straffen voor een situatie die door onze eigen ontbrekende poort
is ontstaan. De asymmetrie lost zichzelf op zodra hij ooit naar Gezin gaat, en tot die tijd is hij
zichtbaar en uitlegbaar in plaats van stil.
Dit heft de twee-Solo-botsing níet op. Twee huishoudens die elk een
Solo-abonnement hebben en later samengevoegd worden, komen nog steeds op dezelfde rij in
plus_entitlements uit; en deze regel werkt alleen vooruit. De sleutel per aankoop uit
ADR-0023 (B2) blijft dus onverkort nodig — dat is de enige maatregel die ook op bestaande
situaties werkt.
Als Plus wegvalt
Behandel "de proef loopt af zonder aankoop" als uitzondering, niet als de normale afloop.
- Herkomst
- Eigenaar, 6 augustus 2026 · correctie op de opzet van het Plus-ontwerpstuk §6.
- Waarom
- Bij een auto-verlengend abonnement met introductieaanbieding is de
standaarduitkomst dat de proef overgaat in betaald, en daarna dat dat abonnement doorloopt. Plus
verliezen is een afwijking, en die heeft altijd een aanwijsbare oorzaak: actief opzeggen,
verlengen uitzetten, een betalingsprobleem of een terugbetaling. Dat is meer dan woordkeuze — het
bepaalt wanneer de app iets mag zeggen: niet op een klok die naar het einde telt, maar op een
gebeurtenis die daadwerkelijk heeft plaatsgevonden.
- Raakt
- TEN-157 · Plus-ontwerpstuk §6 · E-PLUS-24.
Toon geen opzegpad zolang er niets is opgezegd.
- Herkomst
- Eigenaar, 6 augustus 2026 · sluit aan op
E-PLUS-14.
- Waarom
- Een eerdere versie van §6 zette "Doorgaan met Plus" en "Opzeggen in
de App Store" naast elkaar in een waarschuwing op dag 11. Dat strookt niet met het besluit om niet
naar opzeggen te duwen: het is dezelfde uitnodiging als de permanente teller, alleen met een nettere
motivering. Waar niets aan de hand is, zegt de app niets.
- Raakt
- TEN-157 · Plus-ontwerpstuk §6 · E-PLUS-25.
Toon ná een opzegging wél een afteller, met de concrete gevolgen erbij.
- Herkomst
- Eigenaar, 6 augustus 2026 · de keerzijde van
E-PLUS-24.
- Waarom
- "Je hebt opgezegd, je proef loopt over 3 dagen af. Hierna verlies je
toegang tot Budget, Auto en Documenten." Nu is er wél iets aan de hand, en dit is het enige moment
waarop de kosten van stoppen concreet worden — daarmee is het meteen het sterkste re-conversiemoment
dat er is. Niet "nog 3 dagen gratis", maar wát je over drie dagen niet meer kunt.
- Raakt
- TEN-157 · ADR-0023 (B3) — vereist
will_renew en
lapse_reason · E-PLUS-30 (de bijlagendownload hoort hier
ook).
Geldt voor proef én betaald abonnement, met dezelfde schermen en zwaardere aantallen.
Niet voor een naderende jaarlijkse verlenging waar niets is opgezegd: de afteller vóór de
eerste afschrijving is een proef-ding omdat daar iets van gratis naar betaald gaat; een
verlenging verandert niets aan de situatie en verdient dus geen scherm.
Maak bij het wegvallen van Plus glashelder dat de toegang tot die gegevens weg is, met een upgradepad dat de eerder gebruikte modules bij naam noemt.
- Herkomst
- Eigenaar, 6 augustus 2026 · Plus-ontwerpstuk §6.
- Waarom
- "Je gegevens zijn er nog, je kunt er alleen niet meer bij" is de
enige formulering die tegelijk waar en begrijpelijk is. En het upgradepad wordt pas overtuigend als
het over déze gebruiker gaat: "je gebruikte Budget, Auto en Documenten — met Plus staan ze er weer."
Bij een jaarklant weegt dat zwaarder dan bij een proefgebruiker, omdat de aantallen groter zijn; dat
verschil ontstaat vanzelf uit echte tellingen en vraagt geen tweede flow.
Randgeval dat het afloopscherm de volle lading geeft. Wie op de láátste dag opzegt
krijgt geen afteller — opzegging en verlies vallen samen. Hetzelfde geldt bij een terugbetaling. Alles
wat in de afteller staat (welke modules op slot gaan, hoeveel bijlagen er zijn, de downloadknop) moet
daarom óók op het afloopscherm staan. Dat de bijlagen daarna nog 90 dagen bereikbaar blijven
(E-PLUS-28) is precies wat dit randgeval draaglijk maakt.
Verwijder nooit gegevens omdat een abonnement afloopt.
- Herkomst
- Eigenaar, 6 augustus 2026 · Plus-ontwerpstuk §6.
- Waarom
- Vergrendelen mag, wissen niet. Wie stopt met betalen heeft nog
steeds recht op wat hij zelf heeft ingevoerd. Daarnaast een praktisch argument dat net zo hard is:
zonder bewaring kan "toch weer Plus" niets terugbrengen, en dat is erger dan de opslag die je ermee
uitspaart.
Geverifieerd, 6 augustus 2026 — en dit vereenvoudigt de hele vraag. Tendlo is
local-first en er is geen enkel pad waarin het verlies van een Plus-recht data verwijdert: de
runtime-modus hangt uitsluitend aan de Supabase-sessie (app_root.dart:115-117) en de
sync-laag kent het begrip Plus niet. Wat er bij Plus-verlies gebeurt is puur een toegangsgrens —
route-gate (app_router.dart:282-288), vergrendelde tegel
(mijn_leven_screen.dart:55-61), gefilterde snelacties
(module_quick_action_providers.dart:75-95). Wél gewist wordt er bij uitloggen
(sync_connection.dart:53-57, disconnectAndClear()), bij "alles op dit toestel
wissen" (data_reset_service.dart:51-68) en bij een huishoudenswissel
(household_session_reset.dart:42) — geen van drieën gekoppeld aan het entitlement.
Uitgezocht op 6 augustus 2026 — de eerder gemelde valkuil is kleiner dan hij
klonk. Free-modus en cloud-modus gebruiken inderdaad twee bestanden:
app_database.dart:1490-1494 (mijn_pa) tegenover
powersync_open.dart:10-12 (mijn_pa.ps.db). Bij uitloggen roept
sync_connection.dart:53-57 disconnectAndClear() aan, dat in de
PowerSync-laag select powersync_clear(1) uitvoert: het bestand wordt niet verwijderd,
de tabellen worden geleegd — nergens in lib/ staat een pad dat
mijn_pa.ps.db van schijf haalt. De cloudkopie bij Supabase blijft onaangeroerd
(het uitlogpad raakt de server niet; de delete-tak van
supabase_connector.dart:270-278 draait alleen op een echte gebruikersverwijdering), dus
opnieuw inloggen brengt alles terug. Het is dus verdwijning uit beeld, niet dataverlies.
Twee uitzonderingen waar het wél echt weg is — vragen een eigen ticket.
(1) powersync_clear(1) gooit óók de openstaande upload-wachtrij weg zonder die te
versturen — precies waarom "alles op dit toestel wissen" hem gebruikt
(data_reset_service.dart:38-44, privacy_screen.dart:120-128). Wie offline
iets invoert en daarna uitlogt, verliest dat definitief; de server heeft het nooit gezien. De
uitlogknop is een kale knop zonder bevestiging en zonder wachten op de wachtrij
(instellingen_screen.dart:400-402). (2) Ná de 90 dagen uit
E-PLUS-28 is de cloudkopie opgeruimd en is mijn_pa.ps.db het
énige exemplaar; uitloggen leegt dat en er is niets om van terug te halen. De volgorde "Plus valt weg
→ 90 dagen verstrijken → uitloggen" is daarmee wél permanent verlies. Beide worden ondervangen door
één ingreep: een bevestiging bij uitloggen die zegt wat er van het toestel verdwijnt, of er nog iets
in de wachtrij staat, en of er nog een cloudkopie is.
Ruim de cloudkopie 90 dagen na het wegvallen van Plus op; de lokale kopie blijft.
- Herkomst
- Eigenaar, 6 augustus 2026 · akkoord op het voorstel van 90 dagen.
- Waarom
- Lang genoeg dat opnieuw Plus nemen alles terugbrengt alsof er niets
gebeurd is — ook op een nieuw toestel — en kort genoeg om als bewaartermijn met een doel te
verdedigen. Daarna opruimen. Omdat de lokale kopie blijft bestaan
(E-PLUS-27), raakt deze termijn alleen de mogelijkheid om elders
terug te halen.
Waarschuw expliciet dat bijlagen alleen in de cloud bestaan en na de bewaartermijn echt verloren gaan.
- Herkomst
- Eigenaar, 6 augustus 2026 · op de vondst uit de verrijking van
TEN-158.
- Waarom
- Van alle lagen is dit de enige waar de bewaartermijn tot echt verlies
leidt. Foto's en documenten bestaan nergens anders, dus "er wordt niets verwijderd" geldt voor hen
niet zonder voorbehoud. De waarschuwing hoort op drie plekken: in de afteller na opzegging
(E-PLUS-25), op het afloopscherm
(E-PLUS-26) en in het back-upscherm zelf.
Geverifieerd, 6 augustus 2026. Bijlagen zijn metadata plus een pad; de bytes staan
uitsluitend in Supabase Storage (attachments_table.dart:3-7, bucket in
attachment_storage_service.dart:14). Er is geen persistente lokale cache: weergave
gaat via Image.network op een signed URL van een uur, en er zit geen
cached_network_image of flutter_cache_manager in pubspec.yaml.
Bijlagen zijn daarmee ook nu al niet offline beschikbaar.
Geef de back-up een optie "inclusief bijlagen", en bied hem actief aan op het moment van opzeggen.
- Herkomst
- Eigenaar, 6 augustus 2026 · voorstel van de eigenaar zelf, als sluitstuk op
de bewaarregel.
- Waarom
- Met bijlagen in de export is 90 dagen geen risico maar een ruime
overgangsperiode: wie stopt kan álles meenemen, ook wat alleen in de cloud staat.
Het is een keuze, geen standaard — bijlagen maken de export vele malen groter en de meeste
exports hebben ze niet nodig, dus de omvang staat er zichtbaar bij en verandert de knop mee.
Actief aanbieden bij opzegging omdat wie opzegt 90 dagen heeft om zijn bijlagen op te halen en
daar zelf niet aan denkt. De eerlijke bijvangst: "download je bijlagen voordat ze verdwijnen" is
oprechte service én een moment waarop iemand voelt wat hij opgeeft — dat mag, zolang de service echt
is en de knop echt werkt.
- Raakt
- TEN-158 (bestemming, bewaring en de geëxporteerd-markering — die
ontwerpvragen horen dáár en niet in het Plus-stuk) · TEN-173 (de te vroeg gezette markering,
gefixt) · E-PLUS-29 · E-PLUS-33.
Geverifieerd, 6 augustus 2026. De back-up zit niet achter Plus:
backup_screen.dart kent geen entitlement en de route /backup
(app_router.dart:239-240) valt buiten de Plus-gate, die alleen module-routes matcht. De
huidige export bevat alleen databasetabellen (backup_service.dart:40-75;
:211-218 base64't alleen BLOB-kólommen, en de attachments-tabel heeft er geen) — van de
bijlagen gaan dus alleen pad en metadata mee. Bijkomende beperking om te kennen: de export is
lid-gescoopt, niet huishoudensbreed (backup_service.dart:3-9,
:182-205).
Formuleer de afloop als "Plus valt weg", niet als "de proefperiode loopt af".
- Herkomst
- Eigenaar, 6 augustus 2026 · correctie op het Plus-ontwerpstuk §6, waar de
"bewaard"-groep nog "Uit je proef" heette.
- Waarom
- Precies dezelfde situatie geldt voor iemand die na een jaar betaald
abonnement opzegt — en die heeft veel méér opgebouwd. Eén model, één set schermen, één bewaarregel.
Het verschil in gewicht ontstaat vanzelf uit echte tellingen en vraagt geen tweede flow.
Waar het verschil wél echt is, blijft het staan. De afteller vóór de eerste
afschrijving is een proef-ding; de jaarlijkse verlenging is dat niet
(E-PLUS-25). Generaliseren mag die twee niet op één hoop gooien.
Leg de bewaartermijn vast in de privacyverklaring, met doel en grens, en ruim aantoonbaar op.
- Waarom
- Een bewaartermijn heeft onder de AVG een doel en een grens nodig en
moet in de privacyverklaring staan. Het doel is hier goed te formuleren — "zodat je je abonnement kunt
hervatten zonder gegevensverlies" — en de grens is de termijn zelf. Daarbij hoort dat het opruimen
aantoonbaar gebeurt (een geplande taak, niet een voornemen) en dat de gebruiker de termijn kan
bekorten door zijn account te verwijderen.
- Raakt
- Privacyverklaring · een geplande opruimtaak op de server ·
E-PLUS-28.
Storage lezen en exporteren blijven binnen de bewaartermijn van 90 dagen werken zonder Plus.
- Herkomst
- Eigenaar, 6 augustus 2026 — geaccepteerd. Oorspronkelijk afgeleid uit
E-PLUS-28 en E-PLUS-30 · geverifieerd in de code
op 6 augustus 2026. Zonder deze eis is de bewaartermijn een lege belofte zodra cloud-sync achter
Plus gaat.
- Waarom
- Bijlagen worden opgehaald met een signed URL en die vereist een
geldige Supabase-sessie (
attachment_repository.dart:74-79,
attachment_storage_service.dart:44-67). Vandaag gaat dat goed, want cloud-modus
hangt aan de sessie en niet aan het entitlement (app_root.dart:115-117) — wie Plus
verliest maar ingelogd blijft, kan zijn bijlagen de volle 90 dagen binnenhalen. Dat verandert
zodra cloud-sync daadwerkelijk achter Plus gezet wordt, zoals het freemium-besluit voorschrijft:
dan verbreekt het verlies van Plus de verbinding en zijn de bijlagen op datzelfde moment
onbereikbaar — en is de bewaartermijn een lege belofte. Dit is een architectuurvoorwaarde, geen
detail.
Hanteer één bewaartermijn van 90 dagen voor iedereen; laat hem niet meeschalen met de abonnementsduur.
- Herkomst
- Eigenaar, 6 augustus 2026 · beantwoordt de vraag die naast het besluit van
90 dagen (E-PLUS-28) was opengehouden.
- Waarom
- Een jaarklant heeft meer opgebouwd dan een proefgebruiker en
verliest dus meer als de termijn verstrijkt — dat pleitte voor meeschalen. Toch één regel:
één termijn is uitlegbaar aan een klant, differentiëren niet. "Negentig dagen" staat in één
zin in de privacyverklaring en is in één query te implementeren; meeschalen levert een gesprek op
dat je niet wint ("ik heb elf maanden betaald, waarom krijg ik dan de korte termijn?") en maakt van
de bewaartermijn een variabele die overal meegedragen moet worden. Het verschil in gewicht wordt
bovendien al opgevangen door E-PLUS-30: wie meer heeft, heeft ook meer
reden om te exporteren, en de knop staat er.
Deel co-ouderschap standaard niet met de andere ouder: het zijn twee aparte huishoudens, elk met eigen gegevens.
- Herkomst
- Eigenaar, 6 augustus 2026 · beantwoordt de vraag die ontstond bij de
herziening van E-PLUS-20 (de accountgrens): hoort een ex-partner bij het
huishouden met een eigen account?
- Waarom
- Nee. De co-ouderschapsmodule beschrijft perioden binnen
één huishouden — bij wie de kinderen wanneer zijn — en de andere ouder doet daar niet aan mee. Twee
gescheiden ouders zijn twee huishoudens met eigen gegevens, en dat is ook wat de gegevenslaag
vandaag afdwingt: alles leeft binnen één huishouden en één RLS-scope. Synchronisatie tussen die twee
is toekomstmuziek en nadrukkelijk niets voor nu.
Dit bevestigt de accountgrens. De module draait volledig binnen één huishouden en
maakt dus geen tweede account aan. De alleenstaande ouder uit het scenario bij
E-PLUS-20 blijft daarmee Solo, óók als ze co-ouderschap gebruikt —
precies de uitkomst die de herziening moest opleveren. Er is geen pad waarlangs het gebruik van deze
module iemand ongemerkt naar Gezin duwt.
Aandachtspunt voor later — geen eis, en er wordt nu niets voor gebouwd. Zou
er ooit synchronisatie tussen twee huishoudens komen, dan is dat een wezenlijk ander model:
gegevens delen over de grens van een huishouden én van een RLS-scope heen, terwijl vandaag alles
binnen één huishouden leeft. Zorg dat het huidige ontwerp dat niet per ongeluk onmogelijk maakt, maar
bouw er nu niets voor — geen kolom, geen vlag, geen "voorbereidend" veld. En als het er ooit komt:
zoiets vraagt bewuste, wederzijdse instemming van beide ouders en mag nooit standaard
aanstaan. Het gaat over mensen die uit elkaar zijn; een deelstand die per ongeluk aan staat is
daar geen ongemak maar een echt probleem.
De gratis modules zijn er tien, niet negen: Lijstjes hoort in de opsomming.
- Herkomst
- Eigenaar, 6 augustus 2026 · gesprek. Sluit OV-4 van het domeinenstuk, dat
de vraag stelde of het weglaten van Lijstjes bedoeld was of een omissie.
- Waarom
- Het freemium-besluit somde er negen op: Vandaag, Taken, Agenda,
Boodschappen, Maaltijden, Verjaardagen, Schoolvakanties, Afvalkalender, Bewaarlijsten. Lijstjes
ontbrak, en dat kán niet kloppen: hij staat in
kCoreSurfaceModuleIds
(lib/core/modules/module_registry.dart:14-19), staat dus voor ieder lid altijd aan,
heeft geen activatie-schakelaar en is met E-MOD-12 uitdrukkelijk
kern. Een module die je niet kunt uitzetten, kun je ook niet verkopen. De lijst miste
een regel.
Dit is een correctie van een telling, geen herverdeling van tiers. Er verhuist
geen enkele module van Plus naar gratis of andersom. De tier-grens zelf — cloud-sync, gezinsdeling en
álle AI zijn Plus — blijft precies waar hij lag.
Nageteld in de code. Precies vijf registry-modules dragen
tier: ModuleTier.free: bewaarlijsten
(lib/features/bewaarlijsten/bewaarlijsten_module.dart:35), schoolvakanties
(lib/features/gezin/gezin_module.dart:91), verjaardagen (:101),
afvalkalender (lib/features/planning/planning_module.dart:96) en
maaltijden (:124). Daarbij de vier kernoppervlakken — Taken, Agenda,
Lijstjes en Boodschappen — en de tab Vandaag: 5 + 4 + 1 = 10.
Let op de noemer: de tien en de registratietelling meten niet hetzelfde. Vandaag,
Taken, Agenda en Lijstjes zijn géén ModuleDescriptors, dus ze komen niet voor in een
telling over de registry. Na E-MOD-12 verschuift Boodschappen wél naar de
registry, en dan luidt dezelfde tien anders opgeteld: zes gratis registry-modules (de vijf
hierboven plus Boodschappen), drie kernoppervlakken (Taken · Agenda · Lijstjes) en de tab
Vandaag — nog steeds tien. Van de 29 modules uit E-MOD-13 zijn er dan zes
gratis en 23 Plus. Wie die twee tellingen naast elkaar legt zonder de noemer erbij te zeggen,
ziet een tegenspraak die er niet is.
Waarom dit meer is dan een cijfer
Elke plek waar "negen" blijft staan, is een plek waar iemand Lijstjes achter Plus zet
De opsomming wordt overgenomen — in een brief, in een seed, in een galerijfilter. Voor de
dashboardseed maakte het concreet uit: onder de letterlijke lezing van
E-WID-10 telt Lijstjes mee als "aangezette gratis module" en zou hij een
widget krijgen. Dat is precies één van de drie lijstkaarten die
E-WID-19 uit de startstand houdt — niet omdat Lijstjes niet gratis is, maar
omdat drie keer dezelfde kaartvorm als een fout leest. De twee besluiten hangen samen en
spreken elkaar niet tegen: Lijstjes is gratis én staat niet op het verse bord.
En één plek in de code loopt hier al op achter: de doc-comment bij
ModuleDescriptor.tier (lib/core/modules/module_descriptor.dart:124-127)
beschrijft de gratis kern als "Agenda/Taken/Vandaag/Boodschappen" — zonder Lijstjes. Dat is dezelfde
omissie, en hij hoort in het pakket dat Boodschappen zijn descriptor geeft.
Gebied 8
Bewust niet gekozen
Een register dat alleen de gekozen richting bevat, lokt dezelfde discussie opnieuw uit.
Dit zijn de opties die zijn afgevallen, met de reden — zodat een voorstel dat er weer op uitkomt eerst
langs deze redenen moet.
De dubbele knop: twee losse cirkels in het midden van de tabbalk
De + verlaat het exacte midden en schuift ongeveer 62 px naar links, terwijl dat de
enige weg naar snel vastleggen is — je krijgt een chatscherm terwijl je iets wilde opschrijven. Er
ontstaat een dode zone tussen de twee knoppen waar een tik niets doet. Een tab zakt op 360 px van
72 naar 55 px, terwijl het langste label onder concept E juist "Mijn modules" wordt. En het lost het
moduleprobleem niet op, want op de 29 moduleschermen bestaat deze knop helemaal niet.
In geen enkel scenario aan te raden: duurder dan de pil op elke as die gemeten is, en levert
er niets voor terug. Zie E-NAV-10.
De gesplitste knop: één pil met twee helften (vastleggen · AI)
Dit is geen afgewezen optie meer. Hij stond hier van 5 tot 6 augustus 2026, en is op
6 augustus alsnog gekozen — zie E-NAV-10. Het item blijft staan omdat de
bezwaren die er lagen niet zijn weggewuifd maar zijn opgelost of achterhaald, en dat hoort
terugleesbaar te zijn.
Wat er stond: twee helften binnen de bestaande 72 px zijn 36 px breed, onder zowel de 48 px
van Material als de 44 pt van Apple; de middenruimte moet dus naar ~112 px en dan kost een tab ruimte
op een smal toestel. En: op moduleschermen bestaat de knop niet, dus de AppBar-actie is er alsnóg
nodig — de pil vervangt die niet, hij komt erbovenop.
Wat ermee gebeurd is. Het maatbezwaar is opgelost door variant C te kiezen in plaats van de
krappe variant: 48 × 48 px per helft (precies Material) en een middenruimte van 104 px, waarbij het
langste tablabel op 360 px net heel blijft. Het moduleschermbezwaar is achterhaald doordat de balk
mét pil op alle schermen komt — waarmee de pil de AppBar-actie niet aanvult maar
vervangt, en de AI-actie juist uit de kop verdwijnt (E-MOD-09).
N-01 — de dubbele losse knop — blijft wél afgewezen.
Swipe-navigatie: de tabbalk verdwijnt en je veegt tussen de pagina's
Frontale botsing met de app-brede rij-swipe uit TEN-138, die over acht module-families uitgerold
wordt: sleep je de rij of de pagina? Hetzelfde gebaar, twee betekenissen. Daarnaast
verliest de centrale knop zijn anker en de assistent zijn thuis, en ruil je een oriëntatie die gratis
is voor een die gebouwd moet worden. De winst — zo'n 70 px en een samenhangender gevoel — weegt daar
niet tegenop.
Kantelpunt, voor de volledigheid: zou TEN-138 worden ingetrokken, dan verdient dit een
herwaardering. Zie ook E-WID-11, waar hetzelfde conflict binnen een widget
terugkomt.
"1×1"-notatie voor widgetmaten
De rasternotatie veronderstelt dat de gebruiker het raster kent dat hij juist niet ziet — "1×1" en
"2×1" zeggen niemand iets. Ook "klein / breed / groot" is afgewezen, want dat dekt de hoogte niet.
Zie E-WID-01.
Taken verliest zijn eigen tab
In het oorspronkelijke voorstel zou Taken de tabpositie afstaan en via Vandaag, het springboard en een
widget bereikbaar blijven. Afgewezen: dat kost élke gebruiker een tik per bezoek aan het drukst
gebruikte oppervlak van de app, permanent, en het levert alleen ruimte op voor iets waarvan nog
bewezen moet worden dat het een tabpositie verdient. De vrijgekomen positie komt van de Assistent.
Zie E-NAV-03.
De vergelijking van de drie alternatieve routes blijft wél bruikbaar — maar dan als meetlat voor
Dashboard, niet voor Taken. Dat Taken met E-NAV-20 naar plek 4
verhuist, is iets anders dan deze afwijzing: hij verliest daar geen tab, hij staat ergens
anders.
Blijft afgewezen, ook na 6 augustus 2026 — maar lees de grens goed. Op die dag is beslist dat
de gebruiker vanaf fase 4 positie 4 met een andere module mag vullen, en dan is Taken van
zijn balk. Dat is geen herroeping van deze afwijzing: die ging over de standaardstand,
waarin élke gebruiker de tik betaalt. Een gebruiker die zelf kiest, betaalt hem bewust, en
E-NAV-06 houdt Taken via drie wegen bereikbaar. Tot fase 4 ligt positie 4
sowieso vast op Taken. Zie E-NAV-03 en E-NAV-14.
Alleen-lezende widgets
Het ontwerpstuk adviseerde "widgets tonen, ze doen niet" — goedkoper te bouwen, geen gebaarconflict,
geen rechten-check per rij. De eigenaar heeft anders beslist: een dashboard waar je niets kunt
afvinken of toevoegen, is een dashboard niet waard. Zie E-WID-03, en neem de
prijs mee die daar staat.
Het sleepgebaar als enige manier om een map te maken
Elegant en onvindbaar tegelijk: je moet weten dat het bestaat, precies genoeg richten, en het werkt
alleen in een stand die je ook al moet ontdekken. Voor iets dat een randvoorwaarde is, te dun. Het
gebaar blijft wél bestaan — als tweede weg. Zie E-MOD-01 en
E-MOD-02.
Een schakelaar "op mijn dashboard" per module
De app kent al drie betekenissen van aan/uit (aan voor het gezin, aan voor jou, op je beginscherm).
Een vierde erbij maakt van elke module-instelling een puzzel. Het dashboard vult zich uit de galerij
en uit de startstand, niet uit een schakelaar in een instellingenblad of in het lang-indrukmenu.
Dit is in het ontwerpstuk als niet-onderhandelbaar aangemerkt.
Pagina's op het springboard (horizontaal bladeren tussen tegelpagina's)
Een tweede horizontale gebaar-as op hetzelfde scherm is er één te veel. En een module op pagina 3 is
onvindbaar zonder zoeken — met zoeken is de winst van de pagina-indeling weg. Mappen doen hetzelfde
werk zonder een nieuw gebaar. Zie E-MOD-01.
Een vaste bovengrens van twee widgets per module op één dashboard
Voorgesteld in TEN-179 met het argument dat twee nuttig is (Taken als paneel én als telling) en drie
"verzamelen" wordt. Afgewezen: wie vijf lijsten heeft, wil vijf lijstwidgets, en er is geen technisch
bezwaar dat die grens rechtvaardigt. Wat er in de plaats komt is smaller en beter te verdedigen — de
exacte dubbeling wordt tegengehouden, want twee widgets die letterlijk hetzelfde tonen zijn
altijd een vergissing. Zie E-WID-14.
Een permanente proefteller op Vandaag ("Nog 7 dagen Plus-proef · Regel het nu")
Voorgesteld in het Plus-ontwerpstuk §3 als de manier om de proefperiode zichtbaar te houden. Afgewezen
door de eigenaar op 6 augustus 2026, en het argument is sluitend: bij een automatisch verlengend
abonnement met introductieaanbieding is de gewenste uitkomst dat de proef omzet in betaald. Een
dagelijkse teller met "regel het nu" leest dan als een uitnodiging om op te zeggen — een
churn-herinnering vermomd als service. Hij nodigt bovendien veertien dagen lang uit om over de kosten
na te denken, vóórdat iemand waarde heeft opgebouwd: je vraagt om de beslissing op het zwakste moment
dat er is.
Dezelfde afwijzing geldt voor de variant die alleen tijdens een lopende proef aftelt: het verschil
tussen werven en aftellen zit in de motivering, niet in wat de gebruiker elke ochtend ziet. Wat er
wél mag verschijnen staat in E-PLUS-15 t/m
E-PLUS-17, en ná een daadwerkelijke opzegging in
E-PLUS-25. Zie E-PLUS-14.
"De expliciete widgetkeuze wint": een dashboardwidget blijft zijn verborgen lijst tonen
Dit was het voorstel in ADR-0022 — uitdrukkelijk als voorstel opgeschreven, niet aan de
eigenaar voorgelegd, en niet stilzwijgend in te vullen. De redenering luidde: verbergen is een
voorkeur van de kijker, maar de widget is een expliciete keuze van diezelfde kijker, dus die
latere, specifiekere keuze zou moeten winnen.
Afgewezen door de eigenaar op de avond van 6 augustus 2026. Het besluit is het
tegenovergestelde: verbergen wint, en de widget rendert zijn lege staat. Waarom het voorstel
het niet haalt: het maakt van één schakelaar twee betekenissen. Iemand die een lijst uit zijn
overzicht haalt, verwacht hem weg — niet weg op de ene plek en aanwezig op de andere, met een
volgorde-afhankelijke uitkomst die niemand kan uitleggen ("wanneer heb je die widget ook alweer
neergezet?"). Eén schakelaar, één effect. Bovendien is het de veilige faalrichting: verborgen dingen
zijn vaak verborgen omdat je ze niet wilt zien.
Wat het niet is: de instantie wordt niet opgeruimd. De widget blijft staan met zijn lege
staat, precies zoals bij een lijst die verdwijnt of ontdeeld wordt — daarmee is er één gedrag voor
alle drie de gevallen in plaats van drie. Zie E-WID-16,
E-OPS-03 en ADR-0022.
De twee andere uitwegen uit de kernuitzondering: hem versmallen, of het taakgat ongepoort laten
De sectie-audit legde drie uitwegen voor uit het probleem dat de Vandaag-schakelaars van
E-VDG-08 op kernmodules niets kunnen doen. Gekozen is de eigen sleutel;
de andere twee zijn afgewezen, met reden.
(b) De kernuitzondering beperken tot route en springboard, zodat hij niet meer voor de
Vandaag-poort geldt. Dan is "kernmodule" niet langer één begrip maar een begrip met een
uitzonderingslijst per oppervlak — precies het soort regel dat over een half jaar niemand meer
volledig kent. En het verandert de betekenis van een bestaande, geteste poort in plaats van er een
nieuwe vraag naast te zetten.
(c) Het taakgat ongepoort laten en het opruimpakket laten krimpen. Dat lost niets op: de
signalenschakelaar blijft dan op dat gat een dode knop, en er staat een test die dat niet betrapt.
Een schakelaar die zichtbaar is en niets doet, is erger dan geen schakelaar.
Zie E-VDG-08 en E-MOD-12.
De drie andere domeinindelingen: de tien laten staan, alleen de eenlingen opruimen, of terug naar vier
Bij E-MOD-13 lagen vier indelingen voor. Gekozen is het opnieuw snijden tot
zes; de andere drie zijn afgewezen, met reden.
(A1) Laat de tien staan en geef Boodschappen alleen een domein. Bijna gratis — één descriptor
en geen enkel gewijzigd domein-id — maar bij de eerste opening staan er dan vier losse tegels en
tien mappen, waarvan zes met precies één ding erin en vier die heten zoals hun enige inhoud. De
eerste handeling van een zorgvuldige gebruiker is opruimen, en dat is het tegenovergestelde van wat
E-MOD-06 wil ("zodat niemand op een leeg raster start"): niet leeg, maar
rommelig. Het echte bezwaar is de onomkeerbaarheid — na de conversie zijn de mappen van de
gebruiker en mag de app er niet meer in.
(A2) Ruim alleen de eenlingen op en laat de drie grote domeinen ongemoeid. Beter dan A1: geen
map van één meer. Maar de twee echte problemen blijven staan — "Planning" wordt nóg breder (zes
dingen zonder gemeenschappelijk onderwerp) en Financieel blijft negen. En Voorraad zou dan bij
Onderhoud en Vastgoed staan in plaats van bij Maaltijden. A2 haalt de zichtbare fout weg en laat de
fout eronder staan: de indeling volgt nog steeds lib/features/ en niet de manier waarop
iemand naar zijn eigen leven kijkt.
(A4) Vier grove bakken: Gezin · Huis · Geld · Gezondheid. Kost evenveel als de gekozen
indeling en levert precies op wat je wilde vermijden: het ordeningsprobleem verhuist van het
beginscherm naar het mappaneel, waar Huis met elf tegels staat en er géén tweede niveau is om het
mee op te lossen — een map in een map bestaat niet. Vier is te grof voor 29 modules.
Zie E-MOD-13 en
het domeinenstuk, sectie 3.
De startstanden die het niet werden: alles in een map "Basis", sorteren op tier, en twee dashboardseeds
Zes afgevallen varianten uit dezelfde doorloop — drie voor het springboard
(E-MOD-14) en drie voor het dashboard
(E-WID-19). Ze staan hier omdat ze alle zes plausibel klinken.
(B1) Alles in mappen, ook de kernoppervlakken, in een map "Basis". Maximaal rustig en
volstrekt nietszeggend: zeven grijze deurtjes, en niets wat je kunt dóén is één tik ver. Taken zit
dan achter twee tikken terwijl E-NAV-06 juist drie korte wegen
belooft.
(B3) Zet ook de gratis modules los bovenaan; alleen Plus in mappen. Op dag één de beste
eerste indruk van alle varianten — en de variant met een tijdbom. De indeling wordt bevroren op
het abonnement dat je op dag één had. Koopt iemand een week later Plus, dan reorganiseert zijn
beginscherm níét, want E-MOD-10 verbiedt terecht dat de app een opgeslagen
indeling herschrijft. Hij houdt dus voorgoed een indeling waarin "los bovenaan" iets betekende wat
niet meer waar is. Bovendien is tier geen ordeningsbegrip dat een gebruiker herkent: waarom
staat Maaltijden los en Recepten in een map?
(B4) Geen startmappen: één plat raster met het zoekveld erboven. Negen rijen scrollen op dag
één — de "muur van iconen" die precies de reden was om mappen te introduceren. En het draait een
besluit terug dat al genomen is (E-MOD-06).
(C1) De letterlijke lezing van E-WID-10: acht widgets. Ruim twee
schermen scrollen op dag één, met drie lijstkaarten van dezelfde bouwsteen erin (Taken, Lijstjes,
Bewaarlijsten). Drie keer dezelfde kaartvorm leest als een fout, niet als een keuze. En bij Lijstjes
komt er een keuze bij die op dag één niet te maken is: welke lijst toont die widget, als er nog geen
lijst is?
(C3) Twee startstanden: een gratis bord en een Plus-bord. Werkt alleen voor wie Plus koopt
vóór hij de tab één keer opent; iedereen die later upgradet houdt het gratis bord, want de indeling
is opgeslagen en wordt niet herschreven. Lost dus een probleem op voor een kleine groep en
introduceert een tweede seed die voor altijd uit elkaar kan lopen. En bij een koude start met tier
"nog onbekend" moet je alsnog raden — precies wat E-PLUS-02 verbiedt.
(C4) Minimaal: drie widgets, de rest plaatst de gebruiker zelf. Drie kaartjes boven een half
leeg scherm leest als een bord dat nog moet laden, niet als een uitnodiging. Half leeg is bijna leeg,
en dat is precies wat E-WID-10 verbiedt.
Domein-id's hergebruiken met een nieuw label — en sensitive verhuizen naar de module
Hergebruik van bestaande id's met een nieuw label. De zes gebieden hadden ook gebouwd kunnen
worden op de id's die er al zijn: financieel met de naam "Geld", voorraad
met de naam "Eten". Dat is gratis — geen enkele van de 19 tekstsnaren hoeft mee en de gesyncte
sensitive_opt_in_domains_json-set blijft kloppen zonder remap. Afgewezen omdat het de
rekening doorschuift naar iedereen die de code later leest: een domein voorraad dat
"Eten" heet en Boodschappen bevat is een val die je niet ziet aankomen, en de vindbaarheid van een
grep op een domeinnaam verdwijnt volledig. Zie E-MOD-16.
sensitive verplaatsen van DomainDescriptor naar
ModuleDescriptor. Dit is de nettere architectuur — gevoeligheid is een eigenschap van
wat een module doet, niet van de map waarin hij toevallig staat — en het is precies de reden dat de
vraag opkwam: Garanties verlaat het gevoelige gebied puur omdat zijn domein wijzigt. Afgewezen
voor nu: het is meer werk, het raakt de opgeslagen opt-in-set een tweede keer, en het is geen
voorwaarde voor de herindeling. Het staat hier als overweging genoteerd, niet als opdracht — en de
aanleiding om er alsnog naar te kijken is er zodra een tweede module om dezelfde reden van
gevoeligheid verandert.