|null */ public function findById(int $id): ?array; /** * @return array> */ public function findLatest(int $limit = 20): array; /** * @return array> */ public function findPaginated( ?string $search = null, ?string $status = null, ?string $model = null, int $limit = 50, int $offset = 0 ): array; public function countFiltered(?string $search = null, ?string $status = null, ?string $model = null): int; /** * @return array */ public function getStatistics(): array; /** * @return array */ public function getDistinctModels(): array; public function findPreviousId(int $id): ?int; public function findNextId(int $id): ?int; /** * Insert new protokoll entry with status 'pending'. * Sets request_timestamp = NOW(6). * * @return int The inserted ID */ public function insert( string $clientName, string $request, string $model, string $requestIp ): int; /** * Complete a pending protokoll entry with response data. * Sets response_timestamp = NOW(6), calculates tokens_total. */ public function complete( int $id, string $response, int $durationMs, ?int $tokensInput, ?int $tokensOutput ): void; /** * Mark a protokoll entry as failed with error message. */ public function fail(int $id, string $errorMessage): void; /** * Mark stale 'pending' entries as 'error'. * * @param int $minutesOld Age threshold in minutes (default: 10) * @return int Number of affected rows */ public function cleanupStale(int $minutesOld = 10): int; }