Procházet zdrojové kódy

TASKS.md: P1-15 uitgebreid met 3 nieuw gevonden ongegarandeerde launchURL-crashplekken (Menukaart-knop + 2x Website-knop zonder enige guard), horecagelegenheid_current_widget.dart uitgesloten. P1-21 punt 2 gecorrigeerd: lib/flutter_flow/-bestand is gegenereerd, niet zomaar lokaal duurzaam te editen zoals eerder aangenomen — teruggezet naar open taak (custom-widget-route).

bob před 1 měsícem
rodič
revize
99a25b6a09
1 změnil soubory, kde provedl 181 přidání a 62 odebrání
  1. 181 62
      TASKS.md

+ 181 - 62
TASKS.md

@@ -1,11 +1,32 @@
 # Uitgaanskrant — takenlijst
 
-Bijgewerkt: 2026-08-12 (Claude, "ogen van een gebruiker"-reviewsessie).
+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-12, review):** volledige gebruikersdoorloop op
+**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
@@ -314,6 +335,34 @@ puur de zichtbare impact):**
   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
@@ -437,20 +486,60 @@ verwarren — twee losse foutmeldingen in dezelfde log).
   `!= 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.
-- **Nog te controleren of hetzelfde patroon ook elders voorkomt**
-  (bv. `horecagelegenheid_current_widget.dart` heeft vergelijkbare
-  velden, maar daar is maar 1 losse `!= null &&`-treffer gevonden —
-  niet diep genoeg nagekeken deze sessie om zeker te zijn dat het daar
-  wél goed staat).
-- **Scope vermoedelijk groter dan gedacht:** 2026-08-07, live op de
-  emulator, verscheen `Invalid argument(s): No host specified in
-  URI` al herhaaldelijk **op/vanaf de Home-pagina zelf**, vóór enige
-  navigatie naar een horecagelegenheid-detailpagina. Dat wijst erop
-  dat hetzelfde kapotte-guard-patroon ook in Home-gerelateerde
-  componenten zit (bv. de Home-sliderkaartjes of de "OOK LEUK"-tegels),
-  niet alleen in `evenement_horecagelegenheid_widget.dart`. Nog niet
-  tot de exacte plek herleid — bij oppakken van deze taak breder zoeken
-  dan alleen het al gevonden bestand.
+- **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 `InkWell` → `onTap: () 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:268` —
+      `onTap: () 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:414` —
+      `onTap: () 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-component** — `EvenementComponentWidget`
+    (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
@@ -531,24 +620,55 @@ nl-NL` (betrouwbaardere per-app-locale-override dan de systeembrede
 emulator niet altijd doorwerkte zonder reboot) kwam de tekst meteen
 terug — bevestigt dat dit puur een vertaalprobleem is, geen widget-bug.
 
-**P1-7 · Eigenaar: Claude — bezig (2026-08-09).** Favorieten-pagina +
-profielscherm — Bob heeft de scope + designbeslissingen 2026-08-09
-gegeven, absorbeert ook het oude P2-8 (gemeente-favoriet). **Belangrijke
-bevinding vooraf (code-audit, niet eerder gedocumenteerd):** de
-3-tabblad-structuur op `FavorietenWidget` bestaat al (`Persoonlijke
-agenda`/`Favoriete gemeenten`/`Favoriete Gelegenheden`), maar **alle 3
-tabs zijn pure placeholder-tekst — geen enkele API-call/FutureBuilder**.
-Én: het hartje op zowel de horeca-overzichtskaart als de
-horeca-detailpagina is een kale `print('IconButtonFavoriet pressed
-...')`-stub (`horecagelegenheidoverzicht_kaart_widget.dart:334`,
-`horecagelegenheid_current_widget.dart:364`) — **er bestaat nergens in
-de codebase een POST/toggle-call om een favoriet daadwerkelijk op te
-slaan**, alleen de GET-only `FavorietenAgendaCall` (ondanks de naam:
-geeft favoriete horecagelegenheden terug, geen agenda/events). De
-eerdere P0-4-aantekening "hartje... af" klopte dus alleen voor het
-zichtbare icoon, niet voor de functionaliteit erachter.
+**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.
 
-**Bob's beslissingen (2026-08-09):**
+**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`/
@@ -564,31 +684,6 @@ zichtbare icoon, niet voor de functionaliteit erachter.
    eist in-app accountverwijdering voor een app met accountaanmaak —
    zonder dit scherm blokkeert een iOS-submissie, niet alleen P1.
 
-**Open vraag aan Bob (blokkeert het schrijf-/sync-gedeelte):** 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 kan Claude alleen de lokale kant (state, UI,
-hartje-toggle-optimistic-update, logout) bouwen, niet de sync.
-**Onbelemmerd te bouwen, ongeacht antwoord:** `FFAppState`-velden voor
-lokale favorieten-lijsten (gemeenten + horeca), hartje-toggle die lokaal
-al werkt (optimistic UI), uitloggen op de Gebruiker-tab (geen backend
-nodig — alleen `FFAppState`-sessievelden wissen + terug naar Login).
-
-**Geblokkeerd voor Claude (2026-08-09), klein klusje voor Bob:** de
-"+ Add App State Variable"-knop (`?tab=appValues&appValuesTab=state`)
-reageert niet op Claude's klikken — geen dialoog, geen nieuwe rij, 6+
-pogingen zonder resultaat (zie `CLAUDE.md` voor details). **Bob: graag
-deze 2 App State-velden zelf toevoegen** (kost seconden in eigen
-browser):
-1. `favorieteGemeenteIds` — type `List<String>` (gemeente-ID's, zelfde
-   ID-vorm als `gemeenteSelectId`/`gemeentelijst`), Persisted: true.
-2. `favorieteHorecaNids` — type `List<String>` (horeca-`nid`'s, zelfde
-   vorm als `FavorietenAgendaCall.establishmentNid`), Persisted: true.
-
-Zodra deze 2 velden bestaan kan Claude verder (hartje-toggle, tab-content
-vullen) — de rest van de bouw hangt hier niet losstaand van vast.
-
 *(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
@@ -903,10 +998,34 @@ BannerAd failedToLoad: LoadAdError(code: 0, domain: com.google.android.gms.ads,
   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 — dit is een **custom/lokaal bestand** (onderdeel van
-  de FlutterFlow-standaard widgetlibrary), dus in tegenstelling tot
-  pagina's/componenten wél rechtstreeks in de code aan te passen zonder
-  builder-UI (net als `lib/custom_code/`, zie `CLAUDE.md`).
+  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