feat(z01): 상자 이름·계산 규칙을 이름표에서 읽어 보냄 — 이름표엔 이미 있었고 서버가 안 실어 영문으로 뜨던 것

- 목록 응답 kinds 에 group_label — 이름표 base_price_groups 이름(기초단가 · 품셈 기준 · 공종 축) · 화면은 7cb15af1 부터 이 칸을 읽음
- 공종 축 계산 규칙 칸 — 이름표 value_overrides 의 work_item_master 방식 이름(아래 하나를 고름 · 아래를 단계로 다 더함) · 없으면 영문 그대로
- 표 수준 rules 의 mode 는 영문 그대로(기계가 읽는 자리)
- 화면 확인: 상자 넷 한글 · 발파암 다섯 줄 「아래를 단계로 다 더함 | 0.1 · 0.9 · 1」
- 시험: 상자 이름 셋 · 발파암 깍기 합산 · 토사깍기 하나 고름 · Z01·이름표 시험 105 통과

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
This commit is contained in:
2026-09-17 16:54:48 +09:00
co-authored by Claude Opus 5
parent 0ff186c194
commit fd2ed65186
3 changed files with 23 additions and 3 deletions
+8 -1
View File
@@ -427,14 +427,21 @@ def kind_label(kind: str) -> str:
return named.get("name_ko") or kind
def group_label(group: str) -> str:
"""상자 이름 — 이름표 `base_price_groups[갈래].name_ko` 에서만(없으면 영문 그대로 · 화면은 `group_label` 을 읽음)."""
named = (tables.load_labels().get("base_price_groups") or {}).get(group) or {}
return named.get("name_ko") or group
def kinds() -> list[dict[str, Any]]:
"""화면이 상자를 세울 목록 — **서버가 냄**(화면이 제 코드에 들면 새 kind 가 조용히 안 뜸).
갈래 · kind · 한글 이름(이름표) · 줄 수.
갈래 · 갈래 한글 이름 · kind · 한글 이름(이름표) · 줄 수.
"""
return [
{
"group": kind_group(kind),
"group_label": group_label(kind_group(kind)),
"kind": kind,
"label": kind_label(kind),
"rows": len(rows(kind)),
+6 -1
View File
@@ -77,6 +77,8 @@ def base_rows(kind: str) -> list[dict[str, Any]]:
return []
d, name = found
items, by, children = _tree(d)
# 계산 규칙 이름 — 이름표 `value_overrides["work_item_master::<방식>"]`(「아래를 단계로 다 더함」) · 없으면 영문
named = tables.load_labels().get("value_overrides") or {}
rows = []
for item in items:
if not item.get("tables"):
@@ -100,7 +102,10 @@ def base_rows(kind: str) -> list[dict[str, Any]]:
"name": _path(item, by),
"variant": variant,
"pum_tables": [t["pum_table_id"] for t in item["tables"]],
"rule": parent.get("parent_mode"),
"rule": (named.get(f"work_item_master::{parent.get('parent_mode')}") or {}).get(
"name_ko"
)
or parent.get("parent_mode"),
"step_weight": weight,
"effective_date": d.get("pum_edition") or d.get("effective_date"),
}
+9 -1
View File
@@ -39,6 +39,12 @@ def test_산림_평평한_잎_목록과_계산_규칙(client: TestClient) -> Non
listed = client.get("/api/master-data/base-prices").json()["kinds"]
forest = next(i for i in listed if i["kind"] == "work_item_forest")
assert forest["group"] == "work_item" and forest["rows"] == 627 # 갈래마다 한 줄
# 상자 이름은 이름표 것 — 영문 키(work_item)로 뜨던 자리(2026-09-17 브레인 ①)
assert {i["group"]: i["group_label"] for i in listed} == {
"base_price": "기초단가",
"pumsem_basis": "품셈 기준",
"work_item": "공종 축",
}
table = _get(client, "work_item_forest", size=500, axis_role="") # 「전부」 — 총칙까지
assert table["total"] == 627 and table["stats"] == {"work_items": 365, "units": 627}
@@ -55,7 +61,9 @@ def test_산림_평평한_잎_목록과_계산_규칙(client: TestClient) -> Non
assert modes.count("choose_one") == 91 and modes.count("sum_steps") == 3
blast = next(r for r in table["rules"] if r["work_item_code"] == "FP-09-05")
assert [s["weight"] for s in blast["steps"]] == ["0.1", "0.9", "1"]
assert by_code["FP-09-05-02"]["rule"] == "sum_steps"
# 계산 규칙 칸은 이름표 이름 — 「sum_steps」 영문으로는 더해야 하는 줄로 안 읽힘(브레인 ②)
assert by_code["FP-09-05-02"]["rule"] == "아래를 단계로 다 더함"
assert by_code["FP-09-03-02"]["rule"] == "아래 하나를 고름"
assert by_code["FP-09-05-02"]["step_weight"] == "0.9"
# 2026-09-17 FW- 가 옴(데스크탑 서브) — 알림이 사라지는 것이 곧 열쇠가 섰다는 증거.
assert all(r["@id"].startswith("FW-") for r in rows) # 불변 열쇠(데스크탑 서브 7dd2c515)