feat(b09): 자원 축 조인 키 — 카탈로그 밖 자원(AR-) 목록·규격 조인·범위 별칭

- 자재 0 해소 첫 걸음: 사급 자원 19건(AR-M 17·AR-X 2, 이름·규격·단위, 단가 칸 없음)
  resources/data_resource_catalog/ 신설 — 임도 60 + 사방 11 코드 범위의 진짜 자원만
- 규격이 조인 키: AR 항목은 후보가 하나여도 규격이 같아야 고름 · 품셈 칸에 규격이
  없으면 「규격 미정 — 후보 N」(성공으로 안 셈)
- 형식이 하나뿐인 계열만 규격으로 고름(공기압축기(이동식) 3.5·10.3) · 형식 둘이면 규격 미정
- 범위 별칭 한 벌: 화약공→화약취급공(1016) scope FP-09-05 · pum_edition 다르면 안 씀 ·
  scope 없음·겹친 두 코드는 읽을 때 오류
- 일위대가: 맞췄으나 단가 층 없는 줄은 조용히 안 빠지고 드러냄 · 기계 몫이면 막음
- ResourceAxis.py 700줄 초과분(조사용 덤프)을 _Dump.py 로 뗌
- 돌망태 품셈 절 표기 13-8 → 13-11 바로잡음
- 결과: 자원 줄 575→592(자재 0→11) · 못 맞춤 508→491 · 내역 금액 변화 0(막힌 공종 그대로)
- 시험 test_b09_resource_axis_join.py 8건 · 전체 1377 통과

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-13 17:05:36 +09:00
co-authored by Claude Opus 5
parent 75b8532145
commit c541a6bd2f
9 changed files with 879 additions and 88 deletions
@@ -742,6 +742,22 @@ def build_unit_prices(
for row in rows
]
attachable = [(row, ref) for row, ref in attachable if ref in build.book.titles]
# ⚠ **맞췄으나 단가 층이 없는 줄**(카탈로그 밖 `AR-` 자원 · 층을 못 세운 기계)은 조용히
# 빼지 않는다 — 못 맞춘 줄처럼 드러내고, 기계 몫이면 단가를 막는다(2026-09-13 축 C).
# 자재는 종전처럼 드러내기만 한다(자재 단가 층은 7장 수동입력이 선 뒤).
attached_ids = {id(row) for row, _ in attachable}
for row in rows:
if id(row) in attached_ids:
continue
label = f"{row.resource_name} {row.resource_spec}".strip()
labels = build.unattached.setdefault(work_item_code, [])
if label not in labels:
labels.append(label)
if row.resource_kind == "machine":
build.component_gaps.setdefault(
work_item_code, f"{label} 줄이 맞춰졌으나 기계 단가 층이 없습니다"
)
build.partial_ratio.setdefault(work_item_code, _ZERO)
if (
not attachable
and not capacity_rows.get(work_item_code)