feat(vibe): persist durable session plans and events
This commit is contained in:
@@ -644,4 +644,68 @@ export const MIGRATIONS: Migration[] = [
|
||||
EXECUTE FUNCTION propagate_album_release_date_to_tracks();
|
||||
`,
|
||||
},
|
||||
{
|
||||
// Vibe v2 needs an immutable event ledger and revisioned plans. The
|
||||
// legacy session_state table remains in place as a derived-state cache so
|
||||
// existing v2 endpoints can migrate independently.
|
||||
id: '20260801_vibe_session_persistence',
|
||||
sql: `
|
||||
CREATE TABLE IF NOT EXISTS vibe_sessions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL,
|
||||
status TEXT NOT NULL CHECK (status IN ('active', 'paused', 'ended', 'expired', 'replaced')),
|
||||
seed_track_id UUID REFERENCES tracks(id) ON DELETE SET NULL,
|
||||
context JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
policy_version TEXT NOT NULL,
|
||||
started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
last_event_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
ended_at TIMESTAMPTZ
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_vibe_sessions_user_last_event
|
||||
ON vibe_sessions (user_id, last_event_at DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS vibe_events (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
client_event_id UUID,
|
||||
session_id UUID NOT NULL REFERENCES vibe_sessions(id) ON DELETE CASCADE,
|
||||
user_id UUID NOT NULL,
|
||||
track_id UUID REFERENCES tracks(id) ON DELETE SET NULL,
|
||||
type TEXT NOT NULL,
|
||||
occurred_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
position_ms INTEGER,
|
||||
duration_ms INTEGER,
|
||||
payload JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
UNIQUE (session_id, client_event_id)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_vibe_events_session_occurred
|
||||
ON vibe_events (session_id, occurred_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_vibe_events_user_occurred
|
||||
ON vibe_events (user_id, occurred_at DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS vibe_plan_versions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
session_id UUID NOT NULL REFERENCES vibe_sessions(id) ON DELETE CASCADE,
|
||||
version INTEGER NOT NULL CHECK (version > 0),
|
||||
reason TEXT NOT NULL,
|
||||
state_snapshot JSONB NOT NULL,
|
||||
objective_snapshot JSONB NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE (session_id, version)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS vibe_plan_items (
|
||||
plan_version_id UUID NOT NULL REFERENCES vibe_plan_versions(id) ON DELETE CASCADE,
|
||||
ordinal INTEGER NOT NULL CHECK (ordinal >= 0),
|
||||
track_id UUID NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
|
||||
slot_role TEXT,
|
||||
candidate_source TEXT NOT NULL,
|
||||
score REAL NOT NULL,
|
||||
score_breakdown JSONB NOT NULL,
|
||||
explanation JSONB NOT NULL,
|
||||
committed BOOLEAN NOT NULL DEFAULT false,
|
||||
PRIMARY KEY (plan_version_id, ordinal),
|
||||
UNIQUE (plan_version_id, track_id)
|
||||
);
|
||||
`,
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user