# Backend / Systems Updates

Backlog for the systems-level improvements requested after the 2.0.2 queue/playback
bug-fix pass. Items are marked `[✔️]` when landed. Nothing is deleted — completed
work is preserved and checked off.

## Landed

- [✔️] **Queue/playback regression test harness.** Node `node:test` suite that loads
  the real `src/app.js` in a `vm` sandbox (stubbed browser + Tauri globals) and
  exercises the `queueSource` state machine and history dedupe without modifying
  the shipping code. Files: `lightify-tauri/tests/harness.mjs`,
  `lightify-tauri/tests/queue.test.mjs`, `lightify-tauri/package.json` (`npm test`).
  15 tests cover: identity/matching, `uniqueQueueTracks`, `shuffleQueueTracks`
  (preserveFirst), `appendLightifyQueueTracks` (the spotify/context/lightify
  branches — the #3 fix), `consumeLightifyQueueTrack`, source switches,
  `recentHistoryForDisplay` collapse (today's fix), `addToSessionHistory`
  move-to-front, and the advance/recovery guards. **Extended (2026-07-09)** with a
  recording mock `invoke` covering the async advance path — `playNextLightifyQueueTrack`,
  `playNextContextQueueTrack`, `playPreviousLocalQueueTrack`, and the #6 autoplay
  re-sync — plus the drag-reorder/remove helpers. **22 tests, all green.**

- [✔️] **Market-aware playability.** _(landed 2026-07-10, shipped 2.0.7)_
  Region-locked tracks now relink to a playable version instead of silently
  failing. Appended `market=from_token` to every track-list GET (`cmd_album_tracks`,
  playlist `/items` + full-endpoint fallback, liked `me/tracks`, the `tracks?ids=`
  enrichment, and the `type=track` searches) so Spotify relinks and populates
  `is_playable`. Added `is_playable: bool` to `Track` (serde-defaults `true`;
  read in `parse_track` + `parse_album_tracks`, `true` at the embed/SSR/placeholder
  sites). Frontend drops `is_playable === false` tracks in the play/queue builders
  via a pure, tolerant `playableTracks()` helper (missing field → kept), and dims
  unavailable rows with an "Unavailable in your region" tooltip
  (`.list-item.track-unavailable`). Covered by a new harness test (29 tests green).
  Builds on 2.0.5's `cmd_play_uris` skip-invalid.

## Open

- [ ] **Tauri auto-updater (signed).** Wire `@tauri-apps/plugin-updater` + host a
  signed `latest.json` on lightify.stream so 2.0.x patches reach users.
  **BLOCKED — decisions needed:** (a) generate/hold the update signing keypair
  (`tauri signer generate`; private key + password are secrets you must store),
  (b) the update-manifest URL to bake into `tauri.conf.json`
  (e.g. `https://lightify.stream/downloads/latest.json`), (c) release flow to emit
  `latest.json` + signature per build.

- [✔️] **Structured diagnostics log + in-app viewer.** _(landed 2026-07-09)_
  Rust ring buffer (`DiagEntry` / `push_diag`, cap 300) instrumented at device
  transfer (success/failure) and token refresh; `cmd_log_event` bridges frontend
  events (queue recovery, play errors, `audio:error`, engine-ready) into the same
  log; `cmd_get_diagnostics` exposes it, and a "Recent Diagnostics" table is
  appended to the Settings debug report.

- [✔️] **Central Spotify request limiter — enhanced.** _(landed 2026-07-09)_
  Review found the core was already centralized (not ad-hoc): `sp_get` retries 429s
  with Retry-After backoff, `search?` GETs are globally paced across search +
  Beatport, and writes have per-family cooldowns. Per Feature-Respect that working
  logic was kept; added a **shared read cooldown** (`spotify_read_cooldown_until`,
  capped 5s) so concurrent GETs back off together after a 429 instead of each
  hammering, plus **429 observability** via `push_diag` (surfaced in the diagnostics
  report). Rewriting into a generic token-bucket was rejected as higher-risk,
  lower-value.

- [✔️] **Persist queue + session across restarts.** _(landed 2026-07-09)_
  Frontend localStorage (`lightify.session.v1`): queue mirror
  (`queueSource`/`lightifyQueue`/current/contextUri) + `sessionHistory` +
  cleared-at marker, debounced-saved via `refreshVisibleQueueSidebar` /
  `addToSessionHistory` and rehydrated in `enterPlayer` (never auto-resumes;
  ignores queues >12h old). Last-device intentionally NOT persisted — the host
  already auto-selects the Lightify device via `ensure_active_device_id`.

- [ ] **Gapless / prefetch for the local queue.** Add look-ahead prefetch (and
  optional crossfade) over the 4-track `play_uris` batching. **RISK:** touches the
  freshly-stabilized queue playback path — do after the harness covers more of the
  advance logic; guard with new tests first.

- [ ] **Owned-media library MVP (`.lfy` / local DB).** Index the files the OnTheSpot
  bridge already produces, store metadata in a local DB, and add a "play local
  files" path — the roadmap north star (`docs/music-library-design.md`).
  **BLOCKED — decisions needed:** DB choice (e.g. `rusqlite`), the `.lfy` container
  scope for v1 (index-only vs. repackage), and how local playback integrates with
  the current Spotify-Connect engine. Large; own milestone.
