|
|
@@ -7,6 +7,31 @@ Werk uitsluitend binnen deze projectdirectory
|
|
|
zoeken of scannen (bijvoorbeeld geen `find /` over het hele
|
|
|
bestandssysteem) — scope alle bestandsoperaties tot dit project.
|
|
|
|
|
|
+## Sessiegeheugen — lees dit eerst
|
|
|
+
|
|
|
+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.
|
|
|
+
|
|
|
+**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.
|
|
|
+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-workflow — belangrijk
|
|
|
|
|
|
Dit project wordt gebouwd via FlutterFlow (app.flutterflow.io). De
|
|
|
@@ -28,7 +53,8 @@ code-export.
|
|
|
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. Ga er niet van uit dat een lokale bestandswijziging
|
|
|
+ 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**
|
|
|
@@ -36,8 +62,23 @@ code-export.
|
|
|
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.
|
|
|
+- 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.
|
|
|
|
|
|
-## Lokale git-repo + pull/push-workflow (sinds 2026-08-01)
|
|
|
+## Lokale git-repo + pull/push-workflow
|
|
|
|
|
|
De projectdirectory zelf is een schone git-repo met `origin` op
|
|
|
`ssh://gogs.digitalforce.tv:2222/Uitgaanskrant.com/flutterflow.git`,
|
|
|
@@ -46,57 +87,178 @@ 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.
|
|
|
|
|
|
-Vaste workflow na elke afgeronde taak (op expliciet verzoek van de
|
|
|
-gebruiker, 2026-08-01): niet los `flutterflow export-code` draaien,
|
|
|
-maar het bestaande script gebruiken:
|
|
|
+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:
|
|
|
|
|
|
```
|
|
|
-/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
|
|
|
```
|
|
|
|
|
|
-Dit script (interactief van aard: device-run + hot-restart-loop) moet
|
|
|
-via Bash met `run_in_background: true` gestart worden — anders blokkeert
|
|
|
-het op de keypress-loop. Volg de output (Monitor of Read op het
|
|
|
-outputbestand) tot minimaal "All done!" (export gelukt) en idealiter
|
|
|
-ook een succesvolle app-launch op de emulator ("Flutter run key
|
|
|
-commands" / geen build-errors), voordat je verder gaat.
|
|
|
-
|
|
|
-Daarna automatisch (geen aparte bevestiging per keer nodig, staand
|
|
|
-akkoord van de gebruiker):
|
|
|
-1. `git add` — **niet blind `-A`**: controleer `git status --short`
|
|
|
- eerst. Voeg alleen daadwerkelijke FlutterFlow/app-wijzigingen toe
|
|
|
- (lib/, android/, ios/, pubspec, .gitignore e.d.). Sluit `.claude/`
|
|
|
+- **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.
|
|
|
+
|
|
|
+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.
|
|
|
+ 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 -u origin master` (of gewoon `git push` zodra tracking
|
|
|
+3. `git push` (of `git push -u origin master` als tracking nog niet
|
|
|
staat).
|
|
|
|
|
|
-**Let op — belangrijke valkuil:** `flutterflow export-code` overschrijft
|
|
|
-**`.gitignore` telkens terug naar FlutterFlow's eigen standaardversie**
|
|
|
-(bevestigd 2026-08-01) — een eigen toevoeging zoals de `.claude/`-regel
|
|
|
-hieronder verdwijnt dus bij elke pull en moet opnieuw toegevoegd worden
|
|
|
-vóór je commit. (CLAUDE.md zelf wordt door de export NIET verwijderd —
|
|
|
-dat gebeurde één keer doordat de gebruiker zelf de hele projectmap had
|
|
|
-verwijderd en opnieuw had gepulled, niet door de export-tool zelf. Maar
|
|
|
-check voor de zekerheid na elke pull toch even of dit bestand nog
|
|
|
-bestaat; zo niet, opnieuw aanmaken met deze inhoud.)
|
|
|
-
|
|
|
-Voeg dus na elke pull, 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 eigen standaardversie.** Voeg dus
|
|
|
+na elke export, vóór je staged, deze regel weer toe aan `.gitignore`
|
|
|
+als hij ontbreekt:
|
|
|
```
|
|
|
# Claude Code session state (not app code)
|
|
|
.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.)
|
|
|
|
|
|
-## Eerst research, dan bouwen (sinds 2026-08-03)
|
|
|
+## Eerst research, dan bouwen
|
|
|
|
|
|
-Voordat je aan een niet-triviale taak begint (een bug fix, een nieuw
|
|
|
+Voordat je aan een niet-triviale taak begint (een bugfix, een nieuw
|
|
|
patroon, een integratie): zoek eerst kort op internet naar bestaande
|
|
|
-oplossingen/patronen (bijv. "FlutterFlow ConditionalBuilder default
|
|
|
-image", "Drupal 7 Services session auth FlutterFlow") voordat je het
|
|
|
-zelf helemaal uitvindt via trial-and-error in de builder. Dit kan
|
|
|
-sneller zijn dan zelf experimenteren, vooral bij FlutterFlow-builder-
|
|
|
-specifieke UI-flows of Drupal-integratiepatronen. Geldt niet voor
|
|
|
-triviale/mechanische herhaling van een patroon dat al binnen deze
|
|
|
-sessie is uitgezocht en bevestigd werkt.
|
|
|
+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).
|
|
|
+
|
|
|
+## 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.
|
|
|
+
|
|
|
+**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".
|
|
|
+
|
|
|
+**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
|
|
|
+bevestigde pogingen stoppen en aan Bob vragen.
|
|
|
+
|
|
|
+**Patroon: lege/ontbrekende afbeeldings-URL laten crashen.**
|
|
|
+`CachedNetworkImage` gooit een **synchrone** `ArgumentError` bij het
|
|
|
+*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`):
|
|
|
+1. Rechtsklik het Image-widget → **Wrap Widget (Ctrl+B)** →
|
|
|
+ **ConditionalBuilder**.
|
|
|
+2. IF-conditie: **Conditions → Single Condition** → First Value = de
|
|
|
+ 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"**.
|
|
|
+3. THEN-tak: de bestaande Image (blijft staan na de wrap).
|
|
|
+4. ELSE-tak: rechtsklik → Insert Widget → Icon → zoek "image not
|
|
|
+ supported" → eerste Material-resultaat.
|
|
|
+- **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.
|
|
|
+
|
|
|
+**Tooltip toevoegen aan een icon-only widget:** rechtsklik → Wrap
|
|
|
+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).
|
|
|
+
|
|
|
+**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
|
|
|
+"Include"-vinkje in Response & Test — staat die uit, dan wordt de
|
|
|
+letterlijke `[varname]`-tekst meegestuurd i.p.v. de testwaarde.
|
|
|
+
|
|
|
+## Domein/architectuurcontext
|
|
|
+
|
|
|
+- **Drupal 7 Services sessie-auth**: `sessid` + `session_name` (uit
|
|
|
+ `LoginCall`'s response) vormen samen de sessie-cookie:
|
|
|
+ `Cookie: <session_name>=<sessid>`. `token` is een los CSRF-token,
|
|
|
+ alleen nodig bij schrijf-requests (POST/PUT/DELETE), nooit bij GET.
|
|
|
+- **Drupal page cache bootstrapt vóór de sessie** — een ooit anoniem
|
|
|
+ gecachete response (bv. een 403) kan session-bootstrap, hooks én
|
|
|
+ custom-module-logging volledig overslaan. Bij twijfel: Drupal-cache
|
|
|
+ legen en opnieuw testen vóór je verder debugt.
|
|
|
+- **Views numeric filter**: `$view->filter['uid']->value` moet
|
|
|
+ `array('value' => $uid)` zijn, niet `array($uid)` — de foute vorm
|
|
|
+ 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.
|
|
|
+- Favorieten/login zijn P0. Backend-endpoint bestaat al; Drupal 7
|
|
|
+ views die de respons voeden hebben soms nog aanpassing nodig.
|
|
|
+
|
|
|
+## 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.
|
|
|
+- 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
|
|
|
+ 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).
|
|
|
+- Rapporteer nieuw gevonden bugs (vooral op een pagina waar Bob net
|
|
|
+ zelf op zit) direct en duidelijk, niet pas in een latere samenvatting.
|