TASKS.md 17 KB

Uitgaanskrant — takenlijst

Bijgewerkt: 2026-08-04. Zie CLAUDE.md voor werkinstructies/conventies. Elke openstaande taak hieronder is zelfstandig te begrijpen zonder de chat gelezen te hebben waarin hij ontstond.

Formaat van elke taak: **P0-1 · Eigenaar: ...** als eerste regel — een stabiel nummer (verandert niet als andere taken worden afgerond/verwijderd) + wie 'm oppakt. Volgorde binnen elke prioriteit = geschatte ernst/impact, hoogste eerst.

Eigenaar-waarden:

  • Bob — sneller/simpeler voor hem zelf (meestal builder-UI met een bekend fragiele dialoog, zie CLAUDE.md).
  • Claude — zelfstandig/via browser-automation te doen, nog onbeklaimd.
  • Claude — bezig (sessie ) / Bob — bezig — een sessie/persoon is hier nu actief mee bezig.
  • Onbepaald — nog geen eigenaar gekozen.
  • ⚠️ Voorkom dubbel werk: Bob start elke taak in een nieuwe, aparte chat — er kunnen dus meerdere sessies tegelijk actief zijn op hetzelfde project. Voordat je een taak oppakt: check of de Eigenaar-regel al "— bezig" zegt. Zo ja: niet zelfstandig ook gaan zitten werken aan hetzelfde bestand/component — vraag Bob eerst wie 'm afmaakt (dit gebeurde op 2026-08-04: twee sessies pakten onafhankelijk P0-2 op; Bob moest scheidsrechteren). Zet zelf "— bezig" in de Eigenaar-regel zodra je serieus aan een taak begint, en haal het weer weg (of verwijder de taak, zie hieronder) zodra je stopt.

    Afronden: een volledig afgeronde taak wordt verwijderd uit deze lijst (niet gearchiveerd). Bij gedeeltelijke voortgang: taak laten staan met bijgewerkte inhoud die alleen het resterende werk beschrijft.

    Status: actief bij Bob (geen Claude-actie nodig, ter info)

    • FavorietenAgenda 403-foutEigenaar: Bob — bezig. Bob troubleshoot dit zelf. FlutterFlow-requests komen bij nginx binnen met een lege Cookie-header; zijn eigen browser/curl (via dezelfde Cloudflare-edge) sturen de sessie-cookie wél mee. Cloudflare Cache Rule voor SSESS* staat al goed (bypass, eerste regel). Werkhypothese: Cloudflare Bot Management behandelt FlutterFlow's server-side traffic anders op basis van IP-reputatie/ TLS-fingerprint. Niet opnieuw diagnosticeren zonder navraag — check eerst of Bob al verder is.

    P0 — blokkeert livegang

    P0-1 · Eigenaar: Bob (10 sec klusje) — bevestigd nog open (2026-08-05). Home-slider crasht (RangeError) bij 0 API-resultaten. Bob koos: bij 0 resultaten component overslaan (niets tonen), geen melding. CarouselSlider.builder met itemCount: 0 crasht. Native fix: Carousel-widget (component HomeUitgaanSliderComponent → Widget Tree → ConditionalBuilder → If → Container → Carousel) → rechterpaneel → "Empty List Widget" → vink "Show Empty List Widget" aan → Widget Type instellen (bv. Image → Asset "logo800px.png", zelfde als het werkende patroon op HorecagelegenhedenOverzicht, zie P1-1). 2026-08-05, read-only gecheckt in de builder (Claude, geen klik op de checkbox zelf i.v.m. clipping-risico): "Widget Type" staat nog op "Unset". Bob dacht dit al ingesteld te hebben ("volgens mij heb ik dat ingesteld, bij geen gegevens dan een plaatje") — dat klopt dus nog niet, of de instelling ging niet door. De checkbox zelf viel niet af te lezen (rechterpaneel- clipping, zie CLAUDE.md), maar "Unset" bij Widget Type is op zichzelf al genoeg bewijs dat de configuratie niet compleet is. Bob: graag opnieuw instellen en dit keer een Widget Type kiezen (niet alleen de checkbox).

    P0-3 · Eigenaar: Claude — bezig (sessie 2026-08-05 doorlopend). Hartje-icoon op gemeente. Bob koos: heart ergens anders dan de gemeente-dropdown zelf (die blijft ongewijzigd). 2026-08-04, Bob's antwoord: hartje naast de provincienaam én naast de gemeentenaam, in de titel. Bob wil dat elke pagina in de header de provincie- of gemeentenaam toont, zodat gebruikers altijd zien waar ze zitten. 2026-08-05: Bob akkoord met aanpak "voorstel eerst, dan bouwen". Claude stelt een concreet voorstel op voor hoe dit in de gedeelde header verwerkt wordt (welke pagina's, welke plek exact, hoe de naam ophalen — zie de bekende valkuil hieronder), legt dat voor aan Bob, en bouwt na akkoord.

    • Blocker die dit voorstel moet oplossen: geen enkele pagina toont de geselecteerde gemeente-náám als tekst — alleen het numerieke ID (FFAppState().gemeenteSelectId) wordt doorgegeven als filter (bv. plaats/townid param op PUitgaanPageWidget). GemeentenCall. gemeenteName() in lib/backend/api_requests/api_calls.dart bestaat al maar is ongebruikt.
    • Bekende valkuil als dit gebouwd wordt: bind de naam niet live via een List<CustomDataType>-typed lookup function-argument (bv. provincieNaamById/gemeenteNaamById in lib/flutter_flow/custom_functions.dart, al gebouwd, compileert, nog niet gekoppeld) — dat argument-bindingsdialoog loopt vast op de geneste Set Variable-bug (zie CLAUDE.md). Simpeler: naam vastleggen in een plain String App State-variabele op moment van selectie i.p.v. 'm live op te zoeken.

    P0-4 · Eigenaar: Bob. Werkende login + favorieten — resterende deeltjes. Basis is af: login gekoppeld, wachtwoord-vergeten-flow, favorieten drawer-link + 3-tabblad-pagina, hartje op horeca-kaart + -detailpagina. Nog open:

    • Lege-lijst empty-state op de favorietenpagina (nu kale/lege Container als er nog geen favorieten zijn). lib/favorieten/favorieten_widget.dart.
    • Bevestigen dat favorieten écht syncen via Drupal bij inloggen — hangt af van FavorietenAgenda-403 hierboven.

    P0-5 · Eigenaar: Bob. Drupal: anonieme leestoegang onderzoeken voor browse-endpoints. Drupal-niveau, geen Claude-taak.

    P1 — snel na livegang

    P1-1 · Eigenaar: Bob (mechanisch, ~10 sec per stuk) — audit compleet, wachtend op Bob. Loading/foutafhandeling-patroon uitrollen naar overige lijst-/detailpagina's. Referentiepatroon bevestigd (2026-08-04, builder): rechterpaneel → "Empty List Widget""Show Empty List Widget" aan → Widget Type: Image → Asset "logo800px.png". Op HorecagelegenhedenOverzicht zelf al op alle 5 tabs aanwezig (geverifieerd via verse export 2026-08-04/05). 2026-08-05: volledige audit afgerond (Claude) van resterende Carousel-widgets zonder deze fix — allemaal read-only bevestigd "Widget Type: Unset"/leeg:

    1. HomeUitgaanSliderComponent → Carousel (= P0-1, zie daar)
    2. PUitgaanSliderComponent → Carousel — ontbreekt zelfs de ConditionalBuilder-wrapper om de Carousel (i.t.t. de andere 3), dus mogelijk P0-ernstig: dezelfde itemCount:0-RangeError-crash als P0-1 kan hier nog optreden zonder enige vangnet.
    3. EvenementComponent → Carousel (foto-carousel van één evenement)
    4. horecagelegenheidCurrent → Carousel (foto-carousel van één horecagelegenheid)
    5. Waarom bij Bob i.p.v. Claude: de "Show Empty List Widget"- checkbox is structureel onbereikbaar via Claude's browser-automation-viewport (bevestigd op alle 4 hierboven, zie CLAUDE.md bekende problemen) — geen per-component toeval, dus verder proberen door Claude heeft geen zin. Bob: dezelfde twee klikken (checkbox aan + Widget Type instellen) 4x herhalen op bovenstaand lijstje, kost in eigen browser seconden per stuk.

    P1-3 · Eigenaar: Bob — geblokkeerd op rechterpaneel-clipping. Sliderkaartje: datumregel mist de Flexible-wrap. Bevestigd nog open (2026-08-04: regels 310/351 in p_uitgaan_slider_kaart_component_widget.dart hebben Flexible om de Text, regel 273-281 niet). Fix zit in builder: component PUitgaanSliderKaartComponent → Widget Tree → node "Text-datum" (Text-widget, kind van de Row met Icons.calendar_month, tussen "Text-title" en de horecagelegenheid-Row) → rechterpaneel → property "Expansion" → moet net als bij "Text-horecagelegenheid"/"Text-adres" op Flexible gezet worden i.p.v. None. Geblokkeerd: de 3 Expansion-type-iconen (None/Expanded/Flexible) renderen net buiten het zichtbare/klikbare canvas rechts van het "Flex"-invoerveld — bekend rechterpaneel-clippingprobleem (zie CLAUDE.md). Geprobeerd: directe klik op geschatte positie, paneel-scroll, paneel-drag-resize, "Wrap Widget"-dialoog (geen Flexible-optie daarin, alleen structurele widgets) — geen succes. Kost Bob vermoedelijk seconden op zijn eigen scherm.

    P1-4 · Eigenaar: Bob. EstablishmentsCall crasht zonder categoriefilter. horcat ??= null!; — bevestigd nog aanwezig, regel

    1. Nu geen probleem omdat elke aanroep toevallig altijd een filter meegeeft, wel een landmijn voor de toekomst. lib/backend/api_requests/api_calls.dart. Fix zit vermoedelijk in de FlutterFlow API-call-configuratie (default parameterwaarde), niet in lokale code.

    P1-5 · Eigenaar: Bob. "Thuis bezorgen" koppelen aan een echt leverbaar-veld per horecagelegenheid. Wacht op Bob: eerst het API-endpoint aan Drupal-kant configureren. Daarna tonen/verbergen op basis van het echte veld i.p.v. de huidige dode tap.

    P1-6 · Eigenaar: Bob. Letterlijke veldnaam i.p.v. nette placeholder bij ontbrekende data — audit afgerond 2026-08-04, 13 treffers. Patroon: valueOrDefault<String>(<bron>, '<default>') waarbij de default gelijk is aan de veld-/functienaam. Fix is mechanisch (Default Value-tekst aanpassen in de builder op het Text-widget), maar raakt waarschijnlijk dezelfde "Set from Variable"-property als de Empty-URL-fix — zelfde risico-inschatting als het CachedNetworkImage-patroon.

    • horecagelegenheidoverzicht_kaart_widget.dart:357/381/408 — titel/adres/plaats
    • event_current_widget.dart:416 — nid
    • evenement_info_widget.dart:134/156/211/236/291 — adres/plaats/entreeprijs/entreetoelichting/contact
    • evenement_component_widget.dart:216/238 — title/eventDate
    • Grensgevallen (geen letterlijke veldnaam maar wel technische/zinloze placeholder, zelfde fix-aanpak): p_uitgaan_slider_kaart_component_widget.dart:284 toont 'def' als datum ontbreekt; evenement_horecagelegenheid_widget.dart:406 toont 'establishmentnid'.
    • Niet-verdachte gevallen bewust genegeerd (echte inhoudelijke fallback, geen technische naam): 'Evenement' (kaart_tabel_uitgaan_comp_widget.dart:214, kaart_tabel_uitgaan_s_comp_widget.dart:121) en 'Uitgaan' (tag_categorie_component_widget.dart:111).

    P1-7 · Eigenaar: Bob. Account/profielscherm (wachtwoord wijzigen, uitloggen, account verwijderen). Bovenop de login/favorieten-P0-basis. Account verwijderen heeft mogelijk AVG-implicaties aan Drupal-kant.

    P1-8 · Eigenaar: Claude — bezig (sessie Home-cluster). Toegankelijkheid & navigatie, restpunten:

    • Login-pagina: 2 icon-only knoppen zonder tooltip (veld wissen + wachtwoord tonen/verbergen) — login_widget.dart (suffixIcon van een TextFormField — standaard Tooltip-wrap werkt daar niet op, zie CLAUDE.md; bevestigd nog open, geen fix geprobeerd — vraagt een andere aanpak dan Wrap Widget, bv. het hele veld i.p.v. alleen het icoon wrappen).
    • Overige icon-only knoppen buiten de header van tooltip voorziengecheckt 2026-08-04: al gedekt. Hartje op kaarten en drawer-menu-items hebben al AlignedTooltip. De per-pagina AppBar-knoppen (hamburger/terug) zijn qua functie ook "header", zowel via de gedeelde HeaderButtonsComponent (heeft al tooltips) als de losstaande inline kopieën op sommige pagina's (bv. home_widget.dart, event_current_widget.dart) — buiten scope van dit punt.
    • Bevestig-stap toevoegen aan de provincie/gemeente-kiezergedaan 2026-08-04. SelectStateDropDownComponent → Column onder de twee dropdowns → nieuwe Button "Toepassen" → actie Navigate To → home. Relevant: dit scherm is niet alleen via het drawer-menu bereikbaar, het is ook het allereerste scherm na inloggen (nav.dart:117/124) — stond zonder deze knop zonder duidelijke vervolgstap. "Replace Route"-toggle (voorkomt dat Home bovenop dit scherm gestapeld wordt i.p.v. het te vervangen) kon niet aangezet worden door rechterpaneel-clipping — functioneel geen probleem (back-knop vanaf Home gaat dan terug naar dit scherm i.p.v. waar de gebruiker vandaan kwam), maar Bob kan 'm zelf aanzetten: component SelectStateDropDownComponent → Button "Toepassen" → Actions → "Navigate To home" → Replace Route aanvinken.
    • Vaste "terug naar hoofdlijst"-snelkoppeling op detailpagina'sHorecagelegenheidCurrent gedaan 2026-08-04. Nieuwe Button "Alle horecagelegenheden" onderaan de pagina-Column (na TabBar) → actie Navigate To → HorecagelegenhedenOverzicht, parameter plaats = App State gemeenteSelectId. Plek is bewust onderaan i.p.v. in de AppBar: het invoegen van een widget in de AppBar-Row (naast HeaderButtonsComponent) faalde herhaaldelijk stil (geen foutmelding, gewoon geen insertie) — zowel via de kleine inline widget-picker als via de grote centrale "Insert"-modal; de kleine inline-picker op een gewone body-Column werkte wel meteen. Builder-observatie, geen bevestigde bug — als Bob de knop liever in de AppBar wil, eerst dat invoegen zelf proberen. EventCurrent nog open — geen eenduidige "hoofdlijst"-pagina voor events (EventWidget-route is een orphan, zie P2-7); Bob moet kiezen welke pagina hier geldt (vermoedelijk PUitgaanPage met de huidige plaats) voordat dit gebouwd kan worden.
    • Deep-link/query-param robuustheid checken (ongeldig/verlopen nid) — grotendeels gecheckt 2026-08-04, code-niveau, geruststellend. HorecagelegenheidCurrentWidget en EventCurrentWidget gebruiken consequent ?.toList() ?? [] en valueOrDefault<...> rond jsonBody-velden (i.t.t. de HorecagelegenhedenOverzicht-lijstpagina's die wél crashten, zie P1-1) — bij een ongeldige/lege nid toont dit fallback-tekst ('title', 'logo', letterlijke veldnaam — het bekende P1-6-patroon) i.p.v. een crash. EventCurrent heeft zelfs al een correcte if (getJsonField(...) != null)-guard vóór een CachedNetworkImage (regel 621-626) — het juiste patroon uit CLAUDE.md. Niet getest: het live gedrag in de emulator/app zelf (alleen code gelezen, geen flutter run gedaan) — als iemand dit ooit live wil verifiëren, horecagelegenheidCurrent/eventCurrent openen met een bewust niet-bestaand nid in de deep-link.

    P1-9 · Eigenaar: Onbepaald. Visuele polish (los, per pagina): Uitgaan-pagina (typografie/contrast/spacing), Event-pagina, HorecagelegenhedenOverzicht, tabel-kaartje-afstemming met slider-kaartje, categorie-tag mag titel/datum niet overstemmen.

    P1-10 · Eigenaar: Onbepaald, onderzoek nodig. Performance:

    • Dubbele/onnodige netwerkverzoeken checken (audit, nog te doen).
    • 6-7 tabbladen laden allemaal meteen hun eigen data bij elke tabwissel/herbouw (TabBarView bouwt alle tabs eager) — horecagelegenheden_overzicht(_sort_page/_page_data_type)_widget.dart.

    P1-11 · Eigenaar: Onbepaald, onderzoek nodig. Responsive/screensize-audit — o.a. het vaste 200×200px-tegelformaat in het venue-event-grid dat botst met de grid-berekening.

    P2 — features & concept, na livegang

    P2-1 · Eigenaar: Bob — testen in de API, komt terug. Datum-filter: Vandaag / Dit weekend / Deze week.

    P2-2 · Eigenaar: Onbepaald. Google Maps-weergave van horecagelegenheden — bewust niet vóór livegang (Maps API-key + billing, onduidelijk of elke locatie al lat/long heeft, marker-UI — geen quick win).

    P2-3 · Eigenaar: Onbepaald. "In de buurt"/geolocatie-browsen — aanvulling op het provincie/gemeente-model, geen vervanging.

    P2-4 · Eigenaar: Onbepaald. Overige feature-ideeën, geen van alle uitgewerkt: "Wat is er vanavond"-melding/widget · deel-knop op eventpagina · "toevoegen aan agenda" (native kalender) · "events op deze locatie" prominenter op de horeca-detailpagina · reviews/ waardering voor horecagelegenheden (groot, vraagt nieuw Drupal content-type + moderatie, eigen project).

    P2-5 · Eigenaar: Onbepaald. Ad-banners op horeca-overzicht, horeca-detail, event-detail; vaste regel: geen ads op locatie-kiezer/login/account.

    P2-6 · Eigenaar: Onbepaald. Tekstzoeken op titel op de horeca-overzichtspagina (los van de Datatype/Sort-experimenten die Bob daar zelf op test — die zijn actief werk-in-uitvoering, geen dode code).

    P2-7 · Eigenaar: Bob. Opschonen:

    • Merge kaartTabelUitgaanComp + kaartTabelUitgaanSComp — Bob doet dit zelf ("ik kijk er zelf naar").
    • lib/kanweg opnieuw leegmaken indien teruggekomen na een latere export-pull, plus eventuele nieuwe losse dode componenten in lib/evenement/.
    • Eén browse-by-category-patroon i.p.v. twee: nu Home landelijk is, bepalen hoe Home's categorieën en PUitgaanPage's provincie/ gemeente-gescoopte categorieën zich tot elkaar verhouden.
    • Dubbele Provincie/Gemeente-blok in het menu opruimen (12 menu-items waar 6 zouden volstaan).
    • EventWidget-route: heraansluiten of definitief schrappen (losse orphan-route).