Jelajahi Sumber

TASKS: taak 127 (Kopie-knop) verwijderd — A t/m G zijn af

Conform de afsluitroutine wordt een afgeronde taak verwijderd, niet
gearchiveerd; ik had er per ongeluk "✅ AF"-blokken van gemaakt. Scheelt
377 regels context voor elke volgende sessie. Wat open was is verplaatst:
de twee testnodes (222822/222823) staan nu bij de opruimklussen voor Bob,
en de positie van de Kopie-knop stond al bij de testbevindingen (132-I).
De herbruikbare inzichten staan in CLAUDE.md, de resource-code in
snippets/kloonbron-drupal-patch.inc.txt.
bob 1 hari lalu
induk
melakukan
b8b52d386c
1 mengubah file dengan 5 tambahan dan 382 penghapusan
  1. 5 382
      TASKS.md

+ 5 - 382
TASKS.md

@@ -54,7 +54,6 @@ Google Play en één doorloop die alleen Bob kan doen.
 | **122** | Teksten aanmaakpagina's | ✅ **A/B/C af** (Claude 2026-09-20, 19 teksten, export-geverifieerd): verkeerde woorden, typefouten, technische veldnamen en het sterretje bij de categoriekeuze. Open blijven D (hints die het label herhalen), E-restje en F (`Select...` op een NL-pagina) — eigen blok hieronder |
 | **123** | `mijn_stadsrechten` uitbreiden met de keten | **Code staat klaar en is op productie getest.** Vervang regels 316-372 van `custom.evenementen_aanmaken.inc` + `cc all`. Blokkeert 124 |
 | **124-126** | Stadsrechten-cascade op `stadsactiviteitAanmaken` | Voorvullen van provincie/gemeente/plaats (124), een **crash** bij een lege plaatsenlijst (125) en een stille verkeerde plaats bij het wisselen van gemeente (126). Eigen blok hieronder |
-| **127** | **Kopie-knop op `MijnAanmeldingen`** (clonen) | Wens Bob 2026-09-20, **vóór de livegang**. Backend bestaat al; Drupal-patch voor 3 gaten staat klaar en is getest (127-A). App-deel in stappen B t/m F; het activiteitendeel (127-E) deelt de cascade met 124. Eigen blok hieronder |
 | **128-A** | ✅ **KLAAR** — nieuwsbrieven-resource staat live | Gedeployd en getest op productie 2026-09-21. Rest: één tikfout in de omschrijving van tid 36676 (*verstuurt* → verstuurd), zie het blok hieronder |
 | **129** | Sessie-verlopen-melding afmaken/verifiëren | **Niet in deze chat** (Bob 2026-09-21). De afhandeling bestaat: `drupalRequest` herkent 401 en 403-met-"anonymous", zet `sessieVerlopen` en `VerbindingsBanner` hangt in `HeaderButtonsComponent`. Staat alleen **in de builder, niet in de gecommitte `lib/`** — dus nooit geëxporteerd/gecommit. Nalopen of het af is en of de banner ook echt verschijnt. Eigen blok hieronder |
 | **130** | **Inloggen met Facebook/Google (OneAll)** | Wens Bob 2026-09-21. Onderzocht en akkoord: OneAll-abonnement gaat naar **Personal Advanced** ($27/mnd jaarlijks) voor *Direct Connect*. Geen Play-blocker, maar wél de privacyverklaring/Data Safety als het meegaat in de eerste release. Volledig stappenplan in een eigen blok onderaan |
@@ -1048,387 +1047,6 @@ Fix: `Reset Form Fields` + `Update Page State` (Reset Value) op de onderliggende
 velden in de On-Selected van provincie, gemeente én de rechten-dropdown. Overlapt
 met taak 124 — samen oppakken.
 
-### 127 · "Kopie"-knop op `MijnAanmeldingen` — evenement én activiteit klonen
-
-**Eigenaar: Claude — bezig** (sessie 2026-09-21).
-
-**AF en export-geverifieerd:**
-- **127-A** (Drupal, door Bob): `entree_tid 36197`, `logo_url` gevuld,
-  `keten 28666|28737|28739`.
-- **127-B** (infra): App State **`kloonBron`** (JSON, niet persisted); custom
-  functions **`kloonTekst`** / **`kloonLijst`**, beide met een non-nullable
-  return; API Call **`AanmeldingKloonbron`** (top-level, GET, absolute URL) met
-  `'Cookie': '${sessionName}=${sessid}'` — echte interpolatie.
-- **127-C** (de knop): `Kopie` op de `MijnAanmeldingen`-kaart, buiten de
-  bestaande `InkWell` (de kaart-Column is gewrapt in een Column). Volledige
-  keten staat en `dart analyze` geeft **0 errors**:
-
-```dart
-_model.apiResulttzz = await AanmeldingKloonbronCall.call(
-  sessionName: FFAppState().userSessionname,
-  sessid: FFAppState().userSessionid,
-  nid: getJsonField(aanmeldingItemItem, r'$.nid').toString(),
-);
-if ((_model.apiResulttzz?.succeeded ?? true)) {
-  FFAppState().kloonBron = (_model.apiResulttzz?.jsonBody ?? '');
-  if (widget!.type == 'go_out_event') {
-    context.pushNamed(UitgaansevenementAanmakenWidget.routeName,
-      queryParameters: {'horecagelegenheidNid': ... r'$.horecagelegenheidnid' ...});
-  } else {
-    context.pushNamed(StadsactiviteitAanmakenWidget.routeName);
-  }
-}
-```
-
-ℹ️ FlutterFlow genereert bij een Backend Call **zelf** een
-`apiResulttzz -> Succeeded`-conditional; die is blijven staan, dus er wordt
-alleen genavigeerd als de call slaagt. Meegenomen winst, niet apart gebouwd.
-
-**127-C is OP HET TOESTEL BEWEZEN** (2026-09-21, profile-build x86_64 op
-`emulator-5554`, ingelogd als bobcity). Beide takken:
-- **Evenement** (`?type=go_out_event`) → opent `uitgaansevenementAanmaken` mét
-  *Je horecagelegenheid* al op **"Café de Vriendschap"** — dus de page parameter
-  komt door. De rest is nog leeg, want 127-D moet nog.
-- **Activiteit** (`?type=activity`, testnode 222818) → opent
-  `stadsactiviteitAanmaken`, niet het evenementformulier. De type-conditie klopt.
-- **0 exceptions** in `logcat` bij beide.
-
-Omdat er alleen genavigeerd wordt als de call slaagde, bewijst de navigatie
-tegelijk dat de sessie-cookie werkt en `kloonBron` gevuld is.
-
-De i18n-sleutel `g4pbs1et` is vertaald (`nl: Kopie` / `en: Copy`).
-
-**✅ Restpunt 127-C afgerond (2026-09-22):** alle drie de Kopie-knoppen
-(`MijnAanmeldingen` 1×, `mijnProfiel` 2×) staan nu op Fill **`secondaryBackground`**
-+ Text **`primaryText`**, radius 8 / elevation 0 — een rustende knop naast de
-oranje primaire acties, want rood is merk en geen actie (merk-DNA in `CLAUDE.md`).
-Geverifieerd in een verse export. Het Fill Color-veld bleek gewoon bereikbaar via
-het eigenschappen-zoekveld (`Fill` resp. `Text Color`); inklappen van secties was
-niet nodig.
-
-**127-D IS KLAAR EN OP HET TOESTEL BEWEZEN** (2026-09-21). Het
-evenementformulier vult zich; getest met "TEST tijdzone Claude 13sep" op
-`emulator-5554`: titel, zaak (Café de Vriendschap), categorie
-(Activiteiten › Bijeenkomst) en entree-optie staan voorgevuld, datum en
-einddatum bewust leeg, "Evenement indienen" zichtbaar, 0 exceptions.
-
-Zes tekstvelden hangen rechtstreeks aan `Initial Value`:
-`kloonTekst(kloonBron, '<sleutel>')` voor `titel`, `omschrijving`,
-`website_url`, `tickets_url`, `toelichting_entree`, `entree_prijs`.
-
-De vier waarden die de create-actie écht verstuurt gaan via **On Page Load** →
-de bestaande *Update Page State*-actie, uitgebreid met vier velden:
-`createEntreeTid` = `kloonTekst(…, 'entree_tid')`, `createLogoFid` =
-`kloonTekst(…, 'logo_fid')`, `createCategorieTids` = `kloonLijst(…,
-'categorie_tids')`, `createFotosFids` = `kloonLijst(…, 'fotos_fids')`.
-Dat is nodig omdat een voorgeselecteerde dropdown geen `onChanged` vuurt.
-Daarnaast is de weergave van beide dropdowns voorgevuld via *Initial Option
-Value(s)*.
-
-✅ **Restpunt 127-D (logo-/fotopreview) is OPGELOST** (2026-09-22). Geen
-typewijziging nodig geweest: er zijn twee custom functions bij gekomen met
-**ImagePath** als returntype — `kloonBeeld(bron, sleutel)` → *Image Path* en
-`kloonBeelden(bron, sleutel)` → *Image Path + Is List*. Die staan in de
-Set-Variable-dialoog wél gewoon selecteerbaar. Op **beide** aanmaakpagina's is
-in de On-Page-Load → Update Page State nu `createLogoUrl` =
-`kloonBeeld(kloonBron,'logo_url')` en `createFotosUrls` =
-`kloonBeelden(kloonBron,'fotos_urls')` gezet. De bestaande guards
-(`!= null && != ''` resp. `.length > 0`) blijven werken, want de functies geven
-`''` / `[]` terug als er niets te klonen valt.
-**Les voor later:** ImagePath/VideoPath/AudioPath staan gewoon in de
-return-type-dropdown van een Custom Function — een String-functie aan een
-Image-Path-veld binden lukt niet, maar een functie *van het juiste type*
-schrijven lost het in één keer op.
-
-**127-G IS KLAAR** (2026-09-21): dezelfde Kopie-knop staat nu ook op
-`mijnProfiel`, in béide lijsten — onder *Mijn evenementen* en onder
-*Mijn stadsactiviteiten*. Omdat die lijsten al op type gefilterd zijn
-(`type: 'go_out_event'` resp. `'activity'`) is er géén type-conditie nodig:
-elke knop navigeert rechtstreeks naar het juiste formulier.
-
-**127-E IS KLAAR** (2026-09-22): het activiteitenformulier vult zich nu net zo
-volledig als het evenementformulier — negen tekstvelden, vijf dropdowns, logo- en
-fotopreview. Zie het eigen blok hieronder.
-
-**Nog te doen:** alleen nog het restpunt **knopkleur** op `MijnAanmeldingen`
-(de Kopie-knop is nog FlutterFlow-rood `primary`). 127-E en 127-F zijn af
-(2026-09-22), de logo-/fotopreview ook.
-
-**Wens Bob (2026-09-20):** op elke kaart in *Mijn aanmeldingen* een knop **Kopie**.
-Eén tik opent het aanmaakformulier volledig ingevuld; de gebruiker vult de datum
-aan, past eventueel iets aan en dient in. Vóór de livegang. Beide types.
-
-**De datum komt bewust NIET mee** — je kloont juist om hetzelfde op een nieuwe
-datum te zetten. Dat zit al zo in de kloonbron.
-
-#### Wat er al is (gemeten 2026-09-20, niet opnieuw uitzoeken)
-
-`GET /nl/flutterdrup/aanmelding_kloonbron.json?nid=X` **bestaat en staat aan op
-productie** (`custom.mijn_aanmeldingen.inc:248`, resource `aanmelding_kloonbron`,
-operation `index`). Sessie-geauthenticeerd, met eigenaarscheck (403 op andermans
-node, 404 onbekend, 400 bij een ander contenttype). De sleutelnamen zijn met
-opzet gelijk aan wat `evenementen/create` en `stadsactiviteiten/create`
-verwachten — tids en fids, geen weergavewaarden.
-
-Aan de **app-kant is nog niets**: geen API Call, geen knop, 0 treffers op
-`kloonbron` in een verse export.
-
-#### 127-A · Drupal: drie gaten in de kloonbron dichten · Eigenaar: Bob
-
-**Code staat klaar en is op productie getest** (2026-09-20, Claude, read-only via
-`drush php-script` — het bestand is niet gewijzigd). Drie gaten, alle drie hard
-gemeten:
-
-| # | Gat | Bewijs |
-|---|---|---|
-| 1 | **`entree_tid` ontbreekt bij een activiteit** | De veldkaart heeft `'entree' => NULL` voor `activity`, maar `_custom_stadsactiviteit_create()` schrijft wél naar **`field_act_entree`** (Bob 2026-08-26, zelfde vocabulary als `field_goo_entree`). Testnode 222818 heeft `field_act_entree = 36197`; de kloonbron gaf dat niet terug → **dataverlies bij klonen** |
-| 2 | **Geen `logo_url`/`fotos_urls`** | De aanmaakpagina toont de preview uit page state `createLogoUrl`/`createFotosUrls`. Zonder URL's gaat het beeld wél mee (de fid) maar zie je een leeg previewvak — verwarrend |
-| 3 | **Geen plaatsketen bij een activiteit** | Alleen `plaats_tid`. De pagina heeft drie cascade-dropdowns (provincie → gemeente → plaats) en kan uit één tid niet afleiden welke provincie/gemeente erbij horen |
-
-**De patch** staat als `kloonbron-patch.inc` in het sessie-scratchpad van
-2026-09-20; opnieuw te genereren met de beschrijving hieronder. Twee ingrepen in
-`sites/all/modules/custom/custom.mijn_aanmeldingen.inc`:
-
-1. **Regel 125**: `'entree' => NULL,` → `'entree' => 'field_act_entree',`
-2. **Regels 240 t/m 313** (docblock t/m sluitende accolade van
-   `_custom_aanmelding_kloonbron()`) vervangen door de nieuwe versie. Die voegt
-   twee helpers toe (`_custom_aanm_bestand_urls()` en `_custom_aanm_keten()`) en
-   geeft extra terug: `logo_url`, `fotos_urls`, `entree_tid` (nu voor **beide**
-   types, uit het gedeelde blok), en voor een activiteit `provincie_tid`,
-   `gemeente_tid` en **`keten`**.
-
-Daarna `drush @uitgaanskrant.com cc all`.
-
-⚠️ **`keten` heeft bewust exact hetzelfde formaat als taak 123**
-(`"provincie|gemeente|plaats"`, ontbrekende delen leeg). De drie custom functions
-uit taak 124 (`ketenProvincie` / `ketenGemeente` / `ketenPlaats`) zijn daardoor
-1-op-1 herbruikbaar — bouw ze niet twee keer.
-
-**Getest op productie, beide types plus alle randgevallen:**
-
-| invoer | `keten` |
-|---|---|
-| plaats 28739 (Hoogkarspel) | `28666\|28737\|28739` |
-| gemeente 28694 (Amsterdam) | `28666\|28694\|` |
-| provincie 28666 (Noord-Holland) | `28666\|\|` |
-| `NULL` / `0` / onbestaande tid | `\|\|` (geen crash) |
-
-**Gemeten: alle 23 gevulde `field_act_state_municipality_tow`-waarden staan op
-niveau 3 (plaats).** Er is dus geen activiteit waarbij `plaats_tid` en het derde
-deel van de keten uiteenlopen — dat randgeval hoeft niet afgevangen te worden.
-
-ℹ️ **Niet "repareren": `file_create_url()` geeft onder drush `http://`.** Dat is
-een drush-artefact (geen request-context, `$base_url` staat op
-`http://uitgaanskrant.com`). Via een echte HTTP-request levert Drupal gewoon
-`https://` — geverifieerd op `flutterflowmobiel_establishment_info`. Controleer
-het bij de eerste test vanuit de app, maar ga er niet aan sleutelen.
-
-#### 127-B · App: transport via App State · Eigenaar: nader te bepalen
-
-**Waarom niet gewoon On Page Load?** Een `TextField` leest zijn Initial Value
-**tijdens de eerste build**; een Backend Call op *On Page Load* draait in een
-`addPostFrameCallback`, dus daarná. Het veld blijft dan leeg terwijl de data
-binnen is. Zelfde valkuil als bij Initial Option Value (staat in `CLAUDE.md`).
-Daarom: **de call gebeurt op de knop, vóór de navigatie.**
-
-**Besluit Bob 2026-09-20: App State, niet page parameters.** Eén JSON-veld scheelt
-de helft van het bindwerk (1 binding bij het vullen i.p.v. 16) en houdt de route
-schoon.
-
-**Nieuw aan te maken:**
-
-| wat | waar | details |
-|---|---|---|
-| App State `kloonBron` | App Values → State | Type **JSON**, *Is List* uit, **niet** persisted |
-| API Call `AanmeldingKloonbron` | API Calls | GET `https://uitgaanskrant.com/nl/flutterdrup/aanmelding_kloonbron.json`, header `Cookie: [sessionName]=[sessid]` (rechte haken!), query `nid`. Kopieer `MijnAanmeldingenCall` als voorbeeld |
-| Custom function `kloonTekst` | Custom Code | `String kloonTekst(dynamic bron, String sleutel)` — **non-nullable** return, `''` bij ontbreken |
-| Custom function `kloonLijst` | Custom Code | `List<String> kloonLijst(dynamic bron, String sleutel)` — non-nullable, `[]` bij ontbreken |
-
-```dart
-// kloonTekst — plat schrijven, geen closures (FlutterFlow's validator
-// struikelt over een genest (params) { ... }-patroon).
-String kloonTekst(dynamic bron, String sleutel) {
-  if (bron == null || bron is! Map) return '';
-  final waarde = bron[sleutel];
-  if (waarde == null) return '';
-  return waarde.toString();
-}
-
-List<String> kloonLijst(dynamic bron, String sleutel) {
-  final uit = <String>[];
-  if (bron == null || bron is! Map) return uit;
-  final waarde = bron[sleutel];
-  if (waarde is List) {
-    for (final item in waarde) {
-      if (item != null) uit.add(item.toString());
-    }
-  }
-  return uit;
-}
-```
-
-⚠️ **Return type non-nullable houden.** Bij een `String?` eist FlutterFlow een
-"Default Variable Value", en `valueOrDefault` substitueert die óók bij een lege
-string — dan kun je nooit een leeg veld klonen. Geen `getJsonField()` gebruiken:
-die bestaat niet binnen een Custom Function (wel in een Custom Action).
-
-#### 127-C · De knop op de kaart · Eigenaar: nader te bepalen
-
-Huidige opbouw van de kaart (`mijn_aanmeldingen_widget.dart`, itemBuilder):
-`Padding > Container > Padding > InkWell > Column [logo, titel, datum_start,
-status_label]`. De hele kaart is één `InkWell`.
-
-De knop moet **buiten die InkWell** staan, anders vuurt ook de navigatie naar
-`EventCurrent`. Recept (staat in `CLAUDE.md`): rechtsklik de `InkWell` →
-**Wrap Widget → Column** → "+" op die nieuwe Column → de knop. Een `TabBar Page`
-of `InkWell` accepteert maar één kind, een `Column` meerdere.
-
-**Actieketen op de knop:**
-
-1. **Backend Call** → `AanmeldingKloonbron`, `nid` = `$.nid` van het loop-item
-   (`aanmeldingItemItem`), sessie uit App State.
-2. **Update App State** → `kloonBron` = *Action Outputs → JSON Body →
-   No Further Changes*. Doe dit in de **Action Flow Editor** (knop *Edit*, dan het
-   `|<` om de trigger-kolom in te klappen) — in het compacte Actions-paneel
-   reageert het Value-veld niet.
-3. **Add Conditional** op de **page parameter `type`** (`Equal to` `go_out_event`):
-   - TRUE → `Navigate To` **`uitgaansevenementAanmaken`**, page parameter
-     `horecagelegenheidNid` = `$.horecagelegenheid_nid` uit de action output.
-   - FALSE → `Navigate To` **`stadsactiviteitAanmaken`**.
-
-   ⚠️ Conditioneer op de **page parameter**, niet op `$.type` van het item: een
-   JSON-Path-binding krijgt type *Json* en levert `if (getJsonField(...))` op —
-   een `dynamic` als `bool`, die compileert en pas bij runtime crasht. De page
-   parameter is een gewone String, dus een veilige Single Condition.
-
-**Gratis meegenomen:** `horecagelegenheidNid` bestaat al als page parameter en
-heeft in `horecaVoorselectie()` (`custom_functions.dart:245`) al **voorrang** op
-de automatische voorselectie. Voor evenementen hoeft de horecagelegenheid dus
-niet via App State.
-
-#### 127-D · Evenementenformulier voorvullen · Eigenaar: nader te bepalen
-
-14 bindingen. Initial Value = `kloonTekst(FFAppState().kloonBron, '<sleutel>')`.
-
-| kloonbron-sleutel | doel | soort |
-|---|---|---|
-| `titel` | `textFieldTitel` | Initial Value |
-| `omschrijving` | `textFieldOmschrijving` | Initial Value |
-| `entree_prijs` | `textFieldEntreeprijs` | Initial Value |
-| `toelichting_entree` | `textFieldToelichtingEntree` | Initial Value |
-| `website_url` | `textFieldWebsiteURL` | Initial Value |
-| `tickets_url` | `textFieldTicketsURL` | Initial Value |
-| `entree_tid` | `dropDownEntree` | Initial Option Value **+** page state `createEntreeTid` in On Page Load |
-| `categorie_tids` | `dropDownCategorieen` | Initial Option Value (`kloonLijst`) **+** page state `createCategorieTids` |
-| `logo_fid` / `logo_url` | — | page states `createLogoFid` / `createLogoUrl` |
-| `fotos_fids` / `fotos_urls` | — | page states `createFotosFids` / `createFotosUrls` |
-| `horecagelegenheid_nid` | page parameter | ✅ gratis, zie 127-C |
-| datums | — | bewust leeg |
-
-**Waarom een dropdown twee bindingen nodig heeft:** de page state wordt gezet in
-`onChanged`, en die vuurt niet bij een voorselectie. Zonder de tweede binding
-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
-On Page Load — daar speelt het timingprobleem niet.
-
-#### 127-E · Activiteitenformulier voorvullen · ✅ AF (2026-09-22)
-
-Geverifieerd in een verse export, `dart analyze` 0 fouten.
-
-- **On Page Load → Update Page State** (Action 3, ná de bestaande
-  `gemeenteVoorselectie`-conditional) met acht velden:
-  `createProvincieID`→`provincie_tid`, `createPlaatsID`→`plaats_tid`,
-  `createEntreeTid`→`entree_tid`, `createLogoFid`→`logo_fid`,
-  `createCategorieTids`→`categorie_tids` (kloonLijst),
-  `createFotosFids`→`fotos_fids` (kloonLijst),
-  `createLogoUrl`→`logo_url` (**kloonBeeld**),
-  `createFotosUrls`→`fotos_urls` (**kloonBeelden**).
-- **Initial Value op negen TextFields**: `titel`, `omschrijving`, `adres_straat`,
-  `adres_postcode`, `organisator`, `contact`, `website_url`,
-  `toelichting_entree`, `entree_prijs`. (Datum bewust niet — je kloont juist om
-  een nieuwe datum te kiezen.)
-- **Initial Option Value op vijf dropdowns**, zodat de gebruiker de gekloonde
-  keuze ook *ziet*: `DropDownCategorieen` = `kloonLijst(kloonBron,
-  'categorie_tids')`, `DropDownProvincie` = `kloonTekst(kloonBron,
-  'provincie_tid')`, `DropDownEntree` = `kloonTekst(kloonBron,'entree_tid')` —
-  die drie bestaan al bij de eerste build en moeten dus aan **App State**
-  hangen, niet aan page state. `DropDownGemeente` = `createGemeenteID` en
-  `DropDownPlaats` = `createPlaatsID` mogen wél page state, want die zitten
-  achter een Visibility-conditie en worden pas ná de On-Page-Load-`safeSetState`
-  voor het eerst gebouwd.
-- **`gemeenteTid`-navigatieparameter** op beide Kopie-knoppen
-  (`MijnAanmeldingen` Action 4 en `mijnProfiel` Action 3), gebonden aan
-  `apiResult… → JSON Body → $.gemeente_tid`. `gemeenteVoorselectie()` geeft die
-  parameter voorrang, dus `createGemeenteID` klopt bij een kloon en de
-  plaats-dropdown wordt zichtbaar.
-  ⚠️ **Valkuil die hier één keer toesloeg:** op `mijnProfiel` stond die binding
-  eerst op `apiResultvpn` — de output van de On-Page-Load-call
-  (`MijnHorecagelegenheden`), niet van de Kopie-knop zelf. Dat compileert
-  gewoon, geeft stil `gemeenteTid = "null"` en dus een lege plaats-cascade.
-  Controleer bij zo'n binding altijd de **naam** van de action output, niet
-  alleen het JSON-pad. De bronnenlijst rendert daar leeg tot je de hover-truc
-  gebruikt; zoekterm `apiResult` + hover toont de drie outputs wél.
-
-**Volledig af**: zowel de indiening (alle waarden komen uit page state) als de
-weergave (tekstvelden, dropdowns, logo- en fotopreview).
-
-**Op het toestel bewezen (2026-09-22, profile-build x86_64 op emulator-5556,
-account `bobcity`):** Kopie op *Eigen activiteiten* → formulier met titel,
-omschrijving, drie categorieën, provincie/gemeente/plaats (Noord-Holland /
-Drechterland / Hoogkarspel), adres, postcode, entree-type én logo- + fotopreview;
-datumvelden leeg. Ingediend met STATUS 200:
-
-```
-BODY : {"titel":"gggg","plaats_tid":28739,"datum_start":"2026-09-26 17:02:00",
-        "omschrijving":"...","adres":{"thoroughfare":"yyy","postal_code":"gggg",
-        "country":"NL"},"categorie_tids":[36190,36194,36484],
-        "logo_fid":5513220,"fotos_fids":[5513221],"entree_tid":36197}
-→ {"status":"created_pending_review","nid":"222823"}
-```
-
-⚠️ **Op te ruimen door Bob: testnodes 222822 en 222823 op productie** (beide door
-Claude aangemaakt tijdens deze tests; 222823 staat ongepubliceerd).
-
-#### 127-F · `kloonBron` wissen · ✅ AF (2026-09-22)
-
-Vóór elke "nieuw aanmaken"-navigatie staat nu een `Update App State` met
-`kloonBron` op **Clear Value** (genereert `FFAppState().kloonBron = null;`).
-Vier plekken, alle vier geverifieerd in een verse export:
-
-| bestand | knop | doel |
-|---|---|---|
-| `mijn_profiel_widget.dart` | `+ Evenement aanmaken` | `UitgaansevenementAanmaken` |
-| `mijn_profiel_widget.dart` | `+ Activiteit` | `StadsactiviteitAanmaken` |
-| `mijn_profiel_widget.dart` | `+ Activiteit aanmaken` (per stadsrecht) | `StadsactiviteitAanmaken` |
-| `favorieten_widget.dart` | `Stadsactiviteit aanmaken` | `StadsactiviteitAanmaken` |
-
-Dit zijn **alle** ingangen: de aanmaakpagina's zijn verder nergens vanuit de app
-bereikbaar (wel via een directe route).
-
-**Op het toestel bewezen (2026-09-22):** ná een kloon levert "+ Activiteit
-aanmaken" bij een stadsrecht een volledig leeg formulier op (titel, omschrijving,
-categorie "Selecteer…", entree "Select…", geen media), mét de juiste gemeente
-voorgeselecteerd uit `gemeenteTid`.
-
-#### Stand
-
-A t/m G zijn **allemaal af** (127-A Drupal door Bob, B t/m G in de builder).
-Open restpunt: alleen de **kleur** van de Kopie-knop, zie hieronder.
-
-#### Testen
-
-- Kloon een evenement **met** en **zonder** logo/foto's, en één met meerdere
-  categorieën (testnode 222818 heeft er drie).
-- Klonen van een **ongepubliceerde** aanmelding moet gewoon werken — de kloonbron
-  kijkt niet naar `status`. Juist dát is het scenario: een afgekeurde of nog
-  wachtende aanmelding opnieuw indienen.
-- Controleer dat de datumvelden **leeg** zijn en dat indienen zonder datum
-  geweigerd wordt.
-- Na een kloon: terug naar Mijn profiel → *Nieuw evenement* → formulier moet
-  **leeg** zijn (127-F).
-- Controleer in de eerste echte respons dat `logo_url` op `https://` staat.
-
 ### 121 · 15 verweesde mappen in `lib/` · Eigenaar: Bob (Claude verwijdert niets)
 
 Gevonden 2026-09-20 bij het committen van de achterstallige working tree. Deze
@@ -1669,6 +1287,11 @@ genoteerd zodat niemand het opnieuw uitzoekt:
 
 ## 🚦 Bij livegang — schakelaars en opruimklussen · Eigenaar: Bob
 
+- **Twee testnodes op productie weghalen: 222822 en 222823** (stadsactiviteiten,
+  door Claude aangemaakt tijdens de kloontest van 2026-09-22; 222823 staat
+  ongepubliceerd). Claude ruimt niets op Drupal op — dit staat hier alleen als
+  herinnering.
+
 - **AdMob: `Show Test Ads` uitzetten.** App Settings → AdMob (**niet** een vinkje
   op het `AdBanner`-widget — dat paneel heeft alleen *Ad Properties* en *Ad Banner
   Dimensions*; de export schrijft de projectinstelling per widget uit).