Files
Aislo/resources/tester/helper_280_3_draft_frame.cjs
T
eomsangdonandClaude Opus 5.5 4da510f6df fix(482-1 노선 바뀜 구조물 측점): 노선 초안 중 되돌리기 · 다시하기가 관 · 구조물 · 추가 측점도 그 걸음 사진으로 묶음에 넣음 · 초안 측점 맞춤이 상세 틀(옛 · 새 노선)을 앎
- design_pipeline_page follow 되살림 차례 = 계획고 사진 + 가게 관 · 구조물 · 추가 측점(묶음 측점 유령 · 빠짐 없앰)
- Section_Store 가 노선 초안 동안 상세 틀을 정해 넘김 · Drafts = 옛 틀이면 저장분으로 맞춤 · 얹음 · 새 틀이면 저장분 종류 대조 안 함
- 새 시험 test_280_3_route_undo_facilities(헬퍼 둘 · 검증_sub4 읽기만) · 옛 코드에서 되돌리기 넷 실패

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 22:39:37 +09:00

193 lines
7.0 KiB
JavaScript

/* 요구 280-3 원인 3 헬퍼 — 노선 초안 동안 초안 측점 맞춤(`withDraftStations` · `withDraftShapes`)이 상세의 틀을 앎.
* old = 옛 노선 틀 상세(저장 정본 · 새로고침 첫 화면) → 새 틀 초안 대신 저장분으로 · new = 묶음이 갈아끼운 새 틀 →
* 저장분(옛 틀) 종류와 같은 m 로 견주지 않음 · null = 옛 동작(대조). 진짜 TS: Drafts · 측점 계획 · 형상 얹기 · 표.
* 결과 = 표준출력 JSON. 짝 = `test_280_3_route_undo_facilities.py`. */
const fs = require("fs");
const path = require("path");
const ROOT = path.join(__dirname, "..", "..");
const ts = require(path.join(ROOT, "config", "node_modules", "typescript"));
const CATALOG = require("./helper_322_catalog_module.cjs");
const S = {
savedPipes: [],
savedStructures: [],
draftPipes: null,
draftStructures: null,
types: [],
};
const STUBS = {
design_page_data: {
forgetPageData: () => {},
pagePipes: async () => ({ pipe_points: S.savedPipes }),
pageStructures: async () => ({ structures: S.savedStructures }),
},
B05_Profile_Api_Structures: {
fetchStructureTypes: async () => S.types,
readPendingStructures: () => S.draftStructures,
},
B05_Profile_Api_Pipes_Draft: { readPendingPipes: () => S.draftPipes },
B05_Profile_Api_PlusStations: { readPlusDraft: () => null },
B06_Section_Station_Keys: { useStationKeys: () => {}, useStationOwners: () => {} },
ui_template_elements: { showToast: () => {} },
};
const cache = new Map();
function resolveTs(base) {
for (const c of [`${base}.ts`, base]) if (fs.existsSync(c) && fs.statSync(c).isFile()) return c;
throw new Error(`없음: ${base}`);
}
function load(full) {
if (cache.has(full)) return cache.get(full).exports;
const js = ts.transpileModule(fs.readFileSync(full, "utf8"), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
}).outputText;
const box = { exports: {} };
cache.set(full, box);
const req = (r0) => {
if (CATALOG.isCatalogRequest(r0)) return CATALOG;
const r = r0.replace(/\.js$/, "");
const stub = STUBS[r.split("/").pop()];
if (stub) return stub;
if (r.endsWith(".json"))
return JSON.parse(fs.readFileSync(path.join(path.dirname(full), r), "utf8"));
if (r.startsWith("@util/")) return load(resolveTs(path.join(ROOT, "common_util", r.slice(6))));
if (r.startsWith("@ui/")) return STUBS[r.split("/").pop()] ?? {};
if (r.startsWith(".")) return load(resolveTs(path.join(path.dirname(full), r)));
return require(r);
};
new Function("exports", "module", "require", js)(box.exports, box, req);
return box.exports;
}
const P = (...a) => path.join(ROOT, ...a);
const D = load(P("B06_Section", "B06_Section_Section_Drafts.ts"));
const def = JSON.parse(
fs.readFileSync(P("resources", "master_template", "구조물정의.json"), "utf8"),
);
S.types = def.types.map((t) => ({
type_id: t.type_id,
group: t.group,
placement: t.placement,
managed_by: t.managed_by,
name: t.name,
options: (t.options || []).map((o) => ({ key: o.key, label: o.label, default: o.default })),
}));
const sec = (m, kind, extra = {}) => ({
station_id: `station_${String(Math.round(m * 1000)).padStart(12, "0")}`,
chainage_m: m,
label: "",
kind,
center_x: m,
center_y: 0,
center_z: 100,
frame: { left_xy: [0, 1] },
samples: [{ offset_m: 0, elevation_m: 100, valid: true }],
design: { design_elevation_m: 100 },
...extra,
});
const detailOf = (marks, len = 300) => {
const grid = [];
for (let m = 0; m <= len; m += 20) grid.push(m);
const all = [...new Set([...grid, ...marks.map((x) => x.m)])].sort((a, b) => a - b);
const cross = all.map((m, i) => {
const mk = marks.find((x) => x.m === m);
const kind = i === 0 ? "bp" : i === all.length - 1 ? "ep" : mk ? "irregular" : "regular";
return sec(m, kind, mk ? { structure: mk.title, ...(m % 20 === 0 ? { grid: true } : {}) } : {});
});
return { longitudinal: { length_m: len, stations: [] }, cross_sections: cross };
};
const show = (detail) =>
detail.cross_sections
.filter((s) => s.kind === "irregular" || s.structure || s.preview)
.map(
(s) =>
`${s.chainage_m}:${s.kind}${s.grid ? "/grid" : ""}${s.preview ? "/preview" : ""}=${s.structure ?? "-"}[${Object.keys(
s,
)
.filter(
(k) =>
![
"station_id",
"chainage_m",
"label",
"kind",
"center_x",
"center_y",
"center_z",
"frame",
"samples",
"design",
"structure",
"grid",
"preview",
].includes(k),
)
.join(",")}]`,
);
const ud = (id, m) => ({
structure_id: id,
type_id: "cross_underdrain",
placement: "point",
chainage_m: m,
start_m: null,
end_m: null,
options: {},
});
const rw = (id, s, a, e) => ({
structure_id: id,
type_id: "retaining_wall",
placement: "interval",
chainage_m: a,
start_m: s,
end_m: e,
options: {},
});
/** 상세 하나를 맞춘 뒤 — 숨김(빠진 측점) · 구조물 없는 사본 · 측점마다 카드 이름. */
async function run(saved, draft, marks, frame) {
S.savedStructures = saved;
S.draftStructures = draft;
const detail = detailOf(marks);
const before = detail.cross_sections.map((s) => s.chainage_m);
await D.withDraftStations(detail, "p", 1, frame);
await D.withDraftShapes(detail, "p", false, frame);
const after = detail.cross_sections.map((s) => s.chainage_m);
return {
hidden: before.filter((m) => !after.includes(m)),
preview: detail.cross_sections.filter((s) => s.preview).map((s) => s.chainage_m),
names: Object.fromEntries(
detail.cross_sections.filter((s) => s.structure).map((s) => [s.chainage_m, s.structure]),
),
};
}
(async () => {
const out = {};
// 옛 틀 상세(저장 정본 · 새로고침) + 새 틀 초안(+20 m) — 저장분 자리 그대로여야 함
const oldFrame = [ud("A", 100), rw("B", 153, 160, 167)];
const oldMarks = [
{ m: 100, title: "맹암거" },
{ m: 153, title: "옹벽" },
{ m: 160, title: "옹벽" },
{ m: 167, title: "옹벽" },
];
const shifted = [ud("A", 120), rw("B", 173, 180, 187)];
for (const frame of ["old", null])
out[`old_${frame}`] = await run(oldFrame, shifted, oldMarks, frame);
// 새 틀 상세(갈아끼움 뒤) — 옛 틀 B 중심 120 자리에 새 틀 A 가 옴(종류 다름) · 사본 · 숨김 없어야 함
const savedB = [ud("A", 100), rw("B", 113, 120, 127)];
const draftB = [ud("A", 120), rw("B", 133, 140, 147)];
const newMarks = [
{ m: 120, title: "맹암거" },
{ m: 133, title: "옹벽" },
{ m: 140, title: "옹벽" },
{ m: 147, title: "옹벽" },
];
for (const frame of ["new", null])
out[`new_${frame}`] = await run(savedB, draftB, newMarks, frame);
process.stdout.write(JSON.stringify(out));
})().catch((error) => {
process.stderr.write(String(error && error.stack ? error.stack : error));
process.exit(1);
});