- 저장 몸 = Model SheetLogic(workbook · nodes · edges) · 바깥 값 칸 = Eval outsideCells 규칙(알약 outside · 상자 source · 표 · 로직 ref 짐작 · id 「상자!칸」)
- 몸의 outside: SlOutsideAt[](Item 항목 단가 — 칸마다 비목) 도 받음 · 같은 칸은 그쪽이 이김 · 값은 늘 마스터에서
- /outside 물음 = {id, ...SlSource} · 답 = Eval SlOutsideAnswer · 표 범위 칸 「·아래」 「·위」(Model RANGE_LOW · RANGE_HIGH)
- Api 겹친 타입(SlLogic · SlField · SlOutsideValue) 지우고 Model · Eval 것을 씀 · Item 이 쓰는 SlOutside · SlOutsideAt 는 SlQuery 별칭으로 남김
- 시험 test_m01_sl_router.py 를 Model 모양으로
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmELpdXFDRZHhfbGuRhSmL
93 lines
3.7 KiB
TypeScript
93 lines
3.7 KiB
TypeScript
/* =============================================================================
|
|
* 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<T>(path: string, body?: unknown): Promise<T> {
|
|
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<SlListItem[]> {
|
|
return (await send<{ logics: SlListItem[] }>("/list")).logics;
|
|
}
|
|
|
|
export async function slGet(key: string): Promise<SheetLogic> {
|
|
return (await send<{ logic: SheetLogic }>(`/get?${new URLSearchParams({ key }).toString()}`))
|
|
.logic;
|
|
}
|
|
|
|
/** 저장 — 서버가 바깥 값을 마스터에서 다시 넣고 같은 엔진으로 다시 셈(브라우저 계산값은 버림) */
|
|
export async function slSave(logic: SheetLogic & { outside?: SlOutsideAt[] }): Promise<SlSaved> {
|
|
return send<SlSaved>("/save", { logic });
|
|
}
|
|
|
|
export async function slDelete(key: string): Promise<void> {
|
|
await send<{ key: string }>("/delete", { key });
|
|
}
|
|
|
|
/** 바깥 값 한 번에 — 열 때 · 예시값을 바꿀 때 화면이 받아 시트에 넣음 */
|
|
export async function slOutside(items: SlQuery[]): Promise<SlOutsideAnswer[]> {
|
|
return (await send<{ values: SlOutsideAnswer[] }>("/outside", { items })).values;
|
|
}
|
|
|
|
/** 실패 → 쉬운 말(EasyCalc `plainError` 그대로) */
|
|
export function slPlain(e: unknown): string {
|
|
return plainError(e);
|
|
}
|