<?php declare(strict_types=1); if (!defined('DASHBOARD_ROOT')) { http_response_code(403); exit('Direct access denied.'); } class Events { const CAT_CREATE = 1; const CAT_MODIFY = 2; const CAT_DELETE = 3; const CAT_VERIFY = 4; const CAT_READ = 5; const CAT_AUTH = 6; const CAT_SYSTEM = 7; const CAT_FLEET = 8; const CAT_SECURITY = 9; const CAT_LABELS = [ 1 => 'create', 2 => 'modify', 3 => 'delete', 4 => 'verify', 5 => 'read', 6 => 'auth', 7 => 'system', 8 => 'fleet', 9 => 'security', ]; public static function record( int $category, string $action, ?string $targetType = null, ?int $targetId = null, array $meta = [], ?int $adminId = null ): int { $adminId = $adminId ?? ($_SESSION['admin_id'] ?? null); return Database::insert( "INSERT INTO events (category, action, target_type, target_id, admin_id, meta, ip_address, created_at)              VALUES (:cat, :act, :tt, :tid, :aid, :meta, :ip, NOW())", [ ':cat' => $category, ':act' => $action, ':tt' => $targetType, ':tid' => $targetId, ':aid' => $adminId, ':meta' => json_encode($meta, JSON_UNESCAPED_UNICODE), ':ip' => $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0', ] ); } public static function since(int $lastId, int $limit = 50): array { $limit = (int)$limit; return Database::fetchAll( "SELECT id, category, action, target_type, target_id, admin_id, meta, created_at              FROM events WHERE id > :last ORDER BY id ASC LIMIT $limit", [':last' => $lastId] ); } public static function byCategory(int $category, int $limit = 100, int $offset = 0): array { $limit = (int)$limit; $offset = (int)$offset; return Database::fetchAll( "SELECT id, category, action, target_type, target_id, admin_id, ip_address, created_at              FROM events WHERE category = :cat ORDER BY id DESC LIMIT $limit OFFSET $offset", [':cat' => $category] ); } } 