Add three default-off capabilities that stop the play queue from being lost,
all gated behind admin/independent toggles so existing behavior is unchanged
until an operator opts in:
- Named save/load of queues (Feature 1): new saved_queues table (per-user +
reserved __shared__ owner, capped at 50 queues / 1000 songs, JSON song blob
that degrades to empty on corruption); /api/saved-queues router (list/save/
load/delete with ownership 404s, inert 403 when disabled); chat commands
!save / !load [-a] / !queues; BotInstance.loadSavedQueue (replace/append).
- Auto-restore live queue across restart (Feature 2): PlayQueue.snapshot/restore,
queue_state table (one row per bot), a debounced snapshot writer driven off
stateChange, and restore+resume on connect. Cancels the pending snapshot on
disconnect so a stale write can't wipe the row a restart must restore.
- playKeepsQueue (Feature 3): BotInstance.playSingleSong funnels chat !play and
the web /play-song route through one place; when enabled a single-song play
inserts-after-current and jumps instead of clearing the queue.
Config gains savedQueuesEnabled + playKeepsQueue (both default false, strict-
coerced on load like spotify.enabled); the settings API round-trips them.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>