Merge remote-tracking branch 'origin/main_laptop_1' into sub_laptop_8
This commit is contained in:
@@ -0,0 +1 @@
|
||||
_data/
|
||||
@@ -0,0 +1,108 @@
|
||||
/* =============================================================================
|
||||
* M01_SL_Api.ts
|
||||
* 시트 로직 Api — 목록 · 열기 · 저장(서버가 바깥 값을 다시 넣고 같은 엔진으로 다시 셈) · 지우기 ·
|
||||
* 바깥 값 한 번에 받기(품셈 표 · 노임 · 자재 · 장비 · 기존 로직 결과)
|
||||
* 서버 = `M01_SL_Router.py`(`/api/m01/sl/*`) · 정함 `docs/raw/M01_쉬운단가/시트로직_정함.md` 4 · 5 · 6
|
||||
* ========================================================================== */
|
||||
|
||||
import type { Workbook } from "../../A00_Common/spreadsheet/spreadsheet_types";
|
||||
|
||||
/** 바깥 값 하나 — 값은 열 때 · 저장 때 마스터에서 새로(표는 사본으로 들고 있지 않음)
|
||||
* · 표 = 품셈 표 통째(머리 줄 + 줄 · 범위 조건 · 값은 「이름·아래」 「이름·위」 두 칸)
|
||||
* · 노임 · 자재 = 그 줄의 단가(`/calc` 와 같은 셈 · 준용 · 낮은 값)
|
||||
* · 장비 = 기계경비 로직 부름 글(EasyCalc `machineElement` 의 element) + 넘길 입력값 → 한 시간 값
|
||||
* · 로직 = 기존 로직 결과(`/calc` · 돈 로직은 `field` 비목 · 기본 계) */
|
||||
export type SlOutside =
|
||||
| { id: string; kind: "표"; table: string }
|
||||
| { id: string; kind: "노임"; key: string }
|
||||
| { id: string; kind: "자재"; key: string }
|
||||
| {
|
||||
id: string;
|
||||
kind: "장비";
|
||||
element: string;
|
||||
inputs: Record<string, unknown>;
|
||||
field?: SlField;
|
||||
}
|
||||
| {
|
||||
id: string;
|
||||
kind: "로직";
|
||||
key: string;
|
||||
inputs: Record<string, unknown>;
|
||||
field?: SlField;
|
||||
};
|
||||
export type SlField = "노무비" | "재료비" | "경비" | "계";
|
||||
|
||||
/** 바깥 값이 들어갈 자리 — 시트 id · 칸(표는 이 칸을 왼쪽 위로 펼침) */
|
||||
export interface SlOutsideAt {
|
||||
item: SlOutside;
|
||||
sheet: string;
|
||||
cell: string;
|
||||
}
|
||||
|
||||
/** 바깥 값 답 — 표는 `rows`(머리 줄 포함) · 그 밖은 `value` · 못 구하면 ok false + 쉬운 말 */
|
||||
export interface SlOutsideValue {
|
||||
id: string;
|
||||
ok: boolean;
|
||||
value?: number | null;
|
||||
rows?: (string | number | null)[][];
|
||||
name?: string;
|
||||
unit?: string;
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
/** 시트 로직 한 벌 = 통합문서 하나(상자 = 시트) + 바깥 값 자리 */
|
||||
export interface SlLogic {
|
||||
/** 새 로직 null · 저장하면 서버가 `SL-0001` 꼴로 줌 */
|
||||
key: string | null;
|
||||
이름: string;
|
||||
결과단위: string;
|
||||
book: Workbook;
|
||||
outside: SlOutsideAt[];
|
||||
/** 다른 창이 더하는 칸(상자 · 알약 · 선 …)은 그대로 저장 · 돌려줌 */
|
||||
[extra: string]: unknown;
|
||||
}
|
||||
|
||||
/** 목록 한 줄 */
|
||||
export interface SlListItem {
|
||||
key: string;
|
||||
이름: string;
|
||||
결과단위: string;
|
||||
/** 마지막 저장 때(ISO) */
|
||||
saved: string;
|
||||
}
|
||||
|
||||
/** 저장 답 — `logic.book.계산값` 은 서버가 다시 셈한 값 · `values` 는 넣은 바깥 값 */
|
||||
export interface SlSaved {
|
||||
key: string;
|
||||
logic: SlLogic;
|
||||
values: SlOutsideValue[];
|
||||
}
|
||||
|
||||
const notReady = (): never => {
|
||||
throw new Error("준비 중");
|
||||
};
|
||||
|
||||
export async function slList(): Promise<SlListItem[]> {
|
||||
return notReady();
|
||||
}
|
||||
|
||||
export async function slGet(_key: string): Promise<SlLogic> {
|
||||
return notReady();
|
||||
}
|
||||
|
||||
export async function slSave(_logic: SlLogic): Promise<SlSaved> {
|
||||
return notReady();
|
||||
}
|
||||
|
||||
export async function slDelete(_key: string): Promise<void> {
|
||||
return notReady();
|
||||
}
|
||||
|
||||
export async function slOutside(_items: SlOutside[]): Promise<SlOutsideValue[]> {
|
||||
return notReady();
|
||||
}
|
||||
|
||||
/** 실패 → 쉬운 말(EasyCalc `plainError` 그대로) */
|
||||
export function slPlain(_e: unknown): string {
|
||||
return notReady();
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/* =============================================================================
|
||||
* M01_SL_Eval.ts
|
||||
* 시트 로직 화면 계산 — 바깥 값 넣기 → 우리 스프레드시트 엔진(브라우저) → 출력 알약 · 결과 읽기 · 검사
|
||||
* 저장 때는 서버가 같은 엔진을 Node 로(정함 5) · DOM 없음
|
||||
* ========================================================================== */
|
||||
|
||||
import type { SheetLogic, SlOutside } from "./M01_SL_Model";
|
||||
|
||||
/** 알약 값 — 수 · 글 · 참거짓 · 빈 칸 */
|
||||
export type SlValue = number | string | boolean | null;
|
||||
|
||||
/** 바깥 값 하나 — 표는 칸 덩어리(cell 이 왼위) */
|
||||
export interface SlOutsideValue {
|
||||
node: string;
|
||||
cell: string;
|
||||
value: SlValue | SlValue[][];
|
||||
}
|
||||
|
||||
export interface SlEvalResult {
|
||||
/** 상자 id → 출력 알약 이름 → 값 */
|
||||
pills: Record<string, Record<string, SlValue>>;
|
||||
result: { 노무비: number | null; 재료비: number | null; 경비: number | null; 계: number | null };
|
||||
/** 쉬운 말 */
|
||||
errors: string[];
|
||||
}
|
||||
|
||||
const notReady = (): never => {
|
||||
throw new Error("준비 중");
|
||||
};
|
||||
|
||||
/** 바깥 값 칸 목록 — 화면 · 서버가 이 칸에 값을 넣음 */
|
||||
export function outsideCells(_sl: SheetLogic): SlOutside[] {
|
||||
return notReady();
|
||||
}
|
||||
|
||||
/** 바깥 값 넣기 — 새 시트 로직(받은 것은 안 바꿈) */
|
||||
export function applyOutside(_sl: SheetLogic, _values: SlOutsideValue[]): SheetLogic {
|
||||
return notReady();
|
||||
}
|
||||
|
||||
/** 화면 계산 */
|
||||
export function evalLogic(_sl: SheetLogic): SlEvalResult {
|
||||
return notReady();
|
||||
}
|
||||
|
||||
/** 검사 — 빈 입력 알약 · 순환 · 오류 칸(쉬운 말 목록) */
|
||||
export function checkLogic(_sl: SheetLogic): string[] {
|
||||
return notReady();
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/* =============================================================================
|
||||
* M01_SL_Model.ts
|
||||
* 시트 로직 Model — 로직 한 벌 = 통합문서 하나 · 상자 하나 = 시트 하나 · 알약 = 이름 붙은 칸
|
||||
* 선 = 받는 입력 알약 칸에 「'시트 이름'!칸」 참조 수식 · DOM 없음
|
||||
* 모양은 `docs/raw/M01_쉬운단가/시트로직_정함.md` 정함 1~5 그대로
|
||||
* ========================================================================== */
|
||||
|
||||
import type { Workbook } from "../../A00_Common/spreadsheet/spreadsheet_types";
|
||||
|
||||
/** 상자 종류 — 입력값 · 고정값 · 표 · 계산 · 항목 · 다른 로직 · 결과 */
|
||||
export type SlKind = "input" | "const" | "table" | "calc" | "item" | "logic" | "result";
|
||||
|
||||
/** 알약 = 이름 붙은 칸 */
|
||||
export interface SlPill {
|
||||
name: string;
|
||||
/** 「B3」 */
|
||||
cell: string;
|
||||
unit?: string;
|
||||
/** 바깥 값 칸 — 열 때 · 저장 때 마스터에서 넣음 */
|
||||
outside?: boolean;
|
||||
}
|
||||
|
||||
/** 상자 = 시트 하나 */
|
||||
export interface SlNode {
|
||||
id: string;
|
||||
kind: SlKind;
|
||||
name: string;
|
||||
sheetId: string;
|
||||
pillsIn: SlPill[];
|
||||
pillsOut: SlPill[];
|
||||
/** 표 키 · 요소 · 기존 로직 키 · 내 표 id */
|
||||
ref?: string;
|
||||
/** 띠 단계 — 0 입력값 · 1 표 · 2 계산 · 3 항목 · 4 결과 */
|
||||
stage: number;
|
||||
}
|
||||
|
||||
/** 선 — 출력 알약 → 입력 알약 */
|
||||
export interface SlEdge {
|
||||
id: string;
|
||||
from: { node: string; pill: string };
|
||||
to: { node: string; pill: string };
|
||||
}
|
||||
|
||||
/** 바깥 값 칸 */
|
||||
export interface SlOutside {
|
||||
node: string;
|
||||
cell: string;
|
||||
kind: "table" | "price" | "logic";
|
||||
ref: string;
|
||||
}
|
||||
|
||||
/** 내 표 — 품셈에 없는 표(사용자가 만듦) */
|
||||
export interface SlUserTable {
|
||||
id: string;
|
||||
name: string;
|
||||
cols: string[];
|
||||
rows: (number | string | null)[][];
|
||||
}
|
||||
|
||||
export interface SheetLogic {
|
||||
key: string | null;
|
||||
name: string;
|
||||
resultUnit: string;
|
||||
workbook: Workbook;
|
||||
nodes: SlNode[];
|
||||
edges: SlEdge[];
|
||||
userTables?: SlUserTable[];
|
||||
}
|
||||
|
||||
/** 알약 한쪽 끝 */
|
||||
export interface SlEnd {
|
||||
node: string;
|
||||
pill: string;
|
||||
}
|
||||
|
||||
const notReady = (): never => {
|
||||
throw new Error("준비 중");
|
||||
};
|
||||
|
||||
/** 빈 시트 로직 */
|
||||
export function newLogic(_name?: string, _resultUnit?: string): SheetLogic {
|
||||
return notReady();
|
||||
}
|
||||
|
||||
/** 상자 더하기 — 그 종류 틀(칸 A 이름 · B 값 · C 설명)로 시트를 만듦 */
|
||||
export function addNode(
|
||||
_sl: SheetLogic,
|
||||
_kind: SlKind,
|
||||
_name: string,
|
||||
): { sl: SheetLogic; node: SlNode } {
|
||||
return notReady();
|
||||
}
|
||||
|
||||
/** 상자 지우기 — 시트 · 이어진 선 · 받던 참조 수식을 함께 지움 */
|
||||
export function removeNode(_sl: SheetLogic, _node: string): SheetLogic {
|
||||
return notReady();
|
||||
}
|
||||
|
||||
/** 선 잇기 — 받는 알약 칸에 참조 수식 · 순환 · 없는 알약이면 막고 까닭(쉬운 말) */
|
||||
export function connect(
|
||||
_sl: SheetLogic,
|
||||
_from: SlEnd,
|
||||
_to: SlEnd,
|
||||
): { sl: SheetLogic; why: string | null } {
|
||||
return notReady();
|
||||
}
|
||||
|
||||
/** 선 끊기 — 그 참조를 받는 칸 수식에서 뺌 */
|
||||
export function disconnect(_sl: SheetLogic, _edge: string): SheetLogic {
|
||||
return notReady();
|
||||
}
|
||||
|
||||
/** 알약 정하기 — 같은 칸이나 같은 이름이 있으면 바꿈 */
|
||||
export function setPill(
|
||||
_sl: SheetLogic,
|
||||
_node: string,
|
||||
_cell: string,
|
||||
_dir: "in" | "out",
|
||||
_name: string,
|
||||
_extra?: Pick<SlPill, "unit" | "outside">,
|
||||
): SheetLogic {
|
||||
return notReady();
|
||||
}
|
||||
|
||||
/** 알약 빼기 — 이어진 선도 끊음 */
|
||||
export function removePill(
|
||||
_sl: SheetLogic,
|
||||
_node: string,
|
||||
_dir: "in" | "out",
|
||||
_name: string,
|
||||
): SheetLogic {
|
||||
return notReady();
|
||||
}
|
||||
Reference in New Issue
Block a user