فهرست منبع

TASKS/CLAUDE: vertaalronde Deel A, caching-taken af, helppagina live

Sessie waarin Bob de builder-klikken deed en Claude per taak met een verse
export/curl verifieerde. Afgerond: P1-17 Deel A op 3 regels na, taak 58
punten 1-3 (establishments in de edge-cache, cache:true op 8 API Calls,
taxonomie op 2 uur), taak 59 helppagina + privacybeleid, taak 57 punt 1
(Cultuur-icoon) en P1-53 (thuisBezorgen AppBar). P2-36 afgewezen.

CLAUDE.md: Cloudflare-stand bijgewerkt naar twee Cache Rules, plus de les
dat veel vertaalsleutels op Tooltip-nodes zitten.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bob 1 روز پیش
والد
کامیت
460d2948ce
2فایلهای تغییر یافته به همراه192 افزوده شده و 144 حذف شده
  1. 40 13
      CLAUDE.md
  2. 152 131
      TASKS.md

+ 40 - 13
CLAUDE.md

@@ -2838,6 +2838,19 @@ bovenaan in te klappen (chevron rechts) levert 3-4 extra rijen op, meer
 niet. In Bob's eigen browser werkt dit paneel waarschijnlijk gewoon —
 voor hem blijft het de snelste route.
 
+**⚠️ Een groot deel van de vertaalsleutels zit op TOOLTIP-nodes, niet op
+zichtbare labels — daar kom je nooit op door de app te bekijken.** Bevestigd
+2026-09-16: `Terug` (`vnwx710y`) is de tooltip op het terug-pijltje onderaan de
+drawer, `Veld wissen` (`pj545url`) en `Wachtwoord tonen/verbergen` (`n3cyffso`)
+zijn de tooltips rond de twee invoervelden op de Login-pagina. Een tooltip is
+alleen zichtbaar bij tikken, dus zoeken op de Nederlandse tekst in de app helpt
+niet. **Route: widget tree → zoek op `Tooltip`** — de `AlignedTooltip`-nodes
+staan dan in documentvolgorde, dus in dezelfde volgorde als de velden op het
+scherm. Het globe-icoontje zit op het Text/Content-veld ván die tooltip.
+**En: het vertaaldialoogje heeft last van het bekende "ziet er opgeslagen uit,
+was het niet"-patroon** — in één ronde kwamen 2 van de 8 regels door, zonder
+enige foutmelding. Verifieer altijd met een verse export, niet met het paneel.
+
 **Werkend alternatief, per widget (bevestigd 22x achter elkaar):**
 selecteer het widget → in het rechterpaneel staat naast het label
 **"Text"** (bij een `Text`-widget onder "Text Properties", bij een
@@ -3586,23 +3599,37 @@ aantal round trips bij infinite scroll voor 0,01 s. Staat sinds die datum op
 `defaults['filter_groups']` op FALSE — **de pager erven ze wél**, dus dit is
 één wijziging op de Master voor alle zeven.
 
-**Cloudflare cachet sinds 2026-09-15 zes publieke endpoints 5 minuten aan de
-edge — reken daarmee bij élke meting én bij elke Drupal-deploy.** Rule
-"FlutterFlow publieke endpoints": `GET` zonder `SESS`-cookie op
-`flutterflowmobiel1.json`, `flutterflow_events.json`,
-`flutterflowmobiel_establishment_info.json`,
-`flutterflowmobiel_establishment_events.json`, `plaatsen.json` en
-`plaatsen_bij_gemeente.json`; Edge TTL 300 s, "Ignore cache-control" (de origin
-stuurt `no-store`). Gemeten: MISS 1,2 s → HIT 0,06–0,09 s. Drie gevolgen:
+**Cloudflare cachet de publieke endpoints aan de edge, sinds 2026-09-16 verdeeld
+over TWEE Cache Rules — reken daarmee bij élke meting én bij elke Drupal-deploy.**
+Beide rules matchen op `GET` zonder `SESS`-cookie, met "Ignore cache-control"
+(de origin stuurt `no-store`):
+- **"FlutterFlow publieke endpoints" — Edge TTL 300 s (5 min):**
+  `flutterflowmobiel1.json`, `flutterflow_events.json`,
+  `flutterflowmobiel_establishment_info.json`,
+  `flutterflowmobiel_establishment_events.json` en sinds 2026-09-16 ook
+  **`flutterflowmobiel_establishments.json`** (het zwaarste endpoint, 1,3–1,8 s;
+  het horeca-overzicht laadt er zes, één per tab — MISS → HIT gemeten).
+- **"FlutterFlow publieke endpoints 60 minuten" — Edge TTL 2 uur:**
+  `plaatsen.json` en `plaatsen_bij_gemeente.json` (taxonomie, verandert zelden).
+  Het TTL-dropdownmenu heeft geen optie van 1 uur, vandaar 2.
+
+Gemeten: MISS 1,2 s → HIT 0,06–0,09 s. Vier gevolgen:
 - Een `_cb=`-cache-buster omzeilt Cloudflare **én** Drupal's page cache. Een
   `_cb`-test bewijst dus dat de code klopt, maar zegt niets over wat de app
-  ziet — die krijgt tot 5 min het oude antwoord. Na een deploy: `cc all` **en**
-  de rule purgen.
-- `flutterflowmobiel_establishments.json` hoort er bewust **niet** in (filtert
-  per gebruiker op favorieten). Zet nooit een endpoint in de lijst dat een
-  sessie-afhankelijk antwoord geeft.
+  ziet. Na een deploy: `cc all` **en** de juiste rule purgen — vergeet de
+  2-uurs-rule niet als je aan de plaatsen-endpoints hebt gezeten.
+- ⚠️ `flutterflowmobiel_establishments.json` mag **alleen** in de rule met de
+  `SESS`-cookie-voorwaarde: `custom_views_query_alter()` filtert die view voor
+  een ingelogde gebruiker op favorieten. Zonder die voorwaarde beland je met
+  iemands persoonlijke lijst in een gedeelde cache.
 - Basic-Auth-requests worden gewoon meegecachet (HIT gezien met `-u`), dus de
   cache is gedeeld over alle bezoekers — precies de bedoeling voor deze data.
+- **Meet met de query die de app echt gebruikt.** `plaatsen.json` kaal gaf
+  `cf-cache-status: DYNAMIC` (geen rule-match), terwijl
+  `plaatsen.json?limit_levels=2` — wat de app stuurt — netjes HIT gaf. En een
+  eerste paar metingen kan MISS/MISS tonen doordat je op verschillende edge-PoP's
+  landt (`cf-ray` laat dat zien: AMS vs LHR); meet drie keer vóór je concludeert
+  dat een rule niet werkt.
 
 **`flutterflowmobiel1` accepteert (na deploy van 2026-09-15) ook `zoek=`:** een
 hoofdletterongevoelige `LIKE` op `node.title`, gebouwd in

+ 152 - 131
TASKS.md

@@ -28,6 +28,27 @@ FlutterFlow-commit op `main`**, de commit-knop in het Version Control-paneel
 reageerde niet op Claude's klik. `dart analyze` op de verse export: 0 errors.
 Emulator-5556 heeft nu de profile-APK van die export + per-app-locale `nl-NL`.*
 
+### ✅ Sessie 2026-09-16 (Bob klikt, Claude verifieert) — vertalingen, caching, helppagina
+
+*Werkwijze: Claude gaf taken per nummer, Bob voerde ze uit in zijn eigen browser,
+Claude verifieerde elke taak met een verse export of een `curl`. Alles hieronder
+is geverifieerd, niet alleen "Synced" in de builder.*
+
+- **P1-17 Deel A vrijwel af** (zie Bob's 7, taak 3) — restant: 3 regels op het
+  horeca-overzicht, staat als Claude-taak bij de restpunten.
+- **Taak 58 caching: punten 1, 2 en 3 afgerond.** Establishments-endpoint in de
+  5-minuten-rule (MISS → HIT gemeten), `cache: true` op 8 extra API Calls (13 van
+  18 nu), en een tweede Cloudflare-rule met de twee taxonomie-endpoints op 2 uur.
+- **Taak 59 helppagina af**: twee publieke Drupal-nodes + menu-item "Support
+  pagina" in de drawer. Enige restpunt is de 403 op `/nl/account-verwijderen`,
+  verhuisd naar Bob's 7 taak 2 (Play Console).
+- **Taak 57 punt 1 af**: Cultuur-icoon in het menu (`Icons.theater_comedy`).
+- **P1-53 af** (Claude, in de builder): `thuisBezorgen` AppBar op leisteen.
+- **`filterDatumVan`/`filterDatumTot` geplakt** — datumfilter werkt nu in NL én EN.
+- **P2-36 afgewezen door Bob**: kaarttitels blijven Roboto.
+- **Niet opgepakt, bewust:** de builder-opruimronde (Bob: "andere keer") en
+  P2-35, dat eerst op een toestel nagemeten moet worden.
+
 ### ✅ Sessie 2026-09-16 (Claude, builder + verse export per stap) — zoekveld + look&feel
 
 *Opdracht Bob: "maak van het zoekveld een taak, doe dat direct; pas ook de look &
@@ -99,11 +120,14 @@ P1-52 `EventCurrent`, P2-30 horeca-overzicht, P2-31 kaartstijlen, P2-32 titels,
 P2-33 horeca-detail. **Werk uit die lijst, niet uit deze** — hier staan alleen
 de twee dingen die daar niet in voorkomen, gezien op de telefoon-emulator.*
 
-1. **Het Cultuur-icoon in het hoofdmenu springt uit de lijn** — het staat iets
-   lager en groter dan de zes andere icoontjes in het Gemeente-blok. Zelfde soort
-   oorzaak als het "Zoek stad"-icoon dat deze sessie gefixt is (dat stond op
-   `size: 1.0`): kijk met `grep -A3 "leading: Icon(" drawer_component_widget.dart`
-   welke rij een afwijkende `size:` heeft. Kleine ingreep.
+1. ~~Cultuur-icoon in het hoofdmenu~~ **✅ GEDAAN 2026-09-16 (Bob).** Het lag
+   *niet* aan een afwijkende `size:` — alle leading-iconen in de drawer staan op
+   de default. De oorzaak was het icoon zelf: `FontAwesomeIcons.piedPiperAlt`
+   (een tech-bedrijfslogo) heeft een andere glyph-verhouding dan de Material-
+   iconen ernaast. Vervangen door `Icons.theater_comedy` op beide plekken
+   (Gemeente-blok én Provincie-blok), export-geverifieerd. **Les:** een icoon dat
+   "uit de lijn springt" is net zo vaak een verkeerd gekozen FontAwesome-glyph
+   als een verkeerde `size`.
 2. **Het menu is lang doordat het Gemeente-blok en het Provincie-blok dezelfde
    zeven rijen herhalen** (Uitgaan, Activiteiten, Cultuur, Films, Jeugd, Horeca,
    Thuis bezorgen). Overweeg het Provincie-blok standaard ingeklapt te tonen.
@@ -133,77 +157,64 @@ uit de sessie van 15 sep: dezelfde URL drie keer achter elkaar gaf 1,23 s (MISS)
 → 0,10 s (HIT) → 0,11 s (HIT). Drupal's page cache doet dus 12× zoveel als alle
 micro-optimalisaties samen.
 
-1. **`flutterflowmobiel_establishments.json` alsnog in de Cloudflare-rule
-   "FlutterFlow publieke endpoints".** Grootste winst die er nog ligt. Dit is
-   het zwaarste endpoint (100 items per pagina, 1,3–1,8 s gemeten) en het
-   horeca-overzicht laadt er **zes** van, één per tab. Met de bestaande
-   rule-voorwaarde *"GET zonder `SESS`-cookie"* is het veilig: de app stuurt op
-   `HorecagelegenheidoverzichtCall` **geen** sessiecookie mee (`headers: {}` in
-   de export), en de favorietenfilter in `custom_views_query_alter()` grijpt
-   alleen bij een ingelogd verzoek. Verwachte winst: ~1,5 s → ~0,1 s per tab.
-   ⚠️ Zet dit endpoint **nooit** in de rule zonder die cookie-voorwaarde.
-2. **`cache: true` op meer API Calls.** Nu staat de vlag op 5 van de 18:
-   `homeTabel`, `EstablishmentInfo`, `Gemeenten`, `Provincies`,
-   `Horecagelegenheidoverzicht`. Ontbreekt op user-onafhankelijke reads die
-   binnen één sessie vaak herhaald worden: **`homeSlider`**, **`Uitgaanstabel`**,
-   **`UitgaanSlider`**, **`Evenement`** (evenement-detail),
-   **`HorecagelegenheidEvents`**, **`PlaatsenBijGemeente`**, **`Categorieen`**,
-   **`Entreeopties`**. Levert winst bij terugnavigeren binnen een sessie.
-   *De cache is veilig* — `ApiCallOptions extends Equatable` met `params` en
-   `headers` in `props`, dus hij vergelijkt op echte parameterwaarden.
-   *Kanttekening:* FlutterFlow's cache verloopt nooit binnen een sessie, dus
-   voor de **sliders** betekent dit dat een gebruiker die de app uren open laat
-   staan oude slider-inhoud houdt. Voor `Evenement` en `Entreeopties` is dat
-   geen bezwaar.
-3. **Langere edge-TTL voor taxonomie.** `plaatsen.json` en
-   `plaatsen_bij_gemeente.json` veranderen zelden — 30 tot 60 minuten in plaats
-   van 5. Puur een getal in de bestaande Cloudflare-rule.
+1. ~~`flutterflowmobiel_establishments.json` in de Cloudflare-rule~~ **✅ GEDAAN
+   2026-09-16 (Bob), gemeten door Claude:** eerste verzoek `MISS`, tweede `HIT`.
+   Staat in de rule "FlutterFlow publieke endpoints" (5 min) mét de voorwaarde
+   *"GET zonder `SESS`-cookie"* — die voorwaarde is niet optioneel, want
+   `custom_views_query_alter()` filtert deze view per ingelogde gebruiker op
+   favorieten.
+2. ~~`cache: true` op meer API Calls~~ **✅ GEDAAN 2026-09-16 (Bob),
+   export-geverifieerd:** alle 8 (`homeSlider`, `Uitgaanstabel`, `UitgaanSlider`,
+   `Evenement`, `HorecagelegenheidEvents`, `PlaatsenBijGemeente`, `Categorieen`,
+   `Entreeopties`) staan nu op `cache: true`. Dus 13 van de 18.
+   *Kanttekening die blijft gelden:* FlutterFlow's cache verloopt nooit binnen
+   een sessie, dus wie de app uren open laat staan houdt oude **slider**-inhoud.
+   Zie dat als gedrag om in de gaten te houden, niet als bug.
+3. ~~Langere edge-TTL voor taxonomie~~ **✅ GEDAAN 2026-09-16 (Bob), gemeten
+   door Claude (`cf-cache-status: HIT` op beide).** `plaatsen.json` en
+   `plaatsen_bij_gemeente.json` staan nu in een **tweede** Cache Rule
+   ("FlutterFlow publieke endpoints 60 minuten") met Edge TTL **2 uur** — het
+   dropdownmenu heeft geen optie van 1 uur. De eerste rule houdt de vier
+   content-endpoints op 5 minuten. ⚠️ Bij een volgende Drupal-deploy die deze
+   twee endpoints raakt: die rule óók purgen, anders zie je tot 2 uur het oude
+   antwoord.
 4. **Lokaal persistent cachen** (Home meteen tonen uit een opgeslagen snapshot,
    ook offline). Een custom action van gemiddelde omvang die slecht past op
    FlutterFlow's FutureBuilder-patroon, en met Cloudflare op 0,1 s is de winst
    klein. **Niet vóór livegang.**
 
-### 🆕 Taak 59 · Helppagina — antwoord op Bob's vraag, plus hoe te bouwen
-
-**Bob's vraag: "kan ik een helppagina maken waarin URL's van de website zelf
-getoond worden, zodat ik teksten niet 2× hoef bij te houden?" — Ja, en dat is
-ook het advies.** Gemeten 2026-09-16: de site heeft er nu nog niets voor staan.
-`uitgaanskrant.com/nl/help`, `/faq`, `/veelgestelde-vragen`, `/over-ons`,
-`/contact`, `/uitleg`, `/hoe-werkt-het` en `/privacy` geven alle **404**;
-`/account-verwijderen` bestaat wél maar geeft anoniem een **403**.
-
-**Aanpak, twee delen:**
-1. **Bob, in Drupal:** maak één node, bijvoorbeeld `/nl/app-help`, met de
-   inhoud. Wat er in elk geval in hoort: wat Uitgaanskrant is · gemeente kiezen
-   en volgen · inloggen en favorieten · een evenement of stadsactiviteit
-   aanmaken (voor horeca en city-editors) · contact · privacy · account
-   verwijderen. Eén node bijwerken = de app is meteen bij, géén nieuwe release.
-2. **Claude, in de builder (kleine taak):** menu-item **"Help"** onderaan
-   `drawerComponent` (dupliceer een bestaand `ListTile`, zie `CLAUDE.md` — dat
-   is betrouwbaarder dan Insert Widget) met On Tap → **Launch URL** naar die
-   node. Launch URL staat in de Actions-zoeklijst onder categorie *Share*, niet
-   onder Navigation.
-
-**Keuze die Bob daarbij maakt: extern openen of in de app?**
-- **Launch URL** (externe browser) is één actie, nul onderhoud, en de gebruiker
-  ziet de vertrouwde site. Nadeel: hij verlaat de app.
-- **Een WebView-pagina in de app** houdt hem binnen de app en kan de standaard
-  header + terugknop krijgen, maar toont de volledige sitehuisstijl inclusief
-  menu en cookiebanner, tenzij je in Drupal een kale weergave maakt.
-- **Advies: begin met Launch URL.** Dat kost tien minuten en is altijd nog om
-  te bouwen naar een WebView.
-
-⚠️ **Los hiervan, en het blokkeert de store-review:** `/nl/account-verwijderen`
-geeft anoniem een 403. Google's reviewers openen die URL **zonder in te loggen**.
-Daar moet minimaal een publiek zichtbare uitleg staan van hoe je je account laat
-verwijderen. Dit hoort bij Bob's taak 2 (Play Console).
+### ✅ Taak 59 · Helppagina — AFGEROND 2026-09-16 (Bob + Claude)
+
+Twee Drupal-nodes live, allebei **publiek bereikbaar** (anoniem 200, gemeten):
+- **Help:** `https://uitgaanskrant.com/nl/support/mobieleapp`
+- **Privacybeleid:** `https://uitgaanskrant.com/nl/support/privacybeleid`
+
+In de app: menu-item **"Support pagina"** onderaan `drawerComponent`, vlak boven
+"Mijn Account", met `launchURL('https://uitgaanskrant.com/nl/support/mobieleapp')`
+— export-geverifieerd, Engelse vertaling ("Support page") staat er ook in.
+Claude heeft de volledige Nederlandse helptekst aangeleverd (app-uitleg, gemeente
+kiezen/volgen, account + favorieten, zelf aanmelden, privacy met link naar het
+privacybeleid, account verwijderen, contact); Bob heeft die geplaatst en de
+e-mailadressen ingevuld. Bijwerken = één node bewerken, geen nieuwe release.
+
+⚠️ **Eén punt blijft open en het blokkeert de store-review** (hoort bij Bob's
+taak 2, Play Console): **`/nl/account-verwijderen` geeft anoniem een 403.**
+Google's reviewers openen die URL zonder in te loggen. Twee manieren om het te
+dichten: geef `https://uitgaanskrant.com/nl/support/mobieleapp` op als
+account-verwijder-URL (de sectie "Je account verwijderen" staat daar publiek op),
+of maak de oude pagina publiek zichtbaar.
 
 ### 🟢 AFGEROND 2026-09-16 (Claude, sessie "taal-cluster") — browserloos, geen builder aangeraakt
 
 *Geclaimd en uitgevoerd terwijl twee andere sessies in de builder zaten. Dit
 cluster raakt géén FlutterFlow-pagina en géén Chrome — alles is meting +
-kant-en-klare code. Er staat nog **één ding open dat Bob (of een sessie met de
-browser) moet doen**: de twee functie-bodies hieronder plakken.*
+kant-en-klare code.*
+
+**✅ Beide functie-bodies zijn op 2026-09-16 door Bob geplakt en
+export-geverifieerd** — `filterDatumVan` en `filterDatumTot` staan allebei in de
+taalonafhankelijke vorm in `custom_functions.dart`. De Home-chips staan op
+`All` / `Today` / `This weekend` / `This week`, dus de koppeling klopt en het
+datumfilter werkt in beide talen. De code hieronder blijft staan als referentie.
 
 **1 · `filterDatumVan` / `filterDatumTot` taalonafhankelijk — code klaar, moet
 nog in de Custom Code-editor.** Dit blokkeerde Bob's taak 3 (vertaalronde): de
@@ -280,24 +291,20 @@ kopieën (`favorietenCopy`, `drawerComponentCopy`, `kanwegTestUpload`) zaten in
 de oude telling van 134/99 en zijn er nu uit.
 Werkelijke omvang in levende code: **26 leeg, 58 gelijk aan NL, 8 fout**.
 
-**3 · Nieuw gevonden: 8 sleutels hebben geen lege maar een FOUTE Engelse
-vertaling** — die vallen in geen enkele telling op en zijn erger dan leeg, want
-de gebruiker krijgt een tekst die iets anders betekent. Oorzaak is het bekende
-`Duplicate`-patroon (een kopie erft de EN-tekst van het origineel):
-| sleutel | scherm | Nederlands | staat er nu in EN |
+**3 · 8 sleutels hadden geen lege maar een FOUTE Engelse vertaling** — die
+vallen in geen enkele telling op en zijn erger dan leeg, want de gebruiker
+krijgt een tekst die iets anders betekent. Oorzaak is het bekende
+`Duplicate`-patroon (een kopie erft de EN-tekst van het origineel).
+**5 van de 8 zijn op 2026-09-16 gefixt** (`vnwx710y`, `pj545url`, `n3cyffso`,
+`nosgkxy0`, `elx7kse2`) plus de inhoudelijke fout op `wachtwoordVergeten`
+(`503u6v73`, stond op *"Use your username or password to recieve an email"* —
+verkeerde betekenis én een typefout). **De resterende 3 staan alle drie op
+`uitgaansevenementAanmaken` en wachten dus op P2-29:**
+| sleutel | Nederlands | staat er nu in EN | moet worden |
 |---|---|---|---|
-| `vnwx710y` | drawerComponent | Terug | Favorite |
-| `pj545url` | login | Veld wissen | Favorite |
-| `n3cyffso` | login | Wachtwoord tonen/verbergen | Favorite |
-| `nosgkxy0` | SelectStateDropDown | Gemeente volgen | Add to favorites |
-| `elx7kse2` | SelectStateDropDown | Je volgt deze gemeente | Add to favorites |
-| `qsf2va25` | uitgaansevenementAanmaken | Website van het evenement | Website van de activiteit |
-| `nzaqrq0w` | uitgaansevenementAanmaken | Link om kaarten te kopen | Website van de activiteit |
-| `9qx16tm9` | uitgaansevenementAanmaken | Evenement indienen | Activiteit indienen |
-
-Plus één inhoudelijke fout op `wachtwoordVergeten` (`503u6v73`): de Engelse zin
-zegt *"Use your username or password to recieve an email"* — verkeerde betekenis
-én een typefout. Correctie staat in het werkblad.
+| `qsf2va25` | Website van het evenement | Website van de activiteit | Event website |
+| `nzaqrq0w` | Link om kaarten te kopen | Website van de activiteit | Ticket link |
+| `9qx16tm9` | Evenement indienen | Activiteit indienen | Submit event |
 
 **4 · Wezenlijst opnieuw gemeten (aanvulling op P2-7 / Bob's taak 4).**
 Reproduceerbaar bepaald door vanaf de startpagina de widget-graaf te volgen:
@@ -364,17 +371,23 @@ telefoon-emulator bekeken (zie screenshots in `~/uk-shots/2026-09-16/na-*.png`).
   281.5 → 200 hoog en de witte Fill eraf.
 
 **Restpunten als taken (2026-09-16, niet geclaimd):**
-- **P1-53 · `thuisBezorgen` AppBar op leisteen · Eigenaar: Claude.** De nieuwe
-  pagina van sessie 47 heeft nog `backgroundColor: info` (wit + M3-tint). Zelfde
-  klik als P1-51: AppBar-node → Background Color → thema-token **Primary Text**.
-  Check: `grep -c "backgroundColor: FlutterFlowTheme.of(context).info"
-  lib/thuis_bezorgen/thuis_bezorgen_widget.dart` → 0.
-- **P1-54 · `EvenementInfo`: adresregels met iconen · Eigenaar: Claude.** Op
-  `EventCurrent` staan adres en plaats als kale tekst, en "Plaats" springt in
+- **P1-53 · ✅ afgerond 2026-09-16 (Claude, in de builder).** `thuisBezorgen`
+  AppBar stond op `backgroundColor: info`; nu **Primary Text** (leisteen), gelijk
+  aan de rest. Export-geverifieerd: 0× `.info`, 1× `.primaryText`.
+- **P1-54 · `EvenementInfo`: adresregels met iconen · Eigenaar: Claude
+  (toegewezen door Bob, 2026-09-16: "zet klaar als taak voor volgende keer").**
+  Op `EventCurrent` staan adres en plaats als kale tekst, en "Plaats" springt in
   omdat er een lege `Column` vóór staat (`evenement_info_widget.dart` r.~126-160).
   Doel: dezelfde opbouw als de kaarten — `Row` met speldje-icoon + "adres,
   plaats" op één regel, en de datum een kalender-icoon. Rechtsklik `TextAdres` →
   Wrap Widget → Row, dan Insert Widget → Icon vooraan (landt op positie 0).
+- **P1-17 Deel A · laatste 3 regels · Eigenaar: Claude (toegewezen door Bob,
+  2026-09-16).** Deel A is verder helemaal af; dit is wat er nog ligt, alle drie
+  op `horecagelegenhedenOverzichtCurrent`, via het globe-icoontje:
+  `qqb1howd` "Zoek op naam" is nog **leeg** → **Search by name**; `hnnqfnhk`
+  staat op "Eatings" (geen Engels) → **Restaurants**; `ykjsgvsf` staat op
+  "Overnight" → **Accommodation**. Daarna is Deel A rond en blijft alleen Deel B
+  (de twee aanmaakpagina's) over, dat op P2-29 wacht.
 - **P2-34 · ✅ afgerond 2026-09-16 (Claude, optie A, Bob's akkoord).**
   `HorecagelegenheidoverzichtKaart`: de `Row` is in een `Column` gewrapt en de
   `Wrap` met labels staat er nu onder, over de volle kaartbreedte (spacing 6).
@@ -385,21 +398,20 @@ telefoon-emulator bekeken (zie screenshots in `~/uk-shots/2026-09-16/na-*.png`).
   Export-geverifieerd (geen `Align(` meer rond de labels, `List.generate`
   intact), `dart analyze` 0 errors, op de telefoon-emulator nagekeken
   (`~/uk-shots/2026-09-16/na3-horeca-ovz.png`).
-- **P2-35 · `HorecagelegenheidCurrent`: "Geen evenementen"-strook alleen in
-  Agenda-context · Eigenaar: Claude.** Onderin staat permanent
-  `GeenEvenementenComponent` + knop "Alle horecagelegenheden", ook als de zaak
-  events heeft en ook op de Info-tab. Hoort alleen zichtbaar als de
-  agenda-lijst leeg is: Visibility-conditie op het component op "aantal items
-  van de events-call == 0" (Set from Variable → API-response → Number of Items
-  → Equal to 0), of het blok in de Agenda-tab zetten.
-- **P2-36 · Kaarttitels in serif? · Eigenaar: Bob (besluit).** Headline L/M/S
-  staan nu op Noto Serif; de kaarttitels (`titleMedium` op de lijstkaarten,
-  `titleLarge` op de sliderkaart en zaaknaam) zijn nog Roboto, terwijl de site
-  ook kaarttitels in serif zet. Ja → Theme Settings → Typography → rij *Title
-  Large* en *Title Medium* → Font Family-veld → picker → Noto Serif (per rij,
-  níét de Secondary Font Family-knop, zie `CLAUDE.md`). Raakt ook de
-  sectiekoppen op de aanmaakpagina's niet; wél de tabs (`titleMedium` op de
-  TabBar-labels) — check dat na afloop op een toestel.
+- **P2-35 · `HorecagelegenheidCurrent`: "Geen evenementen"-strook · Eigenaar:
+  Claude — eerst NAMETEN op een toestel vóór je gaat bouwen.** De
+  oorspronkelijke bevinding was "staat permanent onderin, ook als de zaak events
+  heeft". In de export van 2026-09-16 klopt dat maar half: de events-tabel
+  (`HorecagelegenheidEventTabelComponentCopy`) doet al keurig
+  `if (evenementen.isEmpty) return GeenEvenementenComponentWidget();` — dat is
+  correct empty-state-gedrag. Wat er wél permanent staat is de **knop "Alle
+  horecagelegenheden"** (`horecagelegenheid_current_widget.dart` r.~1610), los
+  van de tab waar je op staat. Kijk dus eerst op de emulator wat de gebruiker
+  echt ziet vóór je een Visibility-conditie bouwt; mogelijk is de hele taak
+  alleen nog "die knop in de Agenda-tab zetten".
+- **P2-36 · ❌ NEE — besluit Bob 2026-09-16: kaarttitels blijven Roboto.**
+  Niet opnieuw voorstellen. (Voorstel was Title Large/Medium op Noto Serif zetten
+  omdat de site kaarttitels in serif zet; Headline L/M/S staan al wel op serif.)
 - **Website (aanvulling op P2-13, Eigenaar: Bob, Drupal-thema):** (6) op
   telefoon 320 px header (socials + logo + Inloggen/Taal + zoekveld +
   menubalk) vóór het eerste evenement → socials weg, Inloggen/Taal en zoekveld
@@ -483,32 +495,40 @@ daarmee niet meer geblokkeerd en heeft nu een kant-en-klaar werkblad
    niet in de module (de module doet alleen `townid`/datum/`zoek`).
    Structureel (taak 32B, 597 events = 96% van het lek): default-categorie in
    de importer — eigen moment.
-2. **Store-gereedheid (Play Console).** Privacybeleid-tekst staat sinds
-   2026-09-16 live op de website (Bob) — **nog open:** (a) de URL invullen bij
-   Play Console → App content → Privacy policy (dat veld zit in Play Console
-   zelf, niet in FlutterFlow); (b) een link naar diezelfde pagina **in de app**
-   toevoegen — nergens in de levende code staat momenteel een verwijzing naar
-   privacybeleid/voorwaarden (`grep -rn "privacy\|voorwaarden" lib/` geeft 0
-   treffers), en Google eist ook een vindbare link vanuit de app zelf, niet
-   alleen in de store-listing. Kleine builder-taak: `drawerComponent` → een
-   bestaand `ListTile` dupliceren (zie `CLAUDE.md`) → label "Privacybeleid" →
-   On Tap → Launch URL naar de nieuwe pagina (categorie *Share* in de
-   Actions-zoeklijst) — kan gecombineerd met de al geplande "Help"-menu-item-
-   taak hierboven (zelfde plek, zelfde patroon). Data-safety-formulier
-   (Crashlytics, AdMob, login) en account-verwijder-URL
-   (`uitgaanskrant.com/nl/account-verwijderen`, bestaat al) blijven ook open.
-   Beslis de upload-route: via FlutterFlow-deploy (dan hoeft er lokaal niets)
-   of lokaal (dan keystore + `android/key.properties`, want release staat op
-   `signingConfigs.debug`). iOS wel/niet in scope.
+2. **Store-gereedheid (Play Console) · Eigenaar: Bob.** De in-app-link is
+   geregeld (menu-item "Support pagina" → helppagina, die zelf naar het
+   privacybeleid linkt), dus Google's eis van een vindbare link vanuit de app is
+   gedekt. **Wat nog open staat, allemaal in Play Console zelf:**
+   - **(a) Privacy policy-URL invullen:** `https://uitgaanskrant.com/nl/support/privacybeleid`
+     (gemeten 2026-09-16: anoniem 200).
+   - **(b) Account-verwijder-URL.** ⚠️ `uitgaanskrant.com/nl/account-verwijderen`
+     geeft **anoniem een 403** en Google's reviewers openen die URL zonder in te
+     loggen — zo ingevuld blokkeert het de review. Vul in plaats daarvan
+     `https://uitgaanskrant.com/nl/support/mobieleapp` in (daar staat de sectie
+     "Je account verwijderen" publiek op), of maak de oude pagina publiek.
+   - **(c) Data-safety-formulier:** Crashlytics (crashlogs/diagnostiek), AdMob
+     (advertentie-ID), login (gebruikersnaam/e-mail); versleuteld transport +
+     verwijdering mogelijk.
+   - **(d) Upload-route beslissen:** via FlutterFlow-deploy (dan hoeft er lokaal
+     niets) of lokaal — dan keystore + `android/key.properties`, want de
+     release-build staat nog op `signingConfigs.debug`.
+   - **(e) iOS wel/niet in scope** (`project.pbxproj` beweegt mee in elke export,
+     verder is er niets voor ingericht).
 3. **P1-17 · Engelse vertalingen** — werkblad ligt klaar in
    **`TAAK-P1-17-vertalingen.md`** (sleutel + NL + huidige EN + voorgestelde EN
-   per regel). **Deel A (21 regels) kan nu al**: Home-chips, drawer, login,
-   horeca-overzicht, `Selectprovinciegemeente`, gemeentehartje. **Deel B (59
-   regels)** pas ná P2-29, want de twee aanmaakpagina's zijn nog in bewerking.
-   Echte omvang in levende code: 26 leeg + 58 gelijk aan NL + **8 fout** (de
-   oude telling 134/99 bevatte dode kopieën). De chip-functie is al
-   taalonafhankelijk gemaakt — mits de chips exact
-   `All`/`Today`/`This weekend`/`This week` krijgen.
+   per regel). **Deel A is op 2026-09-16 vrijwel helemaal gedaan (Bob):**
+   Home-chips (All/Today/This weekend/This week), drawer, login, gemeentehartje,
+   `Selectprovinciegemeente`, `wachtwoordVergeten` en "Bezorgen" → Delivery,
+   allemaal export-geverifieerd. **Restant: 3 regels op het horeca-overzicht,
+   staat hierboven bij de restpunten als Claude-taak.** **Deel B (59 regels)**
+   wacht nog steeds op P2-29. De chip-functies zijn taalonafhankelijk gemaakt en
+   geplakt, dus het datumfilter werkt in beide talen.
+   ⚠️ **Les uit deze ronde:** dit vertaaldialoogje heeft last van het bekende
+   "ziet er opgeslagen uit, was het niet"-patroon — van de eerste 8 regels kwamen
+   er maar 2 door. Verifieer elke ronde met een verse export, niet met het
+   paneel. Verder zitten veel vertaalsleutels op **Tooltip-nodes** (`Terug`,
+   `Veld wissen`, `Wachtwoord tonen/verbergen`) in plaats van op zichtbare
+   labels; die vind je alleen door in de widget tree op `Tooltip` te zoeken.
 4. **Builder-opruimronde.** P2-7 (21 dode eenheden; begin met
    `drawer_component_copy` + `kanweghorecagelegenheid_current_copy`),
    `HorecagelegenhedenOverzichtCopy3Copy`, `homeCopy` (het datumfilter is af en op een toestel getest, dus mag weg),
@@ -522,8 +542,9 @@ daarmee niet meer geblokkeerd en heeft nu een kant-en-klaar werkblad
 6. **Livegang-schakelaars, als allerlaatste.** App Settings → AdMob → *Show
    Test Ads* UIT; Cloudflare: rate-limiting-rule op Active én de twee
    rate-limiting-vinkjes uit de custom rule `flutterflow` (P1-30).
-7. **Besluit "Thuis bezorgen"** (één zin): verbergen bij livegang, of Claude
-   bouwt de pagina op `flutterflowmobiel_establishments` `services_2`.
+7. ~~Besluit "Thuis bezorgen"~~ **✅ VERVALLEN — de pagina is gebouwd** (sessie
+   47, commit `95c1dec`, op een toestel geverifieerd), en de AppBar staat sinds
+   2026-09-16 ook op de juiste kleur (P1-53).
 
 ### 🚦 Livegang-review 2026-09-15 (Claude, code-audit op de export van 22:56 — géén builder-werk)