fix(persist): one shared z-order across Source + WebcamSceneConfig rows

A webcam dragged between sources reverted to the bottom of the stack on
every relaunch: Source and WebcamSceneConfig each carried independent
per-type SortOrder counters, and Load appended all Sources before all
configs. Save now stamps both tables' SortOrder from the element's index
within scene.Elements; Load merges the two tables' rows by that shared z
(sources-first tie-break preserves legacy rows). Cross-type reorder now
survives a fresh LayoutStore reload.

Task 37 queued: defaults vs current layout split (creator directive) —
capture out-of-scope work in TASKS.md rather than folding it in.
This commit is contained in:
2026-09-20 09:23:46 -07:00
parent f91bf8715d
commit 5a1993b6db
7 changed files with 327 additions and 160 deletions
+48
View File
@@ -0,0 +1,48 @@
# TASK 37 — Defaults vs current layout split
**Status:** ☐ Queued (2026-09-20)
## Idea (creator directive 2026-09-20)
The app establishes a DB of static, branded layout objects as its defaults. Today the DB is BOTH the
defaults and the live workspace: `LayoutStore.Save` deletes and reinserts the whole layout on every
save, so "your last edit" and "the defaults" occupy the same rows. The recurring "reorder doesn't
persist" bug was a symptom of that conflation.
Store TWO data sets:
- **`default`** — the established DB (branded factory scenes/layers), never mutated by user edits.
- **`current`** — whatever the user currently has, stamped with the build-id.
Load rule: honor `current` **iff** its build-id equals the running build's id (`BuildStamp.Id`),
otherwise load `default`. Bonus: one-click "revert to defaults" = drop `current`.
Two implementations were floated (config file vs second rows in the same DB); nothing decided — both
are OPS acceptable to the creator. The proposed conceptual shape:
```
scene[0-4].layerList.[default | current].elementList
```
## Notes / facts established while investigating
- `SceneCatalog` only defines the five canonical scene **names**; the actual default element set
exists only as whatever the DB holds at first migration. There is no standalone in-code factory
element set — "defaults" at migration time = a snapshot of today's DB.
- SortOrder is a DB column only (not on models); `Source` and `WebcamSceneConfig` were stamped with
independent per-type sort counters and load appended all sources before all configs. That
cross-table order bug is ALREADY FIXED (2026-09-20, unified z-space, see commit) — TASK 37 is the
defaults/current data split on top of it.
- `MainViewModel.LoadLayout` (MainViewModel.cs:348) seeds `SceneCatalog.All` when `Scenes.Count == 0`
and SaveLayoutNow deletes/reinserts everything (LayoutStore.Save.cs). Startup path:
`%APPDATA%\ytLlive\ytLlive.db` (MainViewModel.cs:332), `LayoutPathOverride` test seam.
## Acceptance
- A saved `current` layout with a matching build-id restores on start.
- A `current` stamped by a different (older/newer) build-id falls back to `default`.
- Revert-to-default restores `default` for one scene or all.
## Cross-references
- `ai.md` — persistence architecture; `MyMistakes.md` — prior reorder persistence failures.