Просмотр исходного кода

Testronde deel 2: ingelogde flow op telefoon, plus twee nieuwe bevindingen

Bob logde de telefoon in, waardoor de ingelogde schermen ook op telefoonbreedte
getest konden worden. Nieuw gevonden:

- 132-J: de waarschuwing "Je volgt nog geen gemeenten" verschijnt onterecht.
  favorieteGemeenteIds wordt alleen gevuld door SelectStateDropDownComponent,
  dus alleen na een bezoek aan Zoek stad. Reproductie en fix beschreven.
- 132-K: favorieten_horeca.json levert "Kunst & Cultuur" — categorie mist
  in de fields_to_clean-lijst van dat endpoint.

Verder 132-C herschreven na Bob's correctie: stadsrechten HOREN direct te
publiceren, dus de app-tekst klopt en de backend moet mee. CLAUDE.md verwijst
daar nu naar, zodat een volgende sessie niet opnieuw concludeert dat het
huidige gedrag bewust is. En vraag over favorieten_agenda.json beantwoord:
dat endpoint heeft geen omschrijvingsveld, dus "Binnenkort meer..." valt niet
met een binding op te lossen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bob 12 часов назад
Родитель
Сommit
46604c2025
2 измененных файлов с 94 добавлено и 16 удалено
  1. 7 0
      CLAUDE.md
  2. 87 16
      TASKS.md

+ 7 - 0
CLAUDE.md

@@ -5303,6 +5303,13 @@ minder calls per scherm, niet in Views.
   activiteit die "niet online komt" is dus geen bug en geen rollenkwestie, maar
   activiteit die "niet online komt" is dus geen bug en geen rollenkwestie, maar
   wacht gewoon op de redactie; de snackbar ("wordt beoordeeld door de redactie")
   wacht gewoon op de redactie; de snackbar ("wordt beoordeeld door de redactie")
   is voor iedereen correct.
   is voor iedereen correct.
+  ⚠️ **Dit gedrag is per 2026-09-22 als BUG aangemerkt, niet meer als ontwerp:**
+  Bob wil dat een indiener **mét** stadsrechten voor die plaats wél direct
+  publiceert, en alleen een gewone gebruiker langs de redactie gaat. Zolang de
+  Drupal-kant niet om is, blijft de beschrijving hierboven de feitelijke werking
+  — concludeer dus niet opnieuw dat het "bewust zo" is. Zie taak **132-C** in
+  `TASKS.md` voor wat er precies moet gebeuren (server-side check op
+  `field_town_access`, inclusief het provincie/gemeente/plaats-niveauprobleem).
 
 
 - **Geen user-specifieke elementen op overzichtspagina's — besluit Bob,
 - **Geen user-specifieke elementen op overzichtspagina's — besluit Bob,
   2026-09-13.** Concreet: géén favorietenhartje op de kaarten van een
   2026-09-13.** Concreet: géén favorietenhartje op de kaarten van een

+ 87 - 16
TASKS.md

@@ -365,8 +365,9 @@ app-probleem, wel het sterkste argument voor `confirm = FALSE` in de app.
 
 
 ## 🧪 132 · Bevindingen uit de testronde van 2026-09-22 · Eigenaar: nader te bepalen
 ## 🧪 132 · Bevindingen uit de testronde van 2026-09-22 · Eigenaar: nader te bepalen
 
 
-Volledige doorloop op **emulator-5556 (telefoon, uitgelogd)** en **emulator-5554
-(tablet, ingelogd als bobcity)**, verse release-APK uit een eigen export.
+Volledige doorloop op **emulator-5556 (telefoon)** en **emulator-5554 (tablet)**
+met een verse release-APK uit een eigen export, zowel uitgelogd als ingelogd als
+bobcity (Bob logde de telefoon halverwege in).
 `dart analyze` gaf **0 errors**; er is geen enkele exception of overflow in
 `dart analyze` gaf **0 errors**; er is geen enkele exception of overflow in
 `logcat` gevallen. Offline-gedrag, netwerkherstel, zoeken, datumfilters,
 `logcat` gevallen. Offline-gedrag, netwerkherstel, zoeken, datumfilters,
 categoriefilter, login-foutafhandeling en de nieuwsbrief-toggles werkten alle
 categoriefilter, login-foutafhandeling en de nieuwsbrief-toggles werkten alle
@@ -400,15 +401,34 @@ zit achter `if (FFAppState().zoekOpen)` en wordt dus pas gebouwd nadat de state
 gevuld is — de bekende "te laat"-valkuil speelt hier niet). Alternatief: de
 gevuld is — de bekende "te laat"-valkuil speelt hier niet). Alternatief: de
 zoekterm wissen bij het verlaten van de pagina.
 zoekterm wissen bij het verlaten van de pagina.
 
 
-### 132-C · Introtekst `stadsactiviteitAanmaken` belooft iets dat niet gebeurt
-
-Sleutel **`rupw26n4`** (NL én EN) zegt *"Heb je stadsredacteur-rechten voor deze
-plaats, dan staat je activiteit direct online; anders kijken we hem eerst na."*
-`_custom_stadsactiviteit_create()` zet echter **onvoorwaardelijk `status = 0`**,
-óók voor een account met stadsrechten (zie het domeinblok in `CLAUDE.md`). De
-tekst van `uitgaansevenementAanmaken` (`vkjvzuqz`) klopt wél.
-
-Fix: tekst aanpassen naar "we kijken hem eerst na", in beide talen.
+### 132-C · Stadsrechten publiceren NIET direct — backend moet mee · Eigenaar: Bob (Drupal)
+
+**Bob 2026-09-22: "als iemand stadsrechten heeft, mag de activiteit direct
+gepubliceerd worden. Alleen gewone gebruikers die een activiteit aanmaken, die
+moeten eerst in drupal worden goedgekeurd."** De app-tekst klopt dus; de
+**backend** doet het niet.
+
+Huidige stand: `_custom_stadsactiviteit_create()` zet **onvoorwaardelijk
+`$node->status = 0`** en neemt bewust géén `status`-argument aan, en de docblock
+noemt `mijn_stadsrechten` letterlijk *"PUUR INFORMATIEF … GEEN toegangscontrole"*.
+Iedere app-inzending wacht daardoor op de redactie, ook die van bobcity (die
+stadsrechten heeft op Amsterdam, Drechterland, Enkhuizen en Stede Broec).
+
+Wat er moet gebeuren, en waarom het niet triviaal is:
+- De check hoort **server-side**, op de sessie-gebruiker — nooit een `status` uit
+  de client, anders kan iedereen publiceren.
+- Vergelijk `field_town_access` van de gebruiker met de **gekozen plaats** van de
+  activiteit. Let op het niveau-probleem uit `CLAUDE.md`: dat veld kan een
+  **provincie-, gemeente- óf plaats-tid** bevatten (bobcity heeft nu gemeenten,
+  eerder stonden er plaatsen en provincies in). Bepaal het niveau met
+  `count(taxonomy_get_parents_all($tid))` → 1 provincie / 2 gemeente / 3 plaats,
+  en kijk of de gekozen plaats **onder** een van de rechten-tids valt.
+- Valt hij eronder → `status = 1`, anders `status = 0`.
+- ⚠️ Claude komt niet aan Drupal (staande regel). Claude kan hooguit een script
+  met droogdraai aanleveren; uitvoeren doet Bob.
+
+Pas ná deze wijziging klopt de introtekst (`rupw26n4`) met de werkelijkheid. De
+tekst zelf hoeft dus **niet** aangepast; wel controleren zodra de backend om is.
 
 
 ### 132-D · Vier Engelse labels staan op de verkeerde tekst (`Duplicate`-erfenis)
 ### 132-D · Vier Engelse labels staan op de verkeerde tekst (`Duplicate`-erfenis)
 
 
@@ -463,9 +483,17 @@ eerste tab naar die knop (of toon `LegeLijstComponent` met die tekst).
 - **Kopie-knop is nog `primary`-rood** (restpunt van 127-C) en staat los
 - **Kopie-knop is nog `primary`-rood** (restpunt van 127-C) en staat los
   gecentreerd tússen twee kaarten, waardoor hij bij de verkeerde lijkt te horen.
   gecentreerd tússen twee kaarten, waardoor hij bij de verkeerde lijkt te horen.
 - **Persoonlijke agenda toont overal "Binnenkort meer…"**:
 - **Persoonlijke agenda toont overal "Binnenkort meer…"**:
-  `favorieten_widget.dart:435` geeft hardcoded `inhoud: null` mee, terwijl alle
-  andere velden netjes uit `$.veld` komen. Vraag: levert
-  `favorieten_agenda.json` een omschrijvingsveld? Zo ja, binden.
+  `favorieten_widget.dart:435` geeft hardcoded `inhoud: null` mee. **Nagemeten
+  2026-09-22 (respons uit logcat van de ingelogde app):
+  `favorieten_agenda.json` heeft géén omschrijvingsveld.** Volledige veldenset:
+  `node_type, nid, titel, datum, datum_raw, plaats, categorie, logo, adres,
+  postcode, woonplaats, horecagelegenheid, horecagelegenheidNid, matched_via`.
+  De binding is dus niet "vergeten" — er valt niets te binden. Keuze voor Bob:
+  óf een omschrijvingsveld aan de resource toevoegen (Drupal), óf de
+  placeholderregel weghalen zodat de kaart gewoon zonder tekst staat.
+  *(Terzijde: `horecagelegenheidNid` mét hoofdletter N is voor dít endpoint
+  correct — getest, het horeca-blok op de detailpagina komt gewoon door. Niet
+  "gelijktrekken" met de `$.horecagelegenheidnid` van de views.)*
 - **Zoekveld krijgt geen focus** als je het opent met het vergrootglas — je moet
 - **Zoekveld krijgt geen focus** als je het opent met het vergrootglas — je moet
   er zelf nog in tikken.
   er zelf nog in tikken.
 - **Login-melding** zegt *"Controleer je gebruikersnaam en wachtwoord"* terwijl
 - **Login-melding** zegt *"Controleer je gebruikersnaam en wachtwoord"* terwijl
@@ -476,6 +504,49 @@ eerste tab naar die knop (of toon `LegeLijstComponent` met die tekst).
   horeca-overzicht); op het horeca-overzicht legt de 468×60-banner zich over de
   horeca-overzicht); op het horeca-overzicht legt de 468×60-banner zich over de
   onderste kaart heen. Zie ook G0.6.
   onderste kaart heen. Zie ook G0.6.
 
 
+### 132-J · Waarschuwing "Je volgt nog geen gemeenten" verschijnt ONTERECHT
+
+Raakt taak 128. Op `mijnProfiel` → Nieuwsbrieven stond bij bobcity de rode regel
+*"Je volgt nog geen gemeenten, dus de wekelijkse agenda blijft leeg"* — terwijl
+die drie favoriete gemeenten heeft (Alblasserdam, Amsterdam, Arnhem, zichtbaar
+op Favorieten tab 2).
+
+De conditie zelf is goed
+(`if (!(FFAppState().favorieteGemeenteIds.isNotEmpty))`, regel 2302). Het
+probleem is de **bron**: `favorieteGemeenteIds` wordt op precies één plek gevuld,
+in de On-Page-Load van `SelectStateDropDownComponent`
+(`select_state_drop_down_component_widget.dart:115`, via `favorieten_gemeenten.json`).
+Dat component staat alleen op **Zoek stad**. Wie na het inloggen direct naar
+Mijn Profiel gaat, heeft dus een lege lijst en krijgt de verkeerde waarschuwing.
+
+**Reproductie en bewijs (2026-09-22, telefoon-emulator, ingelogd):** Mijn Profiel
+→ Nieuwsbrieven → rode regel staat er. Daarna menu → Zoek stad → terug naar
+Nieuwsbrieven → regel is weg. Twee keer zo gelopen.
+
+Fix: `mijnProfiel` zelf de lijst laten ophalen in On Page Load en de conditie op
+een **page state** hangen — exact het patroon dat elders op diezelfde pagina al
+gebruikt wordt (page state type JSON + *Is List*, gevuld uit een Backend Call,
+conditie *Is Set and Not Empty*; recept staat in `CLAUDE.md`). Een App State die
+maar op één scherm gevuld wordt, is hier de verkeerde bron.
+
+Let op: de tweede, oranje regel eronder (*"De wekelijkse uitgaansagenda gebruikt
+de gemeenten die je volgt"*) staat er altijd en is de algemene toelichting. Met
+0 gemeenten staan er dus twee bijna gelijke regels onder elkaar — overweeg er één
+van te maken.
+
+### 132-K · `&amp;` in de categorie van `favorieten_horeca.json` · Eigenaar: Bob (Drupal)
+
+Favorieten tab 3 toont bij Luxor Live het label **`Kunst &amp; Cultuur`**.
+Nagemeten in de rauwe respons:
+`"categorie":["Kunst &amp; Cultuur","Theater"]`. Dit is het bekende
+`_custom_clean_html()`-patroon uit `CLAUDE.md`: het veld `categorie` staat voor
+dit endpoint niet in de `$fields_to_clean`-lijst. De views leveren diezelfde
+categorie wél schoon uit ("Kunst & Cultuur"), dus het is endpoint-specifiek.
+
+Controleer in dezelfde moeite de andere favorieten-resources
+(`favorieten_agenda.json`, `favorieten_gemeenten.json`) — in de opgevangen
+agenda-respons zaten geen entiteiten, maar daar zat toevallig ook geen `&` in.
+
 ### Wat expliciet GOED was
 ### Wat expliciet GOED was
 
 
 Offline starten (rode banner *Geen verbinding met uitgaanskrant.com* + werkende
 Offline starten (rode banner *Geen verbinding met uitgaanskrant.com* + werkende
@@ -1203,7 +1274,7 @@ selecteert de dropdown wél de juiste waarde maar verstuurt de create-actie leeg
 De page states worden pas bij het indienen gelezen, dus die mogen gewoon in
 De page states worden pas bij het indienen gelezen, dus die mogen gewoon in
 On Page Load — daar speelt het timingprobleem niet.
 On Page Load — daar speelt het timingprobleem niet.
 
 
-#### 127-E · Activiteitenformulier voorvullen · Eigenaar: Claude — grotendeels af (2026-09-22)
+#### 127-E · Activiteitenformulier voorvullen · Eigenaar: Claude — bezig (2026-09-22, preview logo/foto's)
 
 
 **Af en geverifieerd in een verse export (0 analyse-fouten):**
 **Af en geverifieerd in een verse export (0 analyse-fouten):**
 - **On Page Load → Update Page State** (Action 3, ná de bestaande
 - **On Page Load → Update Page State** (Action 3, ná de bestaande
@@ -1245,7 +1316,7 @@ meekrijgt komen uit de page states, en die zijn nu gezet.
 "nieuw aanmaken", krijgt een verse activiteit het vorige kloonformulier te zien.
 "nieuw aanmaken", krijgt een verse activiteit het vorige kloonformulier te zien.
 Dat raakt o.a. de knop "+ Activiteit aanmaken" per stadsrecht op `mijnProfiel`.
 Dat raakt o.a. de knop "+ Activiteit aanmaken" per stadsrecht op `mijnProfiel`.
 
 
-#### 127-F · `kloonBron` wissen · Eigenaar: nader te bepalen
+#### 127-F · `kloonBron` wissen · Eigenaar: Claude — bezig (2026-09-22)
 
 
 Zonder dit blijft een kloon hangen: wie daarna een **vers** evenement aanmaakt,
 Zonder dit blijft een kloon hangen: wie daarna een **vers** evenement aanmaakt,
 krijgt het vorige formulier opnieuw ingevuld.
 krijgt het vorige formulier opnieuw ingevuld.