send('post', '/users', $payload, $settings); } public function rotateUser(string $username, array $payload = [], ?PhotoboothSetting $settings = null): array { return $this->send('post', "/users/{$username}/rotate", $payload, $settings); } public function deleteUser(string $username, ?PhotoboothSetting $settings = null): array { return $this->send('delete', "/users/{$username}", [], $settings); } public function syncConfig(array $payload, ?PhotoboothSetting $settings = null): array { return $this->send('post', '/config', $payload, $settings); } protected function send(string $method, string $path, array $payload = [], ?PhotoboothSetting $settings = null): array { $response = $this->request($settings)->{$method}($path, $payload); if ($response->failed()) { $message = sprintf('Photobooth control request failed for %s', $path); Log::error($message, [ 'path' => $path, 'payload' => Arr::except($payload, ['password']), 'status' => $response->status(), 'body' => $response->json() ?? $response->body(), ]); throw new RequestException($response); } return $response->json() ?? []; } protected function request(?PhotoboothSetting $settings = null): PendingRequest { $settings ??= PhotoboothSetting::current(); $baseUrl = $settings->control_service_base_url ?? config('photobooth.control_service.base_url'); $token = config('photobooth.control_service.token'); if (! $baseUrl || ! $token) { throw new RuntimeException('Photobooth control service is not configured.'); } $timeout = config('photobooth.control_service.timeout', 5); return $this->httpFactory ->baseUrl($baseUrl) ->timeout($timeout) ->withToken($token) ->acceptJson(); } }