|
|
@@ -3099,55 +3099,104 @@ een volgende sessie niet opnieuw hoeft te reconstrueren:
|
|
|
|
|
|
**Overige restpunten (sessie 2026-08-31, live pair-fix):**
|
|
|
|
|
|
-8. **`field_town_access` bevat nog plaats-niveau tids (Drupal-kant).**
|
|
|
- De omzetting naar gemeente-niveau (2026-08-27) wijzigde alleen de
|
|
|
- widget-instellingen, niet de al opgeslagen waarden — bevestigd via
|
|
|
- `mijn_stadsrechten` op Bob's eigen account (`tid` 29946
|
|
|
- = 's-Gravendeel, een Plaats; `parent_titel` = Binnenmaas, de
|
|
|
- gemeente). Gevolg: de rechten-shortcut op `stadsactiviteitAanmaken`
|
|
|
- zet `createGemeenteID` op een plaats-tid en de Plaats-dropdown
|
|
|
- blijft leeg. **De app-binding (`$[:].tid`) is correct; de data niet.**
|
|
|
- Eenmalige drush-migratie nodig voor alle gebruikers met
|
|
|
- `field_town_access`: tids waarvoor
|
|
|
- `count(taxonomy_get_parents_all($tid)) === 3` vervangen door hun
|
|
|
- gemeente-parent (`$parents[1]->tid`), dedupliceren, `user_save()`.
|
|
|
- Eerst devbob, dan productie. Script is in de sessie aan Bob gegeven.
|
|
|
-10. **Basis-URL centraliseren — Fase A af, Fase B open (app-breed, niet
|
|
|
- alleen deze pagina; overweeg een eigen taak-ID).** Aanleiding: op
|
|
|
- devbob kunnen testen zonder overal URL's te wijzigen. **Gedaan:**
|
|
|
- nieuwe App State-variabele **`apiBaseUrl`** (default
|
|
|
- `https://uitgaanskrant.com`), en alle vier de custom actions
|
|
|
- (`stadsactiviteitCreate`, `bestandUpload`, `drupalRequest`,
|
|
|
- `drupalLogin`) bouwen hun URL nu daaruit op. Ze zijn **tolerant**:
|
|
|
- een argument dat met `http(s)://` begint wordt ongewijzigd gebruikt,
|
|
|
- anders wordt het als pad achter `apiBaseUrl` geplakt — dus alle 26
|
|
|
- bestaande aanroepen met een volledige URL blijven werken en kunnen
|
|
|
- in eigen tempo ingekort worden tot een pad. Truc: de parameter zelf
|
|
|
- wordt overschreven (`url = ...`), zodat verderop in de action niets
|
|
|
- aangepast hoefde te worden. **Let op:** custom *Functions* kunnen
|
|
|
- `FFAppState()` NIET lezen (`custom_functions.dart` importeert
|
|
|
- `app_state.dart` niet en dat importblok is niet bewerkbaar) —
|
|
|
- custom *Actions* wel. **Nog open (Fase B):** de 13 top-level API
|
|
|
- Calls in `api_calls.dart` hebben nog een hardcoded host (16
|
|
|
- plekken). Centraliseren betekent ze in de bestaande API Group
|
|
|
- onderbrengen (nu `ProductieGroup`, base-URL-veld) — check eerst of
|
|
|
- het ⋮-menu van een API Call een "Move to group" heeft; zo niet moet
|
|
|
- elke call opnieuw aangemaakt worden ín de groep en moet **elke
|
|
|
- Backend Query die 'm gebruikt opnieuw gebonden** worden (het dure,
|
|
|
- foutgevoelige deel). Hernoem bij die gelegenheid de groep
|
|
|
- `productie` → `drupal`/`backend`, want de naam klopt niet meer zodra
|
|
|
- hij naar devbob wijst.
|
|
|
-11. **Devbob zit achter HTTP Basic Auth** — alleen `apiBaseUrl` omzetten
|
|
|
- naar devbob geeft op álles een 401. Er is een
|
|
|
- `Authorization: Basic <base64>`-header nodig die meegaat wanneer de
|
|
|
- base-URL devbob is: in de custom actions één `if` erbij, voor de API
|
|
|
- Calls een group-level header (extra argument om Fase B te doen).
|
|
|
- Nog niet gebouwd.
|
|
|
-
|
|
|
+8. **`field_town_access` staat volledig op plaats-niveau — 9.292 rijen
|
|
|
+ over 6 accounts (Drupal-kant).** Gemeten 2026-08-31 via SQL:
|
|
|
+ Bee 5200, Disco-Party.nl 2317, bobcity 1254, nomad 517, bobhoreca 2,
|
|
|
+ Team Klein Frankrijk 2 — alles niveau 3 (Plaats). De omzetting naar
|
|
|
+ gemeente-niveau (2026-08-27) wijzigde alleen de widget-instellingen,
|
|
|
+ niet de opgeslagen waarden. **`mijn_stadsrechten` is NIET stuk** —
|
|
|
+ het endpoint geeft correct terug wat er staat (bevestigd: API-length
|
|
|
+ 1254 == SQL-count voor bobcity).
|
|
|
+ **Correctie op een eerdere notitie in deze taak:** de conclusie
|
|
|
+ "bobcity heeft 's-Gravendeel als stadsrecht" was gebaseerd op het
|
|
|
+ eerste item van een `head -20` over de volledige, alfabetisch
|
|
|
+ gesorteerde lijst — geen bewijs van iets. De omvang bleek pas via
|
|
|
+ de database.
|
|
|
+ **Migratiescript is aan Bob gegeven** (dry-run + `$APPLY`-vlag,
|
|
|
+ haalt de hele hiërarchie in 2 queries op i.p.v.
|
|
|
+ `taxonomy_get_parents_all()` per term; plaats-tid → gemeente-ouder,
|
|
|
+ dedupliceren, `user_save()`). Nog niet gedraaid. Eerst devbob.
|
|
|
+ **⚠️ Productbeslissing die eerst gemaakt moet worden:** na conversie
|
|
|
+ houdt bobcity ~300 gemeenten en Bee mogelijk heel Nederland — dan is
|
|
|
+ de "Mijn gemeenten"-shortcut geen snelkoppeling maar een tweede
|
|
|
+ plaatsenlijst. Ofwel de landelijke scope terugbrengen tot wat die
|
|
|
+ accounts echt beheren, ofwel de shortcut anders vormgeven (alleen
|
|
|
+ tonen bij ≤ ~25 gemeenten, of een zoekveld i.p.v. een dropdown).
|
|
|
+ Zonder die keuze heeft de migratie weinig zin.
|
|
|
9. **Categorie-dropdown toont de hele hiërarchie plat.** `categorieen`
|
|
|
geeft `diepte`/`parent_tid` mee; de multiselect toont nu ouder- én
|
|
|
kindtermen door elkaar zonder inspringing. Optionele verfijning.
|
|
|
|
|
|
+**Live test 2026-08-31 — pagina werkt grotendeels, drie bugs gevonden
|
|
|
+en gefixt, twee open.**
|
|
|
+- **Gefixt: sessie-cookie ging nooit mee.** Vijf API Calls hadden
|
|
|
+ `Cookie: {{session_name}}={{sessid}}` — Postman-syntax, die
|
|
|
+ FlutterFlow niet substitueert (`ApiManager` doet geen `{{ }}`-
|
|
|
+ vervanging, stuurt de tekst letterlijk). Moet `[session_name]=[sessid]`
|
|
|
+ zijn. **Hiermee is ook de aanname weerlegd dat `drupalRequest` nodig
|
|
|
+ was omdat API Calls geen cookie konden meesturen** — dat kan wel; het
|
|
|
+ ging destijds mis op de syntax. Zie de nieuwe regel in `CLAUDE.md`.
|
|
|
+ Gefixt: `Entreeopties`, `Categorieen`, `MijnStadsrechten`.
|
|
|
+ **Nog open: `MijnHorecagelegenheden` (regel ~1096) en
|
|
|
+ `FavorietenAgenda` (regel ~131)** — die staan nog op `{{…}}`, dus
|
|
|
+ `mijnProfiel`'s horeca-sectie en Favorieten Tab 1 zijn vermoedelijk
|
|
|
+ al die tijd leeg. (`FavorietenAgendaTESTKANWEG` heeft een hardcoded
|
|
|
+ sessie-cookie; dode call, zie P2-7.)
|
|
|
+- **Gefixt: datumpickers vuurden nooit.** Beide datumvelden hadden hun
|
|
|
+ picker op **On Submit** (`onFieldSubmitted`) terwijl het veld
|
|
|
+ `readOnly` is — dat kan per definitie niet afgaan. Een TextField heeft
|
|
|
+ in FlutterFlow geen On Tap-trigger; oplossing: **Wrap Widget →
|
|
|
+ Container**, actieketen op de Container's On Tap, en op het TextField
|
|
|
+ **Enabled uit** (een `readOnly` veld vangt de tap zelf op en geeft
|
|
|
+ 'm niet door aan de ouder).
|
|
|
+- **Gefixt: crashes op lege API-responses.** `DropDownGemeente`,
|
|
|
+ `DropDownPlaats` en de verzendknop hebben nu Visibility-guards
|
|
|
+ (`createProvincieID` / `createGemeenteID` / `createPlaatsID` Is Set).
|
|
|
+- **Open: geen terugkoppeling na het kiezen van logo/foto's.** Plan
|
|
|
+ staat klaar: `bestandUpload` geeft naast `fid` ook een `url` terug;
|
|
|
+ nieuwe Page State `createLogoUrl` (String) + `createFotosUrls`
|
|
|
+ (List<String>), gevuld met `$.url` in dezelfde Update-Page-State-actie,
|
|
|
+ daarna een Image (logo) en een Wrap met Generate Dynamic Children
|
|
|
+ (foto's). **Blokkade:** de "Set from Variable"-dialoog van de Image's
|
|
|
+ **Path** toont alle losse String-variabelen gedimd en laat alleen
|
|
|
+ `List<String>`-velden selecteren. Debugplan staat hieronder.
|
|
|
+- **Open: categorie-multiselect gefilterd op subniveau.** Bindingen
|
|
|
+ staan nu op `$[?(@.diepte == 1)].tid` / `.naam` (diepte 0 = de 7
|
|
|
+ hoofdcategorieën, diepte 1 = de subcategorieën, bevestigd via curl).
|
|
|
+ **Nog niet live geverifieerd** of FlutterFlow's `getJsonField` deze
|
|
|
+ JSONPath-filtersyntax aankan. Faalt hij, dan een custom function met
|
|
|
+ platte Map-toegang (`categorieVeldOpDiepte(respons, diepte, veld)`),
|
|
|
+ of een `?diepte=1`-parameter op het Drupal-endpoint.
|
|
|
+
|
|
|
+**Debugplan voor de Image-Path-blokkade (eerste stap volgende sessie):**
|
|
|
+1. **Zoekbalk gebruiken.** Typ `createLogoUrl` in "Search variables..."
|
|
|
+ bovenin de dialoog. Deze keuzelijst rendert in dit project vaker
|
|
|
+ items als niet-klikbaar terwijl ze het wel zijn; de gefilterde lijst
|
|
|
+ werkt dan meestal gewoon. Kost 5 seconden, probeer dit eerst.
|
|
|
+2. **Type van de variabele controleren.** Pagina-root → Page State
|
|
|
+ Variables → `createLogoUrl` moet **String** zijn met **Is List uit**.
|
|
|
+ Staat er iets anders, dan is dat meteen de verklaring.
|
|
|
+3. **Tegenproef.** Probeer in dezelfde Path-dialoog een ándere losse
|
|
|
+ String te kiezen (bv. `createLogoFid`). Lukt dat ook niet, dan is
|
|
|
+ het een typefilter op het Path-veld en niet iets aan `createLogoUrl`.
|
|
|
+ Lukt het wél, dan is er iets mis met die ene variabele.
|
|
|
+4. **Tegenproef 2.** Bind de Path aan een App State-String (bv.
|
|
|
+ `userName`). Werkt dát, dan accepteert het veld wél Strings maar
|
|
|
+ geen *Page* State — een scope-probleem, geen typeprobleem.
|
|
|
+5. **Omweg als 1-4 niets opleveren:** custom function
|
|
|
+ `String logoPad(String? url) => url ?? '';` (plat, geen closure,
|
|
|
+ Ctrl+S) en de Path binden aan **Custom Functions → `logoPad`** met
|
|
|
+ `createLogoUrl` als argument. Dat patroon werkt in dit project
|
|
|
+ bewezen om typeblokkades in bindingsdialogen te omzeilen (zie
|
|
|
+ `favorietenBodyNode`).
|
|
|
+6. Werkt de binding, vergeet dan niet de **Visibility → Conditional**
|
|
|
+ op `createLogoUrl` "Is Set and Not Empty" — anders staat er vóór het
|
|
|
+ uploaden een kapotte-afbeeldingsplek. En haal het testplaatje
|
|
|
+ (`https://picsum.photos/seed/489/600`) uit het Path-veld.
|
|
|
+7. Voor de foto's geen losse Image maar een **Wrap** met Generate
|
|
|
+ Dynamic Children over `createFotosUrls` — daar is `List<String>`
|
|
|
+ juist wél het gevraagde type.
|
|
|
+
|
|
|
**Losse observatie (niet blokkerend):** FlutterFlow's Issues-paneel
|
|
|
toont 1 error "Property Override — return type mismatch" wijzend naar
|
|
|
`DropDownProvincie`, terwijl de export 0 Dart-errors geeft en de
|