// frontend/lib/settings/api.ts — 설정: 시스템 스냅샷 + LLM(조회/저장/테스트) + 프로필/토큰/내보내기 import type { LlmConfig, LlmTestResult, LlmUpdate, Me, SystemConfig, TokenCreated, TokenInfo, } from "@/lib/types"; async function ok(r: Response): Promise { if (!r.ok) throw new Error(`${r.status} ${r.statusText}`); return r.json() as Promise; } // 인증 켜짐일 때 세션 쿠키가 함께 가도록 항상 credentials 포함(데모/off 에선 무해). const CREDS: RequestInit = { credentials: "include" }; export const settingsApi = { system: () => fetch("/api/settings/system", { cache: "no-store" }).then((r) => ok(r)), getLlm: () => fetch("/api/settings/llm", { cache: "no-store" }).then((r) => ok(r)), updateLlm: (body: LlmUpdate) => fetch("/api/settings/llm", { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }).then((r) => ok(r)), testLlm: (body: { provider?: string; host?: string; model?: string; api_key?: string }) => fetch("/api/settings/llm/test", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }).then((r) => ok(r)), me: () => fetch("/api/me", { cache: "no-store", ...CREDS }).then((r) => ok(r)), updateProfile: (body: { name?: string; role?: string }) => fetch("/api/me", { method: "PATCH", headers: { "Content-Type": "application/json" }, ...CREDS, body: JSON.stringify(body), }).then((r) => ok(r)), listTokens: () => fetch("/api/me/tokens", { cache: "no-store", ...CREDS }).then((r) => ok(r)), createToken: (name: string) => fetch(`/api/me/tokens?name=${encodeURIComponent(name)}`, { method: "POST", ...CREDS }).then( (r) => ok(r), ), revokeToken: (id: string) => fetch(`/api/me/tokens/${id}`, { method: "DELETE", ...CREDS }).then((r) => ok<{ ok: boolean }>(r), ), exportData: () => fetch("/api/me/export", CREDS).then((r) => { if (!r.ok) throw new Error(`${r.status} ${r.statusText}`); return r.blob(); }), };