-- Multiple conversations per persona. -- -- v1 keyed a transcript on (user_id, persona_id), so a persona had exactly -- one rolling conversation and there was no way to start a fresh topic -- without discarding the old one. The key is now an opaque `conversation_id`, -- with (user_id, persona_id) demoted to an index. -- -- `title` is a short generated summary of the opening exchange, used as the -- conversation's name in the list. Empty until the first turn completes; the -- client falls back to the persona name while it is blank. -- -- SQLite cannot redefine a primary key in place, so this is the standard -- create-copy-drop-rename dance. Existing transcripts carry over with a -- generated id and an empty title. CREATE TABLE persona_chat_conversations_new ( conversation_id TEXT NOT NULL PRIMARY KEY, user_id INTEGER NOT NULL, persona_id TEXT NOT NULL, title TEXT NOT NULL DEFAULT '', messages_json TEXT NOT NULL DEFAULT '[]', turn_count INTEGER NOT NULL DEFAULT 0, created_at BIGINT NOT NULL, updated_at BIGINT NOT NULL ); INSERT INTO persona_chat_conversations_new ( conversation_id, user_id, persona_id, title, messages_json, turn_count, created_at, updated_at ) SELECT lower(hex(randomblob(16))), user_id, persona_id, '', messages_json, turn_count, updated_at, updated_at FROM persona_chat_conversations; DROP INDEX IF EXISTS idx_persona_chat_updated; DROP TABLE persona_chat_conversations; ALTER TABLE persona_chat_conversations_new RENAME TO persona_chat_conversations; CREATE INDEX idx_persona_chat_updated ON persona_chat_conversations (user_id, updated_at DESC); CREATE INDEX idx_persona_chat_persona ON persona_chat_conversations (user_id, persona_id);