diff --git a/A00_Common/design/logic/design_calc_registry.ts b/A00_Common/design/logic/design_calc_registry.ts index 10ee3388a..d21e1a5ea 100644 --- a/A00_Common/design/logic/design_calc_registry.ts +++ b/A00_Common/design/logic/design_calc_registry.ts @@ -4,7 +4,7 @@ * `docs/raw/조사/2026-10-19_472_구조다시세움_목록.md` 1.1 표 # 하나). * * 순수 자료 — 함수 import 없음(타입만). 실행기는 글 이름이라 브라우저에 실려도 서버 쪽 코드가 - * 안 딸려감. 서버 Node 입구 = `design_calc_node.ts`(id → 함수 표 · `build:design-calc`). + * 안 딸려감. 시설 · 토량 · 배수 · 3D · 추천 줄 = `design_calc_registry_facility.ts`(같은 꼴 · 자료만). 서버 Node 입구 = `design_calc_node.ts`(id → 함수 표 · `build:design-calc`). * * 칸: * id — 갈래 이름(`<묶음>.<값>`) @@ -26,6 +26,7 @@ * (같은지 시험 `test_472_3_calc_registry.py`). * ========================================================================== */ +import { FACILITY_ROWS } from "./design_calc_registry_facility"; import type { StageName } from "./design_pipeline_types"; export type CalcSite = "browser_now" | "server_canon" | "server_only" | "browser_only"; @@ -455,236 +456,5 @@ export const CALC_REGISTRY: readonly CalcEntry[] = [ pair: null, mirror: [], }, - /* ── 시설 ─────────────────────────────────────────────────────────────── */ - { - id: "facility.follow", - no: "F1", - label: "시설 따라감(노선 바뀜 → 관 · 구조물 자리)", - inputs: ["route.polyline"], - outputs: ["새 좌표 · 누가거리(input.pipes · input.structures 고침)"], - site: "browser_now", - stage: "follow", - ts: `${U}common_util_route_follow.ts#followStructures`, - runner: "node:facility.follow", - pair: null, - mirror: [ - "test_410_follow_xy", - "test_344_2_route_pairs", - "test_459_route_seat_mirror", - "test_380_3_site_follow", - "test_472_4_follow_node", - ], - note: "파이썬 `common_util_route_follow.follow_structures` = Node 부름 겉 · 저장 때 좌표 맞춤 `fill_structure_coordinates` 는 파이썬 남음(옛 좌표 지킴 · 0.1 mm 반올림 — TS `placeOnLine` 과 규칙 다름)", - }, - { - id: "facility.plus_follow", - no: "F2", - label: "추가 측점 따라감", - inputs: ["route.polyline"], - outputs: ["추가 측점(input.plusStations 고침)"], - site: "browser_now", - stage: "follow", - ts: `${U}common_util_route_follow.ts#followPlusRows`, - runner: "node:facility.plus_follow", - pair: null, - mirror: ["test_459_route_seat_mirror", "test_368_2_plus_stations", "test_472_4_follow_node"], - note: "파이썬 `Plus_Stations.follow_plus_stations` = Node 부름 겉(정본 파일 읽기 · 쓰기)", - }, - { - id: "facility.stations", - no: "F3", - label: "시설 측점 계획", - inputs: ["route.polyline", "input.pipes", "input.structures"], - outputs: ["시설 측점"], - site: "browser_now", - stage: "stations", - ts: `${U}common_util_structure_station.ts#planStations`, - runner: `py:${U}common_util_structure_station.py#plan_stations`, - until: "472-4", - pair: `${U}common_util_structure_station.py#plan_stations`, - mirror: ["test_322_3_plan_mirror", "test_234_1_structure_station"], - note: "파이썬 짝은 B07 · 배수가 넓게 부름", - }, - { - id: "facility.attach", - no: "F4", - label: "형상 얹기(관 세트 · 벽 · 포장 · 맹암거 그림 자료)", - inputs: ["input.pipes", "input.structures", "cross.design"], - outputs: ["그림 자료"], - site: "browser_now", - stage: "cross", - ts: `${U}common_util_structure_attach.ts#attachShapes`, - runner: `py:${B06}B06_Section_Engine_Attach.py#attach_shapes`, - until: "472-4", - pair: `${B06}B06_Section_Engine_Attach.py#attach_shapes`, - mirror: ["test_323_4_attach_mirror"], - }, - { - id: "facility.culvert_sets", - no: "F5", - label: "관 세트(관경 · 날개벽 · 집수정)", - inputs: ["input.pipes"], - outputs: ["관 세트"], - site: "browser_now", - stage: null, - ts: `${U}common_util_culvert_sets.ts#pipeWallHeightM`, - runner: `py:${B06}B06_Section_Engine_Culvert.py#pipe_wall_height_m`, - pair: `${B06}B06_Section_Engine_Culvert.py#pipe_wall_height_m`, - mirror: ["test_b06_culvert_sets_mirror", "test_b06_pipe_wall_height_mirror"], - note: "짝 유지 — 파이썬 소비자 B04 · B07 · B08(472 밖)", - }, - { - id: "facility.walls", - no: "F6", - label: "벽 · 포장", - inputs: ["input.structures"], - outputs: ["벽 · 포장"], - site: "browser_now", - stage: null, - ts: `${U}common_util_structure_walls.ts#wallSpecsFrom`, - runner: `py:${B06}B06_Section_Engine_Structures_Wall.py#wall_specs_from`, - pair: `${B06}B06_Section_Engine_Structures_Wall.py#wall_specs_from`, - mirror: ["test_b06_structure_walls_mirror", "test_b06_structure_pavement_mirror"], - note: "짝 유지 — 포장 짝 common_util_structure_pavement(.py · .ts) · B07 소비", - }, - { - id: "structure.layouts", - no: "F7", - label: "관 길이 · 구조물 폐회로 면적 · 다단 벽", - inputs: ["cross.design", "cross.areas", "facility.attach"], - outputs: ["관 길이 · 구조물 면적 · 선 다단 벽", "db:cross_sections.design"], - site: "browser_now", - stage: null, - ts: `${B06}B06_Section_Structure_Layouts.ts#structureAreaRows`, - runner: "node:structure.layouts", - pair: null, - mirror: ["test_b06_pipe_length", "test_299_ford_span_pipe"], - }, - { - id: "excavation.trench", - no: "F8", - label: "터파기(관 폭 · 벽 단면)", - inputs: ["facility.culvert_sets", "facility.walls"], - outputs: ["터파기 폭 · 단면적"], - site: "browser_now", - stage: null, - ts: `${U}common_util_excavation.ts#wallTrenchAreaM2`, - runner: "node:excavation.trench", - pair: `${U}common_util_excavation.py#wall_trench_area_m2`, - mirror: ["test_excavation_mirror"], - note: "파이썬 짝 운영 부름 0 — 걷음 후보(472-7)", - }, - { - id: "facility.ford", - no: "F9", - label: "세월교 높이 · 깊이", - inputs: ["input.structures"], - outputs: ["높이"], - site: "browser_now", - stage: null, - ts: "A00_Common/design/design_structure_ford_calc.ts#fordHeightM", - runner: "py:B04_PreProcess/B04_PreProcess_Router_Basins.py#ford_height_m", - pair: "B04_PreProcess/B04_PreProcess_Router_Basins.py#ford_height_m", - mirror: ["test_65_ford_defaults", "test_73_11_b08_hydro_box_ford"], - note: "짝 유지(B04 · B08)", - }, - /* ── 토량 ─────────────────────────────────────────────────────────────── */ - { - id: "masshaul.cumulative", - no: "E1", - label: "누가토량", - inputs: ["cross.areas", "structure.layouts", "context.earthwork_conversion"], - outputs: ["누가토량 · 배지", "file:longitudinal.mass_haul"], - site: "browser_now", - stage: null, - ts: `${U}common_util_mass_haul.ts#computeMassHaul`, - runner: "node:masshaul.cumulative", - pair: null, - mirror: [], - note: "브라우저는 그릴 때 셈(B05_Profile_UI_Profile_MassHaul) · 같은 코드", - }, - { - id: "haul.plan", - no: "E2", - label: "유토 배분 · 운반거리", - inputs: ["masshaul.cumulative", "context.haul_equipment_limits"], - outputs: ["배분", "file:longitudinal.mass_haul.haul_plan"], - site: "server_canon", - stage: null, - ts: `${U}common_util_mass_haul_balance.ts#computeHaulPlan`, - runner: "node:haul.plan", - pair: null, - mirror: [], - note: "브라우저 번들 밖(/haul-plan 요청) · 브라우저 실행 여부 협의", - }, - /* ── 배수 · 3D · 추천 ────────────────────────────────────────────────── */ - { - id: "drainage.basins", - no: "D1", - label: "배수유역 세부 나눔", - inputs: ["route.polyline", "input.pipes"], - outputs: ["유역 · 관경 제안"], - site: "server_only", - stage: "drainage", - ts: null, - runner: `py:${U}common_util_drainage_detail.py#build_detail`, - pair: null, - mirror: [], - note: "TS 는 일정만(B05_Profile/logic/B05_Profile_Drainage_Live.ts)", - }, - { - id: "drainage.suggest", - no: "D2", - label: "관 자리 제안", - inputs: ["route.polyline", "drainage.basins"], - outputs: ["제안"], - site: "server_only", - stage: null, - ts: null, - runner: `py:${U}common_util_drainage_detail.py#suggest_pipe_positions`, - pair: null, - mirror: [], - note: "TS 는 모으기만(B05_Profile/logic/B05_Profile_Drainage_Suggest.ts)", - }, - { - id: "corridor.mesh", - no: "D3", - label: "3D 길 모형", - inputs: ["profile.alignment", "cross.design"], - outputs: ["3D", "file:corridor"], - site: "browser_now", - stage: "corridor", - ts: `${B05}B05_Profile_UI_Corridor_Build.ts#buildCorridor`, - runner: "node:corridor.mesh", - pair: null, - mirror: [], - }, - { - id: "footprint.plan", - no: "D4", - label: "평면 발자국(절성토선)", - inputs: ["cross.design", "ground.sample"], - outputs: ["발자국", "store.footprint"], - site: "browser_only", - stage: "footprint", - ts: `${B05L}B05_Profile_PlanFootprint.ts#footprintRecord`, - runner: `browser:${B05L}B05_Profile_Footprint_Stage.ts#footprintStage`, - pair: "B07_DesignDetail/B07_DesignDetail_Engine_Cad_PlanSlope.py#route_frame", - mirror: ["test_346_2_plan_footprint_mirror"], - note: "서버 정본 없음(즉시 후보) · X4 B07 파이썬이 따로 셈(472 밖)", - }, - { - id: "route.recommend", - no: "N1", - label: "노선 추천", - inputs: ["file:dtm_grid", "file:streams"], - outputs: ["추천 노선"], - site: "server_only", - stage: null, - ts: null, - runner: `py:${B05}B05_Profile_Engine_RouteInitial.py#generate_initial_route`, - pair: null, - mirror: ["test_419_1_recommend_engine"], - note: "[적용] 정본은 route.polyline · stations.list 길 · TS 는 보기만(B05_Profile_UI_RouteEdit_Initial_Model.ts)", - }, + ...FACILITY_ROWS, ]; diff --git a/A00_Common/design/logic/design_calc_registry_facility.ts b/A00_Common/design/logic/design_calc_registry_facility.ts new file mode 100644 index 000000000..96048f6f2 --- /dev/null +++ b/A00_Common/design/logic/design_calc_registry_facility.ts @@ -0,0 +1,247 @@ +/* ============================================================================= + * A00_Common/design/logic/design_calc_registry_facility.ts + * 계산 등록부(`design_calc_registry.ts`) 뒤 몫 — 시설 · 토량 · 배수 · 3D · 추천 줄(칸 뜻 = 그 파일 머리). + * 순수 자료 — 함수 import 없음(타입만). + * ========================================================================== */ + +import type { CalcEntry } from "./design_calc_registry"; + +const B05 = "B05_Profile/"; +const B05L = "B05_Profile/logic/"; +const B06 = "B06_Section/"; +const U = "common_util/"; + +export const FACILITY_ROWS: readonly CalcEntry[] = [ + /* ── 시설 ─────────────────────────────────────────────────────────────── */ + { + id: "facility.follow", + no: "F1", + label: "시설 따라감(노선 바뀜 → 관 · 구조물 자리)", + inputs: ["route.polyline"], + outputs: ["새 좌표 · 누가거리(input.pipes · input.structures 고침)"], + site: "browser_now", + stage: "follow", + ts: `${U}common_util_route_follow.ts#followStructures`, + runner: "node:facility.follow", + pair: null, + mirror: [ + "test_410_follow_xy", + "test_344_2_route_pairs", + "test_459_route_seat_mirror", + "test_380_3_site_follow", + "test_472_4_follow_node", + ], + note: "파이썬 `common_util_route_follow.follow_structures` = Node 부름 겉 · 저장 때 좌표 맞춤 `fill_structure_coordinates` 는 파이썬 남음(옛 좌표 지킴 · 0.1 mm 반올림 — TS `placeOnLine` 과 규칙 다름)", + }, + { + id: "facility.plus_follow", + no: "F2", + label: "추가 측점 따라감", + inputs: ["route.polyline"], + outputs: ["추가 측점(input.plusStations 고침)"], + site: "browser_now", + stage: "follow", + ts: `${U}common_util_route_follow.ts#followPlusRows`, + runner: "node:facility.plus_follow", + pair: null, + mirror: ["test_459_route_seat_mirror", "test_368_2_plus_stations", "test_472_4_follow_node"], + note: "파이썬 `Plus_Stations.follow_plus_stations` = Node 부름 겉(정본 파일 읽기 · 쓰기)", + }, + { + id: "facility.stations", + no: "F3", + label: "시설 측점 계획", + inputs: ["route.polyline", "input.pipes", "input.structures"], + outputs: ["시설 측점"], + site: "browser_now", + stage: "stations", + ts: `${U}common_util_structure_station.ts#planStations`, + runner: `py:${U}common_util_structure_station.py#plan_stations`, + until: "472-4", + pair: `${U}common_util_structure_station.py#plan_stations`, + mirror: ["test_322_3_plan_mirror", "test_234_1_structure_station"], + note: "파이썬 짝은 B07 · 배수가 넓게 부름", + }, + { + id: "facility.attach", + no: "F4", + label: "형상 얹기(관 세트 · 벽 · 포장 · 맹암거 그림 자료)", + inputs: ["input.pipes", "input.structures", "cross.design"], + outputs: ["그림 자료"], + site: "browser_now", + stage: "cross", + ts: `${U}common_util_structure_attach.ts#attachShapes`, + runner: `py:${B06}B06_Section_Engine_Attach.py#attach_shapes`, + until: "472-4", + pair: `${B06}B06_Section_Engine_Attach.py#attach_shapes`, + mirror: ["test_323_4_attach_mirror"], + }, + { + id: "facility.culvert_sets", + no: "F5", + label: "관 세트(관경 · 날개벽 · 집수정)", + inputs: ["input.pipes"], + outputs: ["관 세트"], + site: "browser_now", + stage: null, + ts: `${U}common_util_culvert_sets.ts#pipeWallHeightM`, + runner: `py:${B06}B06_Section_Engine_Culvert.py#pipe_wall_height_m`, + pair: `${B06}B06_Section_Engine_Culvert.py#pipe_wall_height_m`, + mirror: ["test_b06_culvert_sets_mirror", "test_b06_pipe_wall_height_mirror"], + note: "짝 유지 — 파이썬 소비자 B04 · B07 · B08(472 밖)", + }, + { + id: "facility.walls", + no: "F6", + label: "벽 · 포장", + inputs: ["input.structures"], + outputs: ["벽 · 포장"], + site: "browser_now", + stage: null, + ts: `${U}common_util_structure_walls.ts#wallSpecsFrom`, + runner: `py:${B06}B06_Section_Engine_Structures_Wall.py#wall_specs_from`, + pair: `${B06}B06_Section_Engine_Structures_Wall.py#wall_specs_from`, + mirror: ["test_b06_structure_walls_mirror", "test_b06_structure_pavement_mirror"], + note: "짝 유지 — 포장 짝 common_util_structure_pavement(.py · .ts) · B07 소비", + }, + { + id: "structure.layouts", + no: "F7", + label: "관 길이 · 구조물 폐회로 면적 · 다단 벽", + inputs: ["cross.design", "cross.areas", "facility.attach"], + outputs: ["관 길이 · 구조물 면적 · 선 다단 벽", "db:cross_sections.design"], + site: "browser_now", + stage: null, + ts: `${B06}B06_Section_Structure_Layouts.ts#structureAreaRows`, + runner: "node:structure.layouts", + pair: null, + mirror: ["test_b06_pipe_length", "test_299_ford_span_pipe"], + }, + { + id: "excavation.trench", + no: "F8", + label: "터파기(관 폭 · 벽 단면)", + inputs: ["facility.culvert_sets", "facility.walls"], + outputs: ["터파기 폭 · 단면적"], + site: "browser_now", + stage: null, + ts: `${U}common_util_excavation.ts#wallTrenchAreaM2`, + runner: "node:excavation.trench", + pair: `${U}common_util_excavation.py#wall_trench_area_m2`, + mirror: ["test_excavation_mirror"], + note: "파이썬 짝 운영 부름 0 — 걷음 후보(472-7)", + }, + { + id: "facility.ford", + no: "F9", + label: "세월교 높이 · 깊이", + inputs: ["input.structures"], + outputs: ["높이"], + site: "browser_now", + stage: null, + ts: "A00_Common/design/design_structure_ford_calc.ts#fordHeightM", + runner: "py:B04_PreProcess/B04_PreProcess_Router_Basins.py#ford_height_m", + pair: "B04_PreProcess/B04_PreProcess_Router_Basins.py#ford_height_m", + mirror: ["test_65_ford_defaults", "test_73_11_b08_hydro_box_ford"], + note: "짝 유지(B04 · B08)", + }, + /* ── 토량 ─────────────────────────────────────────────────────────────── */ + { + id: "masshaul.cumulative", + no: "E1", + label: "누가토량", + inputs: ["cross.areas", "structure.layouts", "context.earthwork_conversion"], + outputs: ["누가토량 · 배지", "file:longitudinal.mass_haul"], + site: "browser_now", + stage: null, + ts: `${U}common_util_mass_haul.ts#computeMassHaul`, + runner: "node:masshaul.cumulative", + pair: null, + mirror: [], + note: "브라우저는 그릴 때 셈(B05_Profile_UI_Profile_MassHaul) · 같은 코드", + }, + { + id: "haul.plan", + no: "E2", + label: "유토 배분 · 운반거리", + inputs: ["masshaul.cumulative", "context.haul_equipment_limits"], + outputs: ["배분", "file:longitudinal.mass_haul.haul_plan"], + site: "server_canon", + stage: null, + ts: `${U}common_util_mass_haul_balance.ts#computeHaulPlan`, + runner: "node:haul.plan", + pair: null, + mirror: [], + note: "브라우저 번들 밖(/haul-plan 요청) · 브라우저 실행 여부 협의", + }, + /* ── 배수 · 3D · 추천 ────────────────────────────────────────────────── */ + { + id: "drainage.basins", + no: "D1", + label: "배수유역 세부 나눔", + inputs: ["route.polyline", "input.pipes"], + outputs: ["유역 · 관경 제안"], + site: "server_only", + stage: "drainage", + ts: null, + runner: `py:${U}common_util_drainage_detail.py#build_detail`, + pair: null, + mirror: [], + note: "TS 는 일정만(B05_Profile/logic/B05_Profile_Drainage_Live.ts)", + }, + { + id: "drainage.suggest", + no: "D2", + label: "관 자리 제안", + inputs: ["route.polyline", "drainage.basins"], + outputs: ["제안"], + site: "server_only", + stage: null, + ts: null, + runner: `py:${U}common_util_drainage_detail.py#suggest_pipe_positions`, + pair: null, + mirror: [], + note: "TS 는 모으기만(B05_Profile/logic/B05_Profile_Drainage_Suggest.ts)", + }, + { + id: "corridor.mesh", + no: "D3", + label: "3D 길 모형", + inputs: ["profile.alignment", "cross.design"], + outputs: ["3D", "file:corridor"], + site: "browser_now", + stage: "corridor", + ts: `${B05}B05_Profile_UI_Corridor_Build.ts#buildCorridor`, + runner: "node:corridor.mesh", + pair: null, + mirror: [], + }, + { + id: "footprint.plan", + no: "D4", + label: "평면 발자국(절성토선)", + inputs: ["cross.design", "ground.sample"], + outputs: ["발자국", "store.footprint"], + site: "browser_only", + stage: "footprint", + ts: `${B05L}B05_Profile_PlanFootprint.ts#footprintRecord`, + runner: `browser:${B05L}B05_Profile_Footprint_Stage.ts#footprintStage`, + pair: "B07_DesignDetail/B07_DesignDetail_Engine_Cad_PlanSlope.py#route_frame", + mirror: ["test_346_2_plan_footprint_mirror"], + note: "서버 정본 없음(즉시 후보) · X4 B07 파이썬이 따로 셈(472 밖)", + }, + { + id: "route.recommend", + no: "N1", + label: "노선 추천", + inputs: ["file:dtm_grid", "file:streams"], + outputs: ["추천 노선"], + site: "server_only", + stage: null, + ts: null, + runner: `py:${B05}B05_Profile_Engine_RouteInitial.py#generate_initial_route`, + pair: null, + mirror: ["test_419_1_recommend_engine"], + note: "[적용] 정본은 route.polyline · stations.list 길 · TS 는 보기만(B05_Profile_UI_RouteEdit_Initial_Model.ts)", + }, +]; diff --git a/resources/tester/test_472_3_calc_registry.py b/resources/tester/test_472_3_calc_registry.py index 5bf35026e..6cd971cdf 100644 --- a/resources/tester/test_472_3_calc_registry.py +++ b/resources/tester/test_472_3_calc_registry.py @@ -31,6 +31,7 @@ HERE = Path(__file__).resolve().parent ROOT = HERE.parents[1] FIXTURE = HERE / "fixtures" / "golden_472" REGISTRY = "A00_Common/design/logic/design_calc_registry.ts" +REGISTRY_PARTS = (REGISTRY, "A00_Common/design/logic/design_calc_registry_facility.ts") NODE_ENTRY = "A00_Common/design/logic/design_calc_node.ts" BROWSER_ENTRY = "A00_Common/main.ts" BUNDLE = ROOT / "config" / "design_calc_node" / "design_calc_node.js" @@ -252,7 +253,7 @@ def test_서버_쪽_코드_브라우저_밖(loaded, reach) -> None: assert server # 유토 배분(common_util_mass_haul_balance) assert [path for path in server if path in browser] == [] assert NODE_ENTRY not in browser - assert reach[REGISTRY] == [REGISTRY] # 순수 자료 — 아무것도 안 끔 + assert reach[REGISTRY] == sorted(REGISTRY_PARTS) # 순수 자료 — 제 몫 파일만(나눔 · 함수 안 끔) def test_Node_입구_도달_경계(reach) -> None: diff --git a/resources/tester/test_472_3_calc_runner.py b/resources/tester/test_472_3_calc_runner.py index 3243a35b6..9e223bc18 100644 --- a/resources/tester/test_472_3_calc_runner.py +++ b/resources/tester/test_472_3_calc_runner.py @@ -41,7 +41,10 @@ def _context() -> dict: def test_NODE_IDS_등록부_입구와_같음() -> None: - src = REGISTRY.read_text(encoding="utf-8") + src = "".join( # 등록부 두 몫(나눔) + path.read_text(encoding="utf-8") + for path in (REGISTRY, REGISTRY.with_name("design_calc_registry_facility.ts")) + ) assert set(re.findall(r'runner: "node:([a-z_.]+)"', src)) == runner.NODE_IDS out = runner.run_bundle_json(runner.BUNDLE, runner.NPM_SCRIPT, {"run": [], "inputs": {}}) assert set(out["available"]) == runner.NODE_IDS