fix(axis): 9-19-3 비탈면 고르기(발파암) 소형브레이커 = 5210-0010(1.0㎥/min) — 값 출처 9-19-1 표·[주]① 이 규격을 정함(브레인 승인) · 범위 별칭이 코드를 적으면 그 항목으로 곧장 이음 · 어어호스는 카탈로그 없어 그대로

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn
This commit is contained in:
2026-09-14 13:15:09 +09:00
co-authored by Claude Opus 5
parent 626f518064
commit bba23376f1
4 changed files with 46 additions and 1 deletions
@@ -574,8 +574,10 @@ def match_table(
# 정상 자원이 조용히 사라진다(2026-09-07 실측 — 부분일치 필터가 매칭 14건을
# 지우고 있었음). 카탈로그에 있는 이름은 **정의상 자원**이다.
# 범위 별칭 — 그 공종 범위 안에서만 카탈로그 쪽 이름으로 바꾼다(「화약공」 → 화약취급공).
# 별칭이 코드를 적었으면 그 항목으로 곧장(규격이 조인 키인 기계가 다시 흐려지지 않게).
entry = scoped_alias_entry(catalog, name_cell, node["work_item_code"])
name_cell = apply_scoped_alias(catalog, name_cell, node["work_item_code"])
entry = _resolve_cell(catalog, name_cell, [name_cell, *value_cells])
entry = entry or _resolve_cell(catalog, name_cell, [name_cell, *value_cells])
if entry is None:
if is_non_resource_label(name_cell):
continue # 머리글·소계 — 못 맞춘 목록에도 안 올린다
@@ -699,6 +701,7 @@ from B09_Estimation.B09_Estimation_ResourceAxis_Sources import ( # noqa: E402
from B09_Estimation.B09_Estimation_ResourceAxis_Join import ( # noqa: E402
apply_scoped_alias,
pick_by_spec,
scoped_alias_entry,
resolve_family,
text_spec_candidates,
unmatched_reason,
@@ -107,6 +107,22 @@ def load_scoped_aliases() -> list[dict[str, str]]:
return load_aliases("resource")
def scoped_alias_entry(
catalog: ResourceCatalog, name_cell: str, work_item_code: str
) -> CatalogEntry | None:
"""범위 별칭이 가리키는 **항목 그 자체**(코드로 곧장) — 없으면 `None`.
⚠ 이름만 돌려주면 규격이 조인 키인 기계(소형브레이커 공압식 넷)는 다시 「규격 미정」 으로
흐려짐 — 별칭이 코드를 적었으면 그 코드가 곧 답(2026-09-14 · 9-19-3 소형브레이커).
"""
wanted = _normalize(name_cell)
for row in catalog.scoped_aliases:
if _normalize(row["from"]) != wanted or not in_scope(work_item_code, row["scope"]):
continue
return next((entry for entry in catalog.entries if entry.code == row["to"]), None)
return None
def apply_scoped_alias(catalog: ResourceCatalog, name_cell: str, work_item_code: str) -> str:
"""범위 안이면 카탈로그 쪽 **이름**으로 바꾼다. 범위 밖이거나 대상 코드가 없으면 원문 그대로."""
wanted = _normalize(name_cell)
@@ -11,6 +11,14 @@
"pum_edition": "2026-01-01",
"basis": "노임 표준 직종명은 「화약취급공」(노임 카탈로그 1016) — 품셈 9-5 표가 줄여 적음. 2026-09-13 사용자 위임 판정(브레인)"
},
{
"axis": "resource",
"from": "소형브레이커",
"to": "5210-0010",
"scope": "FP-09-19-03",
"pum_edition": "2026-01-01",
"basis": "9-19-3 비탈면 고르기(발파암) 표가 규격을 안 적음 — 그 값 「(2.45+3.05)/2/10㎡」 은 9-19-1 토사면 고르기 표(연암 2.45·보통암+경암 3.05)에서 왔고 9-19-1 [주]① 「소형브레이커는 1㎥/분」 → 소형브레이커(공압식) 1.0㎥/min(9-19-3 ← 9-19-1 표 ← [주]①, 값의 출처가 규격을 정함). 2026-09-14 브레인 승인"
},
{
"axis": "variant",
"from": "리핑암",
@@ -40,3 +40,21 @@ def test_육상_발파암_1_3m_들어내기는_0_1m_로_읽고_고른_값_버린
assert not left, left
source = build.factor_sources.get(code, "")
assert "육상 발파암(01m)" in source and "자기 참조" in source, source
def test_비탈면_고르기_발파암_소형브레이커는_1_0_규격으로_코드에_이어짐() -> None:
"""④ 9-19-3 값 「(2.45+3.05)/2/10㎡」 ← 9-19-1 표 ← 9-19-1 [주]① 「소형브레이커는 1㎥/분」 —
값의 출처가 규격을 정함(2026-09-14 브레인 승인). 범위 별칭이 **코드로** 곧장 이음(이름만 돌려주면
규격 후보 넷이 다시 흐려짐). 「어어호스」 는 원문 오기 + 카탈로그에 호스 없음 → 못 붙은 줄 그대로."""
from B09_Estimation.B09_Estimation_ResourceAxis import (
build_resource_axis,
load_combined_catalog,
)
axis = build_resource_axis(load_work_item_master(), load_combined_catalog())
rows = [
(r.resource_code, str(r.amount)) for r in axis.rows if r.work_item_code == "FP-09-19-03"
]
assert ("5210-0010", "0.275") in rows, rows
left = [u.cell for u in axis.unmatched if u.work_item_code == "FP-09-19-03"]
assert left == ["어어호스(3/4인치)"], left