From c3975f4ec148fc8a7db530743c0099df532baed5 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Tue, 8 Sep 2026 20:50:22 +0900 Subject: [PATCH] =?UTF-8?q?refactor(B08):=20=EC=B8=A1=EC=A0=90=EB=B3=84=20?= =?UTF-8?q?=EB=8B=A8=EB=A9=B4=EC=9C=A0=ED=98=95=20=ED=91=9C=EB=A5=BC=20?= =?UTF-8?q?=EA=B3=B5=EC=9A=A9=20=ED=95=A8=EC=88=98=EB=A1=9C=20=EB=83=84=20?= =?UTF-8?q?(B07=20=ED=91=9C=EC=A4=80=EB=8F=84=EA=B0=80=20=EA=B0=99?= =?UTF-8?q?=EC=9D=B4=20=EC=93=B0=EA=B2=8C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기울기 판정이 `section_mode` 를 받아야 도는데, 그 표를 만드는 코드가 B08 라우터 안에만 있었음. B07 표준도는 `build_table` 을 직접 부르면서 그 인자를 못 줘 **늘 「가를 근거 없음」** 으로 떨어졌음(랩탑 보조 실측). ⇒ `section_modes_from_designs(designs)` 를 엔진에 두어 **부르는 쪽마다 다시 짜지 않게** 함. B07 은 저장된 횡단 설계 목록을 이 함수에 넣어 `build_table(..., section_modes=…)` 로 주면 됨. ⚠ 동작은 그대로 — `section_mode` 가 없는 측점은 담지 않고, 못 가르면 여전히 「가를 근거 없음 + 종전값 1:0.3」으로 섬(성토로 눅이지 않음). 내 프로젝트 실측 유지 — 돌쌓기(메) H=2.0 **1:0.35 · 21.190㎡**, 근거 「… right_cut · 자동(성토 쪽) → 성토면」. Co-Authored-By: Claude Opus 5 (1M context) --- .../B08_Quantity_Engine_UnitQuantity.py | 19 +++++++++++++++++++ B08_Quantity/B08_Quantity_Router_Material.py | 7 ++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/B08_Quantity/B08_Quantity_Engine_UnitQuantity.py b/B08_Quantity/B08_Quantity_Engine_UnitQuantity.py index d52dad12..ab920281 100644 --- a/B08_Quantity/B08_Quantity_Engine_UnitQuantity.py +++ b/B08_Quantity/B08_Quantity_Engine_UnitQuantity.py @@ -906,6 +906,25 @@ def verify_no_mix_components(quantities: Iterable[StructureQuantity]) -> list[st return found +def section_modes_from_designs(designs: Iterable[dict[str, Any]]) -> dict[float, str]: + """저장된 횡단 설계 목록 → `{측점: 단면유형}`. + + ⚠ **부르는 쪽마다 다시 짜지 말라고 여기 둔다.** 구조물 전개(B08)와 표준도(B07)가 + 같은 표를 써야 기울기 판정이 두 곳에서 갈리지 않는다. + `design.section_mode` 가 없는 측점은 담지 않는다 — 빈 값을 담으면 「가를 근거 없음」과 + 「모드가 빈 문자열」이 뒤섞인다. + """ + modes: dict[float, str] = {} + for item in designs or (): + design = item.get("design") if isinstance(item, dict) else None + mode = str((design or {}).get("section_mode") or "").strip() + if not mode: + continue + chainage = _num(item.get("chainage_m")) + modes[float(chainage)] = mode + return modes + + def _section_mode_at( structure: dict[str, Any], section_modes: dict[float, str] | None ) -> str | None: diff --git a/B08_Quantity/B08_Quantity_Router_Material.py b/B08_Quantity/B08_Quantity_Router_Material.py index 659cb2fd..9a3058f1 100644 --- a/B08_Quantity/B08_Quantity_Router_Material.py +++ b/B08_Quantity/B08_Quantity_Router_Material.py @@ -32,6 +32,7 @@ from B05_Profile.B05_Profile_Structures_Schema import structure_type_map from B08_Quantity.B08_Quantity_Engine_Handoff import build_handoff, load_mapping, summarize from B08_Quantity.B08_Quantity_Engine_MaterialSummary import build_table as build_material_table from B08_Quantity.B08_Quantity_Engine_UnitQuantity import build_table as build_unit_table +from B08_Quantity.B08_Quantity_Engine_UnitQuantity import section_modes_from_designs from common_util.common_util_project_settings import ( concrete_placing_method, quantity_settings, @@ -95,11 +96,7 @@ async def _section_modes(project_id: UUID) -> dict[float, str]: except Exception: logger.exception("B08 단면유형 조회 실패: project_id=%s", project_id) return {} - return { - float(item["chainage_m"]): str((item.get("design") or {}).get("section_mode") or "") - for item in designs - if (item.get("design") or {}).get("section_mode") - } + return section_modes_from_designs(designs) @router.get("/{project_id}/quantity/material-summary")