From ce2eead558afa8aef95d1e91f4ddb001409e2f40 Mon Sep 17 00:00:00 2001 From: teahubxyz Date: Tue, 20 Oct 2026 20:37:35 +0000 Subject: [PATCH] gandora: STORAGE.md, the contract between the page and whatever stores its tracks Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01K6897PWcUEwHiqZMcVnNF6 --- ventures/gandora/STORAGE.md | 60 +++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 ventures/gandora/STORAGE.md diff --git a/ventures/gandora/STORAGE.md b/ventures/gandora/STORAGE.md new file mode 100644 index 0000000..9d267ab --- /dev/null +++ b/ventures/gandora/STORAGE.md @@ -0,0 +1,60 @@ +# gandora storage contract + +The page keeps everything through one object, `db`, in `index.html`. Today it is IndexedDB in the browser; a backend +replaces it by implementing the same four calls and pointing `db` at the new implementation. Nothing else in the page +touches storage (`brain.js` reads through `db.all()` too). + +``` +db.put(row, store = "tracks") // create or replace, keyed by row.id +db.all(store = "tracks") // every row, newest first (tracks by `made`, stations by `last`) +db.del(id, store = "tracks") +db.open() // internal; a backend adapter can drop it +``` + +Two stores. + +## tracks + +``` +{ + id: "1760998800000-211979153", // spec.made + "-" + hash32(title); stable, made by the page + made: 1760998800000, // ms epoch, when the DJ wrote it + kept: false, // pinned by KEEP (the only pin) + plays: 3, // play starts + loop passes + blob: Blob, // the audio (FLAC from Venice, mp3 from Runware); a backend may return { url } instead + spec: { // the song on paper: enough to re-render it anywhere + title, tags, lyrics, bpm, key, energy, line, // what the DJ wrote (tags = the music prompt, <= 500 chars) + seed, station, stationId, // where it came from + reaction: "🔥 ❤️ \"less snare\" [skipped]", // the listener's reactions, in order; words quoted, skips bracketed + guess: 0.71, // the taste net's prediction when it was cooked (optional) + plays, id, made // mirrored for convenience + } +} +``` + +## stations + +``` +{ + id: "s-1760998800000-211979153", // "s-" + ms + hash32(seed) + seed: "rainy trains", + name: "Platform Nine", // chosen by the DJ on the first track, then stable + taste: { like: [...], avoid: [...], notes: [...] }, // last 8 of each, in words, fed to the DJ + history: [ { id, title, tags, bpm, key, energy, reaction, made } ], // last 8 tracks, no blobs + made: 1760998800000, + last: 1761002400000, // touched on every play and reaction + played: 23 +} +``` + +## what a backend adds + +- identity: rows are per listener; `/user/station/track` links need the listener in the key +- `blob` as a URL the `