CREATE TABLE IF NOT EXISTS platform_user ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, username VARCHAR(64) NOT NULL, display_name VARCHAR(96) NOT NULL, password_hash VARCHAR(255) NOT NULL, user_type VARCHAR(24) NOT NULL, status VARCHAR(24) NOT NULL DEFAULT 'enabled', customer_ref VARCHAR(96) NOT NULL DEFAULT '', tenant_ref VARCHAR(96) NOT NULL DEFAULT '', auth_provider VARCHAR(32) NOT NULL DEFAULT 'local', external_subject VARCHAR(128) NULL, failed_login_count 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_by VARCHAR(96) NOT NULL DEFAULT 'system', updated_by VARCHAR(96) NOT NULL DEFAULT 'system', 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), UNIQUE KEY uk_platform_user_username (username), UNIQUE KEY uk_platform_user_external_identity (auth_provider, external_subject), INDEX idx_platform_user_type_status (user_type, status), CONSTRAINT chk_platform_user_type CHECK (user_type IN ('admin', 'customer')), CONSTRAINT chk_platform_user_status CHECK (status IN ('enabled', 'disabled')) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS platform_user_menu ( user_id BIGINT UNSIGNED NOT NULL, menu_key VARCHAR(48) NOT NULL, granted_by VARCHAR(96) NOT NULL, granted_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), PRIMARY KEY (user_id, menu_key), INDEX idx_platform_user_menu_key (menu_key, user_id), CONSTRAINT fk_platform_user_menu_user FOREIGN KEY (user_id) REFERENCES platform_user(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS platform_user_vehicle ( user_id BIGINT UNSIGNED NOT NULL, vin VARCHAR(64) NOT NULL, valid_from DATETIME(3) NULL, valid_to DATETIME(3) NULL, source_system VARCHAR(32) NOT NULL DEFAULT 'manual', external_ref VARCHAR(128) NOT NULL DEFAULT '', granted_by VARCHAR(96) NOT NULL, granted_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), PRIMARY KEY (user_id, vin), INDEX idx_platform_user_vehicle_vin (vin, user_id), CONSTRAINT fk_platform_user_vehicle_user FOREIGN KEY (user_id) REFERENCES platform_user(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS platform_user_session ( id CHAR(32) NOT NULL PRIMARY KEY, user_id BIGINT UNSIGNED NOT NULL, token_hash BINARY(32) NOT NULL, issued_at DATETIME(3) NOT NULL, expires_at DATETIME(3) NOT NULL, last_seen_at DATETIME(3) NOT NULL, revoked_at DATETIME(3) NULL, remote_addr VARCHAR(96) NOT NULL DEFAULT '', user_agent VARCHAR(255) NOT NULL DEFAULT '', UNIQUE KEY uk_platform_session_token (token_hash), INDEX idx_platform_session_user (user_id, expires_at), INDEX idx_platform_session_expiry (expires_at, revoked_at), CONSTRAINT fk_platform_session_user FOREIGN KEY (user_id) REFERENCES platform_user(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS platform_auth_audit ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, actor VARCHAR(96) NOT NULL, action VARCHAR(64) NOT NULL, target_type VARCHAR(32) NOT NULL DEFAULT '', target_id VARCHAR(96) NOT NULL DEFAULT '', result VARCHAR(24) NOT NULL, detail_json JSON NULL, remote_addr VARCHAR(96) NOT NULL DEFAULT '', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), INDEX idx_platform_auth_audit_created (created_at, action), INDEX idx_platform_auth_audit_target (target_type, target_id, created_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;