소스 검색

TASKS.md: P2-6 herzien na live pagineringstest + P2-14 paginascope bevestigd

- P2-6: live curl-test bevestigt HorecagelegenheidoverzichtCall capt
  op 100 resultaten/aanroep maar ondersteunt al een ongedocumenteerde
  page-parameter (geverifieerd met verschillende data per page).
  Bouwplan uitgebreid: page-param toevoegen + Custom Action die alle
  pagina's ophaalt en samenvoegt, vóór naam- én categoriefilter.
  Bob's akkoord genoteerd om te starten.
- P2-14: Bob bevestigt stadsactiviteit deelt EventCurrent met
  uitgaansevenement (2 plekken totaal, niet 3). Bijvangst genoteerd
  (ontbrekend horeca-blok bij activiteiten op EventCurrent, geen
  actie nu). Akkoord om te starten.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
bob 3 주 전
부모
커밋
f4fa28293b
1개의 변경된 파일76개의 추가작업 그리고 44개의 파일을 삭제
  1. 76 44
      TASKS.md

+ 76 - 44
TASKS.md

@@ -2081,44 +2081,68 @@ overgeslagen, Bob's eigen Sort/Datatype-experiment op die pagina loopt
 nog (zie P2-6); oppakken zodra dat is afgerond, zelfde recept
 (kopieer de AdBanner-node vanaf een van de 3 al werkende pagina's).
 
-**P2-6 · Eigenaar: Claude, wacht op groen licht van Bob (actief bezig
-op dezelfde pagina).** Tekstzoeken op naam, per tab van
+**P2-6 · Eigenaar: Claude, akkoord van Bob (2026-08-25) om te
+starten.** Tekstzoeken op naam **én categorie**, per tab van
 `horecagelegenheden_overzicht_widget.dart`/`..._provincie_page_widget.dart`
-(Bob's besluit 2026-08-25: "op naam kunnen selecteren, tekstveld voor
-overeenkomstige namen", nodig op elke tab). **Bouwplan (client-side
-filter, geen nieuwe Drupal-parameter nodig — de volledige lijst is al
-lokaal na de bestaande API-call):**
-1. Eén `TextField` boven de `TabBar` (filtert altijd de op dat moment
-   actieve tab, geen los veld per tab nodig — simpeler, en de
-   tabs delen toch hetzelfde zoekpatroon). Component/Page State
-   `zoekterm` (String), gebonden via `onChanged`.
-2. Nieuwe **Custom Function** `filterOpNaam(List<dynamic> items, String
-   query, String titelPad) -> List<dynamic>`: itereert `items`, haalt
-   per item `getJsonField(item, titelPad)` op, vergelijkt
-   case-insensitive én **diacritics-genormaliseerd** (bv. "café" moet
-   ook matchen op "cafe" — anders mist een zoekopdracht zonder accent
-   alsnog het juiste resultaat, veelvoorkomend bij horeca-namen).
-   Lege `query` → hele lijst ongewijzigd terug (geen filter-overhead
-   bij het openen van een tab).
-3. Elke tab's `Generate Dynamic Children`-"Value"-binding (nu
-   waarschijnlijk direct de rauwe API-response) wijzigen naar
-   `filterOpNaam(<rauwe lijst>, zoekterm, '$.titel')` (titel-JSON-path
-   per tab kan verschillen, per tab losstaand controleren).
+(Bob's besluit: "op naam kunnen selecteren, tekstveld voor
+overeenkomstige namen", nodig op elke tab; uitgebreid met een
+categorie-filter na een live test hieronder).
+
+**Kritieke bevinding (2026-08-25, Claude, live curl-test op de
+productie-endpoint) — verandert de aanpak:** `HorecagelegenheidoverzichtCall`
+(`flutterflowmobiel_establishments.json`) hangt vast aan een **harde cap
+van 100 resultaten per aanroep**. Test op townid `28666`/`horcat=17967`
+gaf exact 100 terug (verdacht rond getal); een 2e gemeente (`28694`)
+gaf er 75 (onder de cap, dus waarschijnlijk het echte totaal). De
+endpoint **ondersteunt al een niet-gedocumenteerde `page`-parameter**:
+`page=1` op dezelfde 100-resultaten-gemeente gaf een **andere** set van
+100 items (bevestigd via nid-vergelijking, geen overlap) — de data
+bestaat dus compleet op de server, de app haalt er nu alleen page 0 van
+op. **Gevolg: puur client-side filteren op de huidige, single-page
+lijst zou bij een grote gemeente stilletjes items missen** (precies
+Bob's zorg). Categorie-filter-opties moeten bovendien dynamisch
+opgebouwd worden uit de unieke `categorie`-waarden in de dataset (Bob:
+"die kan hij hebben van alle horecagelegenheden die hij inleest"), wat
+dus ook een complete dataset vereist.
+
+**Bijgewerkt bouwplan:**
+1. **Builder:** `HorecagelegenheidoverzichtCall` krijgt een nieuwe
+   parameter `page` (Integer of String, default `0`/`'0'`), toegevoegd
+   aan de bestaande `params`-map (`'page': page`).
+2. Nieuwe **Custom Action** `fetchAlleHorecagelegenheden(String horcat,
+   String townid, String displayId) -> List<dynamic>`: roept
+   `HorecagelegenheidoverzichtCall.call(...)` in een loop aan met
+   oplopende `page` (0, 1, 2, ...), voegt elke pagina's resultaten
+   samen, stopt zodra een pagina **minder dan 100** items teruggeeft
+   (= laatste pagina) of bij een lege/foutieve respons (veiligheidslimiet
+   op bv. 10 iteraties tegen een oneindige loop bij een onverwachte
+   server-bug).
+3. Eén `TextField` boven de `TabBar` (filtert de op dat moment actieve
+   tab). Component/Page State `zoekterm` (String), gebonden via
+   `onChanged`.
+4. Categorie-filter: chips/dropdown, **opties dynamisch opgebouwd** uit
+   de unieke `categorie`-waarden binnen de complete (alle-pagina's)
+   lijst van de actieve tab — geen statische/hardcoded lijst.
+5. Nieuwe **Custom Function** `filterHorecagelegenheden(List<dynamic>
+   items, String zoekterm, String? categorieFilter, String titelPad,
+   String categoriePad) -> List<dynamic>`: combineert naam-match
+   (case-insensitive én **diacritics-genormaliseerd**, bv. "café" moet
+   ook matchen op "cafe") met categorie-match (AND-logica: allebei
+   moeten kloppen als beide ingevuld zijn). Lege `zoekterm`/geen
+   categorie-filter → geen restrictie op dat onderdeel.
+6. Elke tab's `Generate Dynamic Children`-"Value"-binding wijzigen van
+   de rauwe API-response naar het resultaat van stap 2 (Component
+   State, gevuld via een On-Page-Load/On-Tap-trigger die
+   `fetchAlleHorecagelegenheden` aanroept), gefilterd via stap 5.
 **Advies/aandachtspunten:**
-- Client-side filteren i.p.v. een nieuwe Drupal-endpoint-parameter: de
-  lijsten per tab zijn klein genoeg (geen paginering gezien in de
-  bestaande calls) — dus geen performance-reden om dit server-side te
-  doen, en dit blijft zo werkend ongeacht wat Bob's Sort/Datatype-
-  experiment uiteindelijk oplevert (orthogonale features, wel dezelfde
-  pagina — vandaar "wacht op groen licht" i.p.v. blind starten terwijl
-  Bob er middenin zit).
-- Debounce is hier niet nodig (puur client-side lijst-filter op een al
-  geladen array, geen API-call per toetsaanslag) — direct live filteren
-  op elke `onChanged` kan gewoon.
+- Debounce niet nodig — filteren gebeurt op een al volledig lokaal
+  geladen array, geen API-call per toetsaanslag.
+- Dit raakt dezelfde pagina als Bob's Sort/Datatype-experiment —
+  gestart nu met zijn expliciete akkoord (2026-08-25).
 - Style-tip: een "wis"-kruisje (`suffixIcon`) in het zoekveld is fijn
-  UX, maar val niet in de bekende `TextFormField`-`suffixIcon`-
-  Tooltip-beperking uit `CLAUDE.md` (geen Tooltip nodig op zo'n icoon,
-  gewoon een losse `onTap` die `zoekterm` leegt).
+  UX; val niet in de bekende `TextFormField`-`suffixIcon`-Tooltip-
+  beperking uit `CLAUDE.md` (geen Tooltip nodig, gewoon een losse
+  `onTap` die `zoekterm` leegt).
 
 **P2-14 · Eigenaar: Claude (nieuw, 2026-08-25, Bob's idee).**
 Google Maps-icoon achter elk adres — bij horecagelegenheid-,
@@ -2142,15 +2166,23 @@ deep-link):
    **Launch URL** (categorie "Share", zie `CLAUDE.md`) → Value via Set
    from Variable → Custom Functions → `googleMapsUrl` met beide
    parameters gebonden.
-3. Component invoegen naast/achter het bestaande adres-`Text`-widget
-   op `horecagelegenheid_current_widget.dart` en `event_current_widget.dart`
-   (dekt uitgaansevenement; bevestig tijdens de bouw of stadsactiviteit
-   dezelfde detailpagina deelt met event of een eigen widget heeft —
-   nog niet met zekerheid vastgesteld welke pagina "stadsactiviteit"
-   toont).
-Nog te doen vóór bouwen: Bob geeft akkoord om te starten (zie vraag in
-de chat) — dit is nieuw, nog niet eerder besproken/gepland werk, geen
-losstaande blocker verder.
+3. **Paginascope bevestigd (Bob, 2026-08-25): stadsactiviteit deelt
+   dezelfde detailpagina als uitgaansevenement** (`EventCurrent`/
+   `event_current_widget.dart`) — de onderliggende query voor die
+   pagina levert al zowel `activity`- als `go_out_event`-nodes uniform
+   op, dus 1 component-plek dekt beide. **Dus 2 plekken totaal:**
+   `horecagelegenheid_current_widget.dart` en
+   `event_current_widget.dart` (naast/achter het bestaande
+   adres-`Text`-widget op elk).
+4. **Bijvangst, genoteerd voor later (Bob, 2026-08-25): op
+   `EventCurrent` ontbreekt momenteel het "horecagelegenheid"-blok**
+   (de gekoppelde-horeca-sectie die op een echt evenement getoond
+   wordt) voor stadsactiviteiten — logisch, want een activiteit heeft
+   geen gekoppelde horecagelegenheid in het datamodel. Bob noemt dit
+   een mogelijk later te herzien punt, **geen actie nu, geen onderdeel
+   van P2-14** — apart laten staan tot Bob besluit of/hoe dit anders
+   moet.
+**Akkoord van Bob (2026-08-25) om nu te starten** — geen blocker meer.
 
 **P2-7 · Eigenaar: Bob.** Opschonen:
 - Merge `kaartTabelUitgaanComp` + `kaartTabelUitgaanSComp` — Bob doet