From 2e8de105b2e8b56a839bce51c67c84cd0dc17860 Mon Sep 17 00:00:00 2001 From: claudecode Date: Wed, 1 Jul 2026 11:56:35 -0400 Subject: [PATCH] feat: expand threads and npcs schema with deeper tracking fields Adds detailed tracking columns to threads (stakes, origin, next beat, etc.) and npcs (appearance, personality, secrets, disposition, etc.), plus a migration script to add the columns to existing databases. Co-Authored-By: Claude Sonnet 5 --- CLAUDE.md | 55 +++++++++++++++++++++------- scripts/migrate-001-threads-npcs.js | 56 +++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 13 deletions(-) create mode 100644 scripts/migrate-001-threads-npcs.js diff --git a/CLAUDE.md b/CLAUDE.md index d7166af..454068a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -130,22 +130,51 @@ CREATE TABLE campaigns ( --- Trackers --- CREATE TABLE threads ( - id INTEGER PRIMARY KEY, - campaign_id INTEGER NOT NULL REFERENCES campaigns(id), - title TEXT NOT NULL, - status TEXT NOT NULL DEFAULT 'active', - notes TEXT, - created_at TEXT NOT NULL DEFAULT (datetime('now')) + id INTEGER PRIMARY KEY, + campaign_id INTEGER NOT NULL REFERENCES campaigns(id), + title TEXT NOT NULL, + status TEXT NOT NULL DEFAULT 'active', + notes TEXT, + related_npcs TEXT, + related_location TEXT, + origin TEXT, + stakes TEXT, + last_development TEXT, + next_beat TEXT, + suspected_resolution TEXT, + created_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE TABLE npcs ( - id INTEGER PRIMARY KEY, - campaign_id INTEGER NOT NULL REFERENCES campaigns(id), - name TEXT NOT NULL, - description TEXT, - notes TEXT, - motivations TEXT, - created_at TEXT NOT NULL DEFAULT (datetime('now')) + id INTEGER PRIMARY KEY, + campaign_id INTEGER NOT NULL REFERENCES campaigns(id), + name TEXT NOT NULL, + description TEXT, + notes TEXT, + motivations TEXT, + appearance TEXT, + age TEXT, + gender TEXT, + pronouns TEXT, + voice TEXT, + distinguishing_features TEXT, + faction TEXT, + occupation TEXT, + social_status TEXT, + relationship_to_pc TEXT, + loyalty TEXT, + personality_traits TEXT, + fears TEXT, + desires TEXT, + secrets TEXT, + first_encountered TEXT, + last_seen TEXT, + current_location TEXT, + current_goal TEXT, + role_in_threads TEXT, + alive_status TEXT DEFAULT 'alive', + disposition TEXT DEFAULT 'unknown', + created_at TEXT NOT NULL DEFAULT (datetime('now')) ); --- Notes --- diff --git a/scripts/migrate-001-threads-npcs.js b/scripts/migrate-001-threads-npcs.js new file mode 100644 index 0000000..c7e069b --- /dev/null +++ b/scripts/migrate-001-threads-npcs.js @@ -0,0 +1,56 @@ +const Database = require('better-sqlite3'); +const path = require('path'); + +const dbPath = path.join(__dirname, '..', 'data', 'mythic-oracle.db'); + +const db = new Database(dbPath); + +const alterations = [ + { table: 'threads', column: 'related_npcs', sql: 'ALTER TABLE threads ADD COLUMN related_npcs TEXT' }, + { table: 'threads', column: 'related_location', sql: 'ALTER TABLE threads ADD COLUMN related_location TEXT' }, + { table: 'threads', column: 'origin', sql: 'ALTER TABLE threads ADD COLUMN origin TEXT' }, + { table: 'threads', column: 'stakes', sql: 'ALTER TABLE threads ADD COLUMN stakes TEXT' }, + { table: 'threads', column: 'last_development', sql: 'ALTER TABLE threads ADD COLUMN last_development TEXT' }, + { table: 'threads', column: 'next_beat', sql: 'ALTER TABLE threads ADD COLUMN next_beat TEXT' }, + { table: 'threads', column: 'suspected_resolution', sql: 'ALTER TABLE threads ADD COLUMN suspected_resolution TEXT' }, + { table: 'npcs', column: 'appearance', sql: 'ALTER TABLE npcs ADD COLUMN appearance TEXT' }, + { table: 'npcs', column: 'age', sql: 'ALTER TABLE npcs ADD COLUMN age TEXT' }, + { table: 'npcs', column: 'gender', sql: 'ALTER TABLE npcs ADD COLUMN gender TEXT' }, + { table: 'npcs', column: 'pronouns', sql: 'ALTER TABLE npcs ADD COLUMN pronouns TEXT' }, + { table: 'npcs', column: 'voice', sql: 'ALTER TABLE npcs ADD COLUMN voice TEXT' }, + { table: 'npcs', column: 'distinguishing_features', sql: 'ALTER TABLE npcs ADD COLUMN distinguishing_features TEXT' }, + { table: 'npcs', column: 'faction', sql: 'ALTER TABLE npcs ADD COLUMN faction TEXT' }, + { table: 'npcs', column: 'occupation', sql: 'ALTER TABLE npcs ADD COLUMN occupation TEXT' }, + { table: 'npcs', column: 'social_status', sql: 'ALTER TABLE npcs ADD COLUMN social_status TEXT' }, + { table: 'npcs', column: 'relationship_to_pc', sql: 'ALTER TABLE npcs ADD COLUMN relationship_to_pc TEXT' }, + { table: 'npcs', column: 'loyalty', sql: 'ALTER TABLE npcs ADD COLUMN loyalty TEXT' }, + { table: 'npcs', column: 'personality_traits', sql: 'ALTER TABLE npcs ADD COLUMN personality_traits TEXT' }, + { table: 'npcs', column: 'fears', sql: 'ALTER TABLE npcs ADD COLUMN fears TEXT' }, + { table: 'npcs', column: 'desires', sql: 'ALTER TABLE npcs ADD COLUMN desires TEXT' }, + { table: 'npcs', column: 'secrets', sql: 'ALTER TABLE npcs ADD COLUMN secrets TEXT' }, + { table: 'npcs', column: 'first_encountered', sql: 'ALTER TABLE npcs ADD COLUMN first_encountered TEXT' }, + { table: 'npcs', column: 'last_seen', sql: 'ALTER TABLE npcs ADD COLUMN last_seen TEXT' }, + { table: 'npcs', column: 'current_location', sql: 'ALTER TABLE npcs ADD COLUMN current_location TEXT' }, + { table: 'npcs', column: 'current_goal', sql: 'ALTER TABLE npcs ADD COLUMN current_goal TEXT' }, + { table: 'npcs', column: 'role_in_threads', sql: 'ALTER TABLE npcs ADD COLUMN role_in_threads TEXT' }, + { table: 'npcs', column: 'alive_status', sql: "ALTER TABLE npcs ADD COLUMN alive_status TEXT DEFAULT 'alive'" }, + { table: 'npcs', column: 'disposition', sql: "ALTER TABLE npcs ADD COLUMN disposition TEXT DEFAULT 'unknown'" }, +]; + +let added = 0; +let skipped = 0; + +for (const { table, column, sql } of alterations) { + try { + db.exec(sql); + console.log(`Added column ${column} to ${table}`); + added++; + } catch (err) { + console.log(`Skipped ${column} on ${table}: ${err.message}`); + skipped++; + } +} + +console.log(`\nSummary: ${added} column(s) added, ${skipped} column(s) skipped`); + +db.close();