
## Curation Tool Sprint — Continued (22:00–22:21 UTC)

### Session Summary
Extended sprint fixing persistence bugs, adding multi-select delete, testing end-to-end with Playwright.

### Completed This Block
1. **`_stateLoaded` reset on brand switch** — `_stateLoaded = false` added at line 464 of curate/index.html (start of `switchBrand`). Prevents `serverSync` firing during brand-switch loading window.
2. **Assets.json sync** — Uploaded files were not being tracked in assets.json → looked like data loss on refresh. Fix: `/upload` API endpoint now updates assets.json on every upload (gallery-api.py lines ~158–169). Also manually synced all 17 brands' assets.json with actual files on disk (+31 Revolut, +3 Monzo, +1 Cashapp).
3. **Merge guard on `/save-state`** — Server never overwrites existing `crops`/`rejected`/`slotAssign` with empty incoming data (gallery-api.py lines ~188–196).
4. **Multi-select delete** — New UI: click cards to toggle selection (no modifier needed), bulk bar shows count + "Delete Selected" + "Select All" + "Clear". `/delete` API patched to also remove files from assets.json and state.json (crops, rejected, slotAssign).
5. **Crop modal constraints** — `max-width: min(calc(100vw - 140px), 1400px); max-height: calc(100vh - 220px)` applied to cm-img. Large images no longer overflow viewport.
6. **Playwright tests** — End-to-end verified: crop modal opens, crop saves, persists on reload (6 → crop → reload → 7 badges ✅). Multi-select: 3 clicks = 3 selected, deselect works ✅. Delete: file removed from disk + assets.json ✅.

### Current Open Issues
1. **Multi-select conflicts with normal card click flow** — Every card click now toggles selection. This breaks "click card → open picker → REPLACE" normal workflow. Kittoro needs a separate "Select Mode" toggle button.
2. **Logo slot empty** — Assaf uploaded logos to library (timestamp-named files) but Logo slot still shows empty placeholder (`assets/logo.png`). Uploading ≠ placing. He needs to use the REPLACE flow: click Logo slot in iframe → pick from library → REPLACE. Workflow may not be obvious.
3. **Revolut state** — 6 crops, 14 rejected (Playwright-tested 22:15 UTC).

### Infrastructure State (22:21)
- Gallery API: active, port 3099, systemd service `gallery-api.service`
- Server: 178.104.6.235
- Playwright test script: `/root/.openclaw/workspace/scripts/test-curation-tool.js`
- API token: `gallery-delete-2026`

### Key Decisions
- Multi-select delete uses toggle-on-click (no modifier) — but needs "Select Mode" toggle to not break picker flow
- `/delete` API now cleans assets.json AND state.json (crops/rejected/slotAssign)
- Logo slot `src="assets/logo.png"` is intentional — user must REPLACE it from the picker, not via upload
