-- Admin auth + audit for the management console. -- -- Separate from the seed's two existing tiers on purpose: -- * account.php — community member sessions (public users) -- * ADMIN_TOKEN — machine/privileged bearer token -- The console operator (you) is neither. This is a dedicated single-admin login -- with its own session flag, so the console's blast radius never overlaps with -- public accounts or a shared token. -- -- Passwords are stored as a PHP password_hash() (bcrypt). Set via -- api/cli/set-admin-password.php — never inline, never committed. CREATE TABLE IF NOT EXISTS `cja_admin` ( `admin_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(60) NOT NULL, `password_hash` varchar(255) NOT NULL, `created_at` datetime NOT NULL DEFAULT current_timestamp(), `last_login_at` datetime DEFAULT NULL, PRIMARY KEY (`admin_id`), UNIQUE KEY `uq_cja_admin_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- Every privileged action the console takes, logged. This is the accountability -- backstop for a code-writing agent: what was asked, what was published, -- discarded, or rolled back — with who and when. CREATE TABLE IF NOT EXISTS `cja_admin_log` ( `log_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `actor` varchar(60) NOT NULL DEFAULT 'admin', `action` varchar(60) NOT NULL, -- login, run, preview, publish, discard, rollback, upload `detail` varchar(500) DEFAULT NULL, `ip` varchar(45) DEFAULT NULL, `created_at` datetime NOT NULL DEFAULT current_timestamp(), PRIMARY KEY (`log_id`), KEY `idx_cja_admin_log_feed` (`created_at`), KEY `idx_cja_admin_log_action` (`action`, `created_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;