Browse Source

TASKS/CLAUDE: sessie 2026-09-17 laat — 77/78/79/80/82 af, taak 87 erbij

Af en uit TASKS.md gehaald: API-calls Entreeopties/Categorieen van /en/ naar
/nl/ (77), versielabel v0001 uit het menu (78), app-icoon (79). Splash (80)
staat erin, met restpunt over BoxFit.cover. De dubbele fix op
flutterflowmobiel_establishment_events (categorie null -> [], inhoud
schoongemaakt) staat op devbob en is nagemeten; productie-deploy is taak 84.

Nieuw: taak 87 — uitleggen dat een horecagelegenheid alleen via de website
aangemaakt kan worden (lege "Uw Horecagelegenheid"-dropdown is nu een
doodlopende weg). Taak 85 (account-verwijderen) heeft een besluit, taak 86
(Play-testaccount) kan nu al.

CLAUDE.md: app-icoon en splash verifieer je niet in android/res — icoon loopt
via flutter_launcher_icons (pas bij build), splash zit in nav.dart.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bob 23 hours ago
parent
commit
119cd4fbdd
2 changed files with 135 additions and 86 deletions
  1. 23 0
      CLAUDE.md
  2. 112 86
      TASKS.md

+ 23 - 0
CLAUDE.md

@@ -2480,6 +2480,29 @@ en achteraf `svc wifi enable` + `svc data enable`. Controleer met
 echt uit staat). **Vergeet het herstel niet** — een volgende sessie vindt anders
 een emulator zonder netwerk en zoekt de fout in de app.
 
+**App-icoon en splashscreen verifieer je NIET in `android/res` — daar staat altijd
+nog het Flutter-vogeltje.** Bevestigd 2026-09-17, nadat een geslaagde icoon-upload
+ten onrechte als "niet doorgekomen" gemeten werd:
+- **Icoon:** FlutterFlow zet het niet in `mipmap-*/ic_launcher.png`, maar configureert
+  `flutter_launcher_icons` in `pubspec.yaml` met
+  `image_path: 'assets/images/app_launcher_icon.jpg'` (+ `adaptive_icon_foreground`).
+  Die mipmap-PNG's worden pas **tijdens de build** vervangen, dus hun md5 blijft
+  eeuwig `57838d52…` (de Flutter-default). **Juiste check:** exporteer mét
+  `--include-assets` en kijk naar `assets/images/app_launcher_icon.jpg` zelf.
+- **Let op de adaptive icon:** FlutterFlow zet standaard
+  `adaptive_icon_background: '#00000000'` (transparant) en gebruikt hetzelfde
+  volvlakse plaatje als foreground. Android toont van die foreground alleen de
+  middelste ~66%, dus een logo met tekst wordt afgesneden en er zit geen kleur
+  onder. Zet een vaste achtergrondkleur en gebruik als foreground een **PNG met
+  transparantie** waarin alleen het beeldmerk op ±60% van het vlak staat.
+- **Splash:** ook niet in `launch_background.xml` (dat blijft
+  `?android:colorBackground`), maar aan de Flutter-kant in **`nav.dart`**:
+  `appStateNotifier.loading ? Image.asset('assets/images/<logo>', fit: BoxFit.cover)`.
+  Die `BoxFit.cover` blaast een vierkant plaatje op een telefoonscherm zo ver op dat
+  links en rechts wegvallen — lever dus een **staand** plaatje in schermverhouding
+  (bv. 1080×2160) met het logo gecentreerd. De korte witte flits dáárvoor is de
+  native launch screen; die stelt FlutterFlow niet in.
+
 **Een losse verificatie-export (`flutterflow export-code ... --as-debug`) bevat
 GEEN afbeeldingen uit `assets/images/` (alleen `favicon.png`) — voeg
 `--include-assets` toe zodra je er een APK van wilt bouwen.** Bevestigd

+ 112 - 86
TASKS.md

@@ -1,4 +1,57 @@
-## ▶ Nu aan de beurt (stand 2026-09-14)
+## ▶ Nu aan de beurt (stand 2026-09-17, eind van de sessie)
+
+*Sessie 2026-09-17 laat (Bob klikt/deployt, Claude verifieert per verse export
+of curl). **Af:** de twee API-calls `Entreeopties`/`Categorieen` van `/en/` naar
+`/nl/` (77), versielabel `v0001` uit het menu (78), app-icoon geüpload (79),
+splashscreen ingesteld (80, met restpunt bij P1-56), en de dubbele fix op
+`flutterflowmobiel_establishment_events` op devbob (82). **Morgen verder met de
+nummers hieronder** — ze staan verderop in dit bestand volledig uitgeschreven.*
+
+**Open, in volgorde:**
+
+1. **83 · twee Drupal-restjes** — `node_delete(220276)` en de dblog-telling
+   (`SELECT type, severity, COUNT(*) FROM watchdog WHERE type LIKE 'custom%'
+   GROUP BY type, severity;`). Plak de uitkomst, dan kijkt Claude mee.
+2. **84 · taak 82 naar productie** + `cc all` + Cloudflare-rule purgen.
+3. **85 · account-verwijderen-knop** naar `/nl/support/mobieleapp` (besluit is
+   genomen, zie het blok verderop). Claude kan dit ook zelf in de builder doen.
+4. **86 · testaccount voor de Play-review** aanmaken — kan nu al, los van D-U-N-S.
+   Zie taak 63(f).
+5. **87 · uitleggen dat een horecagelegenheid alleen via de website kan** — nieuw,
+   zie het blok hieronder.
+6. **62 · "Account aanmaken"-route op de Login-pagina** (Claude, builder, klein).
+7. **76 · linkerpadding op de horeca-agendakaart** (klein, eigenaar onbepaald).
+
+### 🆕 87 · Uitleggen waar je een horecagelegenheid aanmaakt — kan alleen via de website · Eigenaar: Bob (tekst + URL), Claude (app-kant)
+
+Bob 2026-09-17: *"we moeten nog ergens kwijt dat we uitleggen waar je een
+horecagelegenheid kunt aanmaken. Kan alleen via de website."* Nu staat dat
+nergens — niet in de app en niet op de helppagina.
+
+**Waarom dit er echt toe doet:** `uitgaansevenementAanmaken` heeft een dropdown
+**"Uw Horecagelegenheid"** (sleutel `rqx6m3yf`) die gevuld wordt uit
+`mijn_horecagelegenheden`. Wie nog geen zaak heeft, ziet daar een **lege
+dropdown** en kan dus geen evenement indienen — zonder dat er ook maar iets
+uitlegt waarom, of wat hij dan wél moet doen. Dat is nu een doodlopende weg.
+
+Twee plekken, in deze volgorde:
+
+1. **Helppagina `/nl/support/mobieleapp` (Drupal, Bob).** Eigen kopje, bv. "Je
+   zaak aanmelden": een horecagelegenheid maak je aan op de website, niet in de
+   app; daarna verschijnt hij in de app onder *Uw Horecagelegenheid* en kun je er
+   evenementen bij indienen. **Bob levert de exacte URL** van die aanmeldpagina —
+   die is bij Claude niet bekend.
+2. **In de app, onder de dropdown op `uitgaansevenementAanmaken` (Claude,
+   builder).** Eén `Text` onder de dropdown, stijl `secondary` + onderstreept
+   (zelfde als de andere links in de app), met een `Launch URL` naar die pagina:
+   *"Nog geen zaak aangemeld? Dat doe je op uitgaanskrant.com."* Engelse
+   vertaling meteen meegeven. Eventueel met een Visibility-conditie zodat hij
+   alleen verschijnt bij een lege lijst — maar hem altijd tonen mag ook en is
+   veel minder bouwwerk.
+
+Zelfde afweging geldt voor `stadsactiviteitAanmaken`: check bij het bouwen even
+of die pagina hetzelfde probleem heeft (stadsrechten i.p.v. een zaak).
+
 
 ### ✅ Sessie 2026-09-17 (Claude in de builder, Bob kijkt mee) — zoekveld onder toetsenbord + sliderkaart-overflow
 
@@ -86,21 +139,18 @@ de website-homepage; `/nl/user/register` is anoniem bereikbaar (200).
 
 **🔴 Blokkeert de store-review of de eerste indruk**
 
-- **60 · P1-55 · App-icoon is nog het Flutter-standaardlogo — op Android én iOS.
-  Eigenaar: Bob.** `android/app/src/main/res/mipmap-*/ic_launcher.png` (1443
-  bytes = Flutter-default) en
-  `ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png` tonen
-  allebei het blauwe Flutter-vogeltje; de profile-APK op emulator-5556 heeft dus
-  ook dat icoon in de launcher. App Settings → App Details → **App Icon**: een
-  vierkant 1024×1024-logo uploaden (het `logo800px.png` uit `assets/images/` is
-  te breed voor een icoon — liever alleen het rode beeldmerk op wit). Verifiëren:
-  na een verse export moet `md5sum android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png`
-  ≠ `57838d52c318faff743130c3fcfae0c6`. Dezelfde 512×512 heb je ook voor de
-  Play-listing nodig (taak 63).
-- **61 · P1-56 · Splashscreen is een kaal wit vlak. Eigenaar: Bob.**
-  `launch_background.xml` bevat alleen `?android:colorBackground`, geen logo.
-  App Settings → **Splash Screen**: logo + achtergrondkleur `#F2F2F2` of wit.
-  Twee minuten werk, maar het is het allereerste wat een gebruiker ziet.
+- **61 · P1-56 · Splashscreen — ✅ GEDAAN 2026-09-17 (Bob), restpunt blijft.**
+  Het logo staat erin, maar **niet** in `launch_background.xml`: FlutterFlow doet
+  de splash aan de Flutter-kant, in `nav.dart:447`
+  (`Image.asset('assets/images/uitgaanskrant.com-applogo.jpg', fit: BoxFit.cover)`).
+  Die `BoxFit.cover` op een **vierkant** plaatje blaast het op een telefoonscherm
+  (ruwweg 1:2) zo ver op dat links en rechts wegvallen — je ziet de middelste helft
+  van het logo. Bob 2026-09-17: "ik maak het later mooier". **Voor die ronde:** maak
+  een staand plaatje in schermverhouding (bv. 1080×2160), vlak `#9A141D`, logo
+  gecentreerd op ±70% breedte; dan klopt `cover` vanzelf. Los daarvan blijft er een
+  korte **witte flits** van de Android-native launch screen (`?android:colorBackground`)
+  vóór de Flutter-splash — die stelt FlutterFlow niet in, dus dat is geen builder-werk.
+
 - **62 · P1-57 · Geen "account aanmaken"-route in de app. Eigenaar: Claude
   (builder, klein).** `Login` heeft alleen *Inloggen* en *Wachtwoord vergeten?*;
   de helppagina belooft een "gratis account", maar in de app kun je er geen
@@ -110,10 +160,15 @@ de website-homepage; `/nl/user/register` is anoniem bereikbaar (200).
   (anoniem 200). Engelse vertaling meteen meegeven ("No account yet? Register").
 - **63 · Play Console — aanvulling op Bob's taak 2. Eigenaar: Bob.** Naast
   (a) t/m (e) daar:
-  - **(f) App access / testaccount:** de app heeft een login, dus Google wil
-    inloggegevens van een testaccount (Play Console → App content → *App
-    access*). Maak een apart Drupal-account met wat favorieten en één gevolgde
-    gemeente, zodat de reviewer Favorieten kan zien.
+  - **(f) App access / testaccount — taak 86, kan NU al, los van D-U-N-S.** De
+    app heeft een login, dus Google wil inloggegevens van een testaccount (Play
+    Console → App content → *App access* → "All or some functionality is
+    restricted"). Maak een gewoon Drupal-account (geen extra rollen — de reviewer
+    moet zien wat een normale gebruiker ziet), log er één keer mee in **in de
+    app** en zet er 3-4 favoriete zaken in Amsterdam en één gevolgde gemeente op;
+    anders opent de reviewer Favorieten en ziet vier lege tabs, wat als "broken
+    functionality" gelezen kan worden. ⚠️ Het wachtwoord **niet** in dit bestand
+    zetten (staat in git) — alleen in Play Console en je wachtwoordmanager.
   - **(g) Listing-assets:** 512×512 icoon, feature graphic 1024×500, minimaal
     2 telefoon-screenshots én 7"/10"-tablet-screenshots (de app ondersteunt
     tablets, dan vraagt Google erom), korte (80) + lange (4000) omschrijving.
@@ -127,16 +182,15 @@ de website-homepage; `/nl/user/register` is anoniem bereikbaar (200).
   - **(i) versionCode:** elke upload moet hoger zijn; `1.0.0+1` staat nu in
     `pubspec.yaml`/`local.properties`. Bij een lokale upload-route: ophogen in
     App Settings → App Details vóór elke build.
-- **64 · P1-58 · "Account verwijderen" in de app opent een 403. Eigenaar: Bob
-  (Drupal) of Claude (builder).** Favorieten tab 4 → knop *Account verwijderen*
-  → `launchURL('https://uitgaanskrant.com/nl/account-verwijderen')`
-  (`favorieten_widget.dart:957`). De browser opent zonder Drupal-sessie, dus de
-  gebruiker krijgt anoniem een **403** (gemeten) — precies het probleem dat ook
-  de store-review raakt (Bob's taak 2b). Kies één: (a) Drupal: die pagina
-  anoniem laten redirecten naar het loginformulier met `?destination=` i.p.v.
-  een 403; of (b) builder: de knop naar
-  `https://uitgaanskrant.com/nl/support/mobieleapp` laten wijzen (sectie "Je
-  account verwijderen"). (a) is netter, (b) is 1 minuut.
+- **85 (was 64) · P1-58 · "Account verwijderen" opent een 403 — besluit: optie B.**
+  Gemeten 2026-09-17: `/nl/account-verwijderen` geeft anoniem **403**,
+  `/nl/support/mobieleapp` geeft **200** en heeft de sectie "Je account verwijderen"
+  publiek. **Doen:** de knop op Favorieten tab 4 (`favorieten_widget.dart:957`,
+  Actions → Launch URL) naar `https://uitgaanskrant.com/nl/support/mobieleapp`, en
+  diezelfde URL in Play Console bij *Data deletion* (taak 63b). Eigenaar: Claude
+  (builder, 2 min) óf Bob. De 403-pagina publiek maken mag daarna in alle rust —
+  er hangt dan niets meer van af. *Verificatie: `account-verwijderen` mag niet meer
+  in `favorieten_widget.dart` staan.*
 
 - **74 · P1-62 · ✅ AF 2026-09-17 (Claude, builder + verse export, akkoord Bob).**
   De evenementen-agenda op een horecapagina liep op een telefoon over elkaar heen.
@@ -163,48 +217,34 @@ de website-homepage; `/nl/user/register` is anoniem bereikbaar (200).
   *Terzijde:* de events hebben inmiddels een eigen **Agenda**-tab gekregen (werk
   van een andere sessie) — de Info-tab is daardoor ook rustig geworden.
 
-- **76 · Twee restpunten die pas zichtbaar werden ná taak 74. Eigenaar:
-  onbepaald, allebei klein.**
-  1. ~~De agenda-tekst raakt de linker schermrand~~ **✅ AF 2026-09-17 (Claude).**
-     `HorecagelegenheidEventTabelComponentCurrent` heeft nu
-     `Padding(12, 0, 12, 0)` om de hele `FutureBuilder` — dus ook om de
-     laadspinner en de lege staat, niet alleen om de kaarten.
-     Export-geverifieerd; vóór deze wijziging stond er geen `Padding` in dat
-     bestand.
-  2. **`<p>`-tags staan letterlijk in de omschrijving** ("‹p›It's been a year
-     since…"). Gemeten aan de bron: `flutterflowmobiel_establishment_events`
-     levert `inhoud` met rauwe HTML. Dit is hetzelfde patroon als P2-27b —
-     het veld staat niet in `$fields_to_clean` van dat display-blok in
-     `custom_services_request_postprocess_alter()`. **Drupal-werk (Bob):** voeg
-     `'inhoud'` toe aan de lijst voor dit endpoint, net zoals dat op 15 sep voor
-     `flutterflowmobiel1`/`services_1` is gedaan. Let op de valkuil uit
-     `CLAUDE.md`: dat blok hoort **binnen** de `foreach ($result as &$item)`.
-- **75 · `categorie: null` op sommige events — ⚠️ NIET op te lossen in de
-  builder, hoort in Drupal. Eigenaar: Bob (Drupal/views).** Onderzocht
-  2026-09-17 (Claude). Gemeten: `flutterflowmobiel_establishment_events` gaf op
-  92 events van 120 Amsterdamse zaken **3× `"categorie": null`** (alle drie bij
-  horecanid 75457, Natuurtheater Zeddam). De agenda-code doet
-  `getJsonField(evenementenItem, r'$.categorie').toList()`, en `.toList()` op
-  `null` is een `NoSuchMethodError` — in een profile-build een stil grijs vlak.
-  **Wat ik geprobeerd heb en waarom het niet kan:** de `true`-vlag (`isForList`)
-  is in het *Generate Dynamic Children*-paneel niet te zetten. De enige
-  transform-opties in die dialoog zijn **"To Data Type"** en **"No Further
-  Changes"** — geen "Is List". Het menu naast de variabele biedt alleen
-  *Copy Variable*. Niets gewijzigd; de binding staat onveranderd op `$.categorie`.
-  **En de vlag zou het probleem toch maar half oplossen** — dat is de
-  belangrijkste uitkomst van dit uitzoekwerk. `getJsonField` (zie
-  `flutter_flow_util.dart`) doet bij `isForList: true` en waarde `null` →
-  `[null]`, dus géén crash maar wél een leeg/"null"-label; en bij een
-  **ontbrekend** veld geeft hij `null` terug ongeacht de vlag, dus dan crasht
-  `.toList()` alsnog.
-  **De nette fix zit dus aan de bron:** laat de view voor een event zonder
-  categorie een **lege array** `[]` teruggeven in plaats van `null`. Dan klopt
-  het overal, ook op de plekken die de vlag wél hebben. Hoort logisch samen met
-  taak 32B (events zonder categorie).
-
-
-- **77 · "Account aanmaken" · ⚠️ HELFT AF — de rest is voor Bob (builder) ·
-  Eigenaar: Bob.** Stand 2026-09-17, alles export-geverifieerd, `dart analyze`
+- **76 · Restpunt na taak 74: de agenda-tekst raakt de linker schermrand.**
+  De kaart in `HorecagelegenheidEventTabelComponentCurrent` heeft geen
+  linkerpadding, waardoor "Bubble House – Special Dance Edition" op x=0 begint;
+  elders in de app zit 12 px. Eén padding-waarde op de kaart-`Row`. Eigenaar:
+  onbepaald, klein. *(Het tweede restpunt — `<p>`-tags in `inhoud` — is af, zie 82.)*
+
+- **82 (was 75 + 76.2) · `categorie: null` én rauwe HTML in `inhoud` op
+  `flutterflowmobiel_establishment_events` — ✅ OPGELOST OP DEVBOB 2026-09-17 (Bob),
+  ⚠️ NOG DEPLOYEN NAAR PRODUCTIE.** Beide in het `services_1`-blok van
+  `custom_services_request_postprocess_alter()`: `'inhoud'` toegevoegd aan
+  `$fields_to_clean`, en binnen de `foreach ($result as &$item)` een normalisatie
+  die een ontbrekende/`null` `categorie` op `array()` zet (de app doet
+  `.toList()` op die waarde — op `null` is dat een `NoSuchMethodError` en in een
+  profile-build een stil grijs vlak).
+  **Meting Claude 2026-09-17, horecanid 75457 / 75459:**
+
+  | | productie (nu) | devbob (na de fix) |
+  |---|---|---|
+  | `categorie: null` bij 75457 | 3 | **0** (3× `[]`) |
+  | HTML-tags in `inhoud`, 75457 | 24 van 25 | **0 van 25** |
+  | HTML-tags in `inhoud`, 75459 | 16 van 16 | **0 van 16** |
+
+  **Na deploy:** `drush @uitgaanskrant.com cc all` + de Cloudflare-rule
+  "FlutterFlow publieke endpoints" purgen (dit endpoint zit in die 5-minuten-rule).
+  Daarna meet Claude productie na op dezelfde twee getallen.
+
+- **77 · "Account aanmaken" · ⚠️ HELFT AF · Eigenaar: Claude — bezig
+  (sessie 2026-09-17; Bob: "maak eerst een kopie en oefen daarin").** Stand 2026-09-17, alles export-geverifieerd, `dart analyze`
   0 errors.
   **✅ Af:** de `Column` met de vijf ingelogde items op Favorieten tab 4
   (Uitloggen, Mijn profiel, Wachtwoord wijzigen, Account verwijderen,
@@ -271,13 +311,6 @@ de website-homepage; `/nl/user/register` is anoniem bereikbaar (200).
   door Flutter heen) in een profile-build, app herstarten, en binnen ~5 min
   moet 'ie in Firebase → Crashlytics staan. Zonder deze check weet je na
   livegang niet of je blind bent.
-- **67 · P1-61 · Versielabel "v0001" onderin het menu. Eigenaar: Bob (keuze),
-  Claude bouwt.** `drawerComponent` toont een hardcoded `Text` "v0001"
-  (sleutel `7qpu1l01`). Of weghalen, of binden aan de echte versie: FlutterFlow
-  heeft onder *Global Properties* geen versie, dus dan een 3-regelige custom
-  function met `package_info_plus` (`PackageInfo.fromPlatform()`), of gewoon
-  handmatig "1.0.0" typen en bij elke release bijwerken. Advies: "1.0.0",
-  handmatig — het is één veld.
 - **68 · P1-17 · nameting Deel B op de export van 23:22 (levende code, zonder
   `kanweg`/`copy`): 184 sleutels in gebruik, 18 met lege EN, 49 met EN == NL.**
   De 18 lege: `Waar`, `WebsiteURL` (2×), `TicketsURL`, `Organisatie` (2×),
@@ -286,13 +319,6 @@ de website-homepage; `/nl/user/register` is anoniem bereikbaar (200).
   zijn FlutterFlow-defaults op de dropdowns van de aanmaakpagina's en staan
   dus in het **Nederlands** ook nog op Engels; hoort bij P2-29 (NL: "Kies..." /
   "Zoeken..."). Werkblad `TAAK-P1-17-vertalingen.md` bijwerken met deze telling.
-- **69 · API Calls `Entreeopties` en `Categorieen` lopen over `/en/`, de
-  overige 15 over `/nl/`. Eigenaar: Bob (API Calls-paneel, 2× URL).**
-  `api_calls.dart:77` en `:102`. Anoniem geven beide "Access denied", dus
-  Drupal serveert ze in de taal van het pad — met `/en/` krijg je Engelse
-  termlabels en foutmeldingen in de Nederlandse aanmaakpagina's. Omzetten
-  naar `/nl/` en export-verifiëren (`grep -n "/en/flutterdrup" api_calls.dart`
-  hoort 0 te geven).
 - **70 · P2-7 · de opruimlijst is verouderd — dit genereert de export van
   23:22 nog aan dode eenheden in `lib/`:** `uitgaanspaginas/home_copy`,
   `uitgaanspaginas/home_copy2` (nieuw vandaag), `kanweg/kanweg_home_copy`