refactor(511-B B-6 옛 server-calc 묶음 걷음): 운영 부름 0 · 시험 대조만이던 옛 묶음 걷음 — 걷기 전용 커밋(되돌리기 = 이 커밋 revert)
걷은 것 - B06_Section/B06_Section_Server_Calc_Node.ts 통째(135 줄 · 입구 · haul_plan_for 갈래 · 면적 · 유토곡선 · 다단 벽) - package.json:8 build 안 「&& npm run build:server-calc」 · package.json:10 「build:server-calc」 줄 - B06_Section/B06_Section_Server_Calc_Prebuild.py:61 ROOT · :62-63 옛 묶음 주석 · BUNDLE · :66 _NPM_SCRIPT - 지어진 묶음 config/server_calc_node/B06_Section_Server_Calc_Node.js = git 밖(.gitignore:63-64 그대로) · 폴더마다 찌꺼기 남음 시험 옮김(새 입구 = Prebuild._run_node · 등록부 Node design_calc_node) - 110 · 120 · 131 · 73_4 · 178_1 · helper_472_1_paths = _run_node - b06_ground_unlock · height_unlock = design_calc_node.js 판 검사(build:design-calc) - 472_3 registry · runner = 옛 묶음 대조 → Node 입구 정본 값 · 늘 떠 있는 Node = 새 프로세스 - 511_c = 옛 대 새 대조 → 새 Node = 브라우저 TS(computeHaulPlan · structureAreaRows · extraWallRows) - haul_plan_quantity_unpruned = 새 입구 · /haul-plan 그림 갈래 글 검사 · server_calc_node.mjs = design_calc_node structure.layouts - 글만: Schema · HaulPlan · design_calc_node 주석 · B06 CLAUDE.md · 시험 셋 머리 검증: 고친 시험 15 파일 87 통과 · typecheck 0 — 요구 320-4 · 322 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
stored GET 상세(정본 그대로) → 누가토량(서버 Node 묶음 `computeMassHaul`)
|
||||
server_save [저장] 서버 재계산 — 정본 상세 → 종단 경고 다시 셈(`refresh_alignment` · 472 덧) →
|
||||
`enforce_design_lines` → `_enforce_stored_designs` → server-calc
|
||||
`enforce_design_lines` → `_enforce_stored_designs` → 서버 Node(`_run_node`)
|
||||
server_route 노선 저장 체인(같은 노선 · DB 없이) — `run_section_generation`(고정 geojson · npz)
|
||||
→ `_carry_profile` 같은 노선 갈래(옛 base_pvi · 편집) → `_apply_alignment_edits` →
|
||||
측점 열쇠 이월(`carry_cross_inputs`) → `compute_default_designs` → 상세 읽기 →
|
||||
@@ -131,12 +131,10 @@ def _save_tail(detail: dict[str, Any], root: Path) -> tuple[list, dict | None]:
|
||||
from B06_Section.B06_Section_Router_Design import enforce_design_lines
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import (
|
||||
_AREA_KEYS,
|
||||
_NPM_SCRIPT,
|
||||
BUNDLE,
|
||||
_enforce_stored_designs,
|
||||
_run_node,
|
||||
refresh_alignment,
|
||||
)
|
||||
from common_util.common_util_node_bundle import run_bundle_json
|
||||
from common_util.common_util_surface_sampler import build_surface_sampler
|
||||
|
||||
longitudinal = detail["longitudinal"]
|
||||
@@ -151,9 +149,9 @@ def _save_tail(detail: dict[str, Any], root: Path) -> tuple[list, dict | None]:
|
||||
detail = json.loads(
|
||||
json.dumps(detail, default=str)
|
||||
) # 응답 직렬화와 같은 꼴(`model_dump(json)`)
|
||||
output = run_bundle_json(BUNDLE, _NPM_SCRIPT, {"detail": detail, "context": _context()})
|
||||
output = _run_node({"detail": detail, "context": _context()})
|
||||
if not isinstance(output, dict):
|
||||
raise RuntimeError("server-calc 묶음 실패")
|
||||
raise RuntimeError("서버 Node(_run_node) 실패")
|
||||
sections = detail["cross_sections"]
|
||||
for row in output.get("areas") or []:
|
||||
for section in sections:
|
||||
@@ -261,13 +259,12 @@ def server_route(root: Path) -> dict[str, Any]:
|
||||
|
||||
def stored(root: Path) -> dict[str, Any]:
|
||||
"""정본 그대로 — GET 상세 면적 · 서버 Node 묶음과 같은 누가토량(화면 배지 값)."""
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import _NPM_SCRIPT, BUNDLE
|
||||
from common_util.common_util_node_bundle import run_bundle_json
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import _run_node
|
||||
|
||||
detail = read("detail.json")
|
||||
alignment = detail["longitudinal"].get("profile_alignment") or {}
|
||||
keys = _keys(detail["longitudinal"], detail["cross_sections"], root)
|
||||
output = run_bundle_json(BUNDLE, _NPM_SCRIPT, {"detail": detail, "context": _context()})
|
||||
output = _run_node({"detail": detail, "context": _context()})
|
||||
haul = (output or {}).get("mass_haul")
|
||||
return values_of(
|
||||
detail["cross_sections"],
|
||||
|
||||
@@ -101,10 +101,9 @@ def test_패치가_받는다() -> None:
|
||||
|
||||
|
||||
def _server_rows(sections: list[dict]) -> dict[float, dict]:
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import _NPM_SCRIPT, BUNDLE
|
||||
from common_util.common_util_node_bundle import run_bundle_json
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import _run_node
|
||||
|
||||
output = run_bundle_json(BUNDLE, _NPM_SCRIPT, {"detail": {"cross_sections": sections}})
|
||||
output = _run_node({"detail": {"cross_sections": sections}})
|
||||
assert output, "서버 Node 번들 실행 실패"
|
||||
return {round(r["chainage_m"], 3): r for r in output["areas"]}
|
||||
|
||||
|
||||
@@ -288,15 +288,14 @@ def test_패치가_박스_길이를_받는다():
|
||||
|
||||
@needs_node
|
||||
def test_서버가_박스_본체_길이를_주인_측점에만():
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import _NPM_SCRIPT, BUNDLE
|
||||
from common_util.common_util_node_bundle import run_bundle_json
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import _run_node
|
||||
|
||||
data = json.loads((FIXTURES / "b06_73_4_body_guard_sections.json").read_text("utf-8"))
|
||||
sections = data["cross_sections"]
|
||||
box_at = next(s for s in sections if s.get("box"))
|
||||
neighbour = next(s for s in sections if s["chainage_m"] == 340)
|
||||
neighbour["box"] = copy.deepcopy(box_at["box"])
|
||||
output = run_bundle_json(BUNDLE, _NPM_SCRIPT, {"detail": {"cross_sections": sections}})
|
||||
output = _run_node({"detail": {"cross_sections": sections}})
|
||||
rows = {round(r["chainage_m"], 3): r for r in output["areas"]}
|
||||
assert rows[352.14]["box_length_m"] > 0
|
||||
assert "box_length_m" not in rows[340]
|
||||
|
||||
@@ -145,15 +145,14 @@ def test_세월교_관_길이_없으면_빈칸_알림(tmp_path):
|
||||
|
||||
@needs_node
|
||||
def test_서버가_세월교_관_길이를_주인_측점에만():
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import _NPM_SCRIPT, BUNDLE
|
||||
from common_util.common_util_node_bundle import run_bundle_json
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import _run_node
|
||||
|
||||
data = json.loads((FIXTURES / "b06_73_4_body_guard_sections.json").read_text("utf-8"))
|
||||
sections = data["cross_sections"]
|
||||
ford_at = next(s for s in sections if s.get("ford"))
|
||||
neighbour = next(s for s in sections if s["chainage_m"] == 180)
|
||||
neighbour["ford"] = copy.deepcopy(ford_at["ford"])
|
||||
output = run_bundle_json(BUNDLE, _NPM_SCRIPT, {"detail": {"cross_sections": sections}})
|
||||
output = _run_node({"detail": {"cross_sections": sections}})
|
||||
rows = {round(r["chainage_m"], 3): r for r in output["areas"]}
|
||||
length = rows[173.087]["ford_pipe_length_m"]
|
||||
assert length > 0 and length == int(length) # 1 m 올림
|
||||
|
||||
@@ -5,12 +5,11 @@
|
||||
⇒ 관 링크는 있으나 관 벽이 안 서는 측점에서 카드엔 흙막이가 서고 서버 면적 · B07 엔 없음.
|
||||
|
||||
고침: `ownWallsDrawAt` 한 벌을 세 곳이 함께 씀. 서버 면적은 같은 TS 를 Node 로 돌리므로
|
||||
번들을 새로 빌드해 그 결과로 판정한다.
|
||||
[저장] 재계산 Node 입구(`_run_node`) 결과로 판정한다.
|
||||
"""
|
||||
|
||||
import copy
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
@@ -32,36 +31,17 @@ SOIL_GUARD = {
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def bundle(tmp_path_factory) -> Path:
|
||||
def bundle():
|
||||
"""서버 면적 = [저장] 재계산 Node 입구(`_run_node` · 옛 server-calc 묶음 = 511-B B-6 걷음)."""
|
||||
if not VITE.is_file():
|
||||
pytest.skip("프론트엔드 의존성 미설치")
|
||||
out = tmp_path_factory.mktemp("server_calc")
|
||||
subprocess.run( # noqa: S603 — 고정 실행 파일
|
||||
[
|
||||
"node",
|
||||
str(VITE),
|
||||
"build",
|
||||
"--configLoader",
|
||||
"runner",
|
||||
"--ssr",
|
||||
"../B06_Section/B06_Section_Server_Calc_Node.ts",
|
||||
"--outDir",
|
||||
str(out),
|
||||
"--logLevel",
|
||||
"error",
|
||||
],
|
||||
cwd=str(ROOT),
|
||||
check=True,
|
||||
capture_output=True,
|
||||
)
|
||||
return out / "B06_Section_Server_Calc_Node.js"
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import _run_node
|
||||
|
||||
return _run_node
|
||||
|
||||
|
||||
def _areas(bundle: Path, sections: list, tmp_path: Path) -> dict[float, tuple]:
|
||||
src, dst = tmp_path / "in.json", tmp_path / "out.json"
|
||||
src.write_text(json.dumps({"detail": {"cross_sections": sections}}), encoding="utf-8")
|
||||
subprocess.run(["node", str(bundle), str(src), str(dst)], check=True, cwd=str(ROOT)) # noqa: S603
|
||||
rows = json.loads(dst.read_text(encoding="utf-8"))["areas"]
|
||||
def _areas(bundle, sections: list, tmp_path: Path) -> dict[float, tuple]:
|
||||
rows = bundle({"detail": {"cross_sections": sections}})["areas"]
|
||||
return {row["chainage_m"]: (row["cut_area_m2"], row["fill_area_m2"]) for row in rows}
|
||||
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ Node 입구 = `A00_Common/design/logic/design_calc_node.ts`(`build:design-calc`
|
||||
- 서버 쪽(server_canon · server_only) TS 가 브라우저 import 그래프에 없음 · 등록부는 안 끔.
|
||||
- Node 입구 도달 집합 = logic · common_util · 자료만 + 「알려진 끌림」(`KNOWN_PULLS`) — 그 밖은
|
||||
실패 · 안 나타난 알려진 끌림도 실패(목록에서 지움 — 472-2 2-B · 472-4 가 하나씩 걷어 빈 목록).
|
||||
- Node 입구 값 = 기존 묶음 값(고정 자료 `fixtures/golden_472` · server-calc 면적 · 다단 벽 ·
|
||||
누가토량 · 배분 · corridor 3D) · 터파기 = 파이썬 짝.
|
||||
- Node 입구 값(고정 자료 `fixtures/golden_472` · 면적 · 다단 벽 · 누가토량 끝값 · 배분 두 벌 ·
|
||||
corridor 3D = corridor 묶음) · 터파기 = 파이썬 짝.
|
||||
|
||||
./venv/Scripts/python.exe -m pytest resources/tester/test_472_3_calc_registry.py -q
|
||||
"""
|
||||
@@ -306,19 +306,12 @@ def golden_run() -> dict:
|
||||
return out["results"]
|
||||
|
||||
|
||||
def test_server_calc_묶음과_같음(golden_run) -> None:
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import _NPM_SCRIPT
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import BUNDLE as SC_BUNDLE
|
||||
from common_util.common_util_node_bundle import run_bundle_json
|
||||
|
||||
sc = run_bundle_json(
|
||||
SC_BUNDLE, _NPM_SCRIPT, {"detail": _fixture("detail.json"), "context": _context()}
|
||||
)
|
||||
def test_Node_입구_정본_값(golden_run) -> None:
|
||||
# 옛 server-calc 묶음 걷음(511-B B-6) — 값은 472-1 기준값 시험(`stored` · `server_save`)
|
||||
layouts = golden_run["structure.layouts"]
|
||||
assert layouts["areas"] == sc["areas"] and sc["areas"]
|
||||
assert layouts["extra_walls"] == sc["extra_walls"]
|
||||
assert layouts["areas"] and isinstance(layouts["extra_walls"], list)
|
||||
merged = {**golden_run["masshaul.cumulative"], **golden_run["haul.plan"]}
|
||||
assert merged == sc["mass_haul"]
|
||||
assert merged["haul_plan"] and merged["haul_plan_drawing"]
|
||||
assert merged["final_cumulative_m3"] == -17570.7 # 472-1 화면 참값
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
못박는 것
|
||||
- `NODE_IDS` = 등록부 `node:` 줄 = 입구 표(`available`).
|
||||
- 고정 자료 `fixtures/golden_472` 로 `run_calc` 값 = [저장] 재계산이 부르는 server-calc 묶음 값
|
||||
(`Server_Calc_Prebuild` BUNDLE · 면적 · 다단 벽 · 누가토량 · 배분 · 끝값 −17,570.7).
|
||||
- 고정 자료 `fixtures/golden_472` 로 늘 떠 있는 Node `run_calc` 값 = 같은 묶음 새 프로세스 값
|
||||
(면적 · 다단 벽 · 누가토량 · 배분 · 끝값 −17,570.7).
|
||||
- Node 실행기 아닌 id(파이썬 · 브라우저 실행기)는 ValueError.
|
||||
|
||||
./venv/Scripts/python.exe -m pytest resources/tester/test_472_3_calc_runner.py -q
|
||||
@@ -50,21 +50,14 @@ def test_NODE_IDS_등록부_입구와_같음() -> None:
|
||||
assert set(out["available"]) == runner.NODE_IDS
|
||||
|
||||
|
||||
def test_실행기_값_server_calc_와_같음() -> None:
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import _NPM_SCRIPT, BUNDLE
|
||||
from common_util.common_util_node_bundle import run_bundle_json
|
||||
|
||||
sc = run_bundle_json(
|
||||
BUNDLE, _NPM_SCRIPT, {"detail": _fixture("detail.json"), "context": _context()}
|
||||
)
|
||||
got = runner.run_calc(
|
||||
["structure.layouts", "masshaul.cumulative", "haul.plan"],
|
||||
{"detail": _fixture("detail.json"), "context": _context()},
|
||||
)
|
||||
assert got["structure.layouts"]["areas"] == sc["areas"] and sc["areas"]
|
||||
assert got["structure.layouts"]["extra_walls"] == sc["extra_walls"]
|
||||
def test_늘_떠_있는_Node_새_프로세스와_같음() -> None:
|
||||
# 옛 server-calc 묶음 걷음(511-B B-6) — 늘 떠 있는 Node(`run_calc`) = 같은 묶음 새 프로세스
|
||||
ids = ["structure.layouts", "masshaul.cumulative", "haul.plan"]
|
||||
inputs = {"detail": _fixture("detail.json"), "context": _context()}
|
||||
got = runner.run_calc(ids, inputs)
|
||||
fresh = runner.run_bundle_json(runner.BUNDLE, runner.NPM_SCRIPT, {"run": ids, "inputs": inputs})
|
||||
assert got == fresh["results"] and got["structure.layouts"]["areas"]
|
||||
merged = {**got["masshaul.cumulative"], **got["haul.plan"]}
|
||||
assert merged == sc["mass_haul"]
|
||||
assert merged["final_cumulative_m3"] == -17570.7
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""511-C (요구 320-4) — 유토 배분 E2 = 늘 떠 있는 Node(TS 한 벌) · 옛 server-calc 묶음 값과 0 차.
|
||||
"""511-C (요구 320-4) — 유토 배분 E2 = 늘 떠 있는 Node(TS 한 벌) = 브라우저 자리 TS 0 차.
|
||||
|
||||
못박는 것
|
||||
- /haul-plan 창구 새 길(`_run_view` → 시험 길 `haul.view`) = 옛 server-calc `haul_plan_for` 갈래
|
||||
- /haul-plan 창구 새 길(`_run_view` → 시험 길 `haul.view`)
|
||||
= 브라우저 자리 함수(`computeHaulPlan` 바로 부름) — 프로젝트 일곱
|
||||
(저장 유토곡선 · DB 에서 한 번 뜬 `fixtures/haul_511_c.json`)
|
||||
× 문맥(기본 · 장비 경계 없음 · 구조물 잔토 · 채집석) × 그림 · 수량.
|
||||
- 끝 경우 — 측점 하나(배분 없음 null) · 둘 · 전부 0 · 전부 절토 · 전부 성토.
|
||||
- [저장] 정본 새 길(`Server_Calc_Prebuild._node_output` → 늘 떠 있는 Node 셋) = 옛 server-calc
|
||||
`{detail, context}` 답(면적 · 다단 벽 · 유토곡선 + 배분 두 벌) — golden_472 · 문맥 셋.
|
||||
- [저장] 정본 새 길(`Server_Calc_Prebuild._node_output` → 늘 떠 있는 Node 셋) = 브라우저 자리
|
||||
TS(`structureAreaRows` · `extraWallRows`) · 유토곡선 끝값 · 배분 두 벌 — golden_472 · 문맥 셋
|
||||
(옛 server-calc 묶음 = 511-B B-6 걷음).
|
||||
|
||||
./venv/Scripts/python.exe -m pytest resources/tester/test_511_c_haul_node.py -q
|
||||
"""
|
||||
@@ -31,7 +32,6 @@ if str(ROOT) not in sys.path:
|
||||
|
||||
from B06_Section import B06_Section_Router_HaulPlan as haul_router # noqa: E402
|
||||
from B06_Section import B06_Section_Server_Calc_Prebuild as prebuild # noqa: E402
|
||||
from common_util.common_util_node_bundle import run_bundle_json # noqa: E402
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
shutil.which("node") is None or not (ROOT / "config" / "node_modules" / "vite").is_dir(),
|
||||
@@ -106,14 +106,6 @@ def _browser(tmp_path: Path, calls: list[dict]) -> list:
|
||||
return json.loads(proc.stdout)
|
||||
|
||||
|
||||
def _old_view(result: dict, context: dict):
|
||||
out = run_bundle_json(
|
||||
prebuild.BUNDLE, prebuild._NPM_SCRIPT, {"haul_plan_for": result, "context": context}
|
||||
)
|
||||
assert isinstance(out, dict), out
|
||||
return out["haul_plan"]
|
||||
|
||||
|
||||
def _edge_results() -> dict[str, dict]:
|
||||
conv = PROJECTS["483"]["conversion"]
|
||||
|
||||
@@ -147,7 +139,7 @@ def _edge_results() -> dict[str, dict]:
|
||||
}
|
||||
|
||||
|
||||
def test_창구_새_길_옛_묶음_브라우저_같음(tmp_path):
|
||||
def test_창구_새_길_브라우저_같음(tmp_path):
|
||||
cases = [
|
||||
(f"{rid}·{name}", _result(payload), context)
|
||||
for rid, payload in PROJECTS.items()
|
||||
@@ -167,7 +159,6 @@ def test_창구_새_길_옛_묶음_브라우저_같음(tmp_path):
|
||||
for index, (label, result, context) in enumerate(cases):
|
||||
new = haul_router._run_view(result, context)
|
||||
assert new is not None, label
|
||||
assert new["haul_plan"] == _old_view(result, context), label
|
||||
assert new["haul_plan"] == browser[2 * index], label
|
||||
quantity = haul_router.run_calc_served(
|
||||
["haul.view"],
|
||||
@@ -189,11 +180,20 @@ def test_창구_새_길_옛_묶음_브라우저_같음(tmp_path):
|
||||
|
||||
|
||||
@pytest.mark.parametrize("name", ["기본", "구조물 잔토", "채집석"])
|
||||
def test_저장_정본_새_길_옛_묶음_같음(name, monkeypatch):
|
||||
def test_저장_정본_새_길_브라우저_같음(name, monkeypatch, tmp_path):
|
||||
monkeypatch.setattr(prebuild, "_NODE_CACHE", {})
|
||||
detail = json.loads((GOLDEN / "detail.json").read_text(encoding="utf-8"))
|
||||
node_input = {"detail": detail, "context": _contexts()[name]}
|
||||
old = run_bundle_json(prebuild.BUNDLE, prebuild._NPM_SCRIPT, copy.deepcopy(node_input))
|
||||
new = prebuild._node_output(copy.deepcopy(node_input))
|
||||
assert new == old
|
||||
layouts = "B06_Section/B06_Section_Structure_Layouts.ts"
|
||||
sections = detail["cross_sections"]
|
||||
areas, walls = _browser(
|
||||
tmp_path,
|
||||
[
|
||||
{"mod": layouts, "fn": "structureAreaRows", "args": [sections]},
|
||||
{"mod": layouts, "fn": "extraWallRows", "args": [sections]},
|
||||
],
|
||||
)
|
||||
assert new["areas"] == areas and areas
|
||||
assert new["extra_walls"] == walls
|
||||
assert new["mass_haul"]["haul_plan"] and new["mass_haul"]["haul_plan_drawing"]
|
||||
|
||||
@@ -69,11 +69,10 @@ def test_설계선_트림은_흙막이_쪽(screen: dict) -> None:
|
||||
|
||||
|
||||
def test_서버_면적이_화면과_같음(screen: dict) -> None:
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import _NPM_SCRIPT, BUNDLE
|
||||
from common_util.common_util_node_bundle import run_bundle_json
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import _run_node
|
||||
|
||||
sections = json.loads(FIXTURE.read_text(encoding="utf-8"))["cross_sections"]
|
||||
output = run_bundle_json(BUNDLE, _NPM_SCRIPT, {"detail": {"cross_sections": sections}})
|
||||
output = _run_node({"detail": {"cross_sections": sections}})
|
||||
assert output, "서버 Node 번들 실행 실패"
|
||||
server = {round(r["chainage_m"], 2): r for r in output["areas"]}
|
||||
for row in screen["areas"]:
|
||||
|
||||
@@ -38,7 +38,7 @@ _COMPUTED_FIELDS = {
|
||||
"cut_soil_area_m2",
|
||||
"cut_rock_area_m2",
|
||||
# 배수관 연장(m, 2026-09-08) — 사용자 값이 아니라 **기하가 낸 값**이다. 면적 넷과 **같은
|
||||
# 다리**(`STRUCTURE_ROW_KEYS` → `B06_Section_Server_Calc_Node` →
|
||||
# 다리**(`STRUCTURE_ROW_KEYS` → `design_calc_node` `structure.layouts` →
|
||||
# `recompute_server_side`)로 서버가 다시 내므로 재계산에서 안 사라진다.
|
||||
"pipe_length_m",
|
||||
# B08 하상경사 원천(110) — 관 경사 · 박스 원지반 경사(%) · 관 길이와 같은 다리.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""원지반 잠금 풀기(54-45) — 흙막이 자리 · 다단 · 높이를 원지반이 막지 않음.
|
||||
|
||||
남는 규칙: 벽 윗면 노면 위 금지(d ≥ 0) · 관 보호공 흙막이 m 단위 자리(관 길이 정수).
|
||||
서버 면적은 같은 TS 를 Node 로 돌림(`B06_Section_Server_Calc_Node.ts`) — 번들도 같은 판인지 봄.
|
||||
서버 면적은 같은 TS 를 Node 로 돌림(`design_calc_node.ts` `structure.layouts`) — 번들도 같은 판인지 봄.
|
||||
"""
|
||||
|
||||
import json
|
||||
@@ -14,7 +14,7 @@ import pytest
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
||||
B06 = PROJECT_ROOT / "B06_Section"
|
||||
TSC = PROJECT_ROOT / "config" / "node_modules" / "typescript" / "bin" / "tsc"
|
||||
BUNDLE = PROJECT_ROOT / "config" / "server_calc_node" / "B06_Section_Server_Calc_Node.js"
|
||||
BUNDLE = PROJECT_ROOT / "config" / "design_calc_node" / "design_calc_node.js"
|
||||
|
||||
_RUNNER = """
|
||||
import { writeFileSync } from "node:fs";
|
||||
@@ -101,5 +101,5 @@ def test_화면_서버_같은_판() -> None:
|
||||
), "추가 흙막이 매몰 자리 금지가 남음"
|
||||
bundle = BUNDLE.read_text(encoding="utf-8")
|
||||
assert "outletReceivable" not in bundle and "requireCrossing" not in bundle, (
|
||||
"서버 번들이 옛 판 — npm run build:server-calc"
|
||||
"서버 번들이 옛 판 — npm run build:design-calc"
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""높이 제약 풀기(54-51) — 관 흙막이 · 추가 흙막이 · 사면안정 흙막이 · 옹벽 · 집수정 높이를 사용자 값 그대로.
|
||||
|
||||
남는 규칙: 그림이 안 서는 값(순수 높이 0 이하)만 0.1 에서 멈춤 · 토스트 없음.
|
||||
서버 면적은 같은 TS 를 Node 로 돌림(`B06_Section_Server_Calc_Node.ts`) — 번들도 같은 판인지 봄.
|
||||
서버 면적은 같은 TS 를 Node 로 돌림(`design_calc_node.ts` `structure.layouts`) — 번들도 같은 판인지 봄.
|
||||
"""
|
||||
|
||||
import json
|
||||
@@ -14,7 +14,7 @@ import pytest
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
||||
B06 = PROJECT_ROOT / "B06_Section"
|
||||
TSC = PROJECT_ROOT / "config" / "node_modules" / "typescript" / "bin" / "tsc"
|
||||
BUNDLE = PROJECT_ROOT / "config" / "server_calc_node" / "B06_Section_Server_Calc_Node.js"
|
||||
BUNDLE = PROJECT_ROOT / "config" / "design_calc_node" / "design_calc_node.js"
|
||||
|
||||
_RUNNER = """
|
||||
import { writeFileSync } from "node:fs";
|
||||
@@ -92,5 +92,5 @@ def test_높이_토스트_없음_서버_같은_판() -> None:
|
||||
panel = (B06 / "B06_Section_UI_Cross_Structure_Panel.ts").read_text(encoding="utf-8")
|
||||
assert "Math.min(\n 2," not in panel, "집수정 내공 2m 상한이 남음"
|
||||
bundle = BUNDLE.read_text(encoding="utf-8")
|
||||
assert "EXTRA_WALL_MIN_HEIGHT_M" not in bundle, "서버 번들이 옛 판 — npm run build:server-calc"
|
||||
assert "WALL_MIN_PURE_HEIGHT_M" in bundle, "서버 번들이 옛 판 — npm run build:server-calc"
|
||||
assert "EXTRA_WALL_MIN_HEIGHT_M" not in bundle, "서버 번들이 옛 판 — npm run build:design-calc"
|
||||
assert "WALL_MIN_PURE_HEIGHT_M" in bundle, "서버 번들이 옛 판 — npm run build:design-calc"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
무슨 일이었나 — 관 길이는 횡단 기하가 **m 단위 올림까지** 끝낸 값인데(`CulvertLayout.pipe.lengthM`)
|
||||
**정본(`design`)에 없었다.** 그래서 수량(B08)이 관 11개를 보고도 **연장을 못 내** 배수관 공종이
|
||||
막혀 있었다. B08 창은 「계산을 서버로 옮기든가 저장 때 남기든가」 둘로 갈래를 냈는데, 실제로는
|
||||
**그 계산이 이미 서버 Node 로 돌고 있었다**(`B06_Section_Server_Calc_Node` ←
|
||||
**그 계산이 이미 서버 Node 로 돌고 있었다**(`design_calc_node` `structure.layouts` ←
|
||||
`Server_Calc_Prebuild.recompute_server_side`, [저장]·[확정] 때). 그래서 **그 다리에 값 한 줄만**
|
||||
더 실었다 — 계산을 두 벌로 짜지 않는다(CLAUDE.md 5장).
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ import { join, resolve } from "node:path";
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const ROOT = resolve(import.meta.dirname, "../..");
|
||||
const BUNDLE = join(ROOT, "config/server_calc_node/B06_Section_Server_Calc_Node.js");
|
||||
// 옛 server-calc 묶음 걷음(511-B B-6) — 서버 정본 = 등록부 Node 입구 `structure.layouts`
|
||||
const BUNDLE = join(ROOT, "config/design_calc_node/design_calc_node.js");
|
||||
|
||||
/** 평지 위 표준 횡단 한 측점 — 구조물 없음. */
|
||||
function plainSection(chainage) {
|
||||
@@ -30,7 +31,10 @@ function plainSection(chainage) {
|
||||
{ offset_m: -3, elevation_m: 100 },
|
||||
{ offset_m: 3, elevation_m: 100 },
|
||||
],
|
||||
road_edges: { left: { offset_m: -3, elevation_m: 100 }, right: { offset_m: 3, elevation_m: 100 } },
|
||||
road_edges: {
|
||||
left: { offset_m: -3, elevation_m: 100 },
|
||||
right: { offset_m: 3, elevation_m: 100 },
|
||||
},
|
||||
cut_area_m2: 1.23,
|
||||
fill_area_m2: 4.56,
|
||||
},
|
||||
@@ -42,10 +46,13 @@ const input = join(work, "input.json");
|
||||
const output = join(work, "output.json");
|
||||
writeFileSync(
|
||||
input,
|
||||
JSON.stringify({ detail: { cross_sections: [plainSection(0), plainSection(20)] } }),
|
||||
JSON.stringify({
|
||||
run: ["structure.layouts"],
|
||||
inputs: { detail: { cross_sections: [plainSection(0), plainSection(20)] } },
|
||||
}),
|
||||
);
|
||||
execFileSync("node", [BUNDLE, input, output], { cwd: ROOT });
|
||||
const { areas: rows } = JSON.parse(readFileSync(output, "utf8"));
|
||||
const { areas: rows } = JSON.parse(readFileSync(output, "utf8")).results["structure.layouts"];
|
||||
|
||||
assert.ok(Array.isArray(rows), "결과는 배열이어야 한다");
|
||||
assert.equal(rows.length, 0, `구조물 없는 측점은 결과에 없어야 한다 (받은 수: ${rows.length})`);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
② 형태별 높이 한도(메 2.0 · 찰 3.0 · 콘크리트 5.0) · 원지반 맞춤 자동 자르기 없음.
|
||||
③ 벽 윗면은 노면 위로 올라오지 않음(넘으면 노면에서 멈춤).
|
||||
|
||||
서버 면적은 같은 TS 를 Node 로 돌리므로(`B06_Section_Server_Calc_Node.ts`) 이 함수가 곧 서버 기하.
|
||||
서버 면적은 같은 TS 를 Node 로 돌리므로(`design_calc_node.ts` `structure.layouts`) 이 함수가 곧 서버 기하.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
@@ -132,11 +132,16 @@ def test_수량_계획은_작은_봉우리도_운반으로_센다(tmp_path: Path
|
||||
|
||||
|
||||
def test_서버_정본은_수량과_그림을_따로_둔다() -> None:
|
||||
source = (PROJECT_ROOT / "B06_Section" / "B06_Section_Server_Calc_Node.ts").read_text(
|
||||
# 옛 server-calc 묶음 걷음(511-B B-6) — 저장 정본 = 등록부 Node 입구 · 화면 선반입 = /haul-plan
|
||||
source = (PROJECT_ROOT / "A00_Common" / "design" / "logic" / "design_calc_node.ts").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
view = (PROJECT_ROOT / "B06_Section" / "B06_Section_Router_HaulPlan.py").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
# ③ 화면 선반입(그림)은 거른 계획, 저장 정본은 둘 다.
|
||||
assert "drawing: true" in source
|
||||
assert 'options["drawing"] = True' in view
|
||||
assert "planFor(false)" in source and "planFor(true)" in source
|
||||
assert "haul_plan_drawing" in source
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user