Parcourir la source

TASKS/CLAUDE: 98A op productie, 98B af; permissieveld-notitie gecorrigeerd

Bob's browser zet de permissietekst gewoon goed weg (3 keys in de plist).
Het per-toetsaanslag-probleem is Claude-specifiek, geen FlutterFlow-bug.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bob il y a 11 heures
Parent
commit
92300ae6aa
2 fichiers modifiés avec 73 ajouts et 41 suppressions
  1. 7 4
      CLAUDE.md
  2. 66 37
      TASKS.md

+ 7 - 4
CLAUDE.md

@@ -3703,11 +3703,14 @@ breekt de iOS-build zonder dat de builder er iets over zegt.
 - **Opruimen gaat wél schoon:** de toggle van die permissie uitzetten haalt
 - **Opruimen gaat wél schoon:** de toggle van die permissie uitzetten haalt
   álle entries van dat type weg (geverifieerd: 69 → 0). Doe dat dus meteen als
   álle entries van dat type weg (geverifieerd: 69 → 0). Doe dat dus meteen als
   je dit veroorzaakt hebt, en laat het project niet in die staat achter.
   je dit veroorzaakt hebt, en laat het project niet in die staat achter.
-- **Vuistregel: permissie-teksten zijn voor Claude niet te zetten — overdragen
-  aan Bob**, en hem laten controleren met
+- ✅ **In Bob's eigen browser werkt het veld gewoon** — bevestigd 2026-09-19:
+  hij zette dezelfde tekst en een verse export gaf **precies 3** keys (Camera,
+  PhotoLibrary, Calendar), één per permissie. Dit is dus **Claude-specifiek**,
+  geen FlutterFlow-bug.
+- **Vuistregel: permissie-teksten niet zelf proberen te zetten — meteen
+  overdragen aan Bob**, en laten controleren met
   `grep -c "UsageDescription" ios/Runner/Info.plist` op een verse export (dat
   `grep -c "UsageDescription" ios/Runner/Info.plist` op een verse export (dat
-  hoort gelijk te zijn aan het aantal aangezette permissies). Onbekend of zijn
-  eigen browser hetzelfde doet; dat is de eerste vraag als hij het oppakt.
+  hoort gelijk te zijn aan het aantal aangezette permissies).
 
 
 **Custom Code-editor (Custom Functions/Widgets/Actions): tekst-editor,
 **Custom Code-editor (Custom Functions/Widgets/Actions): tekst-editor,
 betrouwbaar te bewerken — maar wijziging verschijnt pas in een export
 betrouwbaar te bewerken — maar wijziging verschijnt pas in een export

+ 66 - 37
TASKS.md

@@ -20,9 +20,9 @@ oppakken.
 | # | Taak | Kort |
 | # | Taak | Kort |
 |---|---|---|
 |---|---|---|
 | ~~88B~~ | Pagina "Mijn aanmeldingen" | ⚠️ **Al geclaimd** door de sessie 'taken-B1-B7' — niet oppakken |
 | ~~88B~~ | Pagina "Mijn aanmeldingen" | ⚠️ **Al geclaimd** door de sessie 'taken-B1-B7' — niet oppakken |
-| **98** | "Zet in mijn agenda"-knop op een evenement (`add_2_calendar`) | Claude — **BEZIG** (sessie 2026-09-19). Blokkeert op Drupal-deel bij Bob, zie 98A |
+| **98** | "Zet in mijn agenda"-knop op een evenement (`add_2_calendar`) | Claude — **BEZIG** (2026-09-19). 98A en 98B zijn af; alleen de knop op `EventCurrent` rest nog |
 | **65** | Release-build doorloop | ✅ **Uitgelogde deel af 2026-09-19** (0 crashes; 65a, 65b en 65d-kleur opgelost; 65c + 65e open). Rest = ingelogd + Xiaomi → Bob |
 | **65** | Release-build doorloop | ✅ **Uitgelogde deel af 2026-09-19** (0 crashes; 65a, 65b en 65d-kleur opgelost; 65c + 65e open). Rest = ingelogd + Xiaomi → Bob |
-| ~~P2-24 B~~ | Categoriedropdown horeca-overzicht, tab-bewust | ⛔ **Geblokkeerd op Drupal — verplaatst naar Bob**, zie P2-24 B hieronder (gemeten 2026-09-19) |
+| **P2-24 B** | Categoriedropdown horeca-overzicht, tab-bewust | Wacht op Bob's access-callback (zie P2-24 B); custom functions staan klaar |
 | **G0.6** | Play-screenshots schieten | Browserloos op beide AVD's, ±10 min — zeg het en het gebeurt |
 | **G0.6** | Play-screenshots schieten | Browserloos op beide AVD's, ±10 min — zeg het en het gebeurt |
 
 
 ## 👤 BOB — OPEN, in volgorde van wat de livegang blokkeert
 ## 👤 BOB — OPEN, in volgorde van wat de livegang blokkeert
@@ -32,9 +32,7 @@ oppakken.
 | **B1** | **App-icoon: PNG 1024×1024, transparant, beeldmerk op ±60 %** | 🔴 Blokkeert. Op een toestel staat nu "itgaanskrant.co" |
 | **B1** | **App-icoon: PNG 1024×1024, transparant, beeldmerk op ±60 %** | 🔴 Blokkeert. Op een toestel staat nu "itgaanskrant.co" |
 | **G** | Google Play-checklist G0–G4 | Volledige checklist hieronder, afvinkbaar |
 | **G** | Google Play-checklist G0–G4 | Volledige checklist hieronder, afvinkbaar |
 | **66** | Crashlytics: Firebase-console nakijken + Crashtest-knop opruimen | App-kant is bewezen (rapport met status 200); alleen de console-check en het opruimen zijn nog van jou |
 | **66** | Crashlytics: Firebase-console nakijken + Crashtest-knop opruimen | App-kant is bewezen (rapport met status 200); alleen de console-check en het opruimen zijn nog van jou |
-| **98A** | ISO-datum naar **productie** zetten (op devbob af + getest) | 🔴 Blokkeert taak 98; zet bij die ronde ook Repeat rule op *Hide* |
-| **P2-24 B** | Endpoint voor subcategorieën per `horcat`-tid | Blokkeert de tab-bewuste categoriedropdown; drie opties uitgewerkt bij P2-24 B |
-| **98B** | Calendar-permissietekst in App Settings → Permissions | Claude kan dit veld niet zetten (elke toetsaanslag wordt een plist-entry); 10 seconden werk voor jou |
+| **P2-24 B** | `horecacategorieen` publiek maken (1 access callback) | Endpoint bestaat al en geeft al `parent_tid`; alleen `user_is_logged_in` eraf. Blokkeert de tab-bewuste categoriedropdown |
 | **P1-17** | Engelse vertalingen, één ronde | 46 velden op de twee aanmaakpagina's + 3 losse |
 | **P1-17** | Engelse vertalingen, één ronde | 46 velden op de twee aanmaakpagina's + 3 losse |
 | **Bij livegang** | Zes schakelaars en opruimklussen | Eigen blok hieronder |
 | **Bij livegang** | Zes schakelaars en opruimklussen | Eigen blok hieronder |
 | **Drupal** | taak 56, P2-25 | Eigen blokken hieronder (P1-42/P1-43 zijn af, nagemeten 2026-09-19) |
 | **Drupal** | taak 56, P2-25 | Eigen blokken hieronder (P1-42/P1-43 zijn af, nagemeten 2026-09-19) |
@@ -173,7 +171,15 @@ Stappen:
 6. ⏳ **Bewezen bij afronding, nog te doen**: één keer op een echt toestel
 6. ⏳ **Bewezen bij afronding, nog te doen**: één keer op een echt toestel
    tikken en kijken of de agenda-dialoog met de juiste datum opent.
    tikken en kijken of de agenda-dialoog met de juiste datum opent.
 
 
-### 🆕 98B · Calendar-permissietekst zetten · Eigenaar: Bob (builder)
+### ✅ 98B · Calendar-permissietekst — AF (Bob, 2026-09-19)
+
+Verse export geeft precies 3 `UsageDescription`-keys, één `NSCalendarsUsageDescription`
+met de volledige zin. **Belangrijk nevenresultaat: het per-toetsaanslag-probleem
+dat Claude tegenkwam is Claude-specifiek, niet een FlutterFlow-bug** — zie de
+bijgewerkte notitie in `CLAUDE.md`.
+
+<details><summary>oorspronkelijke opdracht</summary>
+
 
 
 App Settings → Permissions → rij **Calendar**: toggle aan en als bericht
 App Settings → Permissions → rij **Calendar**: toggle aan en als bericht
 `Deze app vraagt toegang tot je agenda om een evenement toe te voegen.`
 `Deze app vraagt toegang tot je agenda om een evenement toe te voegen.`
@@ -181,10 +187,15 @@ Controleer daarna op een **verse export**:
 `grep -c "UsageDescription" ios/Runner/Info.plist` → moet **3** geven (Camera,
 `grep -c "UsageDescription" ios/Runner/Info.plist` → moet **3** geven (Camera,
 PhotoLibrary, Calendar). Geeft het er tientallen, dan heeft jouw browser
 PhotoLibrary, Calendar). Geeft het er tientallen, dan heeft jouw browser
 hetzelfde per-toetsaanslag-probleem als Claude's; zet de toggle dan weer uit
 hetzelfde per-toetsaanslag-probleem als Claude's; zet de toggle dan weer uit
-(dat ruimt alles op) en meld het — dan is het een FlutterFlow-bug en moeten we
-de plist-regel anders regelen.
+(dat ruimt alles op) en meld het.
+</details>
+
+### ✅ 98A · ISO-datum aan `flutterflow_events` — AF, STAAT OP PRODUCTIE (2026-09-19)
+
+Geverifieerd op productie mét én zonder cache-buster (dus cache geleegd):
+nid 214439 → `datum_iso: "2026-09-19 09:00"`, nid 222813 → `"2026-12-10 20:30"`.
+Repeat rule staat op *Hide*. Onderstaande devbob-meting blijft als naslag.
 
 
-### ✅ 98A · ISO-datum aan `flutterflow_events` — AF OP DEVBOB, klaar voor productie
 
 
 Bob heeft veld `field_date_1` toegevoegd met label **`datum_iso`**, formatter
 Bob heeft veld `field_date_1` toegevoegd met label **`datum_iso`**, formatter
 Date and time → *custom*, format `Y-m-d H:i:s`, Display *Start date only*.
 Date and time → *custom*, format `Y-m-d H:i:s`, Display *Start date only*.
@@ -819,34 +830,52 @@ op Bob's verzoek geschrapt.
 De blokkade-verhalen hieronder zijn daarmee historie; ze staan er nog omdat de
 De blokkade-verhalen hieronder zijn daarmee historie; ze staan er nog omdat de
 meetmethode nuttig blijft.
 meetmethode nuttig blijft.
 
 
-**⛔ B · Stand 2026-09-19 (Claude, gemeten op productie): dit kan niet in de app,
-het heeft een Drupal-endpoint nodig.** Twee metingen, allebei hard:
-
-1. **`categorieen.json` is sessie-only.** Anoniem geeft hij HTTP 403 met
-   `["Toegang geweigerd voor gebruiker anonymous"]`. Het horeca-overzicht is een
-   publieke pagina, dus deze call is daar onbruikbaar — nog los van de vraag of
-   hij per `horcat`-tid kan filteren.
-2. **De opties zijn niet uit de tabdata af te leiden.** Het veld `categorie` van
-   `flutterflowmobiel_establishments` bevat *alle* categorie-labels van een zaak,
-   over al zijn hoofdcategorieën heen — niet alleen de subcategorie die bij de
-   opgevraagde `horcat` hoort. Gemeten over alle zes de tabs (Amsterdam): tab
-   *Eetgelegenheden* levert 57 verschillende labels op, met o.a. "Catering" (26×)
-   en "Zaalverhuur"; tab *Cultuur* levert "Cafe" (11×). Een zaak die op twee tabs
-   staat is uit deze respons **principieel niet** toe te wijzen aan de juiste
-   hoofdcategorie — er is geen veld dat dat verband legt. Bob's vermoeden
-   ("geeft een paar vreemde opties") is dus geen randgeval maar de regel.
-
-**Wat Bob nodig heeft om B mogelijk te maken — kies één:**
-- **(a) een publiek endpoint** `subcategorieen.json?horcat=<tid>` dat de
-  taxonomie-kinderen van die tid teruggeeft (`tid` + `naam`), of
-- **(b) `categorieen.json` publiek maken** *en* een `horcat`-parameter geven, of
-- **(c) een extra veld in `flutterflowmobiel_establishments`** dat per rij zegt
-  welke categorie-labels onder de opgevraagde `horcat` vallen (dan kan de app het
-  zelf afleiden en is er geen tweede call nodig — waarschijnlijk de goedkoopste).
-
-Zodra dat er is, is het app-deel klein: een dropdown boven de lijst, gevuld uit
-dat endpoint, plus een extra argument op `filterHorecagelegenheden(...)` — precies
-het patroon dat het zoekveld al gebruikt.
+**🔧 B · Stand 2026-09-19 (bijgesteld): het endpoint bestond al — alleen de
+access-regel moet om.** Mijn eerdere conclusie ("kan niet in de app, nieuw
+Drupal-endpoint nodig") was te somber; ik keek naar het verkeerde endpoint.
+
+**Er zijn TWEE categorie-endpoints, en dat is makkelijk te verwarren:**
+
+| Resource | Vocabulary | Waarvoor |
+|---|---|---|
+| `categorieen` | vid **10** (`field_act_categorie` / `field_category2`) | Stadsactiviteit + Uitgaansevenement |
+| `horecacategorieen` | vid **6** (`field_categories`, `horecagelegenheid_category`) | **Horecagelegenheid — dit is degene die we nodig hebben** |
+
+Dat de horeca-tabs in vid 6 zitten blijkt uit `custom_form_alter()` in
+`custom.module`: `taxonomy_get_tree(6, 34)` plus
+`array(1 => 17969, 2 => 17963, 3 => 34, 4 => 17967, 5 => 17968)` — exact de zes
+`horcat`-waarden.
+
+**`_custom_horecacategorieen_service()` geeft al de juiste vorm terug** — het
+loopt via `_custom_term_reference_field_options()`, en die levert per term
+`tid`, `naam`, `diepte` én **`parent_tid`**. Er hoeft dus niets aan die functie
+te gebeuren.
+
+**Enige blokkade: `access callback => user_is_logged_in`.** Het horeca-overzicht
+is een publieke pagina. → Bob, zie zijn taak hierboven.
+
+**Waarom het niet zonder dit endpoint kan:** het veld `categorie` van
+`flutterflowmobiel_establishments` bevat *alle* labels van een zaak, over al zijn
+hoofdcategorieën heen. Tab *Eetgelegenheden* levert zo 57 verschillende labels op
+met o.a. "Catering" (26×) en "Zaalverhuur"; tab *Cultuur* geeft "Cafe" (11×). Een
+zaak die op twee tabs staat is uit die respons principieel niet toe te wijzen aan
+de juiste hoofdcategorie. Met `parent_tid` uit `horecacategorieen` is dat één
+filterregel.
+
+**App-deel (Claude), zodra het endpoint publiek is:**
+1. ✅ Custom functions `horcatSubTids(respons, horcatTid)` en
+   `horcatSubLabels(respons, horcatTid)` — filteren op `parent_tid == horcatTid`,
+   zelfde patroon als het bestaande `categorieSubTids`/`categorieSubLabels`.
+2. Dropdown per tab op `horecagelegenhedenOverzichtCurrent`, gevoed uit één
+   `horecacategorieen`-call (`cache: true`).
+3. Extra argument op `filterHorecagelegenheden(...)` — zelfde route als het
+   zoekveld al gebruikt.
+4. Ontwerpkeuze voor Bob: eerste optie "Alle categorieën" of standaard leeg?
+
+⚠️ **Verifieer als eerste** dat de zes tab-tids (34/17963/17965/17967/17968/17969)
+op `diepte: 0` in de respons staan — dat bevestigt dat `field_categories` op vid 6
+zit. Zo niet, dan wijst `field_categories` naar een andere vocabulary en moet de
+service een ander veld introspecteren.
 
 
 **P2-24.**
 **P2-24.**
 Pagina: **`horecagelegenhedenOverzichtCurrent`**. P2-6 heeft het zoekveld op 5
 Pagina: **`horecagelegenhedenOverzichtCurrent`**. P2-6 heeft het zoekveld op 5