ordered() ->get(); } /** * 즐겨찾기 추가 */ public function addBookmark(int $userId, array $data): ApiBookmark { $maxOrder = ApiBookmark::where('user_id', $userId)->max('display_order') ?? 0; return ApiBookmark::create([ 'user_id' => $userId, 'endpoint' => $data['endpoint'], 'method' => strtoupper($data['method']), 'display_name' => $data['display_name'] ?? null, 'display_order' => $maxOrder + 1, 'color' => $data['color'] ?? null, ]); } /** * 즐겨찾기 제거 */ public function removeBookmark(int $bookmarkId): void { ApiBookmark::where('id', $bookmarkId)->delete(); } /** * 즐겨찾기 수정 */ public function updateBookmark(int $bookmarkId, array $data): ?ApiBookmark { $bookmark = ApiBookmark::find($bookmarkId); if (! $bookmark) { return null; } if (isset($data['display_name'])) { $bookmark->display_name = $data['display_name']; } $bookmark->save(); return $bookmark; } /** * 즐겨찾기 순서 변경 */ public function reorderBookmarks(int $userId, array $order): void { foreach ($order as $index => $id) { ApiBookmark::where('id', $id) ->where('user_id', $userId) ->update(['display_order' => $index]); } } /** * 즐겨찾기 여부 확인 */ public function isBookmarked(int $userId, string $endpoint, string $method): bool { return ApiBookmark::where('user_id', $userId) ->where('endpoint', $endpoint) ->where('method', strtoupper($method)) ->exists(); } /** * 즐겨찾기 토글 */ public function toggleBookmark(int $userId, array $data): array { $existing = ApiBookmark::where('user_id', $userId) ->where('endpoint', $data['endpoint']) ->where('method', strtoupper($data['method'])) ->first(); if ($existing) { $existing->delete(); return ['action' => 'removed', 'bookmark' => null]; } $bookmark = $this->addBookmark($userId, $data); return ['action' => 'added', 'bookmark' => $bookmark]; } /* |-------------------------------------------------------------------------- | Template Operations |-------------------------------------------------------------------------- */ /** * 템플릿 목록 조회 */ public function getTemplates(int $userId, ?string $endpoint = null, ?string $method = null): Collection { $query = ApiTemplate::where(function ($q) use ($userId) { $q->where('user_id', $userId) ->orWhere('is_shared', true); }); if ($endpoint) { $query->where('endpoint', $endpoint); } if ($method) { $query->where('method', strtoupper($method)); } return $query->orderBy('name')->get(); } /** * 템플릿 저장 */ public function saveTemplate(int $userId, array $data): ApiTemplate { return ApiTemplate::create([ 'user_id' => $userId, 'endpoint' => $data['endpoint'], 'method' => strtoupper($data['method']), 'name' => $data['name'], 'description' => $data['description'] ?? null, 'headers' => $data['headers'] ?? null, 'path_params' => $data['path_params'] ?? null, 'query_params' => $data['query_params'] ?? null, 'body' => $data['body'] ?? null, 'is_shared' => $data['is_shared'] ?? false, ]); } /** * 템플릿 수정 */ public function updateTemplate(int $templateId, array $data): ApiTemplate { $template = ApiTemplate::findOrFail($templateId); $template->update([ 'name' => $data['name'] ?? $template->name, 'description' => $data['description'] ?? $template->description, 'headers' => $data['headers'] ?? $template->headers, 'path_params' => $data['path_params'] ?? $template->path_params, 'query_params' => $data['query_params'] ?? $template->query_params, 'body' => $data['body'] ?? $template->body, 'is_shared' => $data['is_shared'] ?? $template->is_shared, ]); return $template->fresh(); } /** * 템플릿 삭제 */ public function deleteTemplate(int $templateId): void { ApiTemplate::where('id', $templateId)->delete(); } /* |-------------------------------------------------------------------------- | History Operations |-------------------------------------------------------------------------- */ /** * 요청 기록 저장 */ public function logRequest(int $userId, array $data): ApiHistory { // 최대 개수 초과 시 오래된 것 삭제 $maxEntries = config('api-explorer.history.max_entries', 100); $count = ApiHistory::where('user_id', $userId)->count(); if ($count >= $maxEntries) { $deleteCount = $count - $maxEntries + 1; ApiHistory::where('user_id', $userId) ->oldest('created_at') ->limit($deleteCount) ->delete(); } return ApiHistory::create([ 'user_id' => $userId, 'endpoint' => $data['endpoint'], 'method' => strtoupper($data['method']), 'request_headers' => $data['request_headers'] ?? null, 'request_body' => $data['request_body'] ?? null, 'response_status' => $data['response_status'], 'response_headers' => $data['response_headers'] ?? null, 'response_body' => $data['response_body'] ?? null, 'duration_ms' => $data['duration_ms'], 'environment' => $data['environment'], ]); } /** * 히스토리 조회 */ public function getHistory(int $userId, int $limit = 50): Collection { return ApiHistory::where('user_id', $userId) ->latest('created_at') ->limit($limit) ->get(); } /** * 히스토리 삭제 */ public function clearHistory(int $userId): int { return ApiHistory::where('user_id', $userId)->delete(); } /** * 단일 히스토리 조회 */ public function getHistoryItem(int $historyId): ?ApiHistory { return ApiHistory::find($historyId); } /* |-------------------------------------------------------------------------- | Environment Operations |-------------------------------------------------------------------------- */ /** * 환경 목록 조회 */ public function getEnvironments(int $userId): Collection { return ApiEnvironment::where('user_id', $userId) ->orderBy('is_default', 'desc') ->orderBy('name') ->get(); } /** * 환경 저장 */ public function saveEnvironment(int $userId, array $data): ApiEnvironment { // 기본 환경으로 설정 시 기존 기본 해제 if ($data['is_default'] ?? false) { ApiEnvironment::where('user_id', $userId) ->update(['is_default' => false]); } return ApiEnvironment::create([ 'user_id' => $userId, 'name' => $data['name'], 'base_url' => $data['base_url'], 'api_key' => $data['api_key'] ?? null, 'auth_token' => $data['auth_token'] ?? null, 'variables' => $data['variables'] ?? null, 'is_default' => $data['is_default'] ?? false, ]); } /** * 환경 수정 */ public function updateEnvironment(int $environmentId, array $data): ApiEnvironment { $environment = ApiEnvironment::findOrFail($environmentId); // 기본 환경으로 설정 시 기존 기본 해제 if ($data['is_default'] ?? false) { ApiEnvironment::where('user_id', $environment->user_id) ->where('id', '!=', $environmentId) ->update(['is_default' => false]); } $environment->update($data); return $environment->fresh(); } /** * 환경 삭제 */ public function deleteEnvironment(int $environmentId): void { ApiEnvironment::where('id', $environmentId)->delete(); } /** * 기본 환경 설정 */ public function setDefaultEnvironment(int $userId, int $environmentId): void { // 기존 기본 해제 ApiEnvironment::where('user_id', $userId) ->update(['is_default' => false]); // 새 기본 설정 ApiEnvironment::where('id', $environmentId) ->where('user_id', $userId) ->update(['is_default' => true]); } /** * 기본 환경 조회 */ public function getDefaultEnvironment(int $userId): ?ApiEnvironment { return ApiEnvironment::where('user_id', $userId) ->where('is_default', true) ->first(); } /** * 기본 환경 초기화 (설정된 환경이 없는 경우) */ public function initializeDefaultEnvironments(int $userId): void { $count = ApiEnvironment::where('user_id', $userId)->count(); if ($count > 0) { return; } $defaults = config('api-explorer.default_environments', []); foreach ($defaults as $index => $env) { $this->saveEnvironment($userId, [ 'name' => $env['name'], 'base_url' => $env['base_url'], 'api_key' => $env['api_key'] ?? null, 'is_default' => $index === 0, ]); } } }