feat(m02-cf): 단가산출 다이어그램 Api 타입 · 함수 머리 · _data 를 git 밖으로

- CfGroup · CfCost · CfQuery · CfValue · CfFill · CfLogic · CfListItem · CfSaved · CfUserElement
- cfList · cfGet · cfSave · cfDelete · cfValues · cfUserElements · cfUserElementAdd · cfUserElementDelete · cfPlain 머리
- CostFlow/.gitignore — _data/

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmELpdXFDRZHhfbGuRhSmL
This commit is contained in:
2026-10-01 16:00:41 +09:00
co-authored by Claude Opus 5.5
parent 66f77cceeb
commit 73fa2e612a
2 changed files with 137 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
_data/
+136
View File
@@ -0,0 +1,136 @@
/* =============================================================================
* M02_CF_Api.ts
* 단가산출 다이어그램 Api — 목록(내 것 + 견본) · 열기 · 저장(서버가 입력 값을 마스터에서 다시 넣고
* 같은 엔진으로 함수 상자 시트를 다시 셈) · 지우기 · 입력 값 한 번에 받기 · 사용자 요소
* 서버 = `M02_CF_Router.py`(`/api/m02/cf/*`) · 정함 `docs/raw/M01_쉬운단가/원가다이어그램_정함.md`
* ========================================================================== */
import type { Workbook } from "../../A00_Common/spreadsheet/spreadsheet_types";
/** 입력 그룹 — M01 저장 그룹 + 사용자 요소 */
export type CfGroup =
"인력" | "재료" | "유가전력" | "기계" | "소요량" | "계수" | "환율" | "요율" | "사용자";
/** 비용 종류 칸 */
export type CfCost = "노무비" | "재료비" | "경비" | "계";
/** 입력 값 물음 한 줄 — 값은 열 때 · 저장 때 마스터(사용자 요소는 `_data`)에서 새로
* · 인력 · 재료 = 그 줄 단가(기존 계산과 같은 셈 · 준용 · 낮은 값) — 재료 key 는 키 또는 검색어 묶음 JSON 글,
* unit(그 줄 단위)을 주면 기존 로직 재료 줄과 같은 단가
* · 유가전력 · 환율 · 요율 · 사용자 = 그 줄 값
* · 기계 = key(EQ…) + field(값 칸 이름 — 가격 · 손료계수 …) 또는 element(기계 시간당 경비 로직 부름 글) + inputs → 한 시간 값
* · 소요량 · 계수 = 표 블록(머리 줄 포함 · 조건 칸 → 값 칸 · 범위는 「이름·아래」 「이름·위」) · row 를 주면 그 줄 하나 */
export type CfQuery =
| { id: string; group: "인력" | "유가전력" | "환율" | "요율" | "사용자"; key: string }
| { id: string; group: "재료"; key: string; unit?: string }
| { id: string; group: "기계"; key: string; field?: string }
| {
id: string;
group: "기계";
element: string;
inputs: Record<string, unknown>;
field?: CfCost;
}
| { id: string; group: "소요량" | "계수"; table: string; row?: number };
/** 입력 값 답 — 표는 `rows`(머리 줄 포함) · 그 밖은 `value` · 못 구하면 ok false + 쉬운 말 */
export interface CfValue {
id: string;
ok: boolean;
value?: number | string | null;
rows?: (string | number | null)[][];
name?: string;
unit?: string;
reason?: string;
}
/** 저장 때 입력 값을 넣을 자리 — 함수 상자 시트 id · 칸(표는 이 칸을 왼쪽 위로 펼침) */
export interface CfFill {
item: CfQuery;
sheet: string;
cell: string;
}
/** 다이어그램 한 벌 = 통합문서(함수 상자 = 시트) + 상자 · 선(다른 창 칸은 그대로 저장 · 돌려줌) */
export interface CfLogic {
/** 새 것 null · 저장하면 서버가 `CF-0001` 꼴로 줌 · 견본은 그 이름(저장하면 새 번호) */
key: string | null;
name: string;
resultUnit?: string;
workbook: Workbook;
/** 입력 값 자리 — 서버가 저장 때 마스터에서 다시 넣음 */
fills?: CfFill[];
[extra: string]: unknown;
}
/** 목록 한 줄 — `sample` = `_sample` 견본(읽기만 · 저장하면 새 번호) */
export interface CfListItem {
key: string;
name: string;
resultUnit: string;
saved: string;
sample: boolean;
}
/** 저장 답 — `logic.workbook.계산값` 은 서버가 다시 셈한 값 · `values` 는 넣은 입력 값 */
export interface CfSaved {
key: string;
logic: CfLogic;
values: CfValue[];
}
/** 사용자 요소 — 마스터에 없는 요소(시험 폴더 `_data` 에만) · 키 `UE-0001` 꼴 */
export interface CfUserElement {
key: string;
group: CfGroup;
이름: string;
규격: string;
단위: string;
값: number | null;
비고?: string;
}
const notReady = (): never => {
throw new Error("준비 중");
};
export async function cfList(): Promise<CfListItem[]> {
return notReady();
}
export async function cfGet(_key: string): Promise<CfLogic> {
return notReady();
}
export async function cfSave(_logic: CfLogic): Promise<CfSaved> {
return notReady();
}
export async function cfDelete(_key: string): Promise<void> {
return notReady();
}
export async function cfValues(_items: CfQuery[]): Promise<CfValue[]> {
return notReady();
}
/** 사용자 요소 목록 */
export async function cfUserElements(): Promise<CfUserElement[]> {
return notReady();
}
/** 사용자 요소 만들기 — 키는 서버가 줌 */
export async function cfUserElementAdd(
_element: Omit<CfUserElement, "key">,
): Promise<CfUserElement> {
return notReady();
}
export async function cfUserElementDelete(_key: string): Promise<void> {
return notReady();
}
/** 실패 → 쉬운 말 */
export function cfPlain(_e: unknown): string {
return notReady();
}