Pārlūkot izejas kodu

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 10 stundas atpakaļ
vecāks
revīzija
92300ae6aa
2 mainītis faili ar 73 papildinājumiem un 41 dzēšanām
  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
   á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.
-- **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
-  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,
 betrouwbaar te bewerken — maar wijziging verschijnt pas in een export

+ 66 - 37
TASKS.md

@@ -20,9 +20,9 @@ oppakken.
 | # | Taak | Kort |
 |---|---|---|
 | ~~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 |
-| ~~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 |
 
 ## 👤 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" |
 | **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 |
-| **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 |
 | **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) |
@@ -173,7 +171,15 @@ Stappen:
 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.
 
-### 🆕 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
 `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,
 PhotoLibrary, Calendar). Geeft het er tientallen, dan heeft jouw browser
 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
 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
 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.**
 Pagina: **`horecagelegenhedenOverzichtCurrent`**. P2-6 heeft het zoekveld op 5