-- MySQL 8.0. Admin message governance and authentication audit tables. -- Execute this script in each tenant business database. CREATE TABLE IF NOT EXISTS im_user_login_logs ( id BIGINT NOT NULL AUTO_INCREMENT, user_id BIGINT NOT NULL, username VARCHAR(64) NOT NULL DEFAULT '', account_type VARCHAR(24) NOT NULL DEFAULT '', account_hash CHAR(64) NOT NULL DEFAULT '', account_mask VARCHAR(128) NOT NULL DEFAULT '', login_type VARCHAR(24) NOT NULL, event_type VARCHAR(24) NOT NULL DEFAULT 'login', session_id VARCHAR(96) NOT NULL DEFAULT '', device_id VARCHAR(255) NOT NULL DEFAULT '', platform VARCHAR(32) NOT NULL DEFAULT 'unknown', app_version VARCHAR(32) NOT NULL DEFAULT '', ip VARCHAR(64) NOT NULL DEFAULT '', region VARCHAR(128) NOT NULL DEFAULT '', user_agent VARCHAR(512) NOT NULL DEFAULT '', risk_level VARCHAR(16) NOT NULL DEFAULT 'low', request_id VARCHAR(64) NOT NULL DEFAULT '', login_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), logout_at DATETIME(3) NULL, metadata JSON NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), PRIMARY KEY (id), INDEX idx_im_user_login_user_time (user_id, login_at DESC, id DESC), INDEX idx_im_user_login_ip_time (ip, login_at DESC, id DESC), INDEX idx_im_user_login_device_time (device_id(64), login_at DESC), INDEX idx_im_user_login_request (request_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CREATE TABLE IF NOT EXISTS im_login_failure_logs ( id BIGINT NOT NULL AUTO_INCREMENT, user_id BIGINT NULL, account_type VARCHAR(24) NOT NULL DEFAULT '', account_hash CHAR(64) NOT NULL DEFAULT '', account_mask VARCHAR(128) NOT NULL DEFAULT '', failure_type VARCHAR(32) NOT NULL, reason VARCHAR(96) NOT NULL DEFAULT '', detail VARCHAR(500) NOT NULL DEFAULT '', ip VARCHAR(64) NOT NULL DEFAULT '', region VARCHAR(128) NOT NULL DEFAULT '', device_id VARCHAR(255) NOT NULL DEFAULT '', platform VARCHAR(32) NOT NULL DEFAULT 'unknown', app_version VARCHAR(32) NOT NULL DEFAULT '', user_agent VARCHAR(512) NOT NULL DEFAULT '', risk_level VARCHAR(16) NOT NULL DEFAULT 'medium', risk_action VARCHAR(24) NOT NULL DEFAULT 'audit_only', request_id VARCHAR(64) NOT NULL DEFAULT '', attempt_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), metadata JSON NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), PRIMARY KEY (id), INDEX idx_im_login_failure_account_time (account_hash, attempt_at DESC, id DESC), INDEX idx_im_login_failure_user_time (user_id, attempt_at DESC, id DESC), INDEX idx_im_login_failure_ip_time (ip, attempt_at DESC, id DESC), INDEX idx_im_login_failure_type_time (failure_type, attempt_at DESC, id DESC), INDEX idx_im_login_failure_request (request_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CREATE TABLE IF NOT EXISTS im_login_lockouts ( id BIGINT NOT NULL, user_id BIGINT NULL, account_hash CHAR(64) NOT NULL, failed_attempts INT NOT NULL DEFAULT 0, window_started_at DATETIME(3) NULL, locked_until DATETIME(3) NULL, last_attempt_at DATETIME(3) NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), PRIMARY KEY (id), UNIQUE INDEX uk_im_login_lockouts_account (account_hash), INDEX idx_im_login_lockouts_user (user_id), INDEX idx_im_login_lockouts_locked (locked_until) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CREATE TABLE IF NOT EXISTS im_message_admin_actions ( id BIGINT NOT NULL AUTO_INCREMENT, action_id VARCHAR(96) NOT NULL, command_id VARCHAR(96) NOT NULL, conversation_type VARCHAR(16) NOT NULL, topic VARCHAR(64) NOT NULL, seqid BIGINT NOT NULL, sender_user_id BIGINT NULL, action VARCHAR(16) NOT NULL, action_status VARCHAR(16) NOT NULL DEFAULT 'pending', reason VARCHAR(500) NOT NULL DEFAULT '', actor_admin_id BIGINT NOT NULL DEFAULT 0, request_id VARCHAR(64) NOT NULL DEFAULT '', before_snapshot JSON NULL, after_snapshot JSON NULL, failure_reason VARCHAR(96) NOT NULL DEFAULT '', failure_message VARCHAR(1000) NOT NULL DEFAULT '', processed_at DATETIME(3) NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), PRIMARY KEY (id), UNIQUE INDEX uk_im_message_admin_action_id (action_id), UNIQUE INDEX uk_im_message_admin_command (command_id), INDEX idx_im_message_admin_target (conversation_type, topic, seqid, id DESC), INDEX idx_im_message_admin_status (action_status, created_at, id), INDEX idx_im_message_admin_actor (actor_admin_id, created_at DESC) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;