Ver Fonte

Bevinding B afgehandeld (Bob: geen hartje), A deels, C erbij: crashpatroon op Home

B - geen hartje op het horecakaartje, Bob's besluit: geeft te veel load. Niet
terugbouwen; favoriet maken loopt via de detailpagina, Favorieten tab 3 heeft
bewust geen hartjes. P1-7 hierop gecorrigeerd.

A - punt 1 opgelost door Bob: take(25) is take(1000), exportgeverifieerd, de 42
Amsterdamse verhuur/catering-zaken komen nu door. Bijvangst: het Generate
Dynamic Children-paneel schrijft in Bob's browser wel weg op deze pagina, dus
die blokkade is Claude-specifiek en zit niet in de paginadata.

C - hetzelfde crashpatroon staat op Home. getJsonField(x, pad).toList() zonder
isList-vlag crasht empirisch bewezen (echte json_path-run) op jsonBody == null
en op een JSON-object; alleen een lege array is veilig. ApiManager levert bij
elke exception jsonBody == null, dus dit vuurt bij een netwerkfout. In levende
code vier bereikbare plekken: Home-slider, P-Uitgaan-slider, horeca-tab 6 en de
categorie-loop op de Home-kaart. De zes in de provinciepagina tellen niet mee -
geen enkele knop navigeert daarheen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bob há 2 dias atrás
pai
commit
6a785d197e
1 ficheiros alterados com 68 adições e 25 exclusões
  1. 68 25
      TASKS.md

+ 68 - 25
TASKS.md

@@ -2,6 +2,10 @@
 
 ### 🐞 Nieuw gevonden 2026-09-13 (Claude, code-audit op verse export)
 
+🔬 **Bezig (Claude, sessie 2026-09-13): offline-crashtest op emulator-5556
+(telefoon), eigen profile-build uit `/tmp/ff-check3`.** Niet tegelijk dezelfde
+test starten.
+
 Twee echte bevindingen uit een browserloze audit; allebei nagemeten tegen
 productie, geen van beide eerder opgeschreven.
 
@@ -12,15 +16,23 @@ Op `horecagelegenhedenOverzichtCurrent` bouwen vijf tabs hun lijst via
 (Verhuur, catering) doet het nog op de oude manier: een eigen Backend Query
 plus `getJsonField(jsonBody, r'$').toList().take(25)`. Gevolgen, op volgorde
 van ernst:
-1. **Harde limiet van 25 zonder paginering.** Gemeten met `curl` op
-   `horcat=17968`: Amsterdam (`townid=28695`) heeft **42** verhuur/catering-
-   zaken, de tab toont er **25**. Arnhem heeft er 3, dus daar valt het niet op.
+1. ✅ **OPGELOST 2026-09-13 (Bob): `.take(25)` staat nu op `.take(1000)`** —
+   exportgeverifieerd. De 42 Amsterdamse verhuur/catering-zaken komen nu
+   allemaal door. **Belangrijke bijvangst: het Generate Dynamic Children-paneel
+   schrijft in Bob's browser dus wél weg op deze pagina** — de blokkade die in
+   `CLAUDE.md` staat is Claude-specifiek, niet iets in de opgeslagen
+   paginadata.
 2. **Geen zoekveld** op deze tab — dit is het bekende "5 van de 6"-restpunt
    uit P2-6, nu exact gelokaliseerd.
-3. **Crasht bij een netwerkfout.** `getJsonField(..., r'$')` geeft `null`
-   terug als `jsonBody` null is (wat `ApiManager` bij elke exception doet), en
-   `.toList()` daarop gooit `NoSuchMethodError`. De andere vijf tabs lezen een
-   `_model`-lijst en hebben dat probleem niet.
+3. ⚠️ **Crasht bij een netwerkfout — nu HARD BEWEZEN, en het raakt meer dan
+   deze tab.** `getJsonField(x, r'$').toList()` is empirisch getest met de
+   echte `json_path`-package: bij `jsonBody == null` (wat `ApiManager` bij
+   **elke** exception teruggeeft) crasht het met `NoSuchMethodError`, net als
+   bij een JSON-**object** (bv. een foutpagina die wel parset); alleen een lege
+   array `[]` is veilig. De vijf gemigreerde tabs hebben dit niet, want
+   `fetchAlleHorecagelegenheden` breekt netjes af op `!response.succeeded` en
+   geeft `[]`. **Zie de aparte bevinding C hieronder — ditzelfde patroon staat
+   ook op Home.**
 4. **De data wordt twee keer opgehaald.** De On-Tap-keten vult netjes
    `_model.alleVerhuurCatering` (regel 483), maar die variabele wordt
    **nergens gelezen** — de tab negeert 'm en haalt alles nog een keer op.
@@ -34,24 +46,55 @@ vrijwel zeker ook de reden dat deze tab destijds niet is meegegaan. **Dit is
 dus geen "even naklikken" — het is dezelfde blokkade, nu met een gemeten
 gevolg: er is content die een gebruiker niet kan zien.**
 
-**B · Het favorietenhartje op de horeca-OVERZICHTSkaart is verdwenen.**
-`favorieteHorecaNids` komt in de hele levende export nog maar op één plek voor:
-de detailpagina (`horecagelegenheid_current_widget.dart:382`). Het component
-`HorecagelegenheidoverzichtKaart` heeft geen hartje meer — `git log -S` wijst
-naar commit `7094b43` (taak 18, 2026-09-11), waarin Copy3 de productiepagina
-werd; de hartje-code staat in die diff als verwijderd. De parameter `nid` wordt
-nog wél aan de kaart doorgegeven maar nergens meer gelezen — het overblijfsel
-dat dit verraadde.
-- **Gevolg 1:** favoriet maken kan alleen nog via de detailpagina.
-- **Gevolg 2:** op **Favorieten tab 3** staan nul hartjes (`Icons.favorite`
-  komt 0x voor in `favorieten_widget.dart`), dus je kunt daar niet ontvolgen —
-  je moet eerst doorklikken naar de zaak.
-- P1-7 beschrijft dit hartje nog als "volledig werkend"; die tekst is dus
-  achterhaald. **Besluit nodig:** terugbouwen op de kaart, of bewust laten en
-  P1-7 bijstellen? Het bouwen zelf is een ConditionalBuilder met
-  `List Contains Item` op `widget!.nid` — het recept staat in `CLAUDE.md` en de
-  werkende versie staat nog in `lib/kanweg/kanweghorecagelegenheid_current_copy/`
-  om van af te kijken.
+**B · ✅ AFGEHANDELD — geen hartje op het horecakaartje, Bob's besluit
+2026-09-13: "geeft te veel load".** Het favorietenhartje op de
+horeca-OVERZICHTSkaart is inderdaad verdwenen (gesneuveld in commit `7094b43`,
+taak 18, toen Copy3 productie werd), maar dat blijft zo — **niet terugbouwen**.
+Favoriet maken loopt voortaan uitsluitend via de detailpagina; op Favorieten
+tab 3 staan dus bewust geen hartjes en ontvolgen gaat via doorklikken naar de
+zaak. P1-7's tekst is hierop gecorrigeerd.
+*(Restje, cosmetisch en zonder haast: de parameter `nid` wordt nog steeds aan
+`HorecagelegenheidoverzichtKaart` doorgegeven maar nergens meer gelezen — het
+overblijfsel van het verwijderde hartje. De pagina gebruikt zijn eigen `nid`
+voor de tap-navigatie, dus er is niets stuk.)*
+
+**C · Hetzelfde crashpatroon staat ook op HOME — de startpagina van de app.**
+Nadat bevinding A's punt 3 hard bewezen was, projectbreed gezocht naar
+`getJsonField(x, pad).toList()` zónder de `isList`-vlag. In **levende** code
+(dus zonder `kanweg/`, `_copy*` en `_orgineel*`) staan 11 plekken. Na filteren
+op wat een gebruiker echt kan bereiken blijven er vier over:
+
+| plek | pad | bereikbaar via |
+|---|---|---|
+| `home_uitgaan_slider_component_widget.dart:161` | `$` | **Home — de startpagina** |
+| `p_uitgaan_slider_component_widget.dart:158` | `$` | P-Uitgaan-pagina |
+| `horecagelegenheden_overzicht_current_widget.dart:1643` | `$` | horeca-overzicht, tab 6 |
+| `home_uitgaantabel_kaart_component_widget.dart:651` | `$.categorie` | Home-tabs (per kaart) |
+
+De zes treffers in `horecagelegenheden_overzicht_provincie_page` tellen
+nauwelijks mee: die pagina staat wel in `nav.dart` maar **geen enkele knop
+navigeert ernaartoe** (alleen via deep-link te bereiken). En
+`SliderUitgaanComponentSmallCurrent` heeft nul gebruikers.
+
+**Wat er gebeurt:** `ApiManager` vangt elke exception af en levert dan
+`ApiCallResponse(null, {}, -1, ...)` — de Future slaagt dus, de `FutureBuilder`
+bouwt door, en `getJsonField(null, r'$')` geeft `null` waarop `.toList()`
+crasht. In een **profile**-build is dat volledig stil: geen rood scherm, geen
+overflow-streep, niets in `dart analyze` — alleen een grijs/leeg vlak, en
+volgens het bekende patroon verdwijnt alles eronder in dezelfde `Column` mee.
+
+**Nog te bepalen (Claude is hier 2026-09-13 mee bezig):** hoe erg dit er in de
+praktijk uitziet op een toestel zónder netwerk. Pas daarna is te zeggen of dit
+vóór livegang gefixt moet worden of dat de app "toch al leeg" is en het
+cosmetisch blijft.
+
+**De fix, als die nodig blijkt,** is dezelfde route die de vijf horeca-tabs al
+namen: niet rechtstreeks uit de Backend Query lezen, maar via een custom action
+die `[]` teruggeeft bij een mislukte call (`fetchAlleHorecagelegenheden` is het
+werkende voorbeeld, zie `!response.succeeded → break`). Een goedkopere variant
+voor alleen de sliders: de `Generate Dynamic Children`-binding een
+**"Is List"**-transform geven, want `getJsonField(..., true)` levert altijd een
+lijst.
 
 **Wat de audit NIET vond (nagemeten, zodat niemand het nog eens doet):**
 - **Het P1-15-patroon is projectbreed schoon.** Alle 16 `launchURL`-aanroepen