Skip to content

feat(curation): persist Dataset Curator panel state across sessions#285

Merged
lstein merged 1 commit into
lstein/feature/server-side-preferencesfrom
lstein/feature/persist-curation-state
May 26, 2026
Merged

feat(curation): persist Dataset Curator panel state across sessions#285
lstein merged 1 commit into
lstein/feature/server-side-preferencesfrom
lstein/feature/persist-curation-state

Conversation

@lstein

@lstein lstein commented May 25, 2026

Copy link
Copy Markdown
Owner

Stacked on top of #284 — base is lstein/feature/server-side-preferences. GitHub will rebase the base to master automatically when #284 merges.

Summary

  • Persist the five Dataset Curator inputs — target count, iterations, method (Diversity FPS / Blocks K-Means), exclude-matches percent, and export path — to the same per-device preferences store introduced in feat(preferences): per-device server-side UI preferences #284.
  • Reopening the panel (or revisiting on another day, or from another browser on the same device after a localStorage eviction) restores the values the user left.
  • The export path migrates automatically: existing localStorage["curationExportPath"] values are picked up by restoreFromLocalStorage and pushed to the server via the existing reconciliation path on first boot.

What's new

Backend (preferences.py)

Ranges mirror the HTML input min/max attrs in curation.html so server validation defends against a stale tab posting an out-of-range value after a future HTML change tightens the bounds.

Frontend

  • state.js: five new entries in PERSISTED_SETTINGS, five new setters exported, five new state defaults that mirror the HTML defaults.
  • curation.js: replaced manual localStorage.getItem/setItem("curationExportPath") calls with state setters. Added a restore-from-state block at the top of setupEventListeners and wired oninput / onchange handlers on the slider, number, iterations, method radios, threshold, and export path. Each handler clamps before calling the setter so out-of-range typed values can't trip server validation.

Test plan

  • pytest tests/backend/test_preferences.py — 12 tests, including two new ones (test_curation_fields_round_trip covering all five fields end-to-end; test_curation_invalid_values_return_422 exercising every range bound and the Literal field).
  • npm test — full 334/334 suite still green.
  • Lint: ruff + eslint + prettier all clean.
  • Manual: open Curator panel, change target count / iterations / method / threshold / export path, close and reopen → values persist. Reload page → still persist. Toggle method between FPS and K-Means → persists.
  • Manual: existing user with localStorage["curationExportPath"] set from before feat(preferences): per-device server-side UI preferences #284 → reload after both PRs land → path appears in the input.

🤖 Generated with Claude Code

Wire the five Dataset Curator inputs — target count, iterations, method
(Diversity FPS vs Blocks K-Means), exclude-matches percent, and export
path — into the shared per-device preferences mechanism so the panel
reopens with the same values the user left.

Backend (preferences.py):
- Add curation_target_count (10..1000), curation_iterations (1..30),
  curation_method (Literal["fps","kmeans"]), curation_exclude_threshold
  (1..100). curation_export_path was already on the model.
- Field ranges mirror the HTML input min/max attrs in curation.html so
  server validation defends against a stale tab posting an out-of-range
  value after a future HTML change tightens the bounds.

Frontend:
- state.js: register the five fields in PERSISTED_SETTINGS so they get
  the standard auto-restore + debounced-PATCH treatment. Existing users'
  curationExportPath localStorage values are migrated to the server on
  first boot via the existing reconciliation path.
- curation.js: replace the manual localStorage reads/writes with state
  setters. Restore every input from `state.curation*` on panel setup;
  wire `oninput` / `onchange` on the slider, number, iterations, method
  radios, threshold, and export path to call the setters. Clamp before
  setting so out-of-range typed values don't trip server validation.

Backend tests:
- test_curation_fields_round_trip covers all five fields end-to-end.
- test_curation_invalid_values_return_422 exercises every range bound
  and the Literal field.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lstein lstein merged commit 6fb9c9e into lstein/feature/server-side-preferences May 26, 2026
@lstein lstein deleted the lstein/feature/persist-curation-state branch May 26, 2026 02:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant