TASKS.md 79 KB

Uitgaanskrant — takenlijst

Bijgewerkt: 2026-08-13 (Claude, zelfstandige code-audit-sessie, geen builder-toegang gebruikt). Zie CLAUDE.md voor werkinstructies/conventies. Elke openstaande taak hieronder is zelfstandig te begrijpen zonder de chat gelezen te hebben waarin hij ontstond.

Deze sessie (2026-08-13, zelfstandig, code-only — geen builder-UI gebruikt omdat niet zeker was of Bob achter zijn scherm zat): twee punten uitgediept, puur via lezen/grep, geen wijzigingen aan app-code. P1-15 uitgebreid met 3 nieuw gevonden crash-plekken die niet in het eerder gedocumenteerde 5-knoppenlijstje zaten: een 6e ongegarandeerde "Menukaart"-knop in hetzelfde bestand (evenement_horecagelegenheid_widget.dart:626-635), en twee "Website"-knoppen die helemaal geen guard hebben (niet eens de kapotte) — evenement_info_widget.dart:268 (component gebruikt op de normaal bereikbare EventCurrent-pagina) en evenement_component_widget.dart:414 (alleen op de al bekende orphan- route EventWidget, zie P2-7). Ook bevestigd dat horecagelegenheid_current_widget.dart géén launchURL-aanroepen bevat — dat eerdere twijfelpunt is nu weggenomen. P1-21's punt 2 gecorrigeerd: de aanname dat lib/flutter_flow/flutter_flow_ad_banner.dart zonder builder-UI en zonder export-risico lokaal aan te passen zou zijn bleek ongeverifieerd en botst met CLAUDE.md's algemene regel over gegenereerde bestanden — teruggedraaid naar "nog op te lossen, waarschijnlijk via een eigen custom widget", niet blind uitgevoerd.

Eerdere sessie (2026-08-12, review): volledige gebruikersdoorloop op een verse build (ff-run-fvm.sh, geïnstalleerde app was nog van 2026-08-09 en dus stale t.o.v. alle fixes van 2026-08-10/11) langs de 5 gevraagde gebieden: overzichtspagina (Home), horecaoverzicht (HorecagelegenhedenOverzicht), evenement (EventCurrent + EvenementHorecagelegenheid), pagina (PUitgaanPage) en horecagelegenheidpagina (HorecagelegenheidCurrent), gecombineerd met een code-audit van diezelfde bestanden. 4 nieuwe bevindingen toegevoegd: nieuwe P0-7 (horecagelegenheid-infodata blijkt structureel leeg — bevestigd op 2 verschillende gelegenheden, geen toeval), nieuwe P1-20 (Home's al-verwijderd-gewaande terugknop is terug via een hergebruikt component en blokkeert soms de hamburger), nieuwe P1-21 (AdBanner op PUitgaanPage toont developer-debugtekst aan echte gebruikers), nieuwe P1-22 (decodeUtf8: false op alle API-calls → emoji in Drupal-content worden ?-tekens). P1-19 uitgebreid met 8 nieuw gevonden zusterinstanties van hetzelfde "kale Row zonder Wrap"-categorietag-patroon, nu bevestigd op exact de pagina's uit deze review (Home, PUitgaanPage, EventCurrent, HorecagelegenheidCurrent). P1-13 live herbevestigd — nog steeds kapot (1529px-overflow op de Activiteiten-tab), geen voortgang t.o.v. 2026-08-10. Zie de individuele taken hieronder voor bewijsvoering (screenshots/log-regels/broncoderegels).

Eerdere sessie (2026-08-10, avond): live pair-sessie — Bob deed alle builder-edits zelf, Claude gaf per punt de exacte stappen en verifieerde daarna elke edit met een verse flutterflow export-code

  • grep (niet op de builder-UI zelf vertrouwd). 9 taken écht afgerond en bevestigd: P1-18 (login-crash + de daaropvolgende success-check-bug), P0-1, P0-3 (beide restpunten — punt 2 uiteindelijk simpeler opgelost dan gepland: HeaderButtonsComponentWidget() hergebruikt op EventCurrent i.p.v. de logica te dupliceren), P1-3, P1-9's schaduw-restpunt, P1-1 (alle 4 sub-punten), P1-12 (opgelost via een Visibility-guard op de rauwe horecaid-parameter, netter dan de oorspronkelijk voorgestelde Default Value). Belangrijke bevinding: minstens 2x deze sessie leek een builder-edit in de UI geslaagd ("Confirm" gedaan, geen foutmelding) maar bleek bij een verse export toch niet doorgezet (P0-3 punt 1 ooit eerder, en een eerste P1-15-poging vanavond) — elke afgeronde taak in een levende sessie nu standaard verifiëren met een verse export vóór 'm als klaar te beschouwen, niet op de UI-status alleen vertrouwen. P1-15 blijft open (5 social-knoppen op EvenementHorecagelegenheid) — eerste poging bleek bij export niet toegepast, Bob gaat hier zelfstandig mee verder.

Eerdere sessie (2026-08-10, middag): twee taken opgepakt. P2-9-bijvangst (dode terug-knop Home) volledig afgerond — Remove Widget-actie, bevestigd via verse export. P1-13: builder-fix uitgevoerd (Expanded+Shrink Wrap uit+Scrollable aan op de StaggeredView-node) maar niet doorgezet naar de export ondanks correcte builder-UI-status ("Synced", geen foutmelding, blijft staan na reload) — bevestigd met 3 onafhankelijke verse flutterflow export-code-runs. Sanity-check bevestigt dat de exportpijplijn zelf werkt (P0-6/P2-9 tonen wél correct) — dit lijkt een specifiek sync-probleem bij deze property-combinatie, zie P1-13 voor het volledige verslag en het verzoek aan Bob om zelf te verifiëren.

Vorige sessie (2026-08-09, avond): twee taken opgepakt. P1-19: builder-fix geprobeerd (Row → Wrap Widget), maar de menu-klik registreerde niet (4 pogingen, geen schade) — teruggegeven aan Bob met exact stappenplan. P1-13: eindelijk de al maanden gezochte volledige stack trace gevangen (nieuwe flutter run --route-truc omzeilt de race met Home's eigen overflow) — root cause nu hard bevestigd (niet-scrollbare MasonryGridView in een kale Column) + concreet fix-voorstel, builder-uitvoering nog open. Bijvangst: een tweede, nog niet eerder gedocumenteerde instantie van P1-19's "kale Row/Column zonder Wrap"-bugfamilie gevonden op PUitgaanSliderKaartComponent:179.

Vorige sessie (2026-08-09, middag): eerste sessie met mcp__android__*- toegang tot beide emulators (i.p.v. alleen losse adb-Bash-commando's) — P0-6 afgerond (5 debug-knoppen op Login verwijderd, builder + export/build + live geverifieerd op telefoon én tablet). Sub-bevinding (hintText-placeholder) blijft open, geblokkeerd op paneel-clipping. P1-17 opnieuw onderzocht en root cause herbevestigd, maar de voorgestelde "Engels weghalen"-fix is door Bob afgewezen — Engels moet beschikbaar blijven; taak blijft open in andere vorm (zie daar).

Deze review-sessie (2026-08-07, middag+avond): volledige doorloop van open taken + code-audit, plus een live "ogen van een gebruiker"-doorloop op de emulator (ná herstart van Bob's desktop/ Android-VM wegens een OOM — app opnieuw opgestart via de standaard ff-run-fvm.sh-workflow, daarna pm clear om een echte eerste-launch-ervaring te simuleren). Concrete live vondsten: zie nieuwe P0-6 (test-navigatieknoppen zichtbaar op de productie- Login-pagina — grootste vondst van de sessie), P1-17 (Engelse locale-fallback + vrijwel geen echte vertalingen), aangevulde P2-9 (onboarding + dode terug-knop op Home, nu live bevestigd i.p.v. ingeschat) en P1-15 (scope groter dan gedacht). Kanttekening: de emulator vertoonde ook wat omgevingsinstabiliteit (kort een "System UI isn't responding"-melding vlak na herstart, en flutter run verloor op een gegeven moment de verbinding met het device) — dat lijkt eerder aan de verse VM-herstart/host-belasting te liggen dan aan de app zelf, dus niet 1-op-1 als app-bug behandelen, maar wel vermeld voor het geval het patroon terugkomt.

Formaat van elke taak: **P0-1 · Eigenaar: ...** als eerste regel — een stabiel nummer (verandert niet als andere taken worden afgerond/verwijderd) + wie 'm oppakt. Volgorde binnen elke prioriteit = geschatte ernst/impact, hoogste eerst.

Eigenaar-waarden:

  • Bob — sneller/simpeler voor hem zelf (meestal builder-UI met een bekend fragiele dialoog, zie CLAUDE.md).
  • Claude — zelfstandig/via browser-automation te doen, nog onbeklaimd.
  • Claude — bezig (sessie ) / Bob — bezig — een sessie/persoon is hier nu actief mee bezig.
  • Onbepaald — nog geen eigenaar gekozen.
  • ⚠️ Voorkom dubbel werk: Bob start elke taak in een nieuwe, aparte chat — er kunnen dus meerdere sessies tegelijk actief zijn op hetzelfde project. Voordat je een taak oppakt: check of de Eigenaar-regel al "— bezig" zegt. Zo ja: niet zelfstandig ook gaan zitten werken aan hetzelfde bestand/component — vraag Bob eerst wie 'm afmaakt (dit gebeurde op 2026-08-04: twee sessies pakten onafhankelijk P0-2 op; Bob moest scheidsrechteren). Zet zelf "— bezig" in de Eigenaar-regel zodra je serieus aan een taak begint, en haal het weer weg (of verwijder de taak, zie hieronder) zodra je stopt.

    Afronden: een volledig afgeronde taak wordt verwijderd uit deze lijst (niet gearchiveerd). Bij gedeeltelijke voortgang: taak laten staan met bijgewerkte inhoud die alleen het resterende werk beschrijft.

    Modelkeuze: Haiku vs Sonnet

    Korte conclusie (2026-08-05, beoordeeld): niet standaard overschakelen op Haiku voor dit project. Bijna elke Claude-taak hier eindigt als een FlutterFlow-builder-interactie (Bob kan zelf geen code bewerken, zie CLAUDE.md), en die builder is canvas-gerenderd Flutter Web zonder normale DOM/accessibility-tree. Dat botst met precies Haiku's zwakke kant: geduldig multi-stap troubleshooten (scroll-pogingen, DOM/shadow-DOM-zoektochten, accessibility geforceerd activeren, herkennen van een "Discard changes?"- dialoog, op tijd stoppen na 1-2 pogingen i.p.v. blijven klikken of per ongeluk een Delete-knop raken). Zelfs taken die er triviaal uitzien (bv. P1-10's cache-toggle: 1 klik + Confirm) bleken pas na 6+ verschillende technieken écht geblokkeerd op een clipping-bug — dat vraagt het uithoudingsvermogen/verstand van Sonnet om zowel de pogingen als het op tijd stoppen goed te doen.

    • Wel Haiku-geschikt — puur lezen/greppen/samenvatten, geen builder-UI, geen destructief risico:
      • De audit-/verificatiestappen die dit bestand al vaak gebruikt om "open" vs "al gefixt" te bevestigen (git log -S"...", gerichte grep) — zie de vuistregel hierboven over verouderde taakstatus.
      • Live emulator-checks (app draaien, deep link/navigatie, scherm/ logs checken) — geen builder-bewerking. Kanttekening (2026-08-05): de eerder als "laag risico, duidelijk slagingscriterium" ingeschatte P1-8-check bleek bij uitvoering juist 2 échte crashes op te leveren (zie P1-1 punt 4 en de nieuwe P1-12) — het navigeren/screenshotten zelf is Haiku-geschikt, maar de opvolging (stacktrace naar exacte broncoderegel herleiden, onderscheid maken tussen "al bekend probleem" en "nieuwe bug", inschatten of normaal gebruik geraakt wordt) vroeg meer redeneerwerk dan verwacht — bij een crash-bevinding op zo'n check de opvolging liever alsnog met Sonnet doen.
    • Niet Haiku-geschikt (Sonnet aanhouden): elke taak die een builder-widget/-property wijzigt (vrijwel alle overige P1/P2-taken), en taken die ontwerpkeuze/afweging vragen zoals P1-9 en de P2-features (P2-2 t/m P2-6, P2-8) — geen mechanisch patroon, dus geen goede Haiku-fit.

    P0 — blokkeert livegang

    (P0-6 volledig afgerond 2026-08-09 avond, incl. hintText-restpunt — door Bob zelf gedaan in de builder, geverifieerd via verse flutterflow export-code: keys d507d3b9/t8h5f8ir in internationalization.dart staan nu op nl: 'E-mailadres'/en: 'Email address' resp. nl: 'Wachtwoord'/en: 'Password'. Uit deze lijst verwijderd.)

    (P0-1 afgerond 2026-08-10 avond — Bob, builder, bevestigd via verse export: HomeUitgaanSliderComponent toont nu if (homeslider.isEmpty) { return Image.asset('assets/images/logo800px.png'); } vóór de Carousel gebouwd wordt. Uit deze lijst verwijderd.)

    (P0-3 afgerond 2026-08-10 avond — Bob, builder, beide restpunten bevestigd via verse export. Punt 1: Flexible(child: Text(...)) staat nu om de gemeente-/provincienaam in HeaderButtonsComponent. Punt 2: eenvoudiger opgelost dan gepland — i.p.v. losse If/Then/Else-logica op EventCurrent na te bouwen (waar Claude eerder 5x vastliep) is de hele losse AppBar-Row daar vervangen door een instantie van de gedeelde HeaderButtonsComponentWidget(), die de naam-logica al bevat. Het laag-risico restpunt (default-locatie 28666/28694 toont nog geen naam bij allereerste app-start) staat als bijvangst bij P2-7 hieronder. Uit deze lijst verwijderd.)

    P0-4 · Eigenaar: Bob. Werkende login + favorieten — resterende deeltjes. Basis is af: login gekoppeld, wachtwoord-vergeten-flow, favorieten drawer-link + 3-tabblad-pagina, hartje op horeca-kaart + -detailpagina. Nog open:

    • Lege-lijst empty-state op de favorietenpagina (nu kale/lege Container als er nog geen favorieten zijn). lib/favorieten/favorieten_widget.dart.
    • Bevestigen dat favorieten écht syncen via Drupal bij inloggenroot cause gevonden + gefixed (Claude, 2026-08-09), zie P1-18. De eerder aan Cloudflare Bot Management toegeschreven "FavorietenAgenda 403-fout" (lege Cookie-header bij FlutterFlow- requests) bleek gewoon het gevolg van de login-sessie die nooit werd opgeslagen — niets met Cloudflare/IP-reputatie te maken. Live bevestigd met testaccount bobcity op emulator: na de fix geeft flutterfavorietenagenda.json status 200 + geldige Cookie/X-CSRF-Token-headers + echte data i.p.v. de eerdere lege/anonieme 403. Kan hiermee als afgerond beschouwd worden zodra Bob dit ook zelf in de FavorietenAgenda-flow (niet alleen de kanweg-testpagina) bevestigt.

    P0-5 · Eigenaar: Bob. Drupal: anonieme leestoegang onderzoeken voor browse-endpoints. Drupal-niveau, geen Claude-taak. Bijvangst 2026-08-12 (Claude, code-audit): alle API-calls in api_calls.dart (o.a. EstablishmentInfoCall, EstablishmentsCall) sturen een hardcoded Basic-Auth-header mee (Authorization: Basic Ym9iOnNlcmhpaQ==, decodeert naar bob:serhii) — dit staat letterlijk in de gecompileerde APK en is dus met een gratis decompiler (bv. jadx) door iedereen uit te lezen. Verduidelijkt door Bob (2026-08-12): dit account is alleen nodig voor de devbob.uitgaanskrant.com-omgeving (dev/staging zit achter een username/wachtwoord-poort) — tegen de productie-URL (uitgaanskrant.com, wat de app daadwerkelijk aanroept) doet de header niets schadelijks, geeft geen foutmelding, is dus effectief dood gewicht daar. Praktisch gevolg: minder urgent dan eerder ingeschat (geen live-productie-credential-lek), maar nog steeds het opruimen waard — een onnodige hardcoded header die alsnog een dev-omgevingswachtwoord blootlegt zodra iemand de APK decompileert, en die zonder functie is zodra de app alleen tegen productie draait.

    P0-7 · Eigenaar: Bob (Drupal-niveau — root cause bevestigd server-side, geen Claude/app-taak). Horecagelegenheid-infodata (titel/inhoud/logo) komt structureel niet aan — bevestigd 2026-08-12 op een verse build, live op 2 verschillende gelegenheden (niet 1 incident). Root cause definitief bevestigd (2026-08-12, Claude, directe curl op de Drupal-endpoint, buiten de app om): het endpoint achter EstablishmentInfoCall (https://uitgaanskrant.com/en/flutterdrup/views/flutterflowmobiel_establishment_info.json?display_id=services_1&nid=<nid>, lib/backend/api_requests/api_calls.dart:907-908) geeft voor elke geteste nid een HTTP 500 terug (Drupal's generieke "The website encountered an unexpected error. Please try again later."-pagina, geen JSON) — getest met 3 verschillende echte nid's uit de live establishments-lijst (91142 = De Beun, 91140 = Hotel Den Helder, 58844 = Brasserie Veldt), allemaal 500. Ook geprobeerd met /nl/ i.p.v. /en/ als taalprefix (de andere API-calls in dit project gebruiken allemaal /nl/ — dit ene endpoint wijkt af) en zonder taalprefix: blijft 500, dus de taalprefix-inconsistentie is niet de oorzaak (wel een aparte kleine inconsistentie om ooit recht te trekken). De app-kant (getJsonField/valueOrDefault/JSONPath) doet exact wat hij moet doen met een kapotte respons: stil terugvallen op de design-time placeholder — dit is dus geen Flutter/FlutterFlow-bug, het is een kapotte Drupal Views-display (services_1 op de flutterflowmobiel_establishment_info-view). Fix zit aan Drupal-kant: de Drupal-watchdog/PHP-errorlog raadplegen voor de exacte exceptie (productie toont geen foutdetails naar buiten, dus die is alleen server-side te vinden) — vermoedelijk een kapotte Views-relatie/veld sinds een eerdere wijziging aan het content-model (bv. de recente favorieten/media-uitbreidingen). Bijvangst tijdens het testen: de establishments-lijst-endpoint (EstablishmentsCall) werkt zelf prima — dat verklaart ook waarom de "events op deze locatie"-carousel op dezelfde pagina wél goede data toont: die gebruikt een ander, werkend endpoint.

    Live bevindingen in de app zelf (2026-08-12, symptoombeeld — de root cause hierboven is inmiddels het echte aanknopingspunt, dit is puur de zichtbare impact):

    • HorecagelegenheidCurrent (horecagelegenheidpagina, bereikt via HorecagelegenhedenOverzicht → kaart tikken): zowel bij "De Beun" (Heiloo) als "Hotel Den Helder" bleef de infosectie permanent (8+ seconden gewacht, geen verandering) op de letterlijke design-time placeholders staan: kop toont "title", body toont "content", logo toont een kapot-plaatje-icoon (rode driehoek). Dit zijn dezelfde velden als P1-6's al gedocumenteerde horecagelegenheid_current_widget.dart:377/500/747 (titel/logo/content) — maar dit weerlegt P1-6's aanname dat het om incidentele ontbrekende data gaat: het gebeurde bij beide geteste gelegenheden, terwijl een ándere sectie op diezelfde pagina (de "events op deze locatie"-carousel onderaan) voor "Hotel Den Helder" wél gewoon echte, gelegenheid-specifieke data toonde. Een betere Default-Value-tekst (P1-6's voorgestelde fix) verhelpt dus niets hier — de onderliggende data komt al niet aan.
    • EvenementHorecagelegenheid (embedded op EventCurrent, bv. bij evenement "Mythic Fest II", nid 214370, alleen zichtbaar als het evenement een horecaid heeft): toont "HorecaNaam" (letterlijke fallback-tekst, niet ingevuld) i.p.v. een echte gelegenheidsnaam, plus een forse layout-overflow. In de flutter run-log verschijnen hierbij herhaaldelijk (in bursts van 3, telkens gelijktijdig met deze sectie):

      Another exception was thrown: RangeError (length): Invalid value: Valid value range is empty: 0
      Another exception was thrown: A RenderFlex overflowed by 109 pixels on the bottom.
      Another exception was thrown: Invalid argument(s): No host specified in URI Logo
      

      Geen volledige stack trace gevangen deze sessie (het "1x volledige dump per proceslevensduur"-limiet, zie CLAUDE.md, werd al verbruikt door Home's eigen overflow vóór deze pagina bereikt werd; een gerichte herhaling met --route "/eventCurrent?nid=214370&horecaid=<echte id>" ná een schone process-start zou de exacte regel moeten opleveren — nid 214370 zonder horecaid reproduceert de crash niet, dus de volgende poging heeft een evenement met een wél ingevulde horecaid nodig, bv. via de widget-tree of een gerichte API-check welk evenement een horecaid heeft).

    • Twee eerder overwogen app-side kandidaat-oorzaken zijn met de curl-test hierboven uitgesloten (voor de volledigheid, om te voorkomen dat een volgende sessie ze opnieuw onderzoekt): het is niet een JSONPath/response-vorm-mismatch in EstablishmentInfoCall, en niet de getJsonField(item, r'''$.nid''').toString()-constructie in de overzicht-kaart-navigatie (horecagelegenheden_overzicht_page_data_type_widget.dart:397-403 e.v.) die een null-veld als de string "null" zou doorgeven — de geteste nid's (91142/91140/58844) waren stuk voor stuk gewoon geldig (bevestigd via de werkende establishments-lijst), en de endpoint faalde alsnog voor alle drie. P0 omdat dit een kernpagina raakt (horecagelegenheidpagina) die voor iedere bezochte gelegenheid vrijwel leeg oogt voor een eindgebruiker.

    Drupal dingen — verzamellijst, batchen bij Bob's eigen Drupal-sessie

    Eigenaar: Bob. Bob's voorkeur (2026-08-13): kleine builder-fixes die toch al wachten op ander Drupal-werk hier verzamelen i.p.v. los oppakken — dan in één builder-bezoek samen met de Drupal-kant afhandelen.

    • Hartje-icoon op de horecagelegenheid-detailpagina (hoort bij P1-7 stap 3, component HorecagelegenheidCurrent): de If-tak (favoriet) van de ConditionalBuilder rond IconButtonFavoriet toont nog Icons.favorite_border i.p.v. het gevulde Icons.favorite, en Fill Color staat op Color(0x0AFFFFFF) i.p.v. wit (zoals de Else-tak). Functioneel al correct (Remove/Add-acties kloppen, bevestigd via export 2026-08-13) — puur cosmetisch restpunt.
    • P1-7 Tab 3 "Favoriete Gelegenheden" kan nog niet gebouwd worden met de bestaande API-calls — blokkeert op P0-7. EstablishmentInfoCall (bedoeld om 1 gelegenheid op te halen via nid) geeft server-side HTTP 500 voor elke nid (zie P0-7, root cause al bevestigd Drupal-kant). EstablishmentsCall (de wél werkende lijst-endpoint) filtert alleen op categorie+plaats (horcat/townid) en heeft geen nid-filter, dus ongeschikt om een specifieke set favoriete nid's op te halen. Nodig: óf P0-7's Drupal-500 fixen (dan is EstablishmentInfoCall weer bruikbaar per nid in een loop), óf een nieuwe Drupal-view die een lijst van meerdere specifieke nid's in 1 call teruggeeft (efficiënter dan N losse calls per favoriet). Claude: geen builder-stappen voor Tab 3 geven vóórdat dit is opgelost — een eerdere instructie deze sessie (2026-08-13) om EstablishmentInfoCall te gebruiken voor Tab 3 was hierdoor fout, tijdig gecorrigeerd vóór uitvoering.

    P1 — snel na livegang

    (P1-18 afgerond 2026-08-10 avond — Bob, builder + Custom Code, in twee stappen. Root cause was een dubbele bug: (1) login_widget.dart behandelde het drupalLogin-resultaat als bool i.p.v. een JSON-map → crashte altijd; (2) de eerste conditie-fix checkte alleen "is $.success aanwezig" i.p.v. de waarde, wat altijd waar was (het veld zat er sowieso in, bij succes én bij falen). Uiteindelijke oplossing — op Bob's eigen voorstel — was simpeler dan een aparte Custom Function: drupal_login.dart retourneert nu null bij een mislukte/foute login i.p.v. een {success: false, ...}-map, en de knop's conditie is teruggebracht tot een simpele, echte null-check (_model.resultDrupalLogin != null, operator "Is Set" op de hele actie-output, geen JSON Path meer nodig). Bevestigd via verse export. Het losse debug-dialoogje (AlertDialog "melding" met de rauwe JSON) is blijven staan — niet meegenomen in deze fix, kan later nog opgeruimd worden als cosmetische bijvangst. Uit deze lijst verwijderd.)

    (P1-1 volledig afgerond 2026-08-10 avond — Bob, builder, alle 4 sub-punten bevestigd via verse export: HomeUitgaanSliderComponent (= P0-1), PUitgaanSliderComponent, EvenementComponent, horecagelegenheidCurrent tonen nu allemaal if (<lijst>.isEmpty) { return Image.asset('assets/images/logo800px.png'); } vóór hun Carousel gebouwd wordt. Uit deze lijst verwijderd.)

    (P1-3 afgerond 2026-08-10 avond — Bob, builder, bevestigd via verse export: Flexible(child: Text(functions.kortDatum(widget!.datum))) staat nu op "Text-datum" in PUitgaanSliderKaartComponent. Uit deze lijst verwijderd.)

    P1-4 · Eigenaar: Bob. EstablishmentsCall crasht zonder categoriefilter. horcat ??= null!; — bevestigd nog aanwezig, regel

    1. Nu geen probleem omdat elke aanroep toevallig altijd een filter meegeeft, wel een landmijn voor de toekomst. lib/backend/api_requests/api_calls.dart. Fix zit vermoedelijk in de FlutterFlow API-call-configuratie (default parameterwaarde), niet in lokale code.

    P1-5 · Eigenaar: Bob. "Thuis bezorgen" koppelen aan een echt leverbaar-veld per horecagelegenheid. Wacht op Bob: eerst het API-endpoint aan Drupal-kant configureren. Daarna tonen/verbergen op basis van het echte veld i.p.v. de huidige dode tap.

    P1-6 · Eigenaar: Bob (mechanisch, maar groot — spreid over sessies). Letterlijke veldnaam i.p.v. nette placeholder bij ontbrekende data. 2026-08-05: audit herhaald (Claude, verse grep) — scope flink groter dan de eerdere 13 treffers van 2026-08-04, met name evenement_horecagelegenheid_widget.dart bleek nog niet meegenomen. Patroon overal hetzelfde: valueOrDefault<String>(<bron>, '<default>') waarbij de default gelijk is aan de veld-/functienaam. Fix is mechanisch (Default Value-tekst aanpassen in de builder op het Text-widget), maar raakt dezelfde "Set from Variable"-property als de Empty-URL-fix — zelfde risico-inschatting als het CachedNetworkImage-patroon. Niet in één sessie proberen af te maken gezien de omvang hieronder (~45 treffers); pak het file-voor-file op.

    • horecagelegenheidoverzicht_kaart_widget.dart:359/383/410 — titel/adres/plaats
    • evenement_info_widget.dart:136/158/213/238/293 — adres/plaats/entreeprijs/entreetoelichting/contact
    • evenement_component_widget.dart:221/242/317/339 — title/eventDate/adres/plaats (317/339 zijn nieuw t.o.v. de 2026-08-04-audit, waren toen nog niet aanwezig of gemist)
    • horecagelegenheid_current_widget.dart:377/500/747 — title/logo/content (volledig nieuw gevonden, stond niet in de vorige audit). Zie P0-7: deze 3 velden bleken 2026-08-12 live op elke geteste gelegenheid permanent op de placeholder te blijven staan (niet incidenteel) — een betere Default-Value-tekst alleen lost dat niet op, eerst P0-7's onderliggende data-probleem oplossen.
    • event_current_widget.dart:327/418/442 — title/nid/date (327 en 442 zijn nieuw t.o.v. de 2026-08-04-audit, alleen nid stond er al in)
    • evenement_horecagelegenheid_widget.dartgrootste blok, ~30 treffers, volledig nieuw t.o.v. de vorige audit (waarschijnlijk pas zichtbaar geworden na de P1-image-crash-fix-uitbreiding van dit component): regels 178(HorecaNaam), 418(establishmentnid), 445(email), 476(Logo), 499(Plaats), 533(Adres), 577/586/597 (Telefoon, 3x — icoon/tekst/tooltip-varianten), 642(menukaart), 710(entreeprijs), 743(EntreeToelichting), 818/827/843(facebook, 3x), 885/894/910(instagram, 3x), 952/961(twitter, 2x), 1016/1025/1041(Website, 3x), 1083/1092/1108(urluk, 3x), 1194(Openingstijden), 1222(OpeningstijdenUitzondering), 1310(Bezorgtijden), 1337(bezorgkosten), 1364(bestellink).
    • Grensgeval (geen letterlijke veldnaam maar wel technische/zinloze placeholder, zelfde fix-aanpak): p_uitgaan_slider_kaart_component_widget.dart:284 toont 'def' als datum ontbreekt.
    • Niet-verdachte gevallen bewust genegeerd (echte inhoudelijke fallback, geen technische naam): 'Evenement' (kaart_tabel_uitgaan_comp_widget.dart:216, kaart_tabel_uitgaan_s_comp_widget.dart:123) en 'Uitgaan' (tag_categorie_component_widget.dart:113).
    • Let op — voor de Facebook/Instagram/Twitter/Website/urluk-knoppen op evenement_horecagelegenheid_widget.dart is dit géén puur cosmetisch probleem, zie P1-15 hieronder: de Default-Value-tekst aanpassen lost daar de crash niet op, alleen de zichtbare tekst als hij (na de P1-15-fix) wél verborgen wordt.

    P1-15 · Eigenaar: Bob (builder — Claude geblokkeerd, zie hieronder). Kapotte zichtbaarheids-conditie op de social-/ contact-knoppen laat de app crashen bij tikken (niet alleen lelijke tekst) — vermoedelijke verklaring voor de herhaalde Invalid argument(s): No host specified in URI-excepties die 2026-08-07 in de live flutter run-log van de andere sessie verschenen (naast de al bekende P1-13-overflows, niet met elkaar verwarren — twee losse foutmeldingen in dezelfde log).

    • Root cause bevestigd (code-niveau, lib/evenement/evenement_horecagelegenheid/evenement_horecagelegenheid_widget.dart): de Facebook- (r. 812-829), Instagram- (879-896), Twitter- (~946-961), Website- (1010-1027) en urluk-knop (1077-1094) zijn elk gewrapt in if (valueOrDefault<String>(<veld>, '<placeholder>') != null && valueOrDefault<String>(...) != ''). Omdat valueOrDefault bij een lege/ontbrekende bron altijd de placeholder-tekst teruggeeft (nooit null/''), is deze conditie altijd waar — de knop is dus altijd zichtbaar én tikbaar, ook zonder échte link. Bij tikken roept onTap launchURL(valueOrDefault<String>(...)) aan (lib/flutter_flow/flutter_flow_util.dart:61, Uri.parse(url)launchUrl(uri)) met de kale placeholder-string (bv. 'facebook', 'Website', 'urluk') als URL — geen geldig schema/host, vandaar de crash. Hetzelfde broken-guard-patroon staat ook op de Telefoon-tekst (r. 571-588) maar die crasht niet (geen launchURL, alleen Text) — daar is het wél puur het P1-6-cosmetica-probleem.
    • Fix (builder): op elk van de 5 knoppen de Visibility/If-conditie niet tegen de valueOrDefault-uitkomst laten toetsen, maar tegen het rale API-veld zelf (dezelfde JSON Path-expressie als de Image-URL-fix in CLAUDE.md, operator "Is Set" i.p.v. != null && != '') — zelfde patroon als het al gedocumenteerde CachedNetworkImage-fix-recept. Zonder deze fix blijft ook een betere Default-Value-tekst (P1-6) een tikbare crash-knop.
    • Bredere codebase-audit afgerond (2026-08-13, Claude, grep op alle launchURL(-aanroepen buiten lib/flutter_flow/) — scope is groter dan de 5 al bekende knoppen, en erger op 2 nieuwe plekken (géén guard, zelfs niet de kapotte):
      • horecagelegenheid_current_widget.dart: geen enkele launchURL(-aanroep in dit bestand — de eerder vermoede 6e plek bestaat niet, dit bestand is voor dit specifieke patroon schoon (was nog niet zeker, nu bevestigd).
      • Nieuw gevonden, 6e knop in hetzelfde bestand (evenement_horecagelegenheid_widget.dart:626-635, "Menukaart"): dezelfde InkWellonTap: () async { await launchURL(EstablishmentInfoCall.establishmentMenukaart(...)!); } als de al bekende 5, maar helemaal geen if-guard eromheen (niet eens de kapotte valueOrDefault-variant) — dus altijd zichtbaar/ tikbaar en een kale force-unwrap (!) op een nullable String?. Zelfde fix als de andere 5: Visibility-conditie op de rauwe EstablishmentInfoCall.establishmentMenukaart(...)-expressie, operator "Is Set".
      • Nieuw gevonden, twee losse bestanden met een onvoorwaardelijke "Website"-knop (géén enkele guard, ook geen kapotte):
      • evenement_info_widget.dart:268onTap: () async { await launchURL(widget!.website!); } binnen EvenementInfoWidget (website is String?, component parameter — zie evenement_info_widget.dart:38). Dit component wordt gebruikt op EventCurrent (event_current_widget.dart) — dus een normaal bereikbare, veelbezochte pagina (niet een edge case). Een event zonder website-URL laat de gebruiker de app laten crashen door simpelweg op "Website" te tikken.
      • evenement_component_widget.dart:414onTap: () async { await launchURL(EvenementCall.eventWebsiteg(columnEvenementResponse.jsonBody)!); } binnen EvenementComponentWidget. Dit component wordt alleen gebruikt in event_widget.dart — de al als orphan/dode route bestempelde EventWidget-pagina (zie P2-7, nergens een pushNamed naartoe) — dus wel een echte bug, maar momenteel niet via normale navigatie bereikbaar. Vervalt automatisch als P2-7's voorstel (route schrappen) wordt uitgevoerd; anders zelfde fix nodig (if (widget!.website != null && widget!.website != '') om de InkWell heen, of Visibility in de builder als dit ooit een losstaande pagina/component wordt).
      • Deze twee "Website"-plekken zijn strikt genomen een ander (eenvoudiger) probleem dan de 6 al bekende knoppen — daar is de guard aanwezig maar kapot (valueOrDefault geeft nooit null/'' terug), hier ontbreekt de guard volledig. Fix is in de builder hetzelfde eindresultaat (Visibility op het rauwe veld, "Is Set"), maar het startpunt is "voeg een conditie toe" i.p.v. "repareer de bestaande conditie".
      • "Op/vanaf de Home-pagina zelf" (2026-08-07-log) blijft niet exact herleid tot een Home-componentEvenementComponentWidget (de meest waarschijnlijke kandidaat gezien dit patroon) blijkt alleen op de orphan EventWidget-route te zitten, niet op Home. Een andere, nog niet gevonden plek blijft mogelijk, of de 2026-08-07-log ving events die al ontstonden op EventCurrent (wél een normale Home-vervolgpagina) via evenement_info_widget.dart:268 hierboven — dat verklaart het waargenomen symptoom net zo goed zonder een aparte Home-specifieke plek nodig te hebben. Niet verder gezocht.
    • Poging door Claude (2026-08-09 avond), geblokkeerd op Widget-Tree-coördinaten — geen wijziging aangebracht. Component EvenementHorecagelegenheid geopend, maar de 5 knoppen (diep genest onder TabBar → TabBarPageInfo) bleken niet betrouwbaar te bereiken: klik-coördinaten op een zichtbare tree-rij selecteerden herhaaldelijk een andere rij, en de offset was niet constant (eerste meting +42px, twee stappen later +21px) — dus geen vaste correctie toe te passen zoals CLAUDE.md's kalibratietruc suggereert. De "Search for widget..."-zoekbalk in het paneel pakte maar één keer focus (na een klik op het "collapse"-icoontje ernaast), en zelfs toen gaf zoeken op Facebook geen enkel resultaat (wijst erop dat de knoppen intern niet zo genoemd zijn — zoek in de builder dus niet blind op die letterlijke naam).
    • Poging door Bob (2026-08-10 avond), alle 5 knoppen ingesteld — bleek bij verse export toch niet toegepast. Bob zette op alle 5 knoppen de conditie om (naar eigen zeggen), maar een export vlak erna toonde voor in ieder geval de Facebook-knop nog exact het oude patroon (valueOrDefault<String>(EstablishmentInfoCall.establishmentFacebook(...), 'facebook') != null && ... != '', regel 812 van evenement_horecagelegenheid_widget.dart) — dus de edit hield niet vast, zelfde "ziet er goed uit in de builder maar komt niet door" patroon als eerder bij P0-3 punt 1. Nuttige precisering deze sessie: de Facebook-waarde komt hier niet via een Component Parameter binnen, maar rechtstreeks uit een API-call die dit component zelf al draait (EstablishmentInfoCall.establishmentFacebook(columnEstablishmentInfoResponse.jsonBody)) — dus geen Component-Parameter-Default-Value-omweg nodig. Bind First Value in de Visibility-conditie direct aan die API-call-respons (in de builder waarschijnlijk zichtbaar als een bronnaam als "columnEstablishmentInfoResponse"/"Establishment Info Response" → veld "Facebook"), operator "Is Set and Not Empty", zonder de valueOrDefault-wrap. Bob gaat hier zelfstandig mee verder. Tip voor de volgende poging: ná het instellen even wegnavigeren en de conditie opnieuw openen om te bevestigen dat hij écht bewaard is, vóórdat je naar de volgende knop gaat — dat had dit keer de vroege ontdekking gescheeld.

    P1-16 · Eigenaar: Bob (Firebase-koppeling is account-/builder-niveau, geen Claude-taak). Geen crash-reporting/analytics (bv. Firebase Crashlytics) ingesteld. Nu is de enige manier om een crash zoals P1-15 hierboven te zien een handmatige flutter run-log tijdens een actieve sessie — na livegang is dat niet meer haalbaar, dan draai je blind. Aanbeveling: instellen vóór livegang, niet pas erna — FlutterFlow heeft ingebouwde Firebase-integratie (Crashlytics minimaal, Analytics optioneel) die met een paar builder-instellingen aan te zetten is. Zonder dit blijft elke toekomstige crash-bug (nieuwe RenderFlex- overflows, een volgende launchURL-achtige misser) onzichtbaar totdat een gebruiker 'm toevallig meldt.

    P1-17 · Eigenaar: Onbepaald. Live bevestigd 2026-08-07 (Claude, emulator met systeemtaal en-US, verse app-data): de app valt terug op Engels zodra het toestel niet op Nederlands staat (geen opgeslagen taalvoorkeur → MaterialApp.locale is null → Flutter matcht het systeem-en-US tegen de ondersteunde ['nl','en']-lijst en kiest en). Dat zou op zich geen probleem zijn als er een echte Engelse vertaling stond — die is er vrijwel niet: van de 169 sleutels in lib/flutter_flow/internationalization.dart zijn er 50 waar nl/en toevallig identiek zijn (onvertaald), 44 waar beide talen leeg zijn (dus zichtbaar niets, zoals de Login-hinttekst uit P0-6), en slechts 1 sleutel met een bewust andere Engelse tekst — en die ene is fout: key 7pacsyhe (het hartje-menu-item in de drawer) toont nl: 'Favorieten' maar en: 'Home', dus een Engelstalig toestel ziet twee menu-items met de tekst "Home" (huis-icoon én hartje-icoon) — verwarrend, de favorieten zijn zo niet te vinden. Iedere gebruiker met een Engelstalig toestel (niet ongebruikelijk, ook onder Nederlanders) krijgt dus een merkbaar kapotte/lege interface. 2026-08-09, Bob: Engels moet blijven aangeboden (niet weghalen als taal) — de eerder voorgestelde "forceer hard op nl"-fix (Engels uit FFLocalizations.languages() verwijderen) is dus afgewezen, niet uitgevoerd. Resterende optie is de grotere, aparte contentklus: de ontbrekende Engelse vertalingen daadwerkelijk invullen (of een losse taalkeuze-instelling bouwen i.p.v. op systeemlocale te vertrouwen). Nog niet opgepakt. Live herbevestigd 2026-08-09 (Claude, emulator): root cause klopt exact zoals hierboven beschreven — op een device met ro.product.locale=en-US verdween de "Wachtwoord vergeten?"-link op Login volledig (lege en-vertaling voor key utppw2si); na adb shell cmd locale set-app-locales com.uitgaanskrant.app --locales nl-NL (betrouwbaardere per-app-locale-override dan de systeembrede settings put system system_locales + broadcast, die op de emulator niet altijd doorwerkte zonder reboot) kwam de tekst meteen terug — bevestigt dat dit puur een vertaalprobleem is, geen widget-bug.

    P1-7 · Eigenaar: Onbepaald. "Favorieten pagina maken" (Bob's naam voor deze taak, 2026-08-13 — was P0-4, samengevoegd met het oude P1-7 favorieten/profielscherm-werk + P2-8 gemeente-favoriet). Bob bouwt de Drupal-kant (views/endpoints) zelf, apart; Claude/deze sessie kan de lokale/UI-kant + look&feel oppakken zolang die niet op Drupal wacht.

    Al afgerond (2026-08-13, geverifieerd via verse export):

    • App State-velden favorieteGemeenteIds en favorieteHorecaNids (beide List<String>, Persisted: true) bestaan nu in lib/app_state.dart.
    • Hartje-toggle op HorecagelegenheidoverzichtKaart (overzichtskaart) volledig werkend: ConditionalBuilder op FFAppState().favorieteHorecaNids.contains(widget!.nid) (ingesteld via "Set from Variable" → Available Options → List Contains Item, zie CLAUDE.md) — If-tak toont gevuld hartje + removeFromFavorieteHorecaNids, Else-tak toont outline hartje + addToFavorieteHorecaNids. Logica én styling (witte Fill Color op beide takken) bevestigd correct.
    • Hartje-toggle op HorecagelegenheidCurrent (detailpagina): zelfde patroon, Remove/Add-acties functioneel correct. Cosmetisch restpunt (icoon/kleur If-tak nog niet aangepast) verplaatst naar de "Drupal dingen"-lijst hierboven — Bob wil dit batchen met een latere Drupal-sessie.

    Nog open:

    • Tab 3 "Favoriete Gelegenheden" vullen met echte data — geblokkeerd, zie "Drupal dingen"-lijst hierboven (hangt aan P0-7). Niet proberen met de bestaande EstablishmentInfoCall (geeft HTTP 500) of EstablishmentsCall (geen nid-filter) vóór dat is opgelost.
    • Tab 2 "Favoriete gemeenten" vullen — geen Drupal-blocker bekend: gemeenteNaamById (custom function) + favorieteGemeenteIds kunnen in principe al een lijst van gemeentenamen tonen. Nog wel uit te zoeken: waar in de app een gemeente daadwerkelijk te favorieten is (er is nog geen hartje-toggle-UI op een gemeente-kiezer gevonden/gebouwd om deze lijst ooit te vullen).
    • Tab 1 "Persoonlijke agenda" (events in favoriete gemeente(n)) — nog niet uitgezocht of hier al een geschikte Drupal-call voor bestaat; vermoedelijk ook Drupal-afhankelijk, nog niet onderzocht.
    • "Gebruiker"-tab (wachtwoord wijzigen, uitloggen, account verwijderen — zie Bob's beslissing 3 hieronder) — nog niet opgepakt. Uitloggen kan volledig lokaal (geen backend nodig, alleen FFAppState-sessievelden wissen + terug naar Login).
    • Open vraag aan Bob (blokkeert de Drupal-sync van favorieten): bestaat er al een Drupal-endpoint om een favoriet (horeca of gemeente) toe te voegen/verwijderen voor een ingelogde gebruiker (bv. Flag-module of een custom Services-resource), of moet dat nog gebouwd worden? Zonder endpoint-naam/-vorm blijft de huidige toggle lokaal-only (secureStorage, geen sync naar Drupal bij inloggen op een ander toestel).

    Bob's beslissingen (2026-08-09, nog steeds leidend):

    1. Favorieten (zowel horeca als gemeenten) worden Drupal-gesynchroniseerd, niet puur lokaal — sync bij app-start én direct na elke toevoegen/verwijderen-actie. Lokale opslag (FFAppState/ secureStorage) blijft daarnaast nodig als cache/snelle UI-state.
    2. "Persoonlijke agenda" (tab 1) = events in de door de gebruiker gefavoriete gemeente(n) (niet de her-toegekende naam "agenda" op de bestaande horeca-GET-call — dat is een aparte, nog te bouwen view).
    3. "Gebruiker"-tab = het oude P1-7-scope (wachtwoord wijzigen, uitloggen, account verwijderen), nu als tab i.p.v. aparte pagina. Account verwijderen heeft mogelijk AVG-implicaties aan Drupal-kant. Let op prioriteit: Apple's App Store Review Guideline 5.1.1(v) eist in-app accountverwijdering voor een app met accountaanmaak — zonder dit scherm blokkeert een iOS-submissie, niet alleen P1.

    *(P1-12 afgerond 2026-08-10 avond — Bob, builder, opgelost via een andere en betere route dan oorspronkelijk voorgesteld: i.p.v. een Default Value op establishmentID toe te voegen (die de crash slechts had gemaskeerd met een nep-waarde "0"), is de hele EvenementHorecagelegenheidWidget-instantie op EventCurrent nu achter een Visibility-conditie gezet die bindt aan de rauwe pagina-parameter horecaid zelf (operator "Is Set"), vóór een eventuele Default Value-substitutie — zelfde "bind aan de rauwe bron, niet aan de gesubstitueerde waarde"-principe als het bekende CachedNetworkImage/P1-15-patroon. Bevestigd via verse export: if (widget!.horecaid != null && widget!.horecaid != '') EvenementHorecagelegenheidWidget(... establishmentID: widget!.horecaid!, ...) — de force-unwrap is nu veilig, want alleen bereikbaar binnen de guard. Uit deze lijst verwijderd.)*

    P1-13 · Eigenaar: Bob (geblokkeerd op een bevestigd FlutterFlow- platformprobleem, geen Claude-taak meer totdat dat opgelost is). Live herbevestigd 2026-08-12 (Claude, verse build, telefoonformaat emulator-5554): nog steeds kapot, exact zoals hieronder beschreven — "BOTTOM OVERFLOWED BY 1529 PIXELS" op de Activiteiten-tab, zichtbaar al na de 2e rij kaartjes, geen scroll mogelijk voorbij dat punt. Geen voortgang t.o.v. 2026-08-10, geen nieuwe informatie deze sessie — puur een bevestiging dat de taak actueel blijft. Root cause + fix zijn bekend en juist toegepast in de builder (door zowel Claude als Bob, op zowel 1 als meerdere tabs), maar de wijziging bereikt nooit de export — zie de uitgebreide blocker-documentatie hieronder. Volgende stap is bij Bob: Issues-paneel checken, de alternatieve SingleChildScrollView-route proberen, of FlutterFlow-support contacteren. Op HorecagelegenhedenOverzicht → tab "Activiteiten" overflowt de kaartjesgrid. Root cause definitief bevestigd (2026-08-09, Claude, verse volledige stack trace + visuele bevestiging op emulator-5554):

    A RenderFlex overflowed by 5382 pixels on the bottom.
    Column:file:///.../lib/horecagelegenhedenoverzicht/horecagelegenheden_overzicht/horecagelegenheden_overzicht_widget.dart:286:29
    

    horecagelegenheden_overzicht_widget.dart:286-382: de Activiteiten-tab is een kale Column (mainAxisSize: MainAxisSize.max, regel 286) met als enige kind een FutureBuilder die uiteindelijk een MasonryGridView.builder bouwt (regel 354) met shrinkWrap: true + physics: NeverScrollableScrollPhysics() (regel 355-356/382) — dit patroon (shrinkWrapped grid zonder eigen scroll) vereist een scrollbare ouder om te werken, maar die ontbreekt hier: de Column zit direct in de TabBarView's Expanded (regel 282-284), zonder SingleChildScrollView eromheen. Met 25 items (regel 340, .take(25)) × Container(width: 600.0, height: 225.0) (regel 388-390) in 1 kolom op telefoonformaat (crossAxisCount: 1 onder kBreakpointSmall, regel 359-363) wil de grid ≈5625px hoog worden terwijl de tab maar een fractie daarvan aan ruimte heeft — vandaar de 5382px-overflow. Verklaart vermoedelijk ook de eerder waargenomen kleinere "on the right"-overflows elders in eerdere sessies (los bevestigd deze sessie op een ander component: zie P1-19's zustervondst op PUitgaanSliderKaartComponent:179, zelfde "kale-Row/Column-zonder-wrap"-familie maar niet dezelfde plek).

    • Bestandspad-correctie (2026-08-10): de hierboven genoemde horecagelegenheden_overzicht_widget.dart bestaat niet meer als zodanig — Bob's project splitst deze pagina inmiddels in HorecagelegenhedenOverzicht (dunne ConditionalBuilder-wrapper, [If/Then/Else 2 Conditions]) die naar horecagelegenheden_overzicht_page_data_type_widget.dart of ..._sort_page_widget.dart doorschakelt. De Activiteiten-tab-Column zit nu op regel ~277 van het PageDataType-bestand (structuur/getallen overigens identiek: Column(mainAxisSize: MainAxisSize.max)FutureBuilderMasonryGridView.builder(shrinkWrap: true, physics: const NeverScrollableScrollPhysics())). Navigeer in de builder dus naar ?page=HorecagelegenhedenOverzicht (niet naar de PageDataType/SortPage-varianten los) — de widget-tree toont dan gewoon de juiste, actieve tak.
    • Fix uitgevoerd in de builder (2026-08-10, Claude) — mechanisch, bevestigd correct qua stappen, maar NIET bevestigd in de export (zie blocker hieronder): op de Column binnen TabBar Page (kind van TabActiviteiten) bleek de Column zelf al binnen een bestaande Expanded(TabBarView(...)) te zitten (dus al bounded-height) — een losse "Scrollable"-toggle op die Column zelf gaf zelfs een expliciete "Invalid Action"-foutdialoog terug ("You can't set Expanded for a widget if it's in a Column that doesn't have a defined Height. This includes a Scrollable Column.") toen ik daarna ook Expanded op het kind probeerde — nuttige bevestiging dat FlutterFlow deze combinatie zelf detecteert en terugdraait. Werkende combinatie (op de StaggeredView-node zelf, kind van de Column, niet op de Column zelf): rechterpaneel → Expansion → Expanded (rechtse van de 3 iconen: None/Flexible/Expanded, in die volgorde — geen tooltip nodig om te onthouden) + Shrink Wrap → uit + Scrollable → aan. Geen foutdialoog bij deze combinatie, paneel toont "Synced"/"Saved", waarde blijft staan na page-reload binnen dezelfde sessie.
    • ⚠️ BLOCKER — bevestigd niet-doorzettend naar de export (2026-08-10, Claude): ondanks bovenstaande drie toggles zichtbaar correct in de builder (en blijvend zo na reload) én "Synced"-status zonder foutmelding, lieten drie onafhankelijke verse flutterflow export-code --as-debug-runs (over ca. 10 minuten, dezelfde opzet als Bob's eigen ff-run-fvm.sh gebruikt) geen enkele wijziging zien: Column/MasonryGridView in het geëxporteerde bestand staan nog altijd exact zoals vóór de builder-edit (shrinkWrap: true, NeverScrollableScrollPhysics, geen nieuwe Expanded). Sanity-check uitgevoerd: de exportpijplijn zelf werkt wél correct — dezelfde export toonde de al langer bevestigde P0-6-hintText-fix (d507d3b9/t8h5f8ir in internationalization.dart) gewoon goed. Ook een heel andere, eenvoudiger wijziging in dezelfde sessie (P2-9's dode terug-knop op Home, kale "Remove Widget"-actie) wél correct in de export terechtgekomen — dus dit is geen algemene sessie-brede exportstoring, het lijkt specifiek aan deze combinatie van property-toggles (Expansion/Shrink Wrap/Scrollable op een StaggeredView diep genest in een TabBarView) gebonden.
    • Update 2026-08-10, later dezelfde sessie: Bob heeft de 3 toggles ook zélf, met eigen muisklikken in zijn eigen browser gezet (Expansion → Expanded, Shrink Wrap → uit, Scrollable → aan) — óók dat kwam niet door in een verse export. Dit sluit "Claude's geautomatiseerde klik triggert geen echt change-event" als verklaring uit: zelfs een echte handmatige muisklik in Bob's eigen, ingelogde browser (bevestigd: mcp__claude-in-chrome__* draait sowieso al in Bob's eigen Chrome, geen aparte sandbox) persisteert deze specifieke combinatie niet. Dit wijst nu sterk op een echt FlutterFlow-platformprobleem met deze property-combinatie op een diep-geneste MasonryGridView/StaggeredView binnen een TabBarView, niet op iets in onze workflow. Nog te proberen (niet meer door Claude gedaan deze sessie, tijd op):
      1. Check het Issues-paneel (rode teller rechtsboven) — een analyzer-fout kan een stille opslag-blokkade veroorzaken (zelfde patroon als in CLAUDE.md gedocumenteerd voor exports).
      2. Browser-refresh vlak vóór het zetten van de toggles proberen, zonder tussendoor iets anders te doen — mogelijk speelt de eerdere "Invalid Action"-dialoog (zie hierboven) een rol in state-corruptie die een refresh oplost.
      3. Alternatieve fix-route proberen: i.p.v. de 3 losse toggles op StaggeredView, de hele Column-inhoud Wrap Widget → SingleChildScrollView (shrinkWrap/physics blijven dan op de bestaande waarde staan — dat patroon werkt al elders in dit project, zie de oorspronkelijke fix-beschrijving hierboven). Dit is een structureel andere widget-tree-bewerking dan de property-toggle die nu blijkt te haperen.
      4. Als niets werkt: FlutterFlow-support contacteren met "widget property change toont als opgeslagen in het paneel, maar bereikt nooit View Code/export" — klinkt als een reproduceerbare bug aan hun kant.
    • Nieuwe theorie van Bob (2026-08-10): mogelijk speelt mee dat alle 6 StaggeredViews op deze pagina dezelfde generieke naam "StaggeredView" dragen (geen custom naam) — misschien faalt de save juist omdat er meerdere identiek-genoemde widgets op dezelfde pagina staan, en werd de fix tot nu toe maar op 1 van de 6 (Activiteiten) toegepast. Deels onderzocht (Claude, 2026-08-10):
      • Widgets van dit type (geen Component) hebben geen losse "Rename"-optie — het contextmenu op de tree-rij biedt Duplicate/Insert/Wrap/Replace/Remove/Comment/Copy Style/Copy Code/Convert to Component/Save as Template, geen "Rename Widget". Dubbelklikken op de widgetnaam bovenin het rechterpaneel opent per ongeluk "Convert to Component" (nieuwe-component-dialoog) — niet gebruiken, dat is een structureel andere, veel grotere wijziging dan bedoeld (geannuleerd, geen schade aangericht).
      • "Value Key"-veld geprobeerd als alternatief voor een unieke identiteit — veld gevonden via de Search properties-zoekbalk, maar het inputveld zelf rendert volledig buiten de geclipte viewport (zie hieronder), dus niet in te vullen door Claude.
      • Poging om de fix ook op de Cultuur-tab te zetten (test: alle 6 tegelijk) liep vast op clipping — ook na Bob's browser fullscreen op een 4K-scherm bleef Shrink Wrap/Scrollable/Value Key buiten de zichtbare/klikbare automation-viewport (bevestigd: het probleem zit in hoe de browser-automation-brug de pagina ziet — vermoedelijk een vaste virtuele CDP-viewportbreedte, los van Bob's fysieke schermresolutie — niet in Bob's venstergrootte zelf, dus verder fullscreen/resizen door Bob heeft geen zin). StaggeredView van TabCultuur is wél betrouwbaar te selecteren (Widget Tree), alleen de eigenlijke toggle-klik niet.
      • Widget Tree → TabActiviteitenTabBar PageColumnStaggeredView staat al goed (Expansion: Expanded, Shrink Wrap: uit, Scrollable: aan — door zowel Claude als Bob bevestigd zichtbaar ingesteld, zie hierboven).
      • Update 2026-08-10, definitieve uitkomst: Bob heeft de toggles zelf op meerdere/alle tabs gezet — óók dat kwam niet door. Verse export ná Bob's wijziging: alle 6 MasonryGridView.builder- instanties (regel 344/524/708/892/1076/1260) staan nog steeds op shrinkWrap: true + const NeverScrollableScrollPhysics(), geen enkele nieuwe Expanded. Sanity-check herhaald: de exportpijplijn zelf werkt gewoon (P2-9's Home-knop-verwijdering staat nog correct in dezelfde export). Dit sluit de naamgevingstheorie definitief uit — of het nu 1 of 6 identiek-genoemde StaggeredView-widgets betreft maakt niets uit voor de save. Samen met de eerdere uitsluiting van "Claude's automation triggert geen change-event" (Bob's eigen handmatige klikken faalden ook) betekent dit: dit is bevestigd een echt FlutterFlow-platformprobleem met deze specifieke property-combinatie (Expansion/Shrink Wrap/Scrollable op een MasonryGridView/StaggeredView diep genest in een TabBarView), onafhankelijk van wie er klikt, hoeveel widgets het betreft, of hun naamgeving. Resterende opties (niet meer geprobeerd deze sessie):
      • Issues-paneel checken op een stille analyzer-blokkade.
      • De alternatieve Wrap Widget → SingleChildScrollView-route proberen (structureel andere widget-tree-actie, mogelijk buiten bereik van deze specifieke bug) — zie de oorspronkelijke fix-beschrijving hierboven.
      • FlutterFlow-support contacteren: "widget property change (Column/ StaggeredView Expansion/ShrinkWrap/Scrollable, diep genest in een TabBarView) toont als correct opgeslagen in zowel de builder-UI als na page-reload, maar bereikt nooit View Code of flutterflow export-code, ongeacht wie de wijziging maakt of hoeveel widget-instanties het betreft" — met dit reproductiepad als bewijs.
    • Reproductierecept dat de race met Home's eigen overflow (P1-19) vermeed (2026-08-09, definitief werkend — vervangt eerdere R+deep-link-pogingen): flutter run direct starten met --route i.p.v. cold-start via am start ná een losse flutter run/hot-restart. Dit zet Flutter's defaultRouteName al vóór de eerste frame, dus go_router opent meteen de juiste pagina — Home wordt nooit gebouwd, dus zijn eigen overflow (P1-19/P1-3-familie) verbruikt de "één-volledige-dump-per-proces"-slot niet meer eerder:

      export PATH="/home/bob/fvm/bin:$HOME/.pub-cache/bin:$PATH"
      fvm flutter run -d emulator-5554 --route "/horecagelegenhedenOverzicht?plaats=28666"
      

      (geen FIFO/R/deep-link-am-start meer nodig voor dít doel. Voor een pagina die zelf niet los bereikbaar is met de juiste parameters via een directe --route, blijft het FIFO/R-recept uit CLAUDE.md nodig.) Bevestigd geprobeerd en verworpen: R (hot-restart) + de deep-link-am start vlak erna in één Bash-call (minimale sleep) — een hot-restart reset altijd naar de initialLocation/Home, en de daarna verstuurde deep-link-intent wordt door de al herstarte app niet meer verwerkt (adb-warning "Activity not started, intent has been delivered to currently running top-most instance" terwijl de app toch weer op Home landde) — dus dit blijft Home's eigen overflow eerst verbruiken. --route bij het opstarten zelf is de werkende oplossing voor dit specifieke race-probleem.

    • Hypothese uit 2026-08-05 (HorecagelegenheidoverzichtKaartWidget's MediaQuery.sizeOf-breedtekeuze) blijft weerlegd — de daadwerkelijke oorzaak is de ontbrekende scroll-wrapper hierboven, niet de tekstkolom-breedtekeuze.

    *(P1-19 volledig afgerond 2026-08-12 avond — live pair-sessie, Bob builder + Claude verse-export-verificatie per stap. Alle 9 live bereikbare kale-Row-met-List.generate-tag-overflows omgezet naar Wrap (rechtsklik Row → Replace → Wrap — niet "Wrap Widget" + "Remove Widget", zie CLAUDE.md voor de valkuil/uitleg): Home (HomeUitgaantabelKaartComponent), PUitgaanSliderKaartComponent, EventCurrent, EvenementHorecagelegenheid (4x: categoriehoreca/ afhaalopties/afhaalbetaalopties/bezorgtin), HorecagelegenheidCurrent (cryptocoins), PUitgaantabelKaartComponent. Alle 9 bevestigd via verse flutterflow export-code + een afsluitende volledige codebase-sweep op het patroon (geen gemiste live plekken meer, 2 resterende treffers bleken Column i.p.v. Row — niet dit bugpatroon). Correctie tijdens de sessie: de taak noemde ook een losstaand uitgaantabel_kaart_component_widget.dart als "gebruikt op zowel Home als PUitgaanPage" — dat klopte niet, dit is orphan/dode code (nergens geïnstantieerd), verplaatst naar P2-7's opschoonlijst. Uit deze lijst verwijderd.)*

    P1-20 · Eigenaar: Onbepaald. Home toont weer een werkende "Terug"-knop naast de hamburger — regressie t.o.v. P2-9-bijvangst (die verwijderde Home's eigen dedicated IconButtonBack, bevestigd 2026-08-10), maar via een ander pad: HomeWidget's AppBar (lib/uitgaanspaginas/home/home_widget.dart:127-168) toont in de FlexibleSpaceBar twee gestapelde lagen — title: met alleen Home's eigen hamburger, en background: met een instantie van de gedeelde HeaderButtonsComponentWidget() (dezelfde component die P0-3 punt 2 op EventCurrent hergebruikte voor de locatienaam-header). Die gedeelde component heeft zélf óók een hamburger + een arrow_back_outlined-knop met tooltip "Terug" (lib/components/header_buttons_component_widget.dart:182-194, onPressed: () => context.pop()) — op EventCurrent hoort die terug-knop er terecht bij (je kwam ergens vandaan), maar op Home (de root-pagina, niets om naar terug te gaan) is hij een dooie-op-zich knop die desondanks zichtbaar en tikbaar is. Bevestigd live (2026-08-12, verse build):

    1. Tikken op de knop zelf toont de tooltip "Terug" en doet verder niets zichtbaars (context.pop() is hier een no-op, geen crash) — puur verwarrend voor een gebruiker die net de app opent.
    2. Belangrijker: de tikgebieden van de hamburger (Home's eigen, title-laag) en van deze Terug-knop (background-laag) liggen zo dicht op elkaar dat een tap bedoeld voor de hamburger soms in plaats daarvan de Terug-tooltip toont — en zodra die tooltip eenmaal getoond is, bleven 3 opeenvolgende taps op exact dezelfde hamburger-positie alleen de tooltip opnieuw tonen (drawer opende niet), tot een tap elders op het scherm of een hardware-back de tooltip resette. Dit kan het openen van het hoofdmenu (de enige manier om provincie/gemeente/horeca te wisselen vanaf Home) voor een gebruiker onbetrouwbaar maken.
    3. Voorgestelde fix (builder): op Home's instantie van HeaderButtonsComponentWidget() (in de background:-slot van de FlexibleSpaceBar) de Terug-knop verbergen — bv. een Visibility-conditie op een nieuwe/bestaande component-parameter (showBackButton: false voor Home, true voor EventCurrent en andere sub-pagina's die 'm al gebruiken), zodat de component herbruikbaar blijft maar niet overal dezelfde knoppen toont.

    P1-21 · Eigenaar: Onbepaald. AdBanner op PUitgaanPage (lib/uitgaanspaginas/p_uitgaan_page/p_uitgaan_page_widget.dart:200-207) toont letterlijke developer-instructietekst aan echte gebruikers i.p.v. een advertentie of een net leeg vak. Dit is FlutterFlow's eigen FlutterFlowAdBanner-widget (lib/flutter_flow/flutter_flow_ad_banner.dart): zolang er geen geladen advertentie is, rendert hij een zwart vlak met de tekst "Ad Loading... If this takes a long time, you may have to check whether the ad is being covered from a parent widget. ... AdBanner will automatically match the size of the banner to the device screen." — bedoeld als build-time debughulp, niet als eindgebruikers-UI. Bevestigd live (2026-08-12): dit bleef 8+ seconden onveranderd zichtbaar (geen doorontwikkeling naar een echte advertentie), en de flutter run-log toonde de reden:

    BannerAd failedToLoad: LoadAdError(code: 0, domain: com.google.android.gms.ads, message: Internal error., ...)
    
    • Punt 1 (showsTestAd) geschrapt als bug — bevestigd verwacht gedrag (2026-08-13, Bob): er is geen losse "test ad"-instelling in de builder (bevestigd via het AdBanner-widget-eigenschappenpaneel — alleen Visibility/Expansion/Padding/Alignment/Ad Properties/ Dimensions, geen test-toggle). De testadvertentie verschijnt omdat Google AdMob de app nog niet heeft goedgekeurd — dat kan pas ná livegang (Google keurt pas goed als de app in productie draait). Actie bij livegang (niet nu, geen losse builder-stap): ná het live zetten van de app bij Google/Apple de advertenties laten reviewen/goedkeuren — pas daarna serveert AdMob automatisch echte advertenties i.p.v. de testvariant.
    • Punt 2 blijft een echte taak, los van goedkeuring: de fallback-UI zelf moet sowieso weg/anders — een gebruiker mag nooit deze debugtekst zien, ook niet ná goedkeuring als een advertentie een keer traag laadt of faalt (bv. geen advertentie-inventory voor deze gebruiker/regio). Voorstel: flutter_flow_ad_banner.dart's fallback-Container vervangen door iets neutraals (leeg vlak met dezelfde hoogte, of gewoon SizedBox.shrink()) i.p.v. de zwarte debug-tekst-box.
      • Correctie (2026-08-13, Claude): de eerdere aanname "wél rechtstreeks in de code aan te passen zonder builder-UI, net als lib/custom_code/" is ongeverifieerd en vermoedelijk fout — niet blind uitvoeren. Dit bestand staat in lib/flutter_flow/, niet in lib/custom_code/ — dat is precies het generatedbestanden- pad dat CLAUDE.md expliciet als niet-duurzaam bestempelt ("directe Edit/Write-wijzigingen aan gegenereerde bestanden worden bij de volgende export overschreven"). git log op dit bestand toont alleen de allereerste commit (nooit een diff bij een van de vele latere flutterflow export-code-syncs) — dat bewijst niet dat een lokale edit zou overleven, alleen dat de FlutterFlow-standaard- versie van dit bestand zelf nooit gewijzigd is. Zonder een bevestigd precedent (een eerdere lokale lib/flutter_flow/*-edit die een export overleefde) een gok nemen op een gebruikersgerichte UI-tekst is niet de moeite waard. Het AdBanner-widget-paneel in de builder heeft geen fallback-tekst/-widget-property (bevestigd 2026-08-13 bij het onderzoeken van punt 1 hierboven — alleen Visibility/Expansion/Padding/Alignment/Ad Properties/Dimensions), dus ook geen bestaande builder-route naar deze fix.
      • Enige betrouwbare pad die overblijft: een eigen custom widget in lib/custom_code/widgets/ bouwen die AdMob rechtstreeks aanroept (vergelijkbare BannerAd/AdWidget-logica als hierboven, maar met een nette fallback) en die op PUitgaanPage de bestaande FlutterFlowAdBanner-instantie vervangt via de builder (Insert Widget → Custom Widget). Groter dan een 1-regelige tekstwijziging — eigen sessie/blok waard, niet iets voor een snelle mechanische doorloop. Nog niet opgepakt.
    • Kanttekening bij P2-5 ("Ad-banners..., na livegang"): P2-5 gaat er nog van uit dat advertenties een niet-gebouwd P2-idee zijn — in werkelijkheid staat er dus al minstens 1 banner live in de code (alleen nog kapot/debug). Check met Bob of P2-5's "waar wel/geen ads"-regel (geen ads op locatie-kiezer/login/account) al is toegepast op deze ene bestaande banner, en of er bewust voor PUitgaanPage gekozen is als eerste plek.

    (P1-22 volledig afgerond 2026-08-13 — live pair-sessie, Bob builder + Claude verse-export-verificatie, gecombineerd met P1-10's cache-toggle in één doorloop per call (Bob's voorstel, scheelde een dubbele builder-bezoekronde). Alle 11 live API-calls hebben nu decodeUtf8: true bevestigd (homeTabel, HomeSlider, Uitgaanstabel, UitgaanSlider, EstablishmentInfo, HorecagelegenheidEvents, gemeenten, provincies, Evenement, Establishments, requestNewPassword) — EstablishmentsCall's toggle werd in de eerste ronde gemist (niet te verwarren met het dode EstablishmentsNewCall, zelfde-klinkende naam), in een 2e verse export alsnog bevestigd correct. Uit deze lijst verwijderd.)

    P1-9 · Eigenaar: Onbepaald. Visuele polish (los, per pagina) — resterend na sessie 2026-08-06:

    1. Nog niet opgepakt: Event-pagina (typografie/contrast/spacing).
    2. (Restpunt PUitgaanSliderKaartComponent-schaduw Offset Y afgerond 2026-08-10 avond — Bob, builder, bevestigd via verse export: beide BoxShadows staan nu op Offset(0.0, 2.0), blur 4.0.)
    3. Al afgerond sessie 2026-08-06 (Claude, builder): PUitgaanSliderKaartComponent schaduw verzacht (blur 6→4, offsetX 12→0, hoekafronding asymmetrisch→uniform) zodat die minder afwijkt van het tabel-kaartje; PUitgaanPage padding toegevoegd tussen advertentiebanner en tabellijst; HorecagelegenheidoverzichtKaart titel kreeg maxLines: 2 (voorkomt ongelijke kaarthoogtes in de grid); categorie-tag-kleur op datzelfde kaartje gelijkgetrokken naar huisstijlrood #9A141D (was paars-blauw #CC4B39EF, afweek van het gedeelde TagCategorieComponentWidget elders in de app).
    4. Al afgerond sessie 2026-08-07 (Claude, builder), live bevestigd op emulator: HorecagelegenhedenOverzicht — TabBar nu gewrapt in een Container met een zachte onderschaduw (#33000000, blur 4, offsetY 2 — zelfde stijl als de kaartjes) zodat de lijst niet meer direct tegen de tabs plakt bij scrollen. HorecagelegenheidoverzichtKaart — de categorie-tag-pilletjes (bv. "Bioscoop"/"Theater" op "De Beun") overlapten rommelig met logo-afbeeldingen; de omringende Column kreeg een halfdoorzichtige donkere achtergrond (#40000000, geen eigen padding — leunt op de al bestaande 8px Padding eromheen) als zachte "backing" tussen tags en logo-artwork.
    5. Bevinding voor volgende sessies (builder-workflow): de "Search properties..."-zoekbalk bovenaan het rechterpaneel is een betrouwbare workaround voor het bekende clipping/scroll-probleem — filtert eigenschappen op naam (bv. "blur", "offset", "radius", "padding") i.p.v. moeten scrollen door een niet-scrollende paneel- sectie. Voor een enkel numeriek veld: klik veld → Ctrl+A → typen → Tab/Enter werkt niet altijd betrouwbaar (soms blijft de oude waarde staan zonder foutmelding) — controleer na elke edit met een screenshot van het gefilterde veld; bij twijfel triple-click + Delete
      • typen i.p.v. Ctrl+A gebruiken, werkte in deze sessie consistenter. Verificatie via View Code (rechtsboven </>-icoon) is nuttig maar risicovol te bereiken: de icoontjes rechtsboven verschuiven afhankelijk van app-state (commit-icoon verschijnt/verdwijnt) — 3x per ongeluk een ander icoon geraakt (2x "Create Commit"-dialoog, 1x "Make Project Public"-dialoog, 1x app-preview) door te gokken op vaste coördinaten. Veiliger: direct navigeren naar https://app.flutterflow.io/code/uitgaanskrant-1qhvtd?component=<Naam> i.p.v. op het icoon te klikken, en binnen die code-view Ctrl+F gebruiken (werkt als browser-find) i.p.v. handmatig scrollen (scroll- wheel-events op die pagina reageren nauwelijks).

    (P1-10 punt 1 — cache-toggle op homeTabel/gemeenten/provincies — afgerond 2026-08-13, gecombineerd met P1-22 in één doorloop per API call, bevestigd via verse export. Punt 2 hieronder blijft open als losse taak.)

    P1-10 · Eigenaar: Onbepaald. Performance — resterend werk (audit afgerond 2026-08-05, Claude, code-niveau):

    1. Groter/structureel, nog te beoordelen: 4 pagina's (Home, horecagelegenheden_overzicht(_sort_page/_page_data_type)_widget.dart) hebben een TabBarView met 6-7 tabs die allemaal gelijktijdig hun eigen API-call vuren bij page-load (Flutter bouwt alle tabs eager, geen lazy-tabs) — ook de tabs die de gebruiker nog niet ziet. De inmiddels aangezette cache: true (zie archiveringsnotitie hierboven) verhelpt dit niet — dat voorkomt alleen herhaling bij een latere rebuild, niet de eerste gelijktijdige burst. Echte fix vraagt een structurele herbouw (bv. IndexedStack met on-demand FutureBuilder per tab-activatie i.p.v. TabBarView) — vermoedelijk custom code. Geen bekend rate-limit-probleem op de Drupal-API, dus mogelijk lage prioriteit ondanks de N×-overhead.
    2. Bijvangst tijdens de audit: dode EstablishmentsNewCall verplaatst naar de P2-7-opschoonlijst.

    P1-11 · Eigenaar: Bob — geblokkeerd op rechterpaneel-clipping (zelfde patroon als P1-3). Responsive/screensize. Vers gecheckt 2026-08-10 avond (Claude, export): nog steeds ongewijzigd, taak blijft volledig valide. 2026-08-05: venue-event-grid-bug uitgezocht (Claude, code-niveau) — root cause gevonden, mechanische builder-fix, nog niet uitgevoerd:

    • Component: HorecagelegenheidEventTabelComponentCopy (lib/horecagelegenhedenoverzicht/horecagelegenheid_event_tabel_component_copy/...widget.dart), gebruikt op de "Events"-tab van HorecagelegenheidCurrent (enige gebruiksplek — geen niet-"_copy"-variant meer aanwezig om simpel in te wisselen).
    • GridView (regel 165-172): crossAxisCount: 2, childAspectRatio: 3.0 → elke grid-cel wordt ≈ (schermbreedte/2) breed × (celbreedte/3) hoog — op een telefoon van 390px breed dus ≈190×63px per cel.
    • Binnen elke cel (regel 178-315): een Row met twee Containers die beide hardcoded width: 200.0, height: 200.0 hebben (tekst-tegel regel 186-187, afbeeldings-tegel regel 294-295/311-312 incl. de CachedNetworkImage zelf). De tekst-Container zit wel in Expanded (dus de breedte krimpt mee), maar de hoogte (200) nietExpanded in een Row regelt alleen de hoofdas (breedte), niet de dwarsas (hoogte). De afbeeldings-Container zit zelfs helemaal niet in Expanded — noch breedte noch hoogte passen zich aan.
    • Gevolg: content wil 200px hoog zijn in een cel van ≈63px hoog, en de afbeeldings-tegel wil alléén al 200px breed zijn terwijl de hele cel maar ≈190px breed is (gedeeld met de tekst-tegel ernaast) — RenderFlex overflowed-fouten/afgeknipte layout op de Events-tab van elke horecagelegenheid-detailpagina.
    • Voorgestelde fix (mechanisch, builder-property-wijzigingen, geen nieuwe widgets nodig): in de builder op HorecagelegenheidEventTabelComponentCopy → Widget Tree → de twee Containers binnen de Row (tekst- en afbeeldings-tegel): (1) hoogte 200 vervangen door een responsieve waarde (bv. Expanded ook op de dwarsas laten werken via een buitenste AspectRatio, of de vaste height: 200 gewoon verwijderen en de Row's hoogte laten bepalen door childAspectRatio), (2) de afbeeldings-Container ook in Expanded wrappen zodat beide tegels de celbreedte delen i.p.v. allebei 200px te claimen.
    • 2026-08-05, poging door Claude: in Widget Tree op de tekst- Container geselecteerd — het "Height"-veld (Container Properties) en de "Expansion"-segmented-control (None/Expanded/Flexible) renderen beide net buiten het browservenster, exact hetzelfde structurele rechterpaneel-clippingprobleem als P1-3 (bevestigd met eigenschappen-zoekfilter, scroll, directe klik op geschatte positie — geen succes, geen wijziging aangebracht). Bob: fix hierboven + P1-3's Expansion-fix in dezelfde sessie oppakken, scheelt heen-en- weer-navigeren.

    P2 — features & concept, na livegang

    P2-1 · Eigenaar: Bob — testen in de API, komt terug. Datum-filter: Vandaag / Dit weekend / Deze week.

    P2-2 · Eigenaar: Onbepaald. Google Maps-weergave van horecagelegenheden — bewust niet vóór livegang (Maps API-key + billing, onduidelijk of elke locatie al lat/long heeft, marker-UI — geen quick win).

    P2-3 · Eigenaar: Onbepaald. "In de buurt"/geolocatie-browsen — aanvulling op het provincie/gemeente-model, geen vervanging.

    P2-4 · Eigenaar: Onbepaald. Overige feature-ideeën, geen van alle uitgewerkt: deel-knop op eventpagina · "toevoegen aan agenda" (native kalender) · "events op deze locatie" prominenter op de horeca-detailpagina · reviews/waardering voor horecagelegenheden (groot, vraagt nieuw Drupal content-type + moderatie, eigen project). (De "Wat is er vanavond"-melding is uitgelicht naar P2-10 hieronder — dat idee weegt zwaarder dan de rest van dit lijstje.)

    P2-9 · Eigenaar: Onbepaald. Onboarding/eerste-gebruik-uitleg. Live bevestigd 2026-08-07 (Claude, emulator, pm clear + verse launch = echte eerste-keer-ervaring): een nieuwe gebruiker opent de app en ziet direct de Home-pagina met bovenaan een carousel met kop "OOK LEUK" ("ook leuk" veronderstelt dat je al iets gezien hebt — vreemd als allereerste tekst) en daaronder een kale lijst events, geen welkomsttekst, geen uitleg wat Uitgaanskrant is, geen prompt om een provincie/gemeente te kiezen. (Zie ook P0-3's opmerking dat de eerste-launch-default-locatie 28666/28694 geen naam toont totdat iemand handmatig kiest.) Zonder duidelijke eerste indruk is de kans groot dat een nieuwe gebruiker de app na 1x openen niet snapt/niet terugkomt. Nog geen concrete builder-fix uitgewerkt — eerst met Bob bespreken wat voor onboarding gewenst is (korte welkomsttekst? meteen naar provincie/gemeente-keuze i.p.v. Home?) vóórdat dit gebouwd wordt.

    • Bijvangst, zelfde verkenning: dode terug-pijl-knop in Home's AppBarafgerond (2026-08-10, Claude). IconButtonBack verwijderd via Widget Tree → rechtsklik → "Remove Widget" (op HomeWidgetAppBarRow, naast IconButtonDrawer). Bevestigd via verse flutterflow export-code: geen enkele referentie meer aan IconButtonBack/het bijbehorende Icons.arrow_back_outlined-icoon in home_widget.dart — de AppBar-Row bevat nu alleen nog de hamburger-menuknop. Geen builder-sync-problemen bij deze simpele Remove-Widget-actie (i.t.t. P1-13's multi-property-toggle, zie daar).

    P2-10 · Eigenaar: Onbepaald. "Vanavond in [gemeente/provincie]"- herinnering (pushmelding of in-app-widget) — uitgelicht uit de ongestructureerde lijst van P2-4 omdat dit vermoedelijk de goedkoopste hefboom is voor terugkerend gebruik: dit type overzichts-app wint of verliest niet op features maar op of mensen 'm blijven openen. Een eenmalige/wekelijkse melding met "dit weekend in [gekozen gemeente]" is een directe reden om terug te komen, i.p.v. te wachten tot iemand toevallig weer aan de app denkt. Hangt af van dezelfde Firebase-infra als P1-16 (Firebase Cloud Messaging naast Crashlytics/Analytics) — logisch om in dezelfde builder-sessie op te pakken als P1-16. Nog niet uitgewerkt qua precieze inhoud/frequentie (voorkom spam-gevoel) — eerst met Bob bespreken vóór bouwen.

    P2-5 · Eigenaar: Onbepaald. Ad-banners op horeca-overzicht, horeca-detail, event-detail; vaste regel: geen ads op locatie-kiezer/login/account.

    P2-6 · Eigenaar: Onbepaald. Tekstzoeken op titel op de horeca-overzichtspagina (los van de Datatype/Sort-experimenten die Bob daar zelf op test — die zijn actief werk-in-uitvoering, geen dode code).

    P2-7 · Eigenaar: Bob. Opschonen:

    • Merge kaartTabelUitgaanComp + kaartTabelUitgaanSComp — Bob doet dit zelf ("ik kijk er zelf naar").
    • lib/uitgaanspaginas/uitgaantabel_kaart_component/uitgaantabel_kaart_component_widget.dart (klasse UitgaantabelKaartComponentWidget, géén Home-/P-prefix) — dode/orphan code, bevestigd 2026-08-12 tijdens P1-19: bestaat wel lokaal in de repo maar wordt nergens in de codebase geïnstantieerd (bevestigd grep, en bevestigd in de builder zelf: Bob kon het component niet vinden om te openen). Eerdere aanname in dit bestand dat dit "gebruikt wordt op zowel Home als PUitgaanPage" was fout — de daadwerkelijk live componenten daar zijn HomeUitgaantabelKaartComponent resp. PUitgaantabelKaartComponent (los, wel actief).
    • lib/kanweg opnieuw leegmaken indien teruggekomen na een latere export-pull, plus eventuele nieuwe losse dode componenten in lib/evenement/.
    • Eén browse-by-category-patroon i.p.v. twee: nu Home landelijk is, bepalen hoe Home's categorieën en PUitgaanPage's provincie/ gemeente-gescoopte categorieën zich tot elkaar verhouden.
    • Dubbele Provincie/Gemeente-blok in het menu opruimen (12 menu-items waar 6 zouden volstaan).
    • EventWidget-route: heraansluiten of definitief schrappen (losse orphan-route). Bevestigd orphan 2026-08-05 (Claude, grep): route staat correct geregistreerd (nav.dart, pad /event, param nid) en geëxporteerd (index.dart), maar geen enkele pushNamed/ navigatie-aanroep in de hele codebase gaat er ooit naartoeEventCurrent (pad /eventCurrent) is overal de daadwerkelijk gebruikte event-detailpagina. Alleen bereikbaar via een handmatige directe URL. Beslissing (verwijderen uit nav.dart+index.dart, of alsnog ergens aan koppelen) ligt bij Bob.
    • Volledige API-call-audit (2026-08-13, Claude, grep op alle klassenamen buiten api_calls.dart zelf, gecombineerd met de live-bereikbaarheid-bevindingen uit P1-19/P2-7): van de 22 gegenereerde API-calls in de builder zijn er 11 ongebruikt. EstablishmentsNewCall (regel hierboven) was hier al 1 van, nu volledig lijstje:
      • Vervangen door custom code, veilig te verwijderen: login (LoginCall) en getcsrf (GetcsrfCall) — de echte login-flow loopt via de custom action drupalLogin (lib/custom_code/actions/drupal_login.dart), die zelf rechtstreeks http.post naar het Drupal-login-endpoint doet én het CSRF-token al uit diezelfde loginrespons haalt (data['token']) — de aparte GetcsrfCall/services/session/token-aanroep is dus overbodig geworden. Bevestigd: geen van beide klassen wordt nog ergens aangeroepen.
      • Test/scratch-duplicaten, veilig te verwijderen (geen enkele live referentie): ZZ userEstablishments TEST (ZZUserEstablishmentsTESTCall), FavorietenAgendaTESTKANWEG (FavorietenAgendaTESTKANWEGCall), ZZZhomeSlider (ZZZhomeSliderCall — enige referentie zit in slider_uitgaan_component_small_current_widget.dart, zelf alleen bereikbaar via lib/kanweg/, dus niet live), homeSlidershortDate (HomeSlidershortDateCall), ZZhome uitgaan (ZZhomeUitgaanCall), zzEstablishmentEvents Copy (ZzEstablishmentEventsCopyCall), EstablishmentsNew (EstablishmentsNewCall, al bekend), QueryCityId (QueryCityIdCall).
      • Nog niét dood, wel ongebruikt — laten staan: FavorietenAgenda (FavorietenAgendaCall) — geen enkele huidige live-referentie, maar dit is de call die P1-7's geplande "Persoonlijke agenda"/Favorieten-tabs straks nodig hebben. Niet verwijderen, gewoon nog niet aangesloten.
      • Live/actief (11, ter controle, niet aanraken): homeTabel, HomeSlider, Uitgaanstabel, UitgaanSlider, EstablishmentInfo, HorecagelegenheidEvents, gemeenten, provincies, Evenement, Establishments (let op: niet hetzelfde als het dode EstablishmentsNew hierboven — bevestigd verwarrend gelijkende naam, zelfde valkuil als bij P1-22's toggle-ronde), requestNewPassword.
      • Verwijderen kan gewoon via de builder (API Calls-paneel → call selecteren → verwijderen) — geen custom code/lokale bestanden bij betrokken, dus geen export-sync-risico zoals bij widget-edits.
    • Laag risico, uit P0-3 gehaald (2026-08-10): de component-load default-toewijzing (eerste app-start, provincie/gemeente-id 28666/28694) krijgt nog geen bijbehorende naam mee — valt terug op lege naam tot iemand handmatig een provincie/gemeente kiest.

    P2-8 · Opgegaan in P1-7 (2026-08-09). Hartje-tap op gemeente-/ provincienaam om te favorieten is nu onderdeel van de bredere Favorieten-pagina/profielscherm-taak — zie P1-7 hierboven voor scope en status.