feat(B08): 자재총괄 — 할증이 붙는 유일한 자리

구조물 원단위의 `destination == "material"` 성분만 모아 자재별 합산 후
할증률을 한 번만 적용. 열은 순수량·할증률·합계 + 관급구분·설치주체·비고이며
금액은 없음(B09 경계).

- 할증률은 코드가 아니라 데이터 — `resources/data_material_surcharge/`
  (품셈 1-3-1 재료 할증률 19종 + sha256 매니페스트). 실무 관측값은
  `observed_practice` 로 분리(법대로 원칙).
- 표에 없는 자재는 0 % 로 넘기지 않고 「할증률 미확보」로 표시.
  이름 조회는 정확 일치 — 부분일치면 `막자갈` 이 `자갈` 할증을 뭄.
- 이중계상 방어 ㉠ — 앞 단계 `surcharge_applied` 깃발을 실제로 읽어 경고.
  자재총괄 응답은 `True`, 원단위표는 `False` 로 어느 쪽 값인지 명시.
- 관급/사급 이름은 B09 와 동일(`owner_supplied`/`contractor_supplied`).
  관급 줄에만 설치 주체(`install_by`)를 붙이고, 미지정은 기본값으로
  때우지 않고 드러냄 — 안전관리비 대상액이 「도급자설치 관급금액」이라서임.
- 라우터 `GET /quantity/material-summary` 신설, 화면에 「구조물 원단위」·
  「자재총괄」 탭 추가. `design_owner` 가 붙은 타입(측구)은 중복 계상 방지로 제외.

검증 — 전용 테스트 23건 통과, 전체 회귀 473 passed(기존 B05 깨짐 1건 제외).
공용 브라우저 실조작으로 탭 5장·머리글·값 4줄·미확보 안내 확인.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-07 23:43:46 +09:00
co-authored by Claude Opus 5
parent fc40265dbe
commit 6a487fc6e3
9 changed files with 759 additions and 2 deletions
@@ -0,0 +1,13 @@
{
"schema_version": "1.0",
"dataset_id": "data_material_surcharge_manifest",
"generated_at": "2026-09-07T00:00:00+09:00",
"built_by": "수작업 — 품셈 1-3-1 재료 할증률표 전사 (지식DB 수량산출_일반.md §3)",
"files": [
{
"file": "material_surcharge_2026-01-01.json",
"sha256": "77ffb9d8ae916252c725d28a4218ff7ecbff6a47bad1b00be8686663e17deb68",
"size_bytes": 2098
}
]
}
@@ -0,0 +1,51 @@
{
"schema_version": "1.0",
"dataset_id": "material_surcharge",
"effective_date": "2026-01-01",
"source": {
"doc": "산림사업 표준품셈 (산림청고시 제2025-82호) 제1장 1-3-1 재료의 할증",
"via": "resources/knowledge/technical_info/01_임도/04_수량분석정보/수량산출_일반.md",
"note": "품셈 항목에 할증이 포함·표시된 경우 중복 적용 금지 — 자재총괄 한 곳에서만 붙인다."
},
"policy": {
"no_invented_values": true,
"unknown_material_is_flagged": true
},
"rates_pct": [
{
"material": "시멘트",
"rate": 2,
"condition": "정치식",
"alt_rate": 3,
"alt_condition": "기타"
},
{ "material": "잔골재", "rate": 10, "alt_rate": 12, "alt_condition": "기타" },
{ "material": "채움재", "rate": 10, "alt_rate": 12, "alt_condition": "기타" },
{ "material": "굵은골재", "rate": 3, "alt_rate": 5, "alt_condition": "기타" },
{ "material": "모래", "rate": 6, "condition": "노반재료" },
{ "material": "부순돌", "rate": 4, "condition": "노반재료" },
{ "material": "자갈", "rate": 4, "condition": "노반재료" },
{ "material": "점질토", "rate": 6, "condition": "노반재료" },
{ "material": "이형철근", "rate": 3, "alt_rate": 7, "alt_condition": "복잡 구조물 주철근" },
{ "material": "원형철근", "rate": 5 },
{ "material": "강판", "rate": 10 },
{ "material": "각재", "rate": 5 },
{ "material": "판재", "rate": 10 },
{
"material": "레미콘",
"rate": 2,
"condition": "무근",
"alt_rate": 1,
"alt_condition": "철근"
},
{ "material": "흄관", "rate": 3 },
{ "material": "떼", "rate": 10 },
{ "material": "초화류", "rate": 10 },
{ "material": "사방용 수목", "rate": 10 },
{ "material": "원석", "rate": 30, "condition": "마름돌용" }
],
"observed_practice": {
"note": "울진 총괄집계 관측 — 참고이지 기본값이 아니다(PLAN 8-10 ★ 법대로).",
"values": { "모래": 10, "자갈": 3, "혼합석": 2, "시멘트": 2, "떼": 10 }
}
}