CREATE TABLE IF NOT EXISTS admin_users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL, display_name TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'disabled')), failed_login_count INTEGER NOT NULL DEFAULT 0, locked_until TEXT, last_login_at TEXT, created_at TEXT NOT NULL, updated_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS site_documents ( id INTEGER PRIMARY KEY AUTOINCREMENT, document_key TEXT NOT NULL UNIQUE, draft_json TEXT NOT NULL, published_json TEXT NOT NULL, updated_by INTEGER, updated_at TEXT NOT NULL, published_at TEXT, FOREIGN KEY (updated_by) REFERENCES admin_users(id) ); CREATE TABLE IF NOT EXISTS revisions ( id INTEGER PRIMARY KEY AUTOINCREMENT, entity_type TEXT NOT NULL, entity_key TEXT NOT NULL, version INTEGER NOT NULL, snapshot_json TEXT NOT NULL, operator_id INTEGER, action TEXT NOT NULL, comment TEXT, created_at TEXT NOT NULL, FOREIGN KEY (operator_id) REFERENCES admin_users(id), UNIQUE(entity_type, entity_key, version) ); CREATE TABLE IF NOT EXISTS audit_logs ( id INTEGER PRIMARY KEY AUTOINCREMENT, operator_id INTEGER, action TEXT NOT NULL, entity_type TEXT NOT NULL, entity_key TEXT, ip_address TEXT, metadata_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL, FOREIGN KEY (operator_id) REFERENCES admin_users(id) ); CREATE INDEX IF NOT EXISTS idx_revisions_entity ON revisions(entity_type, entity_key, version DESC); CREATE INDEX IF NOT EXISTS idx_audit_created_at ON audit_logs(created_at DESC);