Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WRFJmmhPi4exAzHgPZHMT
75 lines
2.7 KiB
TypeScript
75 lines
2.7 KiB
TypeScript
/* =============================================================================
|
|
* M01_MasterData_UI_Logic_Wizard_Api.ts
|
|
* 「새로 만들기」 모달이 쓰는 읽기 길 — 계약 `resources/master_data/_화면_계약.md` 2장
|
|
* 절 목록 API 가 서기 전 = `/tables` 를 절 번호로 찾아 원문번호가 같은 표만 남김
|
|
* ========================================================================== */
|
|
|
|
import { API_BASE_URL } from "@config/config_frontend";
|
|
import { ApiError, type ElementBrief } from "./M01_MasterData_UI_Logic_Api";
|
|
|
|
export interface TableBrief {
|
|
file: string;
|
|
키: string;
|
|
원문번호: string;
|
|
구분: string;
|
|
이름: string;
|
|
기준?: string;
|
|
조건?: Record<string, string>;
|
|
값칸?: Record<string, string>;
|
|
용도?: { 공종?: string; 대상?: string[]; 로직키?: string[] };
|
|
}
|
|
|
|
/** 표 통째 — `줄` 에서 조건 값 목록을 뽑음 */
|
|
export interface TableFull extends TableBrief {
|
|
줄?: Record<string, unknown>[];
|
|
주?: string[];
|
|
}
|
|
|
|
async function getJson<T>(path: string, params: Record<string, string>): Promise<T> {
|
|
const response = await fetch(`${API_BASE_URL}/m01${path}?${new URLSearchParams(params)}`, {
|
|
credentials: "include",
|
|
});
|
|
const data = (await response.json().catch(() => ({}))) as { detail?: unknown } & T;
|
|
if (!response.ok) throw new ApiError(response.status, data.detail ?? response.statusText);
|
|
return data;
|
|
}
|
|
|
|
/** 책 + 절 번호의 표 — 소요량·계수 둘을 다 봄 · 하위 절(13-4-1-1)도 같이 */
|
|
export async function fetchSectionTables(book: string, section: string): Promise<TableBrief[]> {
|
|
const found = await Promise.all(
|
|
["소요량", "계수"].map((group) =>
|
|
getJson<{ tables: TableBrief[] }>("/tables", { group, q: section, size: "100" }),
|
|
),
|
|
);
|
|
return found
|
|
.flatMap((f) => f.tables)
|
|
.filter(
|
|
(t) => t.구분 === book && (t.원문번호 === section || t.원문번호.startsWith(`${section}-`)),
|
|
);
|
|
}
|
|
|
|
const tableCache = new Map<string, Promise<TableFull>>();
|
|
|
|
export function fetchTableFull(file: string, key: string): Promise<TableFull> {
|
|
let got = tableCache.get(key);
|
|
if (!got) {
|
|
got = getJson<{ table: TableFull }>("/table", { file, key }).then((d) => d.table);
|
|
tableCache.set(key, got);
|
|
}
|
|
return got;
|
|
}
|
|
|
|
/** 공표 직종 찾기 */
|
|
export const searchJobs = (q: string): Promise<{ items: ElementBrief[] }> =>
|
|
getJson("/pick", { kind: "job", q, limit: "100" });
|
|
|
|
/** 로직 이름·번호 찾기 — 하위 로직 고르기 */
|
|
export interface LogicBrief {
|
|
키: string;
|
|
원문번호: string;
|
|
이름: string;
|
|
결과단위: string;
|
|
}
|
|
export const searchLogics = (q: string): Promise<{ logics: LogicBrief[] }> =>
|
|
getJson("/logics", { q });
|