/* ============================================================================= * M01_SL_Api.ts * 시트 로직 Api — 목록 · 열기 · 저장(서버가 바깥 값을 다시 넣고 같은 엔진으로 다시 셈) · 지우기 · * 바깥 값 한 번에 받기(품셈 표 · 노임 · 자재 · 장비 · 기존 로직 결과) * 서버 = `M01_SL_Router.py`(`/api/m01/sl/*`) · 정함 `docs/raw/M01_쉬운단가/시트로직_정함.md` 4 · 5 · 6 * ========================================================================== */ import { API_BASE_URL } from "@config/config_frontend"; import { plainError } from "../EasyCalc/M01_EasyCalc_Api"; import { ApiError } from "../M01_MasterData_UI_Logic_Api"; import type { SlOutsideAnswer } from "./M01_SL_Eval"; import type { SheetLogic, SlField, SlSource } from "./M01_SL_Model"; /* 모양 = sub7 Model(SheetLogic · SlSource · SlField) · 답 = Eval(SlOutsideAnswer) · 아래는 Api 몫만. * 저장 때 서버가 바깥 값을 넣는 칸 = ① Model 규칙(알약 outside 참 · 상자 source · 없으면 표 · 로직 ref) * ② 저장 몸의 `outside: SlOutsideAt[]`(Item `itemOutsides` — 장비처럼 칸마다 비목이 다른 것) · 값은 늘 마스터에서. */ export type { SlField }; /** 서버 `/outside` 물음 한 줄 = `{id, ...SlSource}` */ export type SlQuery = { id: string } & SlSource; /** Item 이 쓰는 옛 이름 — `SlQuery` 와 같음(Model `SlOutside` 와 다른 것) */ export type SlOutside = SlQuery; /** 바깥 값 자리 하나 — 시트 id · 칸(표는 이 칸을 왼쪽 위로 펼침) */ export interface SlOutsideAt { item: SlQuery; sheet: string; cell: string; } /** 목록 한 줄 */ export interface SlListItem { key: string; 이름: string; 결과단위: string; /** 마지막 저장 때(ISO) */ saved: string; } /** 저장 답 — `logic.workbook.계산값` 은 서버가 다시 셈한 값 · `values` 는 넣은 바깥 값 */ export interface SlSaved { key: string; logic: SheetLogic; values: SlOutsideAnswer[]; } async function send(path: string, body?: unknown): Promise { let response: Response; try { response = await fetch(`${API_BASE_URL}/m01/sl${path}`, { method: body === undefined ? "GET" : "POST", credentials: "include", headers: { "Content-Type": "application/json" }, body: body === undefined ? undefined : JSON.stringify(body), }); } catch { throw new ApiError(0, ""); } const data = (await response.json().catch(() => ({}))) as { detail?: unknown } & T; if (!response.ok) throw new ApiError(response.status, data.detail ?? response.statusText); return data; } /** 내 시트 로직 목록(저장 차례) */ export async function slList(): Promise { return (await send<{ logics: SlListItem[] }>("/list")).logics; } export async function slGet(key: string): Promise { return (await send<{ logic: SheetLogic }>(`/get?${new URLSearchParams({ key }).toString()}`)) .logic; } /** 저장 — 서버가 바깥 값을 마스터에서 다시 넣고 같은 엔진으로 다시 셈(브라우저 계산값은 버림) */ export async function slSave(logic: SheetLogic & { outside?: SlOutsideAt[] }): Promise { return send("/save", { logic }); } export async function slDelete(key: string): Promise { await send<{ key: string }>("/delete", { key }); } /** 바깥 값 한 번에 — 열 때 · 예시값을 바꿀 때 화면이 받아 시트에 넣음 */ export async function slOutside(items: SlQuery[]): Promise { return (await send<{ values: SlOutsideAnswer[] }>("/outside", { items })).values; } /** 실패 → 쉬운 말(EasyCalc `plainError` 그대로) */ export function slPlain(e: unknown): string { return plainError(e); }