From 8a78927d810c6fe09bdedfc494d1249e779be235 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Wed, 9 Sep 2026 23:07:02 +0900 Subject: [PATCH] =?UTF-8?q?fix(B08):=20=EB=B0=91=EC=88=98=20=EB=8C=80?= =?UTF-8?q?=EC=A1=B0=20=EA=B0=80=EB=93=9C=EA=B0=80=20=EB=AA=BB=20=EB=B3=B4?= =?UTF-8?q?=EB=8D=98=20=EB=A7=88=EC=A7=80=EB=A7=89=20=ED=95=9C=20=EC=A4=84?= =?UTF-8?q?=20=E2=80=94=20=EA=B0=80=EC=84=A4=EC=B0=BD=EA=B3=A0=EC=97=90=20?= =?UTF-8?q?=EB=B0=91=EC=88=98=EB=A5=BC=20=EC=A0=81=EC=9D=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 내역에 실리는 25 줄 중 FP-11-01 가설창고만 밑수가 없어 대조를 건너뛰고 있었음. 품셈 11-1 은 절 머리에 「(단위: …)」가 없어 마스터가 못 채우는 자리라, 매핑에 원문 근거와 함께 「개소」를 적어 통로로 채움([주]① 설치·해체 각각 · [주]③ 1개설치당). - 매핑에 `ancillary` 절을 만들고 그 절도 밑수 대조에 쓰이게 함. - 이제 내역에 실리는 25 줄이 전부 대조됨 — 일부러 m 로 보내면 가드가 잡는 것을 시험으로 확인. Co-Authored-By: Claude Opus 5 (1M context) --- .../B08_Quantity_Engine_Handoff_Mapping.py | 5 +++- .../work_item_mapping_2026-01-01.json | 10 +++++++ resources/tester/test_b08_basis_unit.py | 26 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/B08_Quantity/B08_Quantity_Engine_Handoff_Mapping.py b/B08_Quantity/B08_Quantity_Engine_Handoff_Mapping.py index a99b51a3..dfadd8eb 100644 --- a/B08_Quantity/B08_Quantity_Engine_Handoff_Mapping.py +++ b/B08_Quantity/B08_Quantity_Engine_Handoff_Mapping.py @@ -195,6 +195,8 @@ class WorkItemMapping: earthwork: list[dict[str, Any]] = field(default_factory=list) haul: list[dict[str, Any]] = field(default_factory=list) structure: list[dict[str, Any]] = field(default_factory=list) + #: 준비공 부대시설·가설 — 지금은 **밑수 단위를 적어 두는 자리**로만 쓴다(가설창고 11-1). + ancillary: list[dict[str, Any]] = field(default_factory=list) pending_user: dict[str, Any] = field(default_factory=dict) composite: dict[str, Any] = field(default_factory=dict) concrete_placing: dict[str, Any] = field(default_factory=dict) @@ -213,7 +215,7 @@ class WorkItemMapping: 함께 남길 것 — 근거 없는 단위가 대조의 기준이 되면 안 된다. """ found: dict[str, str] = {} - for row in (*self.earthwork, *self.haul, *self.structure): + for row in (*self.earthwork, *self.haul, *self.structure, *self.ancillary): code, unit = row.get("work_item_code"), row.get("basis_unit") if code and unit and is_quantity_unit(str(unit)): found[str(code)] = str(unit) @@ -266,6 +268,7 @@ def load_mapping(path: Path | None = None) -> WorkItemMapping: earthwork=list(payload.get("earthwork") or []), haul=list(payload.get("haul") or []), structure=list(payload.get("structure") or []), + ancillary=list(payload.get("ancillary") or []), pending_user=payload.get("pending_user") or {}, composite=payload.get("composite") or {}, concrete_placing=payload.get("concrete_placing") or {}, diff --git a/resources/data_work_item_mapping/work_item_mapping_2026-01-01.json b/resources/data_work_item_mapping/work_item_mapping_2026-01-01.json index a1b4d3ff..d8076881 100644 --- a/resources/data_work_item_mapping/work_item_mapping_2026-01-01.json +++ b/resources/data_work_item_mapping/work_item_mapping_2026-01-01.json @@ -222,6 +222,16 @@ "note": "품셈 12-10 · 밑수 1 m" } ], + "ancillary": [ + { + "group": "가설창고(컨테이너)", + "work_item_code": "FP-11-01", + "basis_unit": "개소", + "basis_source": "산림사업 표준품셈(고시 2025-82) 11-1 콘테이너형 가설건축물 — 절 머리에 「(단위: …)」가 없어 마스터가 못 채운 자리. [주]③ 「트럭크레인 사용시간은 **1개설치당** 2시간 기준이다」와 [주]① 「설치 또는 해체 시에 **각각** 적용한다」가 밑수를 1동(개소)당으로 말한다(2026-09-09 원문 대조).", + "master_name": "가설 > 콘테이너형 가설건축물", + "note": "⚠ 이 줄이 비어 있어 **밑수 대조 가드가 이 공종만 못 보고 있었다**(2026-09-09 실측: 내역에 실리는 25 줄 중 유일하게 안 보이던 자리). 개소 수는 현장 조건이라 설계가 정한다." + } + ], "pending_user": { "note": "이름이 비슷한 후보는 있으나 **어느 것인지 정할 근거가 없는** 자리. 임의로 고르지 않고 unmatched 로 낸다(CLAUDE.md 3장).", "items": [ diff --git a/resources/tester/test_b08_basis_unit.py b/resources/tester/test_b08_basis_unit.py index 63591f7b..eae5496a 100644 --- a/resources/tester/test_b08_basis_unit.py +++ b/resources/tester/test_b08_basis_unit.py @@ -275,3 +275,29 @@ def test_매핑에_적힌_밑수가_전부_공종_단위다() -> None: for code, unit in MAPPING.declared_units().items(): assert is_quantity_unit(unit), f"{code}: {unit}" + + +def test_부대시설_가설창고도_대조된다() -> None: + """⚠ 내역에 실리는 25 줄 중 **이 공종만** 밑수가 없어 가드가 못 보고 있었다(2026-09-09). + + 마스터는 절 머리에 「(단위: …)」가 있어야 밑수를 채우는데 11-1 은 그것이 없다. + 매핑에 원문 근거([주]① · [주]③)와 함께 「개소」를 적어 대조가 서게 했다. + """ + from B08_Quantity.B08_Quantity_Engine_Handoff_Mapping import load_mapping + + declared = load_mapping().declared_units() + assert declared.get("FP-11-01") == "개소" + + rows = [ + { + "work_item_code": "FP-11-01", + "name": "가설창고(컨테이너)", + "unit": "m", + "in_bill": True, + } + ] + warnings = verify_unit_matches_basis(rows, extra=declared) + assert len(warnings) == 1 and "개소" in warnings[0] + # 맞는 단위로 보내면 조용하다. + ok = [dict(rows[0], unit="개소")] + assert verify_unit_matches_basis(ok, extra=declared) == []