From 4910fbaccc2dc4f9d29bc754ce945eb354c9706b Mon Sep 17 00:00:00 2001 From: umsangdon Date: Wed, 28 Oct 2026 21:36:42 +0900 Subject: [PATCH] =?UTF-8?q?refactor(B07):=20=ED=9A=A1=EB=8B=A8=20=EB=8D=A7?= =?UTF-8?q?=EA=B7=B8=EB=A6=BC=20=EC=84=9C=EB=B2=84=20=EB=AC=B6=EC=9D=8C?= =?UTF-8?q?=EC=9D=B4=20B06=20=ED=99=94=EB=A9=B4=20=ED=97=88=EB=B8=8C?= =?UTF-8?q?=EB=A5=BC=20=EB=81=84=EC=A7=80=20=EC=95=8A=EA=B2=8C=20=ED=95=A8?= =?UTF-8?q?=20(PLAN=20574-1=20=C2=B7=20=EC=9A=94=EA=B5=AC=20418)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Overlay 가 설계선 · 포장 그리기를 허브(_UI_Cross_Design) 대신 _Design_Line · _Design_Surface 에서 직접 가져옴 - 허브가 상세 창 · CAD · API · 부품 상자를 끌던 사슬 걷힘 — 묶음 482 → 240 KB - 구조물 그림 여섯은 이미 logic 기하만 씀 · SVG 그리기는 B07 이 SVG → CAD 로 옮기므로 그대로 둠 · 가짜 DOM 계속 필요 - 지킴 시험 test_574 — 묶음 입구에서 닿는 TS 에 화면 코드 없음 Co-Authored-By: Claude Opus 5.5 --- .../B07_DesignDetail_Cross_Overlay.ts | 7 +- resources/tester/test_574_b07_extent_no_ui.py | 68 +++++++++++++++++++ 2 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 resources/tester/test_574_b07_extent_no_ui.py diff --git a/B07_DesignDetail/B07_DesignDetail_Cross_Overlay.ts b/B07_DesignDetail/B07_DesignDetail_Cross_Overlay.ts index 23f3dbb4e..ee93e2f2e 100644 --- a/B07_DesignDetail/B07_DesignDetail_Cross_Overlay.ts +++ b/B07_DesignDetail/B07_DesignDetail_Cross_Overlay.ts @@ -19,10 +19,9 @@ import { appendFordOverlay } from "../B06_Section/B06_Section_UI_Cross_Ford"; import { appendFordPavementOverlay } from "../B06_Section/B06_Section_UI_Cross_Ford_Pavement"; import { appendUnderdrainOverlay } from "../B06_Section/B06_Section_UI_Cross_Underdrain"; import { groundLine } from "../B06_Section/logic/B06_Section_Cross_Wall_Hatch_Geom"; -import { - appendCrossDesignOverlay, - appendPavementOverlay, -} from "../B06_Section/B06_Section_UI_Cross_Design"; +// 허브(`_UI_Cross_Design`)가 아닌 그리기 파일에서 직접 — 허브는 상세 창 · CAD · API 를 끈다(574-1) +import { appendCrossDesignOverlay } from "../B06_Section/B06_Section_UI_Cross_Design_Line"; +import { appendPavementOverlay } from "../B06_Section/B06_Section_UI_Cross_Design_Surface"; import { appendRevetmentOverlay } from "../B06_Section/B06_Section_UI_Cross_Revetment"; import { clipPointsToPolygon, clipSegment, pointInPolygon } from "../A00_Common/b_polygon_clip"; diff --git a/resources/tester/test_574_b07_extent_no_ui.py b/resources/tester/test_574_b07_extent_no_ui.py new file mode 100644 index 000000000..beba7120f --- /dev/null +++ b/resources/tester/test_574_b07_extent_no_ui.py @@ -0,0 +1,68 @@ +"""B07 횡단 덧그림 서버 묶음(`b07-extent`)이 화면 코드를 끌지 않음 (574-1). + +묶음 입구에서 값 import 를 따라가 닿는 TS 파일에 확인 창 · CAD · 상세 창 · API · +부품 상자 · B06 허브(`_UI_Cross_Design`)가 없어야 함. `import type` 은 지워지므로 뺌. +""" + +import re +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[2] +ENTRY = ROOT / "B07_DesignDetail" / "B07_DesignDetail_Cross_Extent_Node.ts" +ALIAS = {"@util/": ROOT / "common_util", "@ui/": ROOT / "ui_template"} +_IMPORT = re.compile( + r"^\s*(?:import|export)\s+(type\s+)?(?:([^;]*?)\s+from\s+)?[\"']([^\"']+)[\"']", + re.M | re.S, +) +FORBIDDEN = re.compile( + r"ui_template|_Cad|Cross_Detail|_Api_|B06_Section_UI_Cross_Design\.ts$|three" +) + + +def _type_only(names: str | None) -> bool: + inner = (names or "").strip() + if not inner.startswith("{"): + return False + parts = [p.strip() for p in inner.strip("{} \n").split(",") if p.strip()] + return bool(parts) and all(p.startswith("type ") for p in parts) + + +def _resolve(origin: Path, spec: str) -> Path | None: + for prefix, base in ALIAS.items(): + if spec.startswith(prefix): + target = base / spec[len(prefix) :] + break + else: + if not spec.startswith("."): + return None # node:fs · 라이브러리 + target = origin.parent / spec + for suffix in (".ts", ""): + path = Path(str(target) + suffix).resolve() + if path.is_file(): + return path + return None + + +def _reachable() -> set[Path]: + seen, queue = {ENTRY.resolve()}, [ENTRY.resolve()] + while queue: + current = queue.pop() + if current.suffix != ".ts": + continue + for match in _IMPORT.finditer(current.read_text(encoding="utf-8")): + type_kw, names, spec = match.groups() + if type_kw or _type_only(names): + continue + found = _resolve(current, spec) + if found and found not in seen: + seen.add(found) + queue.append(found) + return seen + + +def test_extent_bundle_pulls_no_screen_code(): + reached = _reachable() + names = {p.relative_to(ROOT).as_posix() for p in reached} + assert "B07_DesignDetail/B07_DesignDetail_Cross_Overlay.ts" in names # 걷기가 실제로 돎 + bad = sorted(n for n in names if FORBIDDEN.search(n)) + assert not bad, bad