CREATE TABLE IF NOT EXISTS qipai_admin_credentials ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, tenant_id BIGINT UNSIGNED NOT NULL, user_id BIGINT UNSIGNED NOT NULL, login_name VARCHAR(64) NOT NULL, password_hash VARCHAR(255) NOT NULL, status VARCHAR(32) NOT NULL DEFAULT 'ACTIVE', failed_attempts INT UNSIGNED NOT NULL DEFAULT 0, locked_until DATETIME(3) NULL, password_changed_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), last_login_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), deleted_at DATETIME(3) NULL, CONSTRAINT fk_qipai_admin_credentials_tenant FOREIGN KEY (tenant_id) REFERENCES qipai_tenants(id), CONSTRAINT fk_qipai_admin_credentials_user FOREIGN KEY (user_id) REFERENCES qipai_users(id), UNIQUE KEY uq_qipai_admin_credentials_login (tenant_id, login_name), UNIQUE KEY uq_qipai_admin_credentials_user (tenant_id, user_id), KEY idx_qipai_admin_credentials_status (tenant_id, status, locked_until) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ALTER TABLE qipai_auth_sessions ADD COLUMN refresh_token_hash CHAR(64) NULL AFTER role_version, ADD COLUMN refresh_expires_at DATETIME(3) NULL AFTER expires_at, ADD KEY idx_qipai_auth_sessions_refresh (status, refresh_expires_at); INSERT IGNORE INTO qipai_schema_migrations (version, name) VALUES ('2026081004', 'm08d_admin_password_auth');