docs: restructure TASKS.md into a catalog — one file per task in TASKS/
TASKS.md is now the index (status table, open items, research pointer). 33 files: 32 task files + 1 research facts file. The full take-saga narrative and all design decisions are preserved verbatim; the catalog makes the queue readable without opening every task body. Schema and AGENTS.md updated to reflect the new layout.
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
# TASK 5 — Layout Persistence (SQLite)
|
||||
|
||||
> Catalog: [`TASKS.md`](../TASKS.md) — status and requirements live here.
|
||||
|
||||
|
||||
**Goal:** Scenes, sources, and asset bytes survive restarts; assets are always available.
|
||||
|
||||
### Status: ✅ Done
|
||||
|
||||
1. ✅ SQLite database (`Microsoft.Data.Sqlite`) at `%APPDATA%\ytLlive\ytLlive.db`; schema versioned via `PRAGMA user_version` (currently **v8**)
|
||||
2. ✅ Assets live in the DB (BLOB keyed by SHA-256 content hash), never file paths — deleting the original file never breaks a scene
|
||||
3. ✅ File-model save/open — the active layout file is tracked (default is the AppData DB); **Save Layout As… / Open Layout…** switch the active file; auto-save writes to whatever is active
|
||||
4. ✅ Auto-save (invisible) — ~1.5s debounce on scene/source add/remove/reorder/rename/hide + any source transform change; flush on window close
|
||||
5. ✅ Startup — load the active file; seed the five canonical scenes only when the DB is empty; (+) re-adds a missing canonical scene and is hidden once all five are present; adding beyond the five is rejected
|
||||
6. ✅ Schema v1 → v9 — webcam columns (v2), singleton `Webcam` + per-scene `WebcamSceneConfig` (v3), `RectWidth`/`RectHeight` round-to-rect restore (v4), `Source.IsBackdrop` + `Source.CaptureKey` (v5), `Scene.HasBackdrop` — backdrop **Live-only by policy** (v6, one-time backfill + `EnforceBackdropPolicy` on every load), `Scene.HasSocialBar` (v7, dropped per-scene toggle — column back-compat, unread), `Socials.BarEnabled` (v8); the `SocialEntry.Software` fediverse-software column is a **column-presence migration** (commented v8→v9, no version bump — `user_version` stays 8); v9 = single-row `Music`. **Load-time rule:** sources load with `IsBackground` derived from `Type` (OR'd with the persisted column so legacy DisplayCapture backdrops keep their flag) — rows saved before the Type setter derived the flag heal on load
|
||||
7. ✅ WindowHandle stays in-memory (per-session); save = transactional rewrite; orphaned assets pruned. **v9 lands in the TASK 8 audio milestone** (single-row `Music` — `TrackPath`/`IsEnabled`)
|
||||
|
||||
### Design decisions
|
||||
|
||||
1. **SQLite database** (`Microsoft.Data.Sqlite`) at `%APPDATA%\ytLlive\ytLlive.db`; schema versioned
|
||||
via `PRAGMA user_version`.
|
||||
2. **Assets live in the DB, not on disk** — `Asset` table stores image bytes (BLOB) keyed by a
|
||||
SHA-256 content hash (unique). Identical image content collapses to one row regardless of file
|
||||
name — the 1:M resource memory model, enforced by the database. No file paths; deleting the
|
||||
original file never breaks a scene.
|
||||
3. **File-model save/open** — the active layout file is tracked (default is the AppData DB).
|
||||
**Save Layout As… / Open Layout…** switch the active file; auto-save writes to whatever is active.
|
||||
4. **Auto-save (invisible)** — ~1.5s debounce on scene add/remove/reorder/rename/hide, source
|
||||
add/remove/reorder, and any source transform change; flush on window close.
|
||||
5. **Schema** — `Scene` (Id, Name, IsHidden, IsChatScene, HasBackdrop, HasSocialBar, SortOrder), `Asset` (Id, Hash, Data,
|
||||
PixelWidth, PixelHeight), `Source` (Id, SceneId FK cascade, AssetId FK, Type, Name, IsEnabled,
|
||||
X/Y/Width/Height/Opacity, MonitorIndex, DeviceId, ClipShape, IsMirrored, SortOrder), `Socials` (Id,
|
||||
BarPosition, BarJustify — back-compat, unread, BarEnabled added via `ALTER`), `SocialEntry` (Id,
|
||||
SocialsId FK cascade, Service, Handle, ProfileUrl, SortOrder) — `user_version` **8** (v1 → v2 =
|
||||
`ALTER TABLE` adds the two webcam columns; v3 = singleton `Webcam` + per-scene `WebcamSceneConfig`;
|
||||
v4 = `WebcamSceneConfig.RectWidth`/`RectHeight` for the round-to-rect restore; v5 = `Source.IsBackdrop`
|
||||
+ `Source.CaptureKey` for the live-capture backdrop; v6 = `Scene.HasBackdrop` — the backdrop is
|
||||
**Live-only by policy** (one-time backfill turns Starting/BRB/Chat/Ending off and drops their backdrop
|
||||
sources; `EnforceBackdropPolicy` re-normalizes every load); v7 = `Scene.HasSocialBar` (per-scene toggle
|
||||
dropped — column back-compat, unread); v8 = `Socials.BarEnabled`). The `SocialEntry.Software`
|
||||
fediverse-software column is a column-presence migration (commented v8→v9, no version bump).
|
||||
`WindowHandle` stays in-memory (per-session). Save = transactional rewrite; orphaned assets pruned.
|
||||
6. **Startup** — load the active file; seed the five canonical scenes
|
||||
(Starting/Live/BRB/Chat/Ending, `SceneCatalog`) only when the DB is empty. The (+)
|
||||
button re-adds a missing canonical scene and is hidden once all five are present;
|
||||
adding beyond the five is rejected — work with less, never more.
|
||||
|
||||
Reference in New Issue
Block a user