$fields Snapshot or before/after payload. */ public function log(int $campaignId, string $action, array $fields, string $username): void { $this->database->execute( "INSERT INTO campaign_audit (id, action, fields, username) VALUES (:id, :action, :fields, :username)", [ 'id' => $campaignId, 'action' => $action, 'fields' => json_encode($fields, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), 'username' => $username, ] ); } /** * All audit entries for one campaign, oldest first. * * @return list> */ public function forRecord(int $campaignId): array { return $this->database->query( 'SELECT audit_id, id, action, fields, username, created_at FROM campaign_audit WHERE id = :id ORDER BY audit_id ASC', ['id' => $campaignId] ); } /** * Most recent audit entries across all campaigns. * * @return list> */ public function recent(int $limit = 50): array { $limit = max(1, $limit); return $this->database->query( "SELECT TOP ({$limit}) audit_id, id, action, fields, username, created_at FROM campaign_audit ORDER BY audit_id DESC" ); } }