|
@@ -4,33 +4,54 @@
|
|
|
|
|
|
|
|
Werk uitsluitend binnen deze projectdirectory
|
|
Werk uitsluitend binnen deze projectdirectory
|
|
|
(`/home/bob/Projects/ff-app/uitgaanskrant-1qhvtd`). Niet daarbuiten
|
|
(`/home/bob/Projects/ff-app/uitgaanskrant-1qhvtd`). Niet daarbuiten
|
|
|
-zoeken of scannen (bijvoorbeeld geen `find /` over het hele
|
|
|
|
|
-bestandssysteem) — scope alle bestandsoperaties tot dit project.
|
|
|
|
|
|
|
+zoeken of scannen — scope alle bestandsoperaties tot dit project.
|
|
|
|
|
|
|
|
-## Sessiegeheugen — lees dit eerst
|
|
|
|
|
|
|
+## Werkwijze binnen een sessie
|
|
|
|
|
|
|
|
-Bob bespreekt elke taak in een **nieuwe, aparte chat**. Dit bestand en
|
|
|
|
|
-`TASKS.md` zijn daarom het geheugen tussen sessies — er is geen eerdere
|
|
|
|
|
-conversatie om op terug te vallen.
|
|
|
|
|
|
|
+- **Meld bij elke nieuwe stap kort vooraf wat je gaat doen**, vóór je
|
|
|
|
|
+ begint (staande voorkeur Bob, 2026-08-04).
|
|
|
|
|
+- Bob bespreekt elke taak in een **nieuwe, aparte chat** — geen
|
|
|
|
|
+ eerdere conversatie om op terug te vallen. `CLAUDE.md` + `TASKS.md`
|
|
|
|
|
+ zijn samen het volledige geheugen tussen sessies.
|
|
|
|
|
+- **Groepeer opgepakte taken per sessie op FlutterFlow-paginagebied**
|
|
|
|
|
+ waar mogelijk (bv. twee taken op dezelfde pagina/component samen
|
|
|
|
|
+ oppakken) — minder heen-en-weer-navigeren in de builder, minder
|
|
|
|
|
+ tokens. Zie de sessie-indeling bovenaan `TASKS.md`.
|
|
|
|
|
+- **`TASKS.md`-status kan achterlopen op de echte code** (Bob werkt
|
|
|
|
|
+ gelijktijdig, en documentatie-updates lopen niet altijd synchroon
|
|
|
|
|
+ met de export). Check een taak die er al even staat met
|
|
|
|
|
+ `git log --oneline -S"<kenmerkende string/tekst>"` of een gerichte
|
|
|
|
|
+ `grep` vóórdat je 'm oppakt — niet blind vertrouwen dat "open"
|
|
|
|
|
+ betekent "nog niet gefixt". (Precedent: 2026-08-04 bleken 2 "open"
|
|
|
|
|
+ P0-taken al op 2026-08-02 gefixt te zijn, git-bevestigd.)
|
|
|
|
|
+- **Eigenaar-tag per taak in `TASKS.md`**: `[Claude]` (zelfstandig of
|
|
|
|
|
+ via browser-automation te doen), `[Bob]` (sneller/simpeler voor Bob
|
|
|
|
|
+ zelf — meestal builder-UI met een bekend fragiele dialoog, zie
|
|
|
|
|
+ hieronder), of `[Bob — bezig]` (al geclaimd). Vuistregel: een kort,
|
|
|
|
|
+ mechanisch herhaald patroon zonder geneste dialogen → Claude;
|
|
|
|
|
+ ConditionalBuilder/JSON-Path-condities, List-typed
|
|
|
|
|
+ function-argumenten, of iets dat eerder al vastliep → Bob.
|
|
|
|
|
|
|
|
-**Vaste afsluitroutine, aan het eind van elke sessie/taak:**
|
|
|
|
|
-1. Werk `TASKS.md` bij: **een afgeronde taak wordt volledig verwijderd
|
|
|
|
|
- uit de lijst** (niet gearchiveerd in een "Afgerond"-sectie — dat is
|
|
|
|
|
- onnodige context/kosten voor toekomstige sessies). Zorg dat elke
|
|
|
|
|
- resterende open taak zelfstandig te begrijpen is (concreet, met
|
|
|
|
|
- bestandspad/context) zonder de chat gelezen te hebben waarin hij
|
|
|
|
|
- ontstond.
|
|
|
|
|
-2. Werk dit bestand (`CLAUDE.md`) bij: **alleen** toevoegen als het
|
|
|
|
|
- een blijvend herbruikbaar inzicht is (een conventie, een
|
|
|
|
|
- architectuurkeuze, een bekende valkuil/bug-patroon) dat een latere
|
|
|
|
|
- sessie anders opnieuw zou moeten uitzoeken. Geen sessieverslag,
|
|
|
|
|
- geen changelog van wat er gedaan is, geen herhaling van
|
|
|
|
|
- redeneringen. Ruim verouderde/dubbele info op in plaats van
|
|
|
|
|
- eronder te plakken — dit bestand moet klein en scanbaar blijven.
|
|
|
|
|
|
|
+## Sessiegeheugen — afsluitroutine
|
|
|
|
|
+
|
|
|
|
|
+Aan het eind van elke sessie/taak:
|
|
|
|
|
+1. **`TASKS.md`**: een afgeronde taak wordt volledig **verwijderd**
|
|
|
|
|
+ (niet gearchiveerd — onnodige context/kosten voor latere sessies).
|
|
|
|
|
+ Elke resterende open taak moet zelfstandig te begrijpen zijn
|
|
|
|
|
+ (concreet, met bestandspad) zonder de ontstaanschat gelezen te
|
|
|
|
|
+ hebben.
|
|
|
|
|
+2. **`CLAUDE.md`**: alleen aanvullen met blijvend herbruikbare inzichten
|
|
|
|
|
+ (conventie, architectuurkeuze, bekend valkuil-patroon) die een
|
|
|
|
|
+ latere sessie anders opnieuw zou moeten uitzoeken. Geen
|
|
|
|
|
+ sessieverslag/changelog. Ruim verouderde info op i.p.v. eronder te
|
|
|
|
|
+ plakken — dit bestand moet klein en scanbaar blijven.
|
|
|
3. Commit + push de gewijzigde `.md`-bestanden direct (geen
|
|
3. Commit + push de gewijzigde `.md`-bestanden direct (geen
|
|
|
- FlutterFlow-export nodig voor pure documentatiewijzigingen — alleen
|
|
|
|
|
- de export/build-cyclus hieronder draaien als er ook echt
|
|
|
|
|
- app-code is gewijzigd).
|
|
|
|
|
|
|
+ FlutterFlow-export nodig voor pure documentatiewijzigingen).
|
|
|
|
|
+
|
|
|
|
|
+**Geen apart memory-systeem meer nodig voor projectfeiten** — die
|
|
|
|
|
+staan allemaal hier en in `TASKS.md`, wat al elke sessie automatisch
|
|
|
|
|
+geladen wordt. (Auto-memory-bestanden zijn per 2026-08-04
|
|
|
|
|
+opgeschoond omdat ze dit bestand 1-op-1 dupliceerden.)
|
|
|
|
|
|
|
|
## FlutterFlow-workflow — belangrijk
|
|
## FlutterFlow-workflow — belangrijk
|
|
|
|
|
|
|
@@ -38,188 +59,157 @@ Dit project wordt gebouwd via FlutterFlow (app.flutterflow.io). De
|
|
|
FlutterFlow-cloudomgeving is de bron van waarheid, niet deze lokale
|
|
FlutterFlow-cloudomgeving is de bron van waarheid, niet deze lokale
|
|
|
code-export.
|
|
code-export.
|
|
|
|
|
|
|
|
-- De gebruiker kan **geen** code rechtstreeks genereren of bewerken in
|
|
|
|
|
- dit repo. Alle wijzigingen aan pagina's, componenten en modellen
|
|
|
|
|
- moeten via de FlutterFlow-website gebeuren.
|
|
|
|
|
-- De enige uitzondering is **custom functions/widgets**
|
|
|
|
|
- (`lib/custom_code/`) — en ook die voert de gebruiker in via de
|
|
|
|
|
- Custom Code-editor op de FlutterFlow-website, niet door hier
|
|
|
|
|
- rechtstreeks bestanden te bewerken.
|
|
|
|
|
|
|
+- Bob kan **geen** code rechtstreeks bewerken in dit repo. Alle
|
|
|
|
|
+ wijzigingen aan pagina's, componenten en modellen moeten via de
|
|
|
|
|
+ FlutterFlow-website. Enige uitzondering: custom functions/widgets
|
|
|
|
|
+ (`lib/custom_code/`) — ook die voert Bob in via de Custom
|
|
|
|
|
+ Code-editor op de website, niet hier lokaal.
|
|
|
- Gevolg: directe Edit/Write-wijzigingen aan gegenereerde bestanden
|
|
- Gevolg: directe Edit/Write-wijzigingen aan gegenereerde bestanden
|
|
|
- (pagina's, blocks, components, models, `lib/flutter_flow/*` e.d.)
|
|
|
|
|
- worden bij de volgende export/sync vanuit FlutterFlow overschreven.
|
|
|
|
|
- Zulke bestanden hier aanpassen is dus **niet duurzaam**.
|
|
|
|
|
-- Werkwijze: gebruik deze lokale repo om code te lezen, logica te
|
|
|
|
|
- ontwerpen en te verifiëren (bijv. met `flutter analyze`) — maar
|
|
|
|
|
- vertaal het eindresultaat naar concrete, stapsgewijze instructies
|
|
|
|
|
- voor wat de gebruiker in de FlutterFlow-builder (of de Custom
|
|
|
|
|
- Code-editor) moet doen, of voer het zelf uit via browser-automation
|
|
|
|
|
- (zie hieronder). Ga er niet van uit dat een lokale bestandswijziging
|
|
|
|
|
- behouden blijft.
|
|
|
|
|
-- Als er via de Chrome-browser (Claude in Chrome) rechtstreeks in de
|
|
|
|
|
- FlutterFlow-builder wordt gewerkt: maak na elke **afgeronde taak**
|
|
|
|
|
- (niet na elke losse klik/handeling) een **commit binnen FlutterFlow
|
|
|
|
|
- zelf** (het eigen versiebeheer, te zien bovenin de builder als
|
|
|
|
|
- "main"/"Synced"), met een duidelijke omschrijving van wat er is
|
|
|
|
|
- veranderd. Dit is geen lokale `git commit`.
|
|
|
|
|
-- **Gebruik `mcp__claude-in-chrome__*` (Bob's eigen, gedeelde Chrome),
|
|
|
|
|
- niet de in-app Browser pane** — dat is de afgesproken tool voor
|
|
|
|
|
- builder-automation.
|
|
|
|
|
-- **Resize de browser niet zelf** (`resize_window` e.d.) — dit is
|
|
|
|
|
- Bob's eigen gedeelde vensters. Als iets buiten beeld valt, meld dat
|
|
|
|
|
- en vraag het aan Bob i.p.v. zelf te resizen.
|
|
|
|
|
-- Bob werkt vaak **gelijktijdig zelf** in dezelfde builder-sessie. Ga
|
|
|
|
|
- er niet van uit dat elke wijziging die je in de widget tree/`git
|
|
|
|
|
- diff` ziet van jezelf komt — check eerst of hij iets claimde
|
|
|
|
|
- ("dat regel ik zelf") voordat je het overschrijft.
|
|
|
|
|
|
|
+ worden bij de volgende export overschreven — **niet duurzaam**.
|
|
|
|
|
+ Gebruik deze repo om te lezen/ontwerpen/verifiëren (`flutter
|
|
|
|
|
+ analyze`), maar voer het eindresultaat uit via de builder (zelf via
|
|
|
|
|
+ browser-automation, of als instructie aan Bob). Ga nooit uit van
|
|
|
|
|
+ behoud van een lokale bestandswijziging.
|
|
|
|
|
+- Werk je rechtstreeks in de builder (Claude in Chrome): commit na
|
|
|
|
|
+ elke **afgeronde taak** binnen FlutterFlow's eigen versiebeheer
|
|
|
|
|
+ ("main"/"Synced" bovenin), met duidelijke omschrijving. Geen lokale
|
|
|
|
|
+ `git commit`.
|
|
|
|
|
+- **Gebruik `mcp__claude-in-chrome__*`** (Bob's gedeelde Chrome), niet
|
|
|
|
|
+ de in-app Browser pane.
|
|
|
|
|
+- **Resize de browser niet zelf.** Bob's eigen gedeelde vensters —
|
|
|
|
|
+ meld en vraag i.p.v. zelf te resizen.
|
|
|
|
|
+- Bob werkt vaak **gelijktijdig zelf** in dezelfde builder-sessie —
|
|
|
|
|
+ check eerst of hij iets claimde ("dat regel ik zelf") voordat je
|
|
|
|
|
+ wijzigingen overschrijft.
|
|
|
- Check bij een mislukte export/pull eerst het **Issues-paneel**
|
|
- Check bij een mislukte export/pull eerst het **Issues-paneel**
|
|
|
- (badge-icoon rechtsboven, naast de sync-checkmarks) voordat je een
|
|
|
|
|
- bug bij jezelf zoekt — een rode teller daar blokkeert *elke* export,
|
|
|
|
|
- ook voor niet-gerelateerde correcte wijzigingen, en is vaak Bob's
|
|
|
|
|
- eigen work-in-progress.
|
|
|
|
|
|
|
+ (badge rechtsboven) voordat je een bug bij jezelf zoekt — een rode
|
|
|
|
|
+ teller blokkeert *elke* export, ook niet-gerelateerde, en is vaak
|
|
|
|
|
+ Bob's eigen work-in-progress.
|
|
|
|
|
|
|
|
## Lokale git-repo + pull/push-workflow
|
|
## Lokale git-repo + pull/push-workflow
|
|
|
|
|
|
|
|
-De projectdirectory zelf is een schone git-repo met `origin` op
|
|
|
|
|
|
|
+Projectdirectory = eigen schone git-repo, `origin`
|
|
|
`ssh://gogs.digitalforce.tv:2222/Uitgaanskrant.com/flutterflow.git`,
|
|
`ssh://gogs.digitalforce.tv:2222/Uitgaanskrant.com/flutterflow.git`,
|
|
|
-branch `master`. Dit is een eigen repo van de gebruiker, los van de
|
|
|
|
|
-grotere/rommelige repo die hoger in de mappenstructuur staat (die met
|
|
|
|
|
-AndroidStudioProjects, Flutter-SDK-installaties e.d.) — commits en
|
|
|
|
|
-pushes horen hier, in de projectdirectory zelf.
|
|
|
|
|
|
|
+branch `master`. Los van de grotere/rommelige repo hoger in de
|
|
|
|
|
+mappenstructuur (AndroidStudioProjects, Flutter-SDK e.d.) — commits en
|
|
|
|
|
+pushes horen hier.
|
|
|
|
|
|
|
|
Vaste workflow na elke afgeronde taak (staand akkoord, geen aparte
|
|
Vaste workflow na elke afgeronde taak (staand akkoord, geen aparte
|
|
|
-bevestiging per keer nodig): niet los `flutterflow export-code`
|
|
|
|
|
-draaien, maar het bestaande script gebruiken:
|
|
|
|
|
|
|
+bevestiging nodig): niet los `flutterflow export-code`, maar:
|
|
|
|
|
|
|
|
```
|
|
```
|
|
|
export PATH="/home/bob/fvm/bin:$HOME/.pub-cache/bin:$PATH" && /home/bob/Projects/ff-run-fvm.sh emulator-5554 uitgaanskrant-1qhvtd -s
|
|
export PATH="/home/bob/fvm/bin:$HOME/.pub-cache/bin:$PATH" && /home/bob/Projects/ff-run-fvm.sh emulator-5554 uitgaanskrant-1qhvtd -s
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-- **De `export PATH=...` prefix is verplicht.** De Bash-tool draait
|
|
|
|
|
- niet-interactief, dus `~/.bashrc` (waar `fvm`/`flutterflow` normaal
|
|
|
|
|
- op PATH komen) wordt niet geladen. Zonder deze prefix faalt het
|
|
|
|
|
- script stil met "fvm: command not found" / "Prerequisites not met,
|
|
|
|
|
- skipping execution" — geen harde error, dus makkelijk te missen.
|
|
|
|
|
-- Dit script is interactief (device-run + hot-restart-loop) — moet via
|
|
|
|
|
- Bash met `run_in_background: true`. Volg de output tot minimaal
|
|
|
|
|
- "All done!" (export gelukt) én idealiter een succesvolle app-launch
|
|
|
|
|
- op de emulator (`Launching lib/main.dart...`, geen nieuwe
|
|
|
|
|
- `EXCEPTION CAUGHT BY RENDERING LIBRARY` t.o.v. bekende issues in
|
|
|
|
|
- `TASKS.md`) voordat je verder gaat.
|
|
|
|
|
|
|
+- **De `export PATH=...` prefix is verplicht** — Bash draait
|
|
|
|
|
+ niet-interactief, `~/.bashrc` wordt niet geladen. Zonder prefix
|
|
|
|
|
+ faalt het script stil ("fvm: command not found" — geen harde error).
|
|
|
|
|
+- Interactief script (device-run + hot-restart-loop) → Bash met
|
|
|
|
|
+ `run_in_background: true`. Volg tot minimaal "All done!" én
|
|
|
|
|
+ idealiter een succesvolle app-launch (`Launching lib/main.dart...`,
|
|
|
|
|
+ geen nieuwe `EXCEPTION CAUGHT BY RENDERING LIBRARY`).
|
|
|
|
|
|
|
|
Daarna automatisch:
|
|
Daarna automatisch:
|
|
|
-1. `git status --short` bekijken, dan `git add` — **niet blind `-A`**.
|
|
|
|
|
- Voeg alleen daadwerkelijke FlutterFlow/app-wijzigingen toe (`lib/`,
|
|
|
|
|
- `android/`, `ios/`, `pubspec*`, `.gitignore` e.d.). Sluit `.claude/`
|
|
|
|
|
- uit (staat in .gitignore) — dat is sessiestate van Claude Code,
|
|
|
|
|
- geen app-code. Wijzigingen die niet van jezelf zijn (Bob's eigen
|
|
|
|
|
- concurrent werk) horen gewoon mee in dezelfde commit — dit is één
|
|
|
|
|
- gedeeld project.
|
|
|
|
|
-2. `git commit` met een duidelijke boodschap.
|
|
|
|
|
-3. `git push` (of `git push -u origin master` als tracking nog niet
|
|
|
|
|
- staat).
|
|
|
|
|
|
|
+1. `git status --short`, dan `git add` — **niet blind `-A`**. Alleen
|
|
|
|
|
+ echte FlutterFlow/app-wijzigingen (`lib/`, `android/`, `ios/`,
|
|
|
|
|
+ `pubspec*`, `.gitignore`). `.claude/` blijft uitgesloten
|
|
|
|
|
+ (sessiestate, geen app-code). Bob's eigen concurrente wijzigingen
|
|
|
|
|
+ horen gewoon mee in dezelfde commit.
|
|
|
|
|
+2. `git commit` met duidelijke boodschap.
|
|
|
|
|
+3. `git push` (`-u origin master` als tracking nog niet staat).
|
|
|
|
|
|
|
|
-**Valkuil: `flutterflow export-code` overschrijft `.gitignore` bij
|
|
|
|
|
-elke export terug naar FlutterFlow's eigen standaardversie.** Voeg dus
|
|
|
|
|
-na elke export, vóór je staged, deze regel weer toe aan `.gitignore`
|
|
|
|
|
-als hij ontbreekt:
|
|
|
|
|
|
|
+**Valkuil:** `flutterflow export-code` overschrijft `.gitignore` bij
|
|
|
|
|
+elke export terug naar FlutterFlow's standaardversie. Voeg na elke
|
|
|
|
|
+export, vóór staging, deze regel weer toe als hij ontbreekt:
|
|
|
```
|
|
```
|
|
|
# Claude Code session state (not app code)
|
|
# Claude Code session state (not app code)
|
|
|
.claude/
|
|
.claude/
|
|
|
```
|
|
```
|
|
|
-(`CLAUDE.md` zelf overleeft een export altijd — alleen bij een volledig
|
|
|
|
|
-verwijderde en opnieuw gepulde projectmap zou het verdwijnen. Check
|
|
|
|
|
-voor de zekerheid toch even of het bestand er nog is.)
|
|
|
|
|
|
|
+(`CLAUDE.md` zelf overleeft een export altijd — check voor de
|
|
|
|
|
+zekerheid toch even.)
|
|
|
|
|
|
|
|
## Eerst research, dan bouwen
|
|
## Eerst research, dan bouwen
|
|
|
|
|
|
|
|
-Voordat je aan een niet-triviale taak begint (een bugfix, een nieuw
|
|
|
|
|
-patroon, een integratie): zoek eerst kort op internet naar bestaande
|
|
|
|
|
-oplossingen/patronen voordat je het zelf helemaal uitvindt via
|
|
|
|
|
-trial-and-error in de builder. Geldt niet voor triviale/mechanische
|
|
|
|
|
-herhaling van een patroon dat al bevestigd werkt (zie hieronder).
|
|
|
|
|
|
|
+Vóór een niet-triviale taak (bugfix, nieuw patroon, integratie): kort
|
|
|
|
|
+online zoeken naar bestaande oplossingen i.p.v. zelf trial-and-error
|
|
|
|
|
+in de builder. Geldt niet voor mechanische herhaling van een patroon
|
|
|
|
|
+dat al bevestigd werkt.
|
|
|
|
|
|
|
|
## FlutterFlow-builder: bekende problemen & patronen
|
|
## FlutterFlow-builder: bekende problemen & patronen
|
|
|
|
|
|
|
|
-**Geneste "Set Variable"-dialoog kan lijken vast te zitten.** Bij het
|
|
|
|
|
-instellen van een conditie (`ConditionalBuilder`, Visibility →
|
|
|
|
|
-Conditional) op een niet-triviaal type (JSON Path, API-response-veld)
|
|
|
|
|
-opent een tweede dialoog bovenop de eerste. Confirm/Cancel op die
|
|
|
|
|
-binnenste dialoog reageren soms niet zichtbaar. Twee bekende oorzaken,
|
|
|
|
|
-in volgorde van proberen:
|
|
|
|
|
-1. **Viewport-clipping** — de knoppen renderen buiten het zichtbare
|
|
|
|
|
- canvas, niet echt vast. Sleep de dialoog omhoog via het handvat
|
|
|
|
|
- bovenin (kleine grijze balk) naar een hogere y-positie; de
|
|
|
|
|
- Confirm/Cancel-knoppen worden dan zichtbaar en werken gewoon.
|
|
|
|
|
-2. **Echt bevroren pagina** (alle clicks, ook op onbetrokken plekken,
|
|
|
|
|
- doen niets) — de widget-wrap zelf is al server-side opgeslagen,
|
|
|
|
|
- maar de conditie-edit niet. Los op door de pagina te herladen
|
|
|
|
|
- (`navigate` naar dezelfde URL); de wrap blijft staan, de
|
|
|
|
|
- half-ingevulde conditie moet opnieuw.
|
|
|
|
|
-- **Kortere weg om deze dialoog te vermijden:** gebruik als operator
|
|
|
|
|
- **"Is Set"** in plaats van "Not Equal To" + lege string — dan is er
|
|
|
|
|
- geen Second Value nodig en dus geen tweede geneste dialoog.
|
|
|
|
|
-- Als dit na 1-2 pogingen (incl. de reload-poging) nog vastloopt: dit
|
|
|
|
|
- kost dan meer tijd dan Bob het zelf kan doen — meld het concreet
|
|
|
|
|
- (component, precieze stappen) en vraag het aan hem i.p.v. te blijven
|
|
|
|
|
- proberen.
|
|
|
|
|
|
|
+**Geneste "Set Variable"-dialoog lijkt vast te zitten.** Bij een
|
|
|
|
|
+conditie (`ConditionalBuilder`, Visibility → Conditional) op een
|
|
|
|
|
+niet-triviaal type (JSON Path, API-response-veld, `List<DataType>`
|
|
|
|
|
+function-argument) opent een tweede dialoog bovenop de eerste;
|
|
|
|
|
+Confirm/Cancel reageren soms niet zichtbaar. Twee oorzaken, in
|
|
|
|
|
+volgorde van proberen:
|
|
|
|
|
+1. **Viewport-clipping** (meest voorkomend) — knoppen renderen buiten
|
|
|
|
|
+ het zichtbare canvas. Sleep de dialoog omhoog via het handvat
|
|
|
|
|
+ bovenin naar een hogere y-positie; de knoppen worden dan zichtbaar
|
|
|
|
|
+ en werken gewoon.
|
|
|
|
|
+2. **Echt bevroren pagina** (alle clicks doen niets) — de widget-wrap
|
|
|
|
|
+ staat al server-side, de conditie-edit niet. Herlaad de pagina
|
|
|
|
|
+ (`navigate` naar dezelfde URL); wrap blijft staan, conditie moet
|
|
|
|
|
+ opnieuw.
|
|
|
|
|
+- **Kortere weg om dit te vermijden:** operator **"Is Set"** i.p.v.
|
|
|
|
|
+ "Not Equal To" + lege string — geen Second Value nodig, dus geen
|
|
|
|
|
+ tweede dialoog.
|
|
|
|
|
+- Loopt dit na 1-2 pogingen (incl. reload) nog vast: kost dan meer
|
|
|
|
|
+ tijd dan Bob het zelf kan doen — meld concreet (component, exacte
|
|
|
|
|
+ stappen) en vraag het aan hem.
|
|
|
|
|
|
|
|
**Component Name kan per ongeluk overschreven worden.** Vlak na
|
|
**Component Name kan per ongeluk overschreven worden.** Vlak na
|
|
|
-paginanavigatie kan een klik bedoeld voor het "Search properties..."
|
|
|
|
|
-veld in plaats daarvan op het Component Name-veld landen (focus/
|
|
|
|
|
-z-order race condition), en typen hernoemt dan stilletjes het hele
|
|
|
|
|
-component. Mitigatie: na een click-before-type altijd eerst een
|
|
|
|
|
-screenshot om focus te bevestigen, zeker vlak na navigatie. Herstel:
|
|
|
|
|
-rechtsklik component in de zoekresultatenlijst → "Rename Component".
|
|
|
|
|
|
|
+paginanavigatie kan een klik bedoeld voor "Search properties..." op
|
|
|
|
|
+het Component Name-veld landen (focus/z-order race), en typen
|
|
|
|
|
+hernoemt dan stilletjes het component. Zelfde risico bij een
|
|
|
|
|
+widget-tree zoekactie die per ongeluk double-click-to-rename triggert
|
|
|
|
|
+i.p.v. navigeren — druk direct **Escape** om te herstellen. Mitigatie:
|
|
|
|
|
+na elke click-before-type eerst een screenshot om focus te bevestigen,
|
|
|
|
|
+zeker vlak na navigatie. Herstel: rechtsklik component in
|
|
|
|
|
+zoekresultaten → "Rename Component".
|
|
|
|
|
|
|
|
-**Rechterpaneel kan te breed zijn voor de viewport.** Sommige
|
|
|
|
|
-controls (Expansion segmented control, Visibility → Conditional
|
|
|
|
|
-expression builder) renderen soms deels buiten beeld — dit is geen
|
|
|
|
|
-`resize_window`-probleem (zie hierboven: niet zelf resizen). Na 1-2
|
|
|
|
|
|
|
+**Rechterpaneel kan te breed zijn voor de viewport.** Sommige controls
|
|
|
|
|
+(Expansion segmented control, Visibility → Conditional
|
|
|
|
|
+expression-builder) renderen soms deels buiten beeld — geen
|
|
|
|
|
+`resize_window`-probleem (niet zelf resizen, zie boven). Na 1-2
|
|
|
bevestigde pogingen stoppen en aan Bob vragen.
|
|
bevestigde pogingen stoppen en aan Bob vragen.
|
|
|
|
|
|
|
|
-**Patroon: lege/ontbrekende afbeeldings-URL laten crashen.**
|
|
|
|
|
|
|
+**Patroon: lege/ontbrekende afbeeldings-URL laat de app crashen.**
|
|
|
`CachedNetworkImage` gooit een **synchrone** `ArgumentError` bij het
|
|
`CachedNetworkImage` gooit een **synchrone** `ArgumentError` bij het
|
|
|
*bouwen* van de widget als `imageUrl` een lege string is — dit gebeurt
|
|
*bouwen* van de widget als `imageUrl` een lege string is — dit gebeurt
|
|
|
-vóórdat er ooit een netwerkverzoek wordt gedaan, dus `errorWidget`/
|
|
|
|
|
-"Show Error Image on Failure" vangt dit **niet** (dat vangt alleen
|
|
|
|
|
-échte laadfouten zoals 404's). Werkende fix, toegepast op 9 van de ~10
|
|
|
|
|
-bekende instanties (zie `TASKS.md`):
|
|
|
|
|
|
|
+vóórdat er ooit een netwerkverzoek is, dus `errorWidget`/"Show Error
|
|
|
|
|
+Image on Failure" vangt dit **niet** (dat vangt alleen échte
|
|
|
|
|
+laadfouten zoals 404's). Werkende fix:
|
|
|
1. Rechtsklik het Image-widget → **Wrap Widget (Ctrl+B)** →
|
|
1. Rechtsklik het Image-widget → **Wrap Widget (Ctrl+B)** →
|
|
|
**ConditionalBuilder**.
|
|
**ConditionalBuilder**.
|
|
|
2. IF-conditie: **Conditions → Single Condition** → First Value = de
|
|
2. IF-conditie: **Conditions → Single Condition** → First Value = de
|
|
|
exacte expressie waar de Image's Path-property al aan gebonden was
|
|
exacte expressie waar de Image's Path-property al aan gebonden was
|
|
|
- (component-parameter, JSON Path, of custom-function-resultaat via
|
|
|
|
|
- "Evenement Response" → API Response Options → JSON Body → JSON
|
|
|
|
|
- Path, bv. `$[0].logo`) → operator **"Is Set"**.
|
|
|
|
|
|
|
+ → operator **"Is Set"**.
|
|
|
3. THEN-tak: de bestaande Image (blijft staan na de wrap).
|
|
3. THEN-tak: de bestaande Image (blijft staan na de wrap).
|
|
|
-4. ELSE-tak: rechtsklik → Insert Widget → Icon → zoek "image not
|
|
|
|
|
|
|
+4. ELSE-tak: rechtsklik → Insert Widget → Icon → "image not
|
|
|
supported" → eerste Material-resultaat.
|
|
supported" → eerste Material-resultaat.
|
|
|
- **Simpeler alternatief indien van toepassing:** de "Default Variable
|
|
- **Simpeler alternatief indien van toepassing:** de "Default Variable
|
|
|
- Value"-toggle op een willekeurige "Set from Variable"-binding
|
|
|
|
|
- substitueert al bij zowel `null` als lege string (bevestigd via
|
|
|
|
|
- in-builder tooltip: "if the resulting value is null or empty") —
|
|
|
|
|
- géén ConditionalBuilder nodig. Werkt hier alleen niet voor
|
|
|
|
|
- Image-widgets met `Image Type: Network`, omdat er nog geen gehoste
|
|
|
|
|
- fallback-afbeeldings-URL bestaat in dit project. Mocht die er ooit
|
|
|
|
|
- komen (bv. een default-logo op de FlutterFlow-CDN of Drupal-server):
|
|
|
|
|
- gebruik dan Default Variable Value + "Show Error Image on Failure"
|
|
|
|
|
- i.p.v. ConditionalBuilder — sneller te bouwen.
|
|
|
|
|
|
|
+ Value"-toggle op een "Set from Variable"-binding substitueert al bij
|
|
|
|
|
+ zowel `null` als lege string (in-builder tooltip: "if the resulting
|
|
|
|
|
+ value is null or empty") — géén ConditionalBuilder nodig. Werkt hier
|
|
|
|
|
+ niet voor Image-widgets met `Image Type: Network` zolang er geen
|
|
|
|
|
+ gehoste fallback-afbeeldings-URL bestaat in dit project. Komt die er
|
|
|
|
|
+ ooit (bv. default-logo op FlutterFlow-CDN/Drupal-server): gebruik
|
|
|
|
|
+ dan Default Variable Value + "Show Error Image on Failure" — sneller
|
|
|
|
|
+ te bouwen dan ConditionalBuilder.
|
|
|
|
|
|
|
|
**Tooltip toevoegen aan een icon-only widget:** rechtsklik → Wrap
|
|
**Tooltip toevoegen aan een icon-only widget:** rechtsklik → Wrap
|
|
|
Widget (Ctrl+B) → 4e rij van de grid (kan geclipt lijken) → 1e icoon
|
|
Widget (Ctrl+B) → 4e rij van de grid (kan geclipt lijken) → 1e icoon
|
|
|
-(spraakwolkje) = "Tooltip". Genereert een `AlignedTooltip` (zelfde
|
|
|
|
|
-stijl als de gedeelde header), geen losse styling nodig. Werkt niet op
|
|
|
|
|
-iconen die embedded zitten als `suffixIcon` van een `TextFormField`
|
|
|
|
|
-(bv. Login-pagina's wis-/toon-wachtwoord-iconen — geen losse
|
|
|
|
|
-wrapbare tree-node).
|
|
|
|
|
|
|
+(spraakwolkje) = "Tooltip". Genereert een `AlignedTooltip`, geen losse
|
|
|
|
|
+styling nodig. Werkt niet op iconen embedded als `suffixIcon` van een
|
|
|
|
|
+`TextFormField` (bv. Login-pagina wis-/toon-wachtwoord-iconen — geen
|
|
|
|
|
+losse wrapbare tree-node).
|
|
|
|
|
|
|
|
**API-call headers: check op hardcoded literals i.p.v. `[varname]`
|
|
**API-call headers: check op hardcoded literals i.p.v. `[varname]`
|
|
|
-templates.** Als een API-call via curl wél werkt maar vanuit de app/
|
|
|
|
|
-Response & Test-panel niet, controleer het Headers-tabblad van de
|
|
|
|
|
-call-configuratie — een handmatig ingeplakte testwaarde (bv. een
|
|
|
|
|
-Cookie-header) kan per ongeluk blijven staan i.p.v. de
|
|
|
|
|
-`[sessionname]=[sessionid]`-template. Check ook het per-variabele
|
|
|
|
|
|
|
+templates.** Werkt een call via curl wél maar vanuit de app/Response &
|
|
|
|
|
+Test-panel niet: check het Headers-tabblad — een handmatig ingeplakte
|
|
|
|
|
+testwaarde (bv. Cookie-header) kan per ongeluk blijven staan i.p.v.
|
|
|
|
|
+`[sessionname]=[sessionid]`. Check ook het per-variabele
|
|
|
"Include"-vinkje in Response & Test — staat die uit, dan wordt de
|
|
"Include"-vinkje in Response & Test — staat die uit, dan wordt de
|
|
|
letterlijke `[varname]`-tekst meegestuurd i.p.v. de testwaarde.
|
|
letterlijke `[varname]`-tekst meegestuurd i.p.v. de testwaarde.
|
|
|
|
|
|
|
@@ -232,33 +222,40 @@ letterlijke `[varname]`-tekst meegestuurd i.p.v. de testwaarde.
|
|
|
- **Drupal page cache bootstrapt vóór de sessie** — een ooit anoniem
|
|
- **Drupal page cache bootstrapt vóór de sessie** — een ooit anoniem
|
|
|
gecachete response (bv. een 403) kan session-bootstrap, hooks én
|
|
gecachete response (bv. een 403) kan session-bootstrap, hooks én
|
|
|
custom-module-logging volledig overslaan. Bij twijfel: Drupal-cache
|
|
custom-module-logging volledig overslaan. Bij twijfel: Drupal-cache
|
|
|
- legen en opnieuw testen vóór je verder debugt.
|
|
|
|
|
|
|
+ legen en opnieuw testen vóór verder debuggen.
|
|
|
- **Views numeric filter**: `$view->filter['uid']->value` moet
|
|
- **Views numeric filter**: `$view->filter['uid']->value` moet
|
|
|
`array('value' => $uid)` zijn, niet `array($uid)` — de foute vorm
|
|
`array('value' => $uid)` zijn, niet `array($uid)` — de foute vorm
|
|
|
faalt stil (geen filter toegepast) i.p.v. een error te geven.
|
|
faalt stil (geen filter toegepast) i.p.v. een error te geven.
|
|
|
-- Provincie/gemeente is en blijft het basismodel voor content-scoping
|
|
|
|
|
- (bevestigd door Bob: mensen zoeken primair lokaal). Home is de
|
|
|
|
|
- landelijke standaard-startpagina zónder verplichte gemeente-keuze
|
|
|
|
|
- vooraf (task #31, afgerond) — dat vervangt niet het provincie/
|
|
|
|
|
- gemeente-model, het is een aanvullende ingang.
|
|
|
|
|
|
|
+- Provincie/gemeente blijft het basismodel voor content-scoping
|
|
|
|
|
+ (bevestigd: mensen zoeken primair lokaal). Home is de landelijke
|
|
|
|
|
+ standaard-startpagina zónder verplichte gemeente-keuze vooraf — dat
|
|
|
|
|
+ vervangt het provincie/gemeente-model niet, het is een aanvullende
|
|
|
|
|
+ ingang. De `Home`-prefixed componenten (`HomeUitgaantabelKaartComponent`
|
|
|
|
|
+ e.d.) zijn een **bewuste kopie** van `PUitgaanSliderComponent`/
|
|
|
|
|
+ `UitgaantabelKaartComponent` + een eigen cityid-loze API-call — geen
|
|
|
|
|
+ dode code, niet meenemen in opschoonacties.
|
|
|
- Favorieten/login zijn P0. Backend-endpoint bestaat al; Drupal 7
|
|
- Favorieten/login zijn P0. Backend-endpoint bestaat al; Drupal 7
|
|
|
views die de respons voeden hebben soms nog aanpassing nodig.
|
|
views die de respons voeden hebben soms nog aanpassing nodig.
|
|
|
|
|
+- **Geen enkele "hasError"/netwerkfout-afhandeling bevestigd aanwezig**
|
|
|
|
|
+ in de app (gecheckt 2026-08-04, hele `lib/` doorzocht) — elke
|
|
|
|
|
+ FutureBuilder die alleen op `!snapshot.hasData` checkt, blijft bij
|
|
|
|
|
+ een mislukte call voor altijd op de laadspinner hangen. Ga er dus
|
|
|
|
|
+ niet van uit dat er ergens al een werkend voorbeeldpatroon staat om
|
|
|
|
|
+ te kopiëren — dit moet nog van de grond af ontworpen worden (zie
|
|
|
|
|
+ P0-taak in `TASKS.md`).
|
|
|
|
|
|
|
|
## Samenwerken met Bob
|
|
## Samenwerken met Bob
|
|
|
|
|
|
|
|
-- Bob is de enige developer/eigenaar en werkt vaak **zelf gelijktijdig**
|
|
|
|
|
- in dezelfde FlutterFlow-builder-sessie. Neem niet aan dat elke
|
|
|
|
|
- wijziging van jou komt.
|
|
|
|
|
|
|
+- Bob is de enige developer/eigenaar, werkt vaak **zelf gelijktijdig**
|
|
|
|
|
+ in dezelfde builder-sessie. Neem niet aan dat elke wijziging van jou
|
|
|
|
|
+ komt.
|
|
|
- Prioriteit: "eerst een werkende app live, daarna features" — P0
|
|
- Prioriteit: "eerst een werkende app live, daarna features" — P0
|
|
|
- (blokkeert livegang) weegt zwaar boven P1 (polish/performance) en P2
|
|
|
|
|
- (nieuwe features). Bob herprioriteert soms fors zelf (bv. login+
|
|
|
|
|
- favorieten van P2 naar P0) — volg dat exact.
|
|
|
|
|
-- Als Bob een taak terugclaimt ("dat regel ik zelf") — stop daar direct
|
|
|
|
|
|
|
+ weegt zwaar boven P1 en P2. Bob herprioriteert soms fors zelf (bv.
|
|
|
|
|
+ login+favorieten van P2 naar P0) — volg dat exact.
|
|
|
|
|
+- Claimt Bob een taak terug ("dat regel ik zelf") — stop daar direct
|
|
|
mee en pak iets anders onafhankelijks op.
|
|
mee en pak iets anders onafhankelijks op.
|
|
|
-- **Als iets veel tijd kost door handmatige builder-acties** (vastzittende
|
|
|
|
|
- dialogen, geclipte controls e.d.): na 1-2 serieuze pogingen stoppen
|
|
|
|
|
- en concreet aan Bob voorstellen dat hij het zelf doet (met exacte
|
|
|
|
|
- stappen) i.p.v. door te blijven proberen.
|
|
|
|
|
-- Browser niet zelf resizen (zie boven).
|
|
|
|
|
|
|
+- Kost iets veel tijd door handmatige builder-acties (vastzittende
|
|
|
|
|
+ dialogen, geclipte controls): na 1-2 serieuze pogingen stoppen en
|
|
|
|
|
+ concreet aan Bob voorstellen dat hij het zelf doet (exacte stappen).
|
|
|
- Rapporteer nieuw gevonden bugs (vooral op een pagina waar Bob net
|
|
- Rapporteer nieuw gevonden bugs (vooral op een pagina waar Bob net
|
|
|
zelf op zit) direct en duidelijk, niet pas in een latere samenvatting.
|
|
zelf op zit) direct en duidelijk, niet pas in een latere samenvatting.
|