diff --git a/server/database/init.sql b/server/database/init.sql deleted file mode 100644 index 98351516..00000000 --- a/server/database/init.sql +++ /dev/null @@ -1,99 +0,0 @@ --- Initialize authentication database -PRAGMA foreign_keys = ON; - --- Users table (single user system) -CREATE TABLE IF NOT EXISTS users ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - username TEXT UNIQUE NOT NULL, - password_hash TEXT NOT NULL, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - last_login DATETIME, - is_active BOOLEAN DEFAULT 1, - git_name TEXT, - git_email TEXT, - has_completed_onboarding BOOLEAN DEFAULT 0 -); - --- Indexes for performance -CREATE INDEX IF NOT EXISTS idx_users_username ON users(username); -CREATE INDEX IF NOT EXISTS idx_users_active ON users(is_active); - --- API Keys table for external API access -CREATE TABLE IF NOT EXISTS api_keys ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - user_id INTEGER NOT NULL, - key_name TEXT NOT NULL, - api_key TEXT UNIQUE NOT NULL, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - last_used DATETIME, - is_active BOOLEAN DEFAULT 1, - FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE -); - -CREATE INDEX IF NOT EXISTS idx_api_keys_key ON api_keys(api_key); -CREATE INDEX IF NOT EXISTS idx_api_keys_user_id ON api_keys(user_id); -CREATE INDEX IF NOT EXISTS idx_api_keys_active ON api_keys(is_active); - --- User credentials table for storing various tokens/credentials (GitHub, GitLab, etc.) -CREATE TABLE IF NOT EXISTS user_credentials ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - user_id INTEGER NOT NULL, - credential_name TEXT NOT NULL, - credential_type TEXT NOT NULL, -- 'github_token', 'gitlab_token', 'bitbucket_token', etc. - credential_value TEXT NOT NULL, - description TEXT, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - is_active BOOLEAN DEFAULT 1, - FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE -); - -CREATE INDEX IF NOT EXISTS idx_user_credentials_user_id ON user_credentials(user_id); -CREATE INDEX IF NOT EXISTS idx_user_credentials_type ON user_credentials(credential_type); -CREATE INDEX IF NOT EXISTS idx_user_credentials_active ON user_credentials(is_active); - --- User notification preferences (backend-owned, provider-agnostic) -CREATE TABLE IF NOT EXISTS user_notification_preferences ( - user_id INTEGER PRIMARY KEY, - preferences_json TEXT NOT NULL, - updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE -); - --- VAPID key pair for Web Push notifications -CREATE TABLE IF NOT EXISTS vapid_keys ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - public_key TEXT NOT NULL, - private_key TEXT NOT NULL, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP -); - --- Browser push subscriptions -CREATE TABLE IF NOT EXISTS push_subscriptions ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - user_id INTEGER NOT NULL, - endpoint TEXT NOT NULL UNIQUE, - keys_p256dh TEXT NOT NULL, - keys_auth TEXT NOT NULL, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE -); - --- Session custom names (provider-agnostic display name overrides) -CREATE TABLE IF NOT EXISTS session_names ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - session_id TEXT NOT NULL, - provider TEXT NOT NULL DEFAULT 'claude', - custom_name TEXT NOT NULL, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, - UNIQUE(session_id, provider) -); - -CREATE INDEX IF NOT EXISTS idx_session_names_lookup ON session_names(session_id, provider); - --- App configuration table (auto-generated secrets, settings, etc.) -CREATE TABLE IF NOT EXISTS app_config ( - key TEXT PRIMARY KEY, - value TEXT NOT NULL, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP -); diff --git a/server/database/schema.js b/server/database/schema.js new file mode 100644 index 00000000..21c1b8eb --- /dev/null +++ b/server/database/schema.js @@ -0,0 +1,102 @@ +export const APP_CONFIG_TABLE_SQL = `CREATE TABLE IF NOT EXISTS app_config ( + key TEXT PRIMARY KEY, + value TEXT NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +);`; + +export const USER_NOTIFICATION_PREFERENCES_TABLE_SQL = `CREATE TABLE IF NOT EXISTS user_notification_preferences ( + user_id INTEGER PRIMARY KEY, + preferences_json TEXT NOT NULL, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE +);`; + +export const VAPID_KEYS_TABLE_SQL = `CREATE TABLE IF NOT EXISTS vapid_keys ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + public_key TEXT NOT NULL, + private_key TEXT NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +);`; + +export const PUSH_SUBSCRIPTIONS_TABLE_SQL = `CREATE TABLE IF NOT EXISTS push_subscriptions ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + user_id INTEGER NOT NULL, + endpoint TEXT NOT NULL UNIQUE, + keys_p256dh TEXT NOT NULL, + keys_auth TEXT NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE +);`; + +export const SESSION_NAMES_TABLE_SQL = `CREATE TABLE IF NOT EXISTS session_names ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + session_id TEXT NOT NULL, + provider TEXT NOT NULL DEFAULT 'claude', + custom_name TEXT NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, + UNIQUE(session_id, provider) +);`; + +export const SESSION_NAMES_LOOKUP_INDEX_SQL = `CREATE INDEX IF NOT EXISTS idx_session_names_lookup ON session_names(session_id, provider);`; + +export const DATABASE_SCHEMA_SQL = `PRAGMA foreign_keys = ON; + +CREATE TABLE IF NOT EXISTS users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT UNIQUE NOT NULL, + password_hash TEXT NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + last_login DATETIME, + is_active BOOLEAN DEFAULT 1, + git_name TEXT, + git_email TEXT, + has_completed_onboarding BOOLEAN DEFAULT 0 +); + +CREATE INDEX IF NOT EXISTS idx_users_username ON users(username); +CREATE INDEX IF NOT EXISTS idx_users_active ON users(is_active); + +CREATE TABLE IF NOT EXISTS api_keys ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + user_id INTEGER NOT NULL, + key_name TEXT NOT NULL, + api_key TEXT UNIQUE NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + last_used DATETIME, + is_active BOOLEAN DEFAULT 1, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE +); + +CREATE INDEX IF NOT EXISTS idx_api_keys_key ON api_keys(api_key); +CREATE INDEX IF NOT EXISTS idx_api_keys_user_id ON api_keys(user_id); +CREATE INDEX IF NOT EXISTS idx_api_keys_active ON api_keys(is_active); + +CREATE TABLE IF NOT EXISTS user_credentials ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + user_id INTEGER NOT NULL, + credential_name TEXT NOT NULL, + credential_type TEXT NOT NULL, + credential_value TEXT NOT NULL, + description TEXT, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + is_active BOOLEAN DEFAULT 1, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE +); + +CREATE INDEX IF NOT EXISTS idx_user_credentials_user_id ON user_credentials(user_id); +CREATE INDEX IF NOT EXISTS idx_user_credentials_type ON user_credentials(credential_type); +CREATE INDEX IF NOT EXISTS idx_user_credentials_active ON user_credentials(is_active); + +${USER_NOTIFICATION_PREFERENCES_TABLE_SQL} + +${VAPID_KEYS_TABLE_SQL} + +${PUSH_SUBSCRIPTIONS_TABLE_SQL} + +${SESSION_NAMES_TABLE_SQL} + +${SESSION_NAMES_LOOKUP_INDEX_SQL} + +${APP_CONFIG_TABLE_SQL} +`;