26 lines
1.3 KiB
SQL
26 lines
1.3 KiB
SQL
-- Per-user audio playback resume points.
|
|
--
|
|
-- One row per (user, audio file). The floating audio player writes the
|
|
-- last-known position for a track so it can resume there next time the
|
|
-- same file is played, on any device the user is signed in on.
|
|
--
|
|
-- audio_key is the track URL with its query string / hash stripped
|
|
-- (audio URLs may be signed or cache-busted, so the path is the stable
|
|
-- identity). The schema is owned by the frontend; the backend only
|
|
-- stores and round-trips it. position_seconds/duration_seconds mirror
|
|
-- the HTMLAudioElement's currentTime/duration (floats).
|
|
--
|
|
-- updated_at is supplied by the client, not defaulted to now(), so the
|
|
-- upsert can resolve multi-tab / multi-device conflicts with a
|
|
-- newest-wins rule (see AudioProgressRepo.Upsert) and so anonymous
|
|
-- IndexedDB entries keep their original timestamp when synced on login.
|
|
CREATE TABLE IF NOT EXISTS audio_progress (
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
audio_key TEXT NOT NULL,
|
|
position_seconds DOUBLE PRECISION NOT NULL DEFAULT 0,
|
|
duration_seconds DOUBLE PRECISION,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
PRIMARY KEY (user_id, audio_key),
|
|
CHECK (position_seconds >= 0)
|
|
);
|