- M02 종류별 탭 [종류 더하기] = 본보기(구조물 정본 원본) 복사 — 키 자동 · 이름 「본보기 2」 · 옵션 · 표시 · 그룹 · 배치 · 규칙 · 종류 덧칸 · 반영 그대로 · 종류.{새}.본보기 · 관 지점 종류 · 복사본은 본보기 밖
- 구조물 표 = 본보기 처음값 이어받음(resolveCatalog · resolve_catalog 짝 · 줄 칸 base) · baseType/base_type · specFor(명세) · 덧단 · 길이 전후 풀기 · 옹벽 추가 단 콘크리트
- 검사(화면 = 서버 짝) — 본보기 = 원본 · 같은 군 · 자리꼴 · 정본 · 만든 뒤 고정 · 복사본은 본보기가 숨긴 칸 이어받음 · 서버 덧칸 본보기 받음
- 특수 동작 = 동작 이름 — 바로 안 놓기 · 포장 나누기 = 포장_물넘이_겹침 · 월류 높이 기다림 = 월류단면
- 정본 목록 = 표 — 파이썬 관 지점 종류 = catalog owner · B05 시설 서브폼 = 표 형상 · 안 쓰는 손 목록 걷음
- drawing_views — 스키마에서 빼고 읽을 때 버림 · M02 [저장] 때 빠짐(코드는 마스터 안 고침)
- 이관 = 지난 판 이름 대신 측점 계획 자리(planted)로 가름 · all_type_names 걷음
- 허용 거리 = common_util_structure_station.py 한 곳(SAME_STATION_M · EDGE_TOLERANCE_M · PIPE_MATCH_M) · TS 표는 station.ts 머리
- 시험: test_323_7_new_type(템플릿 · 일곱 갈래 · 그림 · 검사 짝 · 서버 읽기) · 322-0 유령 시험 = 자리 · 옛 도움 파일 동작 · 표 길 · 기대 글 고침
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ji4nuyLVHcxrXWHTdb5nRD
99 lines
4.6 KiB
JavaScript
99 lines
4.6 KiB
JavaScript
/* M02 구조물 명세 이름 고치기(`M02_SO_Def_Spec_Model.ts` · PLAN 52-11) 단위검증 헬퍼 —
|
|
* TS 를 그 자리에서 트랜스파일해 Node 로 돌리고 결과를 JSON 으로 냄(pytest 가 판정).
|
|
* 정의는 진짜 `구조물정의.json` 을 읽어 메모리 사본만 고침(파일 쓰기 없음). */
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1)
|
|
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
|
|
|
|
const ROOT = path.join(__dirname, "..", "..");
|
|
// 이웃 TS(`./…`)는 같은 길로 읽음 — 명세 파일이 서로 import 함
|
|
const cache = {};
|
|
const load = (...parts) => {
|
|
const file = path.join(ROOT, ...parts);
|
|
if (cache[file]) return cache[file].exports;
|
|
const js = ts.transpileModule(fs.readFileSync(file, "utf8"), {
|
|
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
|
|
}).outputText;
|
|
const box = (cache[file] = { exports: {} });
|
|
const near = (id) =>
|
|
CATALOG.isCatalogRequest(id) // 구조물 표(본보기 · 323-7)
|
|
? CATALOG
|
|
: id.startsWith(".")
|
|
? load(path.relative(ROOT, path.resolve(path.dirname(file), `${id}.ts`)))
|
|
: require(id);
|
|
new Function("exports", "module", "require", js)(box.exports, box, near);
|
|
return box.exports;
|
|
};
|
|
const m = load("M02_MasterTemplete", "StructOptions", "M02_SO_Def_Spec_Model.ts");
|
|
const { PIPE_SPEC } = load("A00_Common", "design", "design_structure_pipe.ts");
|
|
const real = () =>
|
|
JSON.parse(
|
|
fs.readFileSync(path.join(ROOT, "resources", "master_template", "구조물정의.json"), "utf8"),
|
|
);
|
|
|
|
const out = {};
|
|
const def = real();
|
|
const rows = m.specNameRows(def, PIPE_SPEC);
|
|
out.levels = [0, 1, 2].map((lv) => rows.filter((r) => r.level === lv).length);
|
|
out.unique = new Set(rows.map((r) => r.nameKey)).size === rows.length;
|
|
out.pipeTitle = rows.find((r) => r.nameKey === "pipe");
|
|
out.optional = rows.find((r) => r.nameKey === "soil_add");
|
|
out.basinForm = rows.find((r) => r.nameKey === "inlet.form=I");
|
|
|
|
// 이름 고침 — 그룹 제목 · 항목 · 값 · 선택 컨테이너
|
|
const work = real();
|
|
const pick = (k) => m.specNameRows(work, PIPE_SPEC).find((r) => r.nameKey === k);
|
|
m.setSpecName(work, "pipe", pick("pipe"), "관 본체");
|
|
m.setSpecName(work, "pipe", pick("pipe.diameter"), "관 지름");
|
|
m.setSpecName(work, "pipe", pick("pipe.diameter=800"), "Ø800");
|
|
m.setSpecName(work, "pipe", pick("soil_add"), "흙막이 더");
|
|
out.groupName = work.그룹.pipe.find((g) => g.id === "grv6lny").이름;
|
|
out.names = ["pipe", "pipe.diameter", "pipe.diameter=800", "soil_add"].map(
|
|
(k) => work.종류.pipe.이름[k] ?? null,
|
|
);
|
|
out.reread = ["pipe", "pipe.diameter", "pipe.diameter=800", "soil_add"].map((k) => pick(k).label);
|
|
// 구조는 그대로 — types · 동작 · 다른 종류 · 이름 표 키 수(새 키 없음)
|
|
const before = real();
|
|
out.sameTypes = JSON.stringify(work.types) === JSON.stringify(before.types);
|
|
out.sameKeys =
|
|
Object.keys(work.종류.pipe.이름).length === Object.keys(before.종류.pipe.이름).length;
|
|
|
|
// 이름 표가 빈 종류 — 명세 글로 읽고 고치면 이름 표가 생김
|
|
const bare = real();
|
|
delete bare.종류.pipe.이름;
|
|
const bareRows = m.specNameRows(bare, PIPE_SPEC);
|
|
out.bareLabel = bareRows.find((r) => r.nameKey === "inlet.structure=기슭막이").label;
|
|
m.setSpecName(
|
|
bare,
|
|
"pipe",
|
|
bareRows.find((r) => r.nameKey === "inlet"),
|
|
"유입",
|
|
);
|
|
out.bareGroup = bare.그룹.pipe.find((g) => g.id === "gnbf9m9").이름;
|
|
|
|
// 정의 그룹 꼴(52-12) — 맹암거 = 그룹 제목 › 칸 · 옆도랑 = 그룹 밖 칸 › 선택지
|
|
const g = real();
|
|
const ud = g.types.find((t) => t.type_id === "cross_underdrain");
|
|
const udRows = m.groupNameRows(g, ud);
|
|
out.udRows = udRows.map((r) => [r.level, r.nameKey, r.label]);
|
|
m.setSpecName(g, ud.type_id, udRows[0], "맹암거 본체");
|
|
m.setSpecName(g, ud.type_id, udRows[1], "암거 높이 칸");
|
|
out.udGroup = g.그룹.cross_underdrain[0].이름;
|
|
out.udLabel = ud.options[0].label;
|
|
const side = g.types.find((t) => t.type_id === "ditch_side");
|
|
const sideRows = m.groupNameRows(g, side);
|
|
out.sideHead = sideRows[0];
|
|
const lshape = sideRows.find((r) => r.nameKey === "form=L형");
|
|
out.sideChoice = lshape && [lshape.level, lshape.label];
|
|
m.setSpecName(g, side.type_id, lshape, "L 모양");
|
|
out.sideName = g.종류.ditch_side.이름["form=L형"];
|
|
out.sideChoices = side.options.find((o) => o.key === "form").choices;
|
|
out.sideReread = m.groupNameRows(g, side).find((r) => r.nameKey === "form=L형").label;
|
|
out.bareKind = m.groupNameRows(
|
|
g,
|
|
g.types.find((t) => t.type_id === "open_ditch"),
|
|
).length;
|
|
|
|
process.stdout.write(JSON.stringify(out));
|