fix(b08): 건설 산출 이름을 const_ 앞꼬리로 — 뒤꼬리(work_item_master_const_…)면 work_item_master_* 로 끝 파일을 고르는 B08 밑수 대조가 건설을 집어 대조가 통째로 빠졌음(전체 시험 빨강 2) · 고르는 쪽이 산림을 집는지 시험 하나

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-17 12:58:44 +09:00
co-authored by Claude Opus 5
parent 642a5be937
commit 0d56e727cb
11 changed files with 27 additions and 18 deletions
@@ -357,9 +357,9 @@ def write_outputs(result: tuple, registry_path: Path, tag: str) -> None:
save_registry(registry_path, registry)
date = master["effective_date"]
master_path = OUT_DIR / f"work_item_master_{tag}{date}.json"
undet_path = OUT_DIR / f"form_undetermined_{tag}{date}.json"
basis_path = OUT_DIR / f"basis_missing_{tag}{date}.json"
master_path = OUT_DIR / f"{tag}work_item_master_{date}.json"
undet_path = OUT_DIR / f"{tag}form_undetermined_{date}.json"
basis_path = OUT_DIR / f"{tag}basis_missing_{date}.json"
master_path.write_text(json.dumps(master, ensure_ascii=False, indent=1), encoding="utf-8")
undet_path.write_text(
@@ -32,7 +32,7 @@ KEY_PREFIX = "CW" # Construction Work item
BOOK_NAME = "2026년_건설공사_표준품셈.md"
CODE_PREFIX = "CP" # Construction Pumsem — 목차 코드
DATASET_ID = "work_item_master_const"
FILE_TAG = "const" # 산출 파일 이름 꼬리 — 산림 파일과 안 부딪힘
FILE_TAG = "const" # 산출 파일 이름 **앞**에 붙임 — ⚠ 뒤에 붙이면 `work_item_master_*` 로 산림을 고르는 쪽(B08 밑수 대조 · B09 근거표)이 건설을 집음
DIVISIONS = ("공통부문", "토목부문", "건축부문", "기계설비부문", "유지관리부문")
_LEADER = re.compile(r"·{2,}")
+1 -1
View File
@@ -38,7 +38,7 @@ def _read(path: str, _mtime_ns: int) -> dict[str, Any]:
def doc(kind: str) -> tuple[dict[str, Any], str] | None:
"""그 품셈의 공종 축 끝 판(문서 · 파일 이름) — 없으면 None(건설은 아직 없음)."""
found = []
for path in sorted(FOLDER.glob("work_item_master_*.json")):
for path in sorted(FOLDER.glob("*work_item_master_*.json")): # 건설은 `const_` 앞꼬리
d = _read(str(path), path.stat().st_mtime_ns)
if (d.get("dataset_version") or {}).get("dataset_id") == SOURCE_OF[kind]:
found.append((d, path.name))
@@ -1,7 +1,7 @@
{
"schema_version": "1.0",
"dataset_id": "data_work_item_master_manifest",
"generated_at": "2026-09-17T12:34:57+09:00",
"generated_at": "2026-09-17T12:57:59+09:00",
"built_by": "B08_Quantity/B08_Quantity_Build_WorkItemMaster.py",
"source": {
"dataset_id": "pum_forest",
@@ -12,7 +12,7 @@
"files": [
{
"file": "work_item_master_2026-01-01.json",
"sha256": "9c8da999439a186f17467832fe898d16e2f88172a2b9a2916728cbb350540259",
"sha256": "af00d1436125a45b2f9ad72d5d3937d47f1698ce1262fea2b4bdd957977ec1c7",
"size_bytes": 956887
},
{
@@ -1,7 +1,7 @@
{
"schema_version": "1.0",
"dataset_id": "data_work_item_master_manifest",
"generated_at": "2026-09-17T12:34:57+09:00",
"generated_at": "2026-09-17T12:57:59+09:00",
"built_by": "B08_Quantity/B08_Quantity_Build_WorkItemMaster.py",
"source": {
"dataset_id": "pum_const",
@@ -11,17 +11,17 @@
},
"files": [
{
"file": "work_item_master_const_2026-01-01.json",
"sha256": "e38814f0ea1e542a44097ff7f706dccec62faa737aa67dea6686ee4395820564",
"size_bytes": 3752147
"file": "const_work_item_master_2026-01-01.json",
"sha256": "b1574590d7d6206f48e1bcca5fcc4b5bdebbb07ecaaf376c700a75e7794c1faa",
"size_bytes": 3752144
},
{
"file": "form_undetermined_const_2026-01-01.json",
"file": "const_form_undetermined_2026-01-01.json",
"sha256": "dbb4f245cb9aee71325ab73c1325ee5f06ff19e0e7527de2053d08a7eb16282e",
"size_bytes": 486761
},
{
"file": "basis_missing_const_2026-01-01.json",
"file": "const_basis_missing_2026-01-01.json",
"sha256": "0ae14342e37ba5f394c36cc4dd8cea1b505b13d6520e0a12979c21676d6ffcdb",
"size_bytes": 74228
}
@@ -4,7 +4,7 @@
"effective_date": "2026-01-01",
"pum_edition": "2026-01-01",
"toc_edition": "2026-01-01",
"generated_at": "2026-09-17T12:34:57+09:00",
"generated_at": "2026-09-17T12:57:59+09:00",
"dataset_version": {
"dataset_id": "pum_const",
"effective_date": "2026-01-01",
@@ -44,7 +44,7 @@
"empty": 100,
"work_item": 997
},
"keys_newly_issued": 1367,
"keys_newly_issued": 0,
"toc_duplicate_rows": 0,
"toc_corrections": 0
},
@@ -4,7 +4,7 @@
"effective_date": "2026-01-01",
"pum_edition": "2026-01-01",
"toc_edition": "산림청고시제2025-82호",
"generated_at": "2026-09-17T12:34:57+09:00",
"generated_at": "2026-09-17T12:57:59+09:00",
"dataset_version": {
"dataset_id": "pum_forest",
"effective_date": "2026-01-01",
@@ -20,7 +20,7 @@ from B08_Quantity import B08_Quantity_Build_WorkItemMaster as forest
from B08_Quantity import B08_Quantity_Build_WorkItemMaster_Const as const
OUT = forest.OUT_DIR
CONST_MASTER = OUT / "work_item_master_const_2026-01-01.json"
CONST_MASTER = OUT / "const_work_item_master_2026-01-01.json"
@pytest.fixture(scope="module")
@@ -140,3 +140,12 @@ def test_산림_산출도_그대로_금액_불변() -> None:
"items"
]
assert json.loads(json.dumps(fresh, ensure_ascii=False)) == saved_items
def test_산림을_고르는_쪽이_건설_파일을_안_집음() -> None:
"""⚠ `work_item_master_*` 로 끝 파일을 고르는 자리가 있음(B08 밑수 대조 · B09 근거표) —
건설 산출을 `work_item_master_const_…` 로 두면 그쪽이 건설을 집어 밑수 대조가 통째로 빠졌음(2026-09-17)."""
from B08_Quantity.B08_Quantity_Engine_BasisUnit import load_master
assert load_master()["dataset_id"] == "work_item_master_forest"
assert not list(OUT.glob("work_item_master_*const*.json"))
+1 -1
View File
@@ -94,7 +94,7 @@ def test_불변_열쇠가_오면_id_로_씀_자료_파일은_판_id_로_가림(
"variant_keys": ["", ""]},
],
} # fmt: skip
(folder / "work_item_master_const_2026-01-01.json").write_text(
(folder / "const_work_item_master_2026-01-01.json").write_text(
json.dumps(fake, ensure_ascii=False), encoding="utf-8"
)
monkeypatch.setattr(work_items, "FOLDER", folder)