-- Initial schema for Favoritter. -- Creates core tables: users, sessions, signup_requests, faves, tags, fave_tags, site_settings. CREATE TABLE users ( id INTEGER PRIMARY KEY, username TEXT NOT NULL UNIQUE COLLATE NOCASE, display_name TEXT NOT NULL DEFAULT '', bio TEXT NOT NULL DEFAULT '', avatar_path TEXT NOT NULL DEFAULT '', password_hash TEXT NOT NULL, role TEXT NOT NULL DEFAULT 'user' CHECK (role IN ('user', 'admin')), profile_visibility TEXT NOT NULL DEFAULT 'public' CHECK (profile_visibility IN ('public', 'limited')), default_fave_privacy TEXT NOT NULL DEFAULT 'public' CHECK (default_fave_privacy IN ('public', 'private')), must_reset_password INTEGER NOT NULL DEFAULT 0, disabled INTEGER NOT NULL DEFAULT 0, created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')) ); CREATE TABLE sessions ( token TEXT PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, expires_at TEXT NOT NULL, created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')) ); CREATE INDEX idx_sessions_user_id ON sessions(user_id); CREATE INDEX idx_sessions_expires ON sessions(expires_at); CREATE TABLE signup_requests ( id INTEGER PRIMARY KEY, username TEXT NOT NULL UNIQUE COLLATE NOCASE, password_hash TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'approved', 'rejected')), created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), reviewed_at TEXT, reviewed_by INTEGER REFERENCES users(id) ); CREATE TABLE faves ( id INTEGER PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, description TEXT NOT NULL, url TEXT NOT NULL DEFAULT '', image_path TEXT NOT NULL DEFAULT '', privacy TEXT NOT NULL DEFAULT 'public' CHECK (privacy IN ('public', 'private')), created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')) ); CREATE INDEX idx_faves_user_id ON faves(user_id); CREATE INDEX idx_faves_privacy ON faves(privacy); CREATE INDEX idx_faves_created ON faves(created_at); CREATE TABLE tags ( id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE COLLATE NOCASE ); CREATE TABLE fave_tags ( fave_id INTEGER NOT NULL REFERENCES faves(id) ON DELETE CASCADE, tag_id INTEGER NOT NULL REFERENCES tags(id) ON DELETE CASCADE, PRIMARY KEY (fave_id, tag_id) ); CREATE INDEX idx_fave_tags_tag_id ON fave_tags(tag_id); CREATE TABLE site_settings ( id INTEGER PRIMARY KEY CHECK (id = 1), site_name TEXT NOT NULL DEFAULT 'Favoritter', site_description TEXT NOT NULL DEFAULT '', signup_mode TEXT NOT NULL DEFAULT 'open' CHECK (signup_mode IN ('open', 'requests', 'closed')), updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')) ); INSERT INTO site_settings (id) VALUES (1);