, api_key: string} */ public function register(string $displayName, string $role): array { if (!in_array($role, self::ROLES, true)) { throw new InvalidArgumentException('Unbekannte Rolle: ' . $role); } $deskIndex = $role === 'user' ? null : $this->findFreeDesk(); $apiKey = ApiKeyGenerator::generate(); $now = $this->db->now(); $stmt = $this->db->pdo()->prepare( 'INSERT INTO agents (display_name, role, api_key_hash, desk_index, state, created_at, last_seen_at) VALUES (:display_name, :role, :api_key_hash, :desk_index, :state, :created_at, :created_at)' ); $stmt->execute([ 'display_name' => $displayName, 'role' => $role, 'api_key_hash' => ApiKeyGenerator::hash($apiKey), 'desk_index' => $deskIndex, 'state' => 'idle', 'created_at' => $now, ]); $agent = $this->findById((int) $this->db->pdo()->lastInsertId()); return ['agent' => $agent, 'api_key' => $apiKey]; } private function findFreeDesk(): ?int { $stmt = $this->db->pdo()->query( 'SELECT desk_index FROM agents WHERE desk_index IS NOT NULL' ); $occupied = array_map('intval', array_column($stmt->fetchAll(), 'desk_index')); for ($i = 0; $i < $this->deskCount; $i++) { if (!in_array($i, $occupied, true)) { return $i; } } return null; } /** @return array|null */ public function findById(int $id): ?array { $stmt = $this->db->pdo()->prepare('SELECT * FROM agents WHERE id = :id'); $stmt->execute(['id' => $id]); $row = $stmt->fetch(); return $row === false ? null : $this->hidingKey($row); } /** @return array|null */ public function findByApiKey(string $apiKey): ?array { $stmt = $this->db->pdo()->prepare('SELECT * FROM agents WHERE api_key_hash = :hash'); $stmt->execute(['hash' => ApiKeyGenerator::hash($apiKey)]); $row = $stmt->fetch(); return $row === false ? null : $this->hidingKey($row); } /** @return array> */ public function all(): array { $stmt = $this->db->pdo()->query('SELECT * FROM agents ORDER BY id ASC'); return array_map(fn (array $row) => $this->hidingKey($row), $stmt->fetchAll()); } /** @return array */ public function updateActivity(int $id, string $state, ?int $currentTicketId): array { $stmt = $this->db->pdo()->prepare( 'UPDATE agents SET state = :state, current_ticket_id = :ticket_id, last_seen_at = :now WHERE id = :id' ); $stmt->execute([ 'state' => $state, 'ticket_id' => $currentTicketId, 'now' => $this->db->now(), 'id' => $id, ]); $agent = $this->findById($id); if ($agent === null) { throw new NotFoundException('Agent nicht gefunden: ' . $id); } return $agent; } /** @param array $row @return array */ private function hidingKey(array $row): array { unset($row['api_key_hash']); return $row; } }