Selaa lähdekoodia

Consolidate session memory into CLAUDE.md + TASKS.md for cross-chat continuity

Every future task will be discussed in a fresh chat, so CLAUDE.md and
TASKS.md now serve as the persistent memory: CLAUDE.md holds durable
conventions/pitfalls (FlutterFlow builder quirks, git workflow, domain
context), TASKS.md holds the current self-contained task backlog.
Standing rule added: completed tasks are removed from TASKS.md rather
than archived, to keep future-session context minimal.
bob 1 kuukausi sitten
vanhempi
commit
f96d3cd625
2 muutettua tiedostoa jossa 402 lisäystä ja 41 poistoa
  1. 203 41
      CLAUDE.md
  2. 199 0
      TASKS.md

+ 203 - 41
CLAUDE.md

@@ -7,6 +7,31 @@ Werk uitsluitend binnen deze projectdirectory
 zoeken of scannen (bijvoorbeeld geen `find /` over het hele
 bestandssysteem) — scope alle bestandsoperaties tot dit project.
 
+## Sessiegeheugen — lees dit eerst
+
+Bob bespreekt elke taak in een **nieuwe, aparte chat**. Dit bestand en
+`TASKS.md` zijn daarom het geheugen tussen sessies — er is geen eerdere
+conversatie om op terug te vallen.
+
+**Vaste afsluitroutine, aan het eind van elke sessie/taak:**
+1. Werk `TASKS.md` bij: **een afgeronde taak wordt volledig verwijderd
+   uit de lijst** (niet gearchiveerd in een "Afgerond"-sectie — dat is
+   onnodige context/kosten voor toekomstige sessies). Zorg dat elke
+   resterende open taak zelfstandig te begrijpen is (concreet, met
+   bestandspad/context) zonder de chat gelezen te hebben waarin hij
+   ontstond.
+2. Werk dit bestand (`CLAUDE.md`) bij: **alleen** toevoegen als het
+   een blijvend herbruikbaar inzicht is (een conventie, een
+   architectuurkeuze, een bekende valkuil/bug-patroon) dat een latere
+   sessie anders opnieuw zou moeten uitzoeken. Geen sessieverslag,
+   geen changelog van wat er gedaan is, geen herhaling van
+   redeneringen. Ruim verouderde/dubbele info op in plaats van
+   eronder te plakken — dit bestand moet klein en scanbaar blijven.
+3. Commit + push de gewijzigde `.md`-bestanden direct (geen
+   FlutterFlow-export nodig voor pure documentatiewijzigingen — alleen
+   de export/build-cyclus hieronder draaien als er ook echt
+   app-code is gewijzigd).
+
 ## FlutterFlow-workflow — belangrijk
 
 Dit project wordt gebouwd via FlutterFlow (app.flutterflow.io). De
@@ -28,7 +53,8 @@ code-export.
   ontwerpen en te verifiëren (bijv. met `flutter analyze`) — maar
   vertaal het eindresultaat naar concrete, stapsgewijze instructies
   voor wat de gebruiker in de FlutterFlow-builder (of de Custom
-  Code-editor) moet doen. Ga er niet van uit dat een lokale bestandswijziging
+  Code-editor) moet doen, of voer het zelf uit via browser-automation
+  (zie hieronder). Ga er niet van uit dat een lokale bestandswijziging
   behouden blijft.
 - Als er via de Chrome-browser (Claude in Chrome) rechtstreeks in de
   FlutterFlow-builder wordt gewerkt: maak na elke **afgeronde taak**
@@ -36,8 +62,23 @@ code-export.
   zelf** (het eigen versiebeheer, te zien bovenin de builder als
   "main"/"Synced"), met een duidelijke omschrijving van wat er is
   veranderd. Dit is geen lokale `git commit`.
+- **Gebruik `mcp__claude-in-chrome__*` (Bob's eigen, gedeelde Chrome),
+  niet de in-app Browser pane** — dat is de afgesproken tool voor
+  builder-automation.
+- **Resize de browser niet zelf** (`resize_window` e.d.) — dit is
+  Bob's eigen gedeelde vensters. Als iets buiten beeld valt, meld dat
+  en vraag het aan Bob i.p.v. zelf te resizen.
+- Bob werkt vaak **gelijktijdig zelf** in dezelfde builder-sessie. Ga
+  er niet van uit dat elke wijziging die je in de widget tree/`git
+  diff` ziet van jezelf komt — check eerst of hij iets claimde
+  ("dat regel ik zelf") voordat je het overschrijft.
+- Check bij een mislukte export/pull eerst het **Issues-paneel**
+  (badge-icoon rechtsboven, naast de sync-checkmarks) voordat je een
+  bug bij jezelf zoekt — een rode teller daar blokkeert *elke* export,
+  ook voor niet-gerelateerde correcte wijzigingen, en is vaak Bob's
+  eigen work-in-progress.
 
-## Lokale git-repo + pull/push-workflow (sinds 2026-08-01)
+## Lokale git-repo + pull/push-workflow
 
 De projectdirectory zelf is een schone git-repo met `origin` op
 `ssh://gogs.digitalforce.tv:2222/Uitgaanskrant.com/flutterflow.git`,
@@ -46,57 +87,178 @@ grotere/rommelige repo die hoger in de mappenstructuur staat (die met
 AndroidStudioProjects, Flutter-SDK-installaties e.d.) — commits en
 pushes horen hier, in de projectdirectory zelf.
 
-Vaste workflow na elke afgeronde taak (op expliciet verzoek van de
-gebruiker, 2026-08-01): niet los `flutterflow export-code` draaien,
-maar het bestaande script gebruiken:
+Vaste workflow na elke afgeronde taak (staand akkoord, geen aparte
+bevestiging per keer nodig): niet los `flutterflow export-code`
+draaien, maar het bestaande script gebruiken:
 
 ```
-/home/bob/Projects/ff-run-fvm.sh emulator-5554 uitgaanskrant-1qhvtd -s
+export PATH="/home/bob/fvm/bin:$HOME/.pub-cache/bin:$PATH" && /home/bob/Projects/ff-run-fvm.sh emulator-5554 uitgaanskrant-1qhvtd -s
 ```
 
-Dit script (interactief van aard: device-run + hot-restart-loop) moet
-via Bash met `run_in_background: true` gestart worden — anders blokkeert
-het op de keypress-loop. Volg de output (Monitor of Read op het
-outputbestand) tot minimaal "All done!" (export gelukt) en idealiter
-ook een succesvolle app-launch op de emulator ("Flutter run key
-commands" / geen build-errors), voordat je verder gaat.
-
-Daarna automatisch (geen aparte bevestiging per keer nodig, staand
-akkoord van de gebruiker):
-1. `git add` — **niet blind `-A`**: controleer `git status --short`
-   eerst. Voeg alleen daadwerkelijke FlutterFlow/app-wijzigingen toe
-   (lib/, android/, ios/, pubspec, .gitignore e.d.). Sluit `.claude/`
+- **De `export PATH=...` prefix is verplicht.** De Bash-tool draait
+  niet-interactief, dus `~/.bashrc` (waar `fvm`/`flutterflow` normaal
+  op PATH komen) wordt niet geladen. Zonder deze prefix faalt het
+  script stil met "fvm: command not found" / "Prerequisites not met,
+  skipping execution" — geen harde error, dus makkelijk te missen.
+- Dit script is interactief (device-run + hot-restart-loop) — moet via
+  Bash met `run_in_background: true`. Volg de output tot minimaal
+  "All done!" (export gelukt) én idealiter een succesvolle app-launch
+  op de emulator (`Launching lib/main.dart...`, geen nieuwe
+  `EXCEPTION CAUGHT BY RENDERING LIBRARY` t.o.v. bekende issues in
+  `TASKS.md`) voordat je verder gaat.
+
+Daarna automatisch:
+1. `git status --short` bekijken, dan `git add` — **niet blind `-A`**.
+   Voeg alleen daadwerkelijke FlutterFlow/app-wijzigingen toe (`lib/`,
+   `android/`, `ios/`, `pubspec*`, `.gitignore` e.d.). Sluit `.claude/`
    uit (staat in .gitignore) — dat is sessiestate van Claude Code,
-   geen app-code.
+   geen app-code. Wijzigingen die niet van jezelf zijn (Bob's eigen
+   concurrent werk) horen gewoon mee in dezelfde commit — dit is één
+   gedeeld project.
 2. `git commit` met een duidelijke boodschap.
-3. `git push -u origin master` (of gewoon `git push` zodra tracking
+3. `git push` (of `git push -u origin master` als tracking nog niet
    staat).
 
-**Let op — belangrijke valkuil:** `flutterflow export-code` overschrijft
-**`.gitignore` telkens terug naar FlutterFlow's eigen standaardversie**
-(bevestigd 2026-08-01) — een eigen toevoeging zoals de `.claude/`-regel
-hieronder verdwijnt dus bij elke pull en moet opnieuw toegevoegd worden
-vóór je commit. (CLAUDE.md zelf wordt door de export NIET verwijderd —
-dat gebeurde één keer doordat de gebruiker zelf de hele projectmap had
-verwijderd en opnieuw had gepulled, niet door de export-tool zelf. Maar
-check voor de zekerheid na elke pull toch even of dit bestand nog
-bestaat; zo niet, opnieuw aanmaken met deze inhoud.)
-
-Voeg dus na elke pull, vóór je staged, deze regel weer toe aan
-`.gitignore` als hij ontbreekt:
+**Valkuil: `flutterflow export-code` overschrijft `.gitignore` bij
+elke export terug naar FlutterFlow's eigen standaardversie.** Voeg dus
+na elke export, vóór je staged, deze regel weer toe aan `.gitignore`
+als hij ontbreekt:
 ```
 # Claude Code session state (not app code)
 .claude/
 ```
+(`CLAUDE.md` zelf overleeft een export altijd — alleen bij een volledig
+verwijderde en opnieuw gepulde projectmap zou het verdwijnen. Check
+voor de zekerheid toch even of het bestand er nog is.)
 
-## Eerst research, dan bouwen (sinds 2026-08-03)
+## Eerst research, dan bouwen
 
-Voordat je aan een niet-triviale taak begint (een bug fix, een nieuw
+Voordat je aan een niet-triviale taak begint (een bugfix, een nieuw
 patroon, een integratie): zoek eerst kort op internet naar bestaande
-oplossingen/patronen (bijv. "FlutterFlow ConditionalBuilder default
-image", "Drupal 7 Services session auth FlutterFlow") voordat je het
-zelf helemaal uitvindt via trial-and-error in de builder. Dit kan
-sneller zijn dan zelf experimenteren, vooral bij FlutterFlow-builder-
-specifieke UI-flows of Drupal-integratiepatronen. Geldt niet voor
-triviale/mechanische herhaling van een patroon dat al binnen deze
-sessie is uitgezocht en bevestigd werkt.
+oplossingen/patronen voordat je het zelf helemaal uitvindt via
+trial-and-error in de builder. Geldt niet voor triviale/mechanische
+herhaling van een patroon dat al bevestigd werkt (zie hieronder).
+
+## FlutterFlow-builder: bekende problemen & patronen
+
+**Geneste "Set Variable"-dialoog kan lijken vast te zitten.** Bij het
+instellen van een conditie (`ConditionalBuilder`, Visibility →
+Conditional) op een niet-triviaal type (JSON Path, API-response-veld)
+opent een tweede dialoog bovenop de eerste. Confirm/Cancel op die
+binnenste dialoog reageren soms niet zichtbaar. Twee bekende oorzaken,
+in volgorde van proberen:
+1. **Viewport-clipping** — de knoppen renderen buiten het zichtbare
+   canvas, niet echt vast. Sleep de dialoog omhoog via het handvat
+   bovenin (kleine grijze balk) naar een hogere y-positie; de
+   Confirm/Cancel-knoppen worden dan zichtbaar en werken gewoon.
+2. **Echt bevroren pagina** (alle clicks, ook op onbetrokken plekken,
+   doen niets) — de widget-wrap zelf is al server-side opgeslagen,
+   maar de conditie-edit niet. Los op door de pagina te herladen
+   (`navigate` naar dezelfde URL); de wrap blijft staan, de
+   half-ingevulde conditie moet opnieuw.
+- **Kortere weg om deze dialoog te vermijden:** gebruik als operator
+  **"Is Set"** in plaats van "Not Equal To" + lege string — dan is er
+  geen Second Value nodig en dus geen tweede geneste dialoog.
+- Als dit na 1-2 pogingen (incl. de reload-poging) nog vastloopt: dit
+  kost dan meer tijd dan Bob het zelf kan doen — meld het concreet
+  (component, precieze stappen) en vraag het aan hem i.p.v. te blijven
+  proberen.
+
+**Component Name kan per ongeluk overschreven worden.** Vlak na
+paginanavigatie kan een klik bedoeld voor het "Search properties..."
+veld in plaats daarvan op het Component Name-veld landen (focus/
+z-order race condition), en typen hernoemt dan stilletjes het hele
+component. Mitigatie: na een click-before-type altijd eerst een
+screenshot om focus te bevestigen, zeker vlak na navigatie. Herstel:
+rechtsklik component in de zoekresultatenlijst → "Rename Component".
+
+**Rechterpaneel kan te breed zijn voor de viewport.** Sommige
+controls (Expansion segmented control, Visibility → Conditional
+expression builder) renderen soms deels buiten beeld — dit is geen
+`resize_window`-probleem (zie hierboven: niet zelf resizen). Na 1-2
+bevestigde pogingen stoppen en aan Bob vragen.
+
+**Patroon: lege/ontbrekende afbeeldings-URL laten crashen.**
+`CachedNetworkImage` gooit een **synchrone** `ArgumentError` bij het
+*bouwen* van de widget als `imageUrl` een lege string is — dit gebeurt
+vóórdat er ooit een netwerkverzoek wordt gedaan, dus `errorWidget`/
+"Show Error Image on Failure" vangt dit **niet** (dat vangt alleen
+échte laadfouten zoals 404's). Werkende fix, toegepast op 9 van de ~10
+bekende instanties (zie `TASKS.md`):
+1. Rechtsklik het Image-widget → **Wrap Widget (Ctrl+B)** →
+   **ConditionalBuilder**.
+2. IF-conditie: **Conditions → Single Condition** → First Value = de
+   exacte expressie waar de Image's Path-property al aan gebonden was
+   (component-parameter, JSON Path, of custom-function-resultaat via
+   "Evenement Response" → API Response Options → JSON Body → JSON
+   Path, bv. `$[0].logo`) → operator **"Is Set"**.
+3. THEN-tak: de bestaande Image (blijft staan na de wrap).
+4. ELSE-tak: rechtsklik → Insert Widget → Icon → zoek "image not
+   supported" → eerste Material-resultaat.
+- **Simpeler alternatief indien van toepassing:** de "Default Variable
+  Value"-toggle op een willekeurige "Set from Variable"-binding
+  substitueert al bij zowel `null` als lege string (bevestigd via
+  in-builder tooltip: "if the resulting value is null or empty") —
+  géén ConditionalBuilder nodig. Werkt hier alleen niet voor
+  Image-widgets met `Image Type: Network`, omdat er nog geen gehoste
+  fallback-afbeeldings-URL bestaat in dit project. Mocht die er ooit
+  komen (bv. een default-logo op de FlutterFlow-CDN of Drupal-server):
+  gebruik dan Default Variable Value + "Show Error Image on Failure"
+  i.p.v. ConditionalBuilder — sneller te bouwen.
+
+**Tooltip toevoegen aan een icon-only widget:** rechtsklik → Wrap
+Widget (Ctrl+B) → 4e rij van de grid (kan geclipt lijken) → 1e icoon
+(spraakwolkje) = "Tooltip". Genereert een `AlignedTooltip` (zelfde
+stijl als de gedeelde header), geen losse styling nodig. Werkt niet op
+iconen die embedded zitten als `suffixIcon` van een `TextFormField`
+(bv. Login-pagina's wis-/toon-wachtwoord-iconen — geen losse
+wrapbare tree-node).
+
+**API-call headers: check op hardcoded literals i.p.v. `[varname]`
+templates.** Als een API-call via curl wél werkt maar vanuit de app/
+Response & Test-panel niet, controleer het Headers-tabblad van de
+call-configuratie — een handmatig ingeplakte testwaarde (bv. een
+Cookie-header) kan per ongeluk blijven staan i.p.v. de
+`[sessionname]=[sessionid]`-template. Check ook het per-variabele
+"Include"-vinkje in Response & Test — staat die uit, dan wordt de
+letterlijke `[varname]`-tekst meegestuurd i.p.v. de testwaarde.
+
+## Domein/architectuurcontext
+
+- **Drupal 7 Services sessie-auth**: `sessid` + `session_name` (uit
+  `LoginCall`'s response) vormen samen de sessie-cookie:
+  `Cookie: <session_name>=<sessid>`. `token` is een los CSRF-token,
+  alleen nodig bij schrijf-requests (POST/PUT/DELETE), nooit bij GET.
+- **Drupal page cache bootstrapt vóór de sessie** — een ooit anoniem
+  gecachete response (bv. een 403) kan session-bootstrap, hooks én
+  custom-module-logging volledig overslaan. Bij twijfel: Drupal-cache
+  legen en opnieuw testen vóór je verder debugt.
+- **Views numeric filter**: `$view->filter['uid']->value` moet
+  `array('value' => $uid)` zijn, niet `array($uid)` — de foute vorm
+  faalt stil (geen filter toegepast) i.p.v. een error te geven.
+- Provincie/gemeente is en blijft het basismodel voor content-scoping
+  (bevestigd door Bob: mensen zoeken primair lokaal). Home is de
+  landelijke standaard-startpagina zónder verplichte gemeente-keuze
+  vooraf (task #31, afgerond) — dat vervangt niet het provincie/
+  gemeente-model, het is een aanvullende ingang.
+- Favorieten/login zijn P0. Backend-endpoint bestaat al; Drupal 7
+  views die de respons voeden hebben soms nog aanpassing nodig.
+
+## Samenwerken met Bob
+
+- Bob is de enige developer/eigenaar en werkt vaak **zelf gelijktijdig**
+  in dezelfde FlutterFlow-builder-sessie. Neem niet aan dat elke
+  wijziging van jou komt.
+- Prioriteit: "eerst een werkende app live, daarna features" — P0
+  (blokkeert livegang) weegt zwaar boven P1 (polish/performance) en P2
+  (nieuwe features). Bob herprioriteert soms fors zelf (bv. login+
+  favorieten van P2 naar P0) — volg dat exact.
+- Als Bob een taak terugclaimt ("dat regel ik zelf") — stop daar direct
+  mee en pak iets anders onafhankelijks op.
+- **Als iets veel tijd kost door handmatige builder-acties** (vastzittende
+  dialogen, geclipte controls e.d.): na 1-2 serieuze pogingen stoppen
+  en concreet aan Bob voorstellen dat hij het zelf doet (met exacte
+  stappen) i.p.v. door te blijven proberen.
+- Browser niet zelf resizen (zie boven).
+- Rapporteer nieuw gevonden bugs (vooral op een pagina waar Bob net
+  zelf op zit) direct en duidelijk, niet pas in een latere samenvatting.

+ 199 - 0
TASKS.md

@@ -0,0 +1,199 @@
+# Uitgaanskrant — takenlijst
+
+Bijgewerkt: 2026-08-04. Zie `CLAUDE.md` voor werkinstructies/conventies.
+Elke openstaande taak hieronder is bedoeld om zonder eerdere chatcontext
+opgepakt te kunnen worden — bestandspaden en concrete stappen staan
+erbij waar bekend.
+
+## Status: actief bij Bob (geen Claude-actie nodig, ter info)
+
+- **FavorietenAgenda 403-fout**: Bob is dit zelf aan het troubleshooten.
+  FlutterFlow-requests komen bij nginx binnen met een lege
+  Cookie-header; zijn eigen browser/curl (via dezelfde Cloudflare-edge)
+  sturen de sessie-cookie wél mee. Cloudflare Cache Rule voor `SSESS*`
+  staat al goed (bypass, eerste regel). Werkhypothese: Cloudflare Bot
+  Management behandelt FlutterFlow's server-side traffic anders op
+  basis van IP-reputatie/TLS-fingerprint. Niet opnieuw diagnosticeren
+  zonder navraag — check eerst of Bob al verder is.
+
+## P0 — blokkeert livegang
+
+- [ ] **Home-slider crasht (RangeError) bij 0 API-resultaten.**
+  `CarouselSlider.builder` met `itemCount: 0` crasht. De originele
+  `PUitgaanSliderComponent` had deze bug (al gefixt daar, zie
+  "afgerond" hieronder). `HomeUitgaantabelKaartComponent`/de
+  Home-slider is een kopie van diezelfde code voor de landelijke
+  (cityid-loze) query — waarschijnlijk dezelfde bug geërfd. Check en
+  fix met hetzelfde patroon (empty-state check vóór de builder).
+
+- [ ] **Werkende login + favorieten — resterende deeltjes.** Grote
+  basis is af (zie "afgerond"): login echt gekoppeld, wachtwoord-
+  vergeten-flow, favorieten drawer-link + 3-tabblad-pagina, hartje op
+  horeca-kaart + horeca-detailpagina. Nog open:
+  - Lege-lijst empty-state op de favorietenpagina (nu kale/lege
+    Container als er nog geen favorieten zijn).
+  - Bevestigen dat favorieten écht syncen via Drupal bij inloggen
+    (i.p.v. alleen lokaal opgeslagen) — hangt af van het
+    FavorietenAgenda-403-issue hierboven.
+  - Hartje op **gemeente** (zie apart item hieronder — geblokkeerd op
+    een designvraag).
+
+- [ ] **Hartje-icoon op gemeente — geblokkeerd op designvraag.** Bob
+  koos: heart ergens anders dan de gemeente-dropdown zelf (dropdown
+  blijft ongewijzigd). Blocker: **geen enkele pagina toont de
+  geselecteerde gemeente-náám als tekst** — alleen het numerieke ID
+  (`FFAppState().gemeenteSelectId`) wordt doorgegeven als filter (bv.
+  `plaats`/`townid` param op `PUitgaanPageWidget`). `GemeentenCall.
+  gemeenteName()` in `lib/backend/api_requests/api_calls.dart` bestaat
+  al maar is ongebruikt. **Voordat je bouwt: vraag Bob expliciet waar
+  de gemeente-naam + hartje moeten komen** (meest voor de hand
+  liggende kandidaat: AppBar van `PUitgaanPageWidget`, de pagina die je
+  bereikt na het kiezen van een gemeente in de drawer) — niet zelf
+  raden aan de layout.
+  - Gerelateerd: een custom function `provincieNaamById`/
+    `gemeenteNaamById` (in `lib/flutter_flow/custom_functions.dart`,
+    committed, compileert) is al gebouwd maar nog **niet gekoppeld**
+    aan een widget — de binding-poging liep vast op een FlutterFlow-
+    builderbug met `List<CustomDataType>`-argumenten (zie CLAUDE.md,
+    "geneste Set Variable-dialoog"). Simpeler alternatief dat die bug
+    vermijdt: naam vastleggen in een plain String App State-variabele
+    op het moment van selectie, i.p.v. 'm live op te zoeken via een
+    List-typed lookup function.
+
+- [ ] **"Hello Worlddd" — letterlijke debugtekst op de live
+  Event-pagina.** Geen veldnaam-fallback, een vergeten testregel.
+  `lib/evenement/evenement_info/evenement_info_widget.dart:185-188`
+  (translation key `kslnk9ez`).
+
+- [ ] **Overflow-bug in Event→Horeca-kaartje.** Zelfde
+  Row+Icon+Text-zonder-Flexible-patroon dat al 2x eerder gefixt is
+  (slider + tabelkaart, zie "afgerond") — nu op de adres/plaats- én
+  telefoonregel.
+  `lib/evenement/evenement_horecagelegenheid/evenement_horecagelegenheid_widget.dart:471-599`.
+
+- [ ] **Foutafhandeling ontbreekt op HorecagelegenhedenOverzicht.** 6
+  FutureBuilders checken alleen "geen data nog", geen enkele checkt op
+  een mislukte call — bij een netwerkfout blijft het laadwieltje
+  voor altijd draaien.
+  `lib/horecagelegenhedenoverzicht/horecagelegenheden_overzicht/horecagelegenheden_overzicht_widget.dart`
+  (regels 276, 460, 644, 828, 1012, 1196).
+
+- [ ] **Drupal: anonieme leestoegang onderzoeken voor browse-
+  endpoints.** Bob's eigen actie op Drupal-niveau, geen Claude-taak.
+
+## P1 — snel na livegang
+
+- [ ] **Lege image-URL crash (CachedNetworkImage) — 1 van 10
+  resterend.** Patroon en volledige uitleg staan in `CLAUDE.md`
+  ("Patroon: lege/ontbrekende afbeeldings-URL laten crashen"). 9 van
+  de 10 bekende instanties zijn al gefixt en gepusht. **Laatste
+  resterende:** component `EvenementHorecagelegenheid`, widget
+  `Column > Carousel > Carousel Page > Image` (Path gebonden aan
+  `fotoosItem`, een lijst-item-string). De `ConditionalBuilder`-wrap
+  staat al (server-side opgeslagen), maar de IF-conditie is nog
+  `Unset` — het instellen ervan liep herhaaldelijk vast op de geneste
+  Set Variable-dialoogbug (zie CLAUDE.md). Volgende poging: gewoon
+  opnieuw proberen met de "Is Set"-operator (korte weg, geen Second
+  Value nodig); lukt dat niet binnen 1-2 pogingen, vraag het aan Bob
+  (exacte stappen staan in CLAUDE.md).
+  - Nog niet gecontroleerd of er ook op andere, nog niet doorzochte
+    pagina's instanties van dit patroon voorkomen — de 10 bekende
+    kwamen uit een gerichte `grep -rl "CachedNetworkImage"` over
+    `lib/**/*_widget.dart`; die grep zelf is waarschijnlijk nog
+    compleet, maar een her-check na toekomstige nieuwe pagina's is
+    verstandig.
+
+- [ ] **Loading/foutafhandeling-patroon repliceren naar andere
+  lijstpagina's.** Het patroon dat al werkt op de Uitgaan-pagina
+  (eventenlijst) toepassen op overige lijst-/detailpagina's (Event,
+  HorecagelegenheidCurrent, sliders) — nu geen enkele foutstatus
+  daar, alleen "geen data nog".
+
+- [ ] **"Thuis bezorgen" koppelen aan een echt leverbaar-veld per
+  horecagelegenheid.** Wacht op Bob: hij moet eerst het
+  API-endpoint aan Drupal-kant configureren. Daarna: tonen/verbergen
+  op basis van het echte veld i.p.v. de huidige dode tap.
+
+- [ ] **Overflow op Home-pagina.** Live gereproduceerd tijdens het
+  testen (2026-08-03): `RenderFlex overflowed by 7338 pixels` in een
+  `Column` zonder `Expanded`/scrollcontainer.
+  `lib/uitgaanspaginas/home/home_widget.dart:316`.
+
+- [ ] **~25+ plekken tonen letterlijke veldnaam i.p.v. nette
+  placeholder** (bv. "titel", "adres", "def") bij ontbrekende data.
+  Nog niet geïnventariseerd welke exact — audit-agent-bevinding,
+  concrete lijst nog te maken.
+
+- [ ] **EstablishmentsCall crasht zonder categoriefilter.**
+  `horcat ??= null!;` — nu geen probleem omdat elke aanroep toevallig
+  altijd een filter meegeeft, wel een landmijn voor de toekomst.
+  `lib/backend/api_requests/api_calls.dart:1151`.
+
+- [ ] **Sliderkaartje: datumregel mist de Flexible-wrap.** Zelfde
+  patroon als de twee regels eronder die al gefixt zijn (consistentie).
+  `p_uitgaan_slider_kaart_component_widget.dart:273-306`.
+
+- [ ] **Account/profielscherm** (wachtwoord wijzigen, uitloggen,
+  account verwijderen) — bovenop de login/favorieten-P0-basis. Account
+  verwijderen heeft mogelijk AVG-implicaties aan Drupal-kant.
+
+- [ ] **Toegankelijkheid & navigatie, restpunten:**
+  - Login-pagina: 2 icon-only knoppen zonder tooltip (veld wissen +
+    wachtwoord tonen/verbergen) — `login_widget.dart:270-280,
+    392-401`. Let op: dit zijn `suffixIcon`s van een `TextFormField`,
+    de standaard Tooltip-wrap werkt daar niet op (zie CLAUDE.md).
+  - Overige icon-only knoppen buiten de header van tooltip voorzien.
+  - Bevestig-stap toevoegen aan de provincie/gemeente-kiezer (nu geen
+    "Toepassen"-knop of bevestiging).
+  - Vaste "terug naar hoofdlijst"-snelkoppeling op detailpagina's
+    (nu alleen letterlijk terug/`context.pop`).
+  - Deep-link/query-param robuustheid checken (ongeldig/verlopen
+    `nid`, bv. gedeelde link naar verwijderd event).
+
+- [ ] **Visuele polish** (los, per pagina): Uitgaan-pagina
+  (typografie/contrast/spacing), Event-pagina, HorecagelegenhedenOverzicht,
+  tabel-kaartje-afstemming met slider-kaartje, categorie-tag mag
+  titel/datum niet overstemmen in dichte lijstweergaves.
+
+- [ ] **Performance:**
+  - Dubbele/onnodige netwerkverzoeken checken (audit, nog te doen).
+  - 6-7 tabbladen laden allemaal meteen hun eigen data bij elke
+    tabwissel/herbouw (TabBarView bouwt alle tabs eager) —
+    `horecagelegenheden_overzicht(_sort_page/_page_data_type)_widget.dart`.
+
+- [ ] **Responsive/screensize-audit** — o.a. het vaste 200×200px-
+  tegelformaat in het venue-event-grid dat botst met de
+  grid-berekening.
+
+## P2 — features & concept, na livegang
+
+- [ ] **Datum-filter**: Vandaag / Dit weekend / Deze week.
+- [ ] **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).
+- [ ] **"In de buurt"/geolocatie-browsen** — aanvulling op het
+  provincie/gemeente-model, geen vervanging.
+- [ ] "Wat is er vanavond"-melding/widget.
+- [ ] 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.
+- [ ] Ad-banners op horeca-overzicht, horeca-detail, event-detail;
+  vaste regel: geen ads op locatie-kiezer/login/account.
+- [ ] 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).
+- [ ] **Opschonen:**
+  - Merge `kaartTabelUitgaanComp` + `kaartTabelUitgaanSComp` — Bob
+    doet dit zelf ("ik kijk er zelf naar").
+  - `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).