diff --git a/B05_Profile/B05_Profile_UI_Drainage_Facility_Fields.ts b/B05_Profile/B05_Profile_UI_Drainage_Facility_Fields.ts index da745045..0cb5a3a2 100644 --- a/B05_Profile/B05_Profile_UI_Drainage_Facility_Fields.ts +++ b/B05_Profile/B05_Profile_UI_Drainage_Facility_Fields.ts @@ -9,7 +9,7 @@ * ========================================================================== */ import { FORD_MANNING_N, FORD_SLOPE } from "@config/config_frontend"; -import revetmentSabang from "../resources/data_masonry/revetment_sabang_2026-01-01.json"; +import revetmentSabang from "../resources/master_data/ref/수량_사방기슭막이치수_사방기술교본_2026-01-01.json"; /* ── 유입구 구조 ──────────────────────────────────────────────────────────── */ diff --git a/B06_Section/B06_Section_UI_Cross_Lean.ts b/B06_Section/B06_Section_UI_Cross_Lean.ts index e6daa9d8..8804ea3a 100644 --- a/B06_Section/B06_Section_UI_Cross_Lean.ts +++ b/B06_Section/B06_Section_UI_Cross_Lean.ts @@ -1,6 +1,6 @@ /* ============================================================================= * B06_Section_UI_Cross_Lean.ts - * 횡단도 벽 전면 기울기 — 품셈 13-4-4 [주]⑪ 표준경사 표(`resources/data_masonry/masonry_slope_*`)를 + * 횡단도 벽 전면 기울기 — 품셈 13-4-4 [주]⑪ 표준경사 표(`resources/master_data/old/3_품셈_산림_돌쌓기경사_*`)를 * 읽는 자리 하나(2026-09-14 B5 · B08 과 한 벌). 표 읽기 식은 `common_util_masonry_slope.ts`(파이썬 짝). * * 따로 뗀 까닭 — 표(JSON)를 가져오는 모듈을 상수 파일에 두면 그 상수를 쓰는 기하 조각을 Node 로 @@ -10,7 +10,7 @@ * ========================================================================== */ import { type WallLeanInput, wallLeanRatio } from "../common_util/common_util_masonry_slope"; -import masonrySlope from "../resources/data_masonry/masonry_slope_2026-01-01.json"; +import masonrySlope from "../resources/master_data/old/3_품셈_산림_돌쌓기경사_13-4-4_2026-01-01.json"; /** 벽 전면 기울기 n — 표를 못 고르면 종전 0.3. */ export function leanOf(input: WallLeanInput): number { diff --git a/B08_Quantity/B08_Quantity_Build_WorkItemMaster.py b/B08_Quantity/B08_Quantity_Build_WorkItemMaster.py index 6f56ed26..7e449c65 100644 --- a/B08_Quantity/B08_Quantity_Build_WorkItemMaster.py +++ b/B08_Quantity/B08_Quantity_Build_WorkItemMaster.py @@ -56,8 +56,8 @@ from B08_Quantity.B08_Quantity_Build_WorkItemMaster_Table import ( # noqa: F401 ) ROOT = Path(__file__).resolve().parent.parent -SOURCE = ROOT / "resources" / "data_cost_input_value" / "pum_forest_2026.json" -OUT_DIR = ROOT / "resources" / "data_work_item_master" +SOURCE = ROOT / "resources" / "master_data" / "old" / "3_품셈_산림_표전체_2026-01-01.json" +OUT_DIR = ROOT / "resources" / "master_data" / "old" #: 불변 열쇠 장부 — **판이 붙지 않는다.** 판마다 새로 짓는 산출물이 아니라 대대로 잇는 장부다. KEY_REGISTRY = OUT_DIR / "work_item_keys.json" diff --git a/B08_Quantity/B08_Quantity_Build_WorkItemMaster_Const.py b/B08_Quantity/B08_Quantity_Build_WorkItemMaster_Const.py index 77273c82..5683918c 100644 --- a/B08_Quantity/B08_Quantity_Build_WorkItemMaster_Const.py +++ b/B08_Quantity/B08_Quantity_Build_WorkItemMaster_Const.py @@ -25,9 +25,9 @@ from pathlib import Path from typing import Any ROOT = Path(__file__).resolve().parent.parent -SOURCE = ROOT / "resources" / "data_cost_input_value" / "pum_const_2026.json" +SOURCE = ROOT / "resources" / "master_data" / "old" / "3_품셈_건설_표전체_2026-01-01.json" #: 건설 열쇠 장부 — 산림 장부(`work_item_keys.json`)와 일련번호를 안 섞음 -CONST_KEY_REGISTRY = ROOT / "resources" / "data_work_item_master" / "work_item_keys_const.json" +CONST_KEY_REGISTRY = ROOT / "resources" / "master_data" / "old" / "work_item_keys_const.json" KEY_PREFIX = "CW" # Construction Work item BOOK_NAME = "2026년_건설공사_표준품셈.md" CODE_PREFIX = "CP" # Construction Pumsem — 목차 코드 diff --git a/B08_Quantity/B08_Quantity_Build_WorkItemMaster_Keys.py b/B08_Quantity/B08_Quantity_Build_WorkItemMaster_Keys.py index d7a709b2..0e60288d 100644 --- a/B08_Quantity/B08_Quantity_Build_WorkItemMaster_Keys.py +++ b/B08_Quantity/B08_Quantity_Build_WorkItemMaster_Keys.py @@ -33,7 +33,8 @@ PATH_SEP = " › " AXIS_POLICY = ( Path(__file__).resolve().parent.parent / "resources" - / "data_work_item_master" + / "master_data" + / "old" / "axis_policy.json" ) diff --git a/B08_Quantity/B08_Quantity_Engine_BasisUnit.py b/B08_Quantity/B08_Quantity_Engine_BasisUnit.py index c56424cb..bd2b3366 100644 --- a/B08_Quantity/B08_Quantity_Engine_BasisUnit.py +++ b/B08_Quantity/B08_Quantity_Engine_BasisUnit.py @@ -20,8 +20,8 @@ import json from pathlib import Path from typing import Any, Iterable -MASTER_DIR = Path(__file__).resolve().parents[1] / "resources" / "data_work_item_master" -MASTER_PREFIX = "work_item_master_" +MASTER_DIR = Path(__file__).resolve().parents[1] / "resources" / "master_data" / "old" +MASTER_PREFIX = "2_공종_산림_마스터_" #: 같은 뜻인데 표기만 다른 단위 — **환산이 아니라 표기 흡수**다. UNIT_ALIASES = { diff --git a/B08_Quantity/B08_Quantity_Engine_Formwork.py b/B08_Quantity/B08_Quantity_Engine_Formwork.py index bc4bc0d1..e595413c 100644 --- a/B08_Quantity/B08_Quantity_Engine_Formwork.py +++ b/B08_Quantity/B08_Quantity_Engine_Formwork.py @@ -23,8 +23,8 @@ from dataclasses import dataclass, field from pathlib import Path from typing import Any -DATASET_DIR = Path(__file__).resolve().parents[1] / "resources" / "data_formwork" -DATASET_PREFIX = "formwork_reuse_" +DATASET_DIR = Path(__file__).resolve().parents[1] / "resources" / "master_data" / "old" +DATASET_PREFIX = "3_품셈_산림_거푸집사용횟수_" #: 거푸집으로 보는 성분 이름. 정확히 같은 이름으로만 본다 — 부분일치면 「거푸집씻기」가 걸린다. FORMWORK_NAMES = frozenset({"합판거푸집", "유로폼", "문양거푸집", "거푸집"}) diff --git a/B08_Quantity/B08_Quantity_Engine_Handoff_Mapping.py b/B08_Quantity/B08_Quantity_Engine_Handoff_Mapping.py index b61ab755..c043e310 100644 --- a/B08_Quantity/B08_Quantity_Engine_Handoff_Mapping.py +++ b/B08_Quantity/B08_Quantity_Engine_Handoff_Mapping.py @@ -15,22 +15,22 @@ from dataclasses import dataclass, field from pathlib import Path from typing import Any -DATASET_DIR = Path(__file__).resolve().parents[1] / "resources" / "data_work_item_mapping" -DATASET_PREFIX = "work_item_mapping_" +DATASET_DIR = Path(__file__).resolve().parents[1] / "resources" / "master_data" / "ref" +DATASET_PREFIX = "공종_수량연결_실무_" #: 철근 갈래표 — **품셈 12-3 [주]① 원문**이 구조물 예시로 갈라 둔 것이라 사람이 고르는 값이 #: 아니다(거푸집 사용횟수 1-7-1 과 같은 자리). 원문 예시에 안 걸리면 지어내지 않는다. -REBAR_DIR = Path(__file__).resolve().parents[1] / "resources" / "data_rebar" -REBAR_PREFIX = "rebar_complexity_" +REBAR_DIR = Path(__file__).resolve().parents[1] / "resources" / "master_data" / "old" +REBAR_PREFIX = "3_품셈_산림_철근가공갈래_" #: 돌쌓기 규격 갈래표 — 저장 제원 값으로 자동 판정한다(사람이 고르는 값이 아니다). -MASONRY_DIR = Path(__file__).resolve().parents[1] / "resources" / "data_masonry" -MASONRY_PREFIX = "masonry_class_" +MASONRY_DIR = Path(__file__).resolve().parents[1] / "resources" / "master_data" / "old" +MASONRY_PREFIX = "3_품셈_산림_돌쌓기규격갈래_" #: 목재공작물 구조 갈래표 — 품셈 13-13-1 [주]③ 이 **재료 구성**으로 가른다. -TIMBER_DIR = Path(__file__).resolve().parents[1] / "resources" / "data_timber" -TIMBER_PREFIX = "timber_structure_class_" +TIMBER_DIR = Path(__file__).resolve().parents[1] / "resources" / "master_data" / "old" +TIMBER_PREFIX = "3_품셈_산림_목재구조갈래_" def load_timber_table(path: Path | None = None) -> dict[str, Any]: diff --git a/B08_Quantity/B08_Quantity_Engine_MaterialSummary.py b/B08_Quantity/B08_Quantity_Engine_MaterialSummary.py index 5e025581..86489e39 100644 --- a/B08_Quantity/B08_Quantity_Engine_MaterialSummary.py +++ b/B08_Quantity/B08_Quantity_Engine_MaterialSummary.py @@ -53,8 +53,8 @@ from typing import Any, Iterable from common_util.common_util_quantity_spread import spread_by_unit # ── 데이터 자리 ────────────────────────────────────────────────────── -DATASET_DIR = Path(__file__).resolve().parents[1] / "resources" / "data_material_surcharge" -DATASET_PREFIX = "material_surcharge_" +DATASET_DIR = Path(__file__).resolve().parents[1] / "resources" / "master_data" / "ref" +DATASET_PREFIX = "품셈_산림_재료할증_울진_" #: 이 표가 받는 성분 갈래. 나머지는 각자 다른 표로 간다. ACCEPTED_DESTINATION = "material" diff --git a/B08_Quantity/B08_Quantity_Engine_ObservedUnit.py b/B08_Quantity/B08_Quantity_Engine_ObservedUnit.py index aab337de..a21ee73c 100644 --- a/B08_Quantity/B08_Quantity_Engine_ObservedUnit.py +++ b/B08_Quantity/B08_Quantity_Engine_ObservedUnit.py @@ -32,8 +32,8 @@ from dataclasses import dataclass, field from pathlib import Path from typing import Any -DATASET_DIR = Path(__file__).resolve().parents[1] / "resources" / "data_structure_unit" -DATASET_PREFIX = "structure_unit_observed_" +DATASET_DIR = Path(__file__).resolve().parents[1] / "resources" / "master_data" / "ref" +DATASET_PREFIX = "수량_구조물원단위_울진_" #: 값이 어디서 왔나 — 한 표에 섞이므로 줄마다 단다. BASIS_DERIVED = "derived" # 저장된 치수에서 식으로 diff --git a/B08_Quantity/B08_Quantity_Engine_Pipe.py b/B08_Quantity/B08_Quantity_Engine_Pipe.py index 023b4128..56bbd2a5 100644 --- a/B08_Quantity/B08_Quantity_Engine_Pipe.py +++ b/B08_Quantity/B08_Quantity_Engine_Pipe.py @@ -222,8 +222,8 @@ NOTE_WALL_HEIGHT_PIPE = " · 높이는 횡단도와 같은 관경 기준 최소 #: 독립 기슭막이 치수 **한 벌**(`resources/data_masonry/revetment_sabang_*.json`) — B05 칸 밑 근거와 #: 이 사유가 같은 파일을 읽음(2026-09-14 브레인 판정). 높이는 **설계자 입력** — 등록부 기본 2.5 걷음. -REVET_SABANG_DIR = Path(__file__).resolve().parents[1] / "resources" / "data_masonry" -REVET_SABANG_PREFIX = "revetment_sabang_" +REVET_SABANG_DIR = Path(__file__).resolve().parents[1] / "resources" / "master_data" / "ref" +REVET_SABANG_PREFIX = "수량_사방기슭막이치수_사방기술교본_" UNCONFIRMED_OWN_HEIGHT = "높이를 안 적음 — {rule}({source}) 설계자 입력 · 적으면 금액이 섬" diff --git a/B08_Quantity/B08_Quantity_Engine_UnitQuantity_StoneSpec.py b/B08_Quantity/B08_Quantity_Engine_UnitQuantity_StoneSpec.py index e22b0719..667c88af 100644 --- a/B08_Quantity/B08_Quantity_Engine_UnitQuantity_StoneSpec.py +++ b/B08_Quantity/B08_Quantity_Engine_UnitQuantity_StoneSpec.py @@ -131,8 +131,8 @@ STONE_PILE_BASIS = "⚠ 정본에 없는 줄 — 소광리 시트에만 있음( #: ⚠ 지금까지 **건설품셈 참고자료 한 벌**(돌 종류로 안 갈리는 표)로만 돌고 있었다. #: 그 값이 「깬돌」 계열이라, **자재로는 야면석을 내면서 계수는 깬돌**을 쓰는 어긋남이 #: 있었다(2026-09-08 지식DB 대조). 랩탑 창이 `stone_kind` 칸을 만들어 축이 생겼다. -STONE_KIND_DIR = Path(__file__).resolve().parents[1] / "resources" / "data_masonry" -STONE_KIND_PREFIX = "stone_kind_" +STONE_KIND_DIR = Path(__file__).resolve().parents[1] / "resources" / "master_data" / "ref" +STONE_KIND_PREFIX = "품셈_산림_돌종류계수_울진_" STONE_KIND_OPTION = "stone_kind" @@ -336,8 +336,8 @@ BLINDING_OPTION_KEYS = ("blinding_concrete", "base_blinding") #: 표준경사표 — 품셈 13-4-4 [주]⑪. 파일이 없으면 종전 기본값(0.3)으로 돈다. -SLOPE_DIR = Path(__file__).resolve().parents[1] / "resources" / "data_masonry" -SLOPE_PREFIX = "masonry_slope_" +SLOPE_DIR = Path(__file__).resolve().parents[1] / "resources" / "master_data" / "old" +SLOPE_PREFIX = "3_품셈_산림_돌쌓기경사_" #: 사용자가 덮어쓰는 칸 — 값이 있으면 **그 값이 이긴다**(확정 ⑨). FACE_SLOPE_KEYS = ("face_slope_ratio",) #: 성토/절토는 **측점 단면유형(`design.section_mode`) + 설치 측**으로 판정한다 @@ -469,7 +469,7 @@ def dry_masonry_height_note(height_m: float) -> str | None: #: 뒷길이 표준표 — 품셈 13-4-4 [주]⑩. 안 고른 돌쌓기는 붙박이 45 가 아니라 이 표의 하한 #: (2026-09-14 브레인 판정 ㉮ 「범위 안에 드는 규격 중 가장 작은 것」). 파일이 없으면 종전 45. -BACK_LENGTH_PREFIX = "masonry_back_length_" +BACK_LENGTH_PREFIX = "3_품셈_산림_돌쌓기뒷길이_" @lru_cache(maxsize=1) diff --git a/B09_Estimation/B09_Estimation_BasisSheet.py b/B09_Estimation/B09_Estimation_BasisSheet.py index ee948bf4..f17d2872 100644 --- a/B09_Estimation/B09_Estimation_BasisSheet.py +++ b/B09_Estimation/B09_Estimation_BasisSheet.py @@ -24,8 +24,8 @@ from typing import Any from B09_Estimation.B09_Estimation_PriceBook import PriceKind from B09_Estimation.B09_Estimation_ResourceAxis_UnitBasis import similar_occupation_note -_MANIFEST = ("resources", "data_cost_input_value", "_manifest.json") -_MASTER_DIR = ("resources", "data_work_item_master") +_MANIFEST = ("resources", "master_data", "old", "_manifest.json") +_MASTER_DIR = ("resources", "master_data", "old") SHEET_NOTE = ( "산출기초는 새로 세는 장이 아니라 **줄에 달린 근거를 한 장으로 모은 것**입니다 —" diff --git a/B09_Estimation/B09_Estimation_Engine_Cost_Input.py b/B09_Estimation/B09_Estimation_Engine_Cost_Input.py index b2d31fc0..c4f4fd80 100644 --- a/B09_Estimation/B09_Estimation_Engine_Cost_Input.py +++ b/B09_Estimation/B09_Estimation_Engine_Cost_Input.py @@ -131,6 +131,6 @@ class CostInput: enabled_items: tuple[str, ...] | str = DEFAULT_ITEMS #: 요율 데이터 파일명. **연도를 갈아끼우는 자리.** - rate_file_name: str = "rates_2026.json" + rate_file_name: str = "1_기초_제비율_토목_조달청_2026-04-13.json" #: 매니페스트 밖 요율 파일(옛 연도 재현 검산 전용). 주면 이쪽이 우선. rate_file_path: str | None = None diff --git a/B09_Estimation/B09_Estimation_LaborSurcharge.py b/B09_Estimation/B09_Estimation_LaborSurcharge.py index dfc8bd67..eeeb59be 100644 --- a/B09_Estimation/B09_Estimation_LaborSurcharge.py +++ b/B09_Estimation/B09_Estimation_LaborSurcharge.py @@ -32,7 +32,7 @@ from decimal import Decimal from functools import lru_cache from typing import Any -_DATASET = ("resources", "data_cost_input_value", "coef_2026.json") +_DATASET = ("resources", "master_data", "old", "3_품셈_산림_계수_2026-01-01.json") _FOREST_SPEC = ( "resources", "knowledge", diff --git a/B09_Estimation/B09_Estimation_MachineCost.py b/B09_Estimation/B09_Estimation_MachineCost.py index 2e62c4cc..0de4ee7a 100644 --- a/B09_Estimation/B09_Estimation_MachineCost.py +++ b/B09_Estimation/B09_Estimation_MachineCost.py @@ -34,7 +34,7 @@ from B09_Estimation.B09_Estimation_Guards import ( ) from B09_Estimation.B09_Estimation_PriceBook import Money3 -_CATALOG_SUBPATH = ("resources", "data_cost_input_value") +_CATALOG_SUBPATH = ("resources", "master_data", "old") _THOUSAND = Decimal(1000) @@ -224,7 +224,9 @@ class MachineCatalog: raise MachineCostError(f"기종 카탈로그에 없는 코드입니다: {machine_code}") from exc -def load_machine_catalog(file_name: str = "mach_base_2026.json") -> MachineCatalog: +def load_machine_catalog( + file_name: str = "3_품셈_건설_기계경비기준_8장_2026-01-01.json", +) -> MachineCatalog: """취득가 613건에 손료계수 387건을 붙여 카탈로그 한 벌을 만든다.""" variables = _read_json(file_name)["variables"] coefficients = { diff --git a/B09_Estimation/B09_Estimation_MachineExpenseSheet.py b/B09_Estimation/B09_Estimation_MachineExpenseSheet.py index 3a15b0f1..b2c8b7d7 100644 --- a/B09_Estimation/B09_Estimation_MachineExpenseSheet.py +++ b/B09_Estimation/B09_Estimation_MachineExpenseSheet.py @@ -33,7 +33,7 @@ from B09_Estimation.B09_Estimation_PriceBook import PriceKind #: 조합 사용(굴착기+부착장비)일 때의 본체 잡재료비율 — 품셈 제8장 [주]⑤. COMBINED_MISC_PERCENT = 16 -_CATALOG_SUBPATH = ("resources", "data_cost_input_value") +_CATALOG_SUBPATH = ("resources", "master_data", "old") _THOUSAND = Decimal(1000) _ZERO = Decimal(0) @@ -66,7 +66,9 @@ def _project_root() -> str: @lru_cache(maxsize=1) def _loss_records() -> dict[str, dict[str, Any]]: """기종코드 → 손료계수 원문 줄(상각·정비·관리 계수까지).""" - path = os.path.join(_project_root(), *_CATALOG_SUBPATH, "mach_base_2026.json") + path = os.path.join( + _project_root(), *_CATALOG_SUBPATH, "3_품셈_건설_기계경비기준_8장_2026-01-01.json" + ) with open(path, encoding="utf-8") as handle: payload = json.load(handle) records = payload["variables"]["mach_loss_coef"]["records"] diff --git a/B09_Estimation/B09_Estimation_MachineOperating.py b/B09_Estimation/B09_Estimation_MachineOperating.py index 6fe7802e..25aa1a63 100644 --- a/B09_Estimation/B09_Estimation_MachineOperating.py +++ b/B09_Estimation/B09_Estimation_MachineOperating.py @@ -27,8 +27,8 @@ from dataclasses import dataclass, field from decimal import Decimal from typing import Any -_CATALOG_SUBPATH = ("resources", "data_cost_input_value") -_OUTPUT_SUBPATH = ("resources", "data_cost_machine_operating") +_CATALOG_SUBPATH = ("resources", "master_data", "old") +_OUTPUT_SUBPATH = ("resources", "master_data", "old") #: 품셈 8-4 운전경비 표의 머리글 — 이 여섯이 다 있어야 그 표로 본다. _REQUIRED_HEADERS = ("분류번호", "기계명", "규격", "주연료", "잡재료", "조종원") @@ -359,8 +359,8 @@ def enrich_with_catalog( def load_operating_records( - pum_file: str = "pum_const_2026.json", - labor_file: str = "labor_const_2026-01-01.json", + pum_file: str = "3_품셈_건설_표전체_2026-01-01.json", + labor_file: str = "1_기초_노임_건설업_대한건설협회_2026-01-01.json", ) -> OperatingParseResult: from B09_Estimation.B09_Estimation_MachineCost import load_machine_catalog @@ -394,7 +394,7 @@ def write_operating_records( """파생 파일로 낸다. **어느 기준자료 판에서 파생됐는지**를 함께 적는다.""" directory = output_dir or os.path.join(_project_root(), *_OUTPUT_SUBPATH) os.makedirs(directory, exist_ok=True) - path = os.path.join(directory, "machine_operating_2026.json") + path = os.path.join(directory, "3_품셈_건설_기계운전경비_8-4_2026-01-01.json") payload = { "schema_version": "1.0", @@ -419,7 +419,7 @@ def write_operating_records( #: 시도별 유가 판 — 품셈 8-1-7 5호 「유류가격은 **해당지역의 가격**으로 한다」. #: ⚠ **파일이 있을 때만 지역을 고를 수 있다** — 없으면 전국평균 한 벌로 돈다(코드로 막지 않음). -REGIONAL_OIL_FILE = "oil_regional_2026-09-09.json" +REGIONAL_OIL_FILE = "1_기초_유가_시도별_오피넷_2026-09-09.json" #: 운전경비표 연료 종류 → 유가 판 변수. ⚠ 종류를 안 읽고 경유로 때우면 휘발유 기계가 싸게 섬 #: (2026-09-14 661 뒤 ② — 플레이트 콤팩터·진동기·믹서·래머·커터가 경유값이었음). FUEL_VARIABLES = {"경유": "oil_diesel", "휘발유": "oil_gasoline"} @@ -455,7 +455,9 @@ def load_regional_fuel_table( def load_fuel_price( - oil_file: str = "oil_2026-08-14.json", region: str | None = None, kind: str = "경유" + oil_file: str = "1_기초_유가_전국평균_오피넷_2026-08-14.json", + region: str | None = None, + kind: str = "경유", ) -> tuple[Decimal, dict[str, str]]: """경유 단가와 그 판의 신원. `region`(시도코드)을 주면 **그 지역 값**으로 선다. @@ -490,7 +492,9 @@ def load_fuel_price( } -def load_operator_wages(labor_file: str = "labor_const_2026-01-01.json") -> dict[str, Decimal]: +def load_operator_wages( + labor_file: str = "1_기초_노임_건설업_대한건설협회_2026-01-01.json", +) -> dict[str, Decimal]: """직종코드 → 일당.""" records = _read_json(*_CATALOG_SUBPATH, labor_file)["variables"]["labor_rate"]["records"] return { @@ -513,7 +517,9 @@ LABOR_RELIABILITY_LABEL = { } -def load_labor_reliability(labor_file: str = "labor_const_2026-01-01.json") -> dict[str, str]: +def load_labor_reliability( + labor_file: str = "1_기초_노임_건설업_대한건설협회_2026-01-01.json", +) -> dict[str, str]: """직종코드 → 신뢰도 기호(`*`·`**`). 정상 공표 직종은 아예 안 담는다.""" records = _read_json(*_CATALOG_SUBPATH, labor_file)["variables"]["labor_rate"]["records"] return { diff --git a/B09_Estimation/B09_Estimation_MachineProductivity_Data.py b/B09_Estimation/B09_Estimation_MachineProductivity_Data.py index 828f1cb9..7605154c 100644 --- a/B09_Estimation/B09_Estimation_MachineProductivity_Data.py +++ b/B09_Estimation/B09_Estimation_MachineProductivity_Data.py @@ -17,8 +17,8 @@ from functools import lru_cache from pathlib import Path from typing import Any -DATA_DIR = Path(__file__).resolve().parent.parent / "resources" / "data_machine_productivity" -PREFIX = "machine_productivity_" +DATA_DIR = Path(__file__).resolve().parent.parent / "resources" / "master_data" / "old" +PREFIX = "3_품셈_산림건설_기계작업량_" class MachineProductivityDataError(FileNotFoundError): diff --git a/B09_Estimation/B09_Estimation_MaterialCatalog.py b/B09_Estimation/B09_Estimation_MaterialCatalog.py index 8fe5721b..ff2401b4 100644 --- a/B09_Estimation/B09_Estimation_MaterialCatalog.py +++ b/B09_Estimation/B09_Estimation_MaterialCatalog.py @@ -27,7 +27,7 @@ from dataclasses import dataclass, field from decimal import Decimal from typing import Any -_CATALOG_SUBPATH = ("resources", "data_cost_input_value") +_CATALOG_SUBPATH = ("resources", "master_data", "old") #: 두 창이 맞춘 구분 이름 — 값을 바꾸면 B08 자재총괄과 안 맞는다. SUPPLY_OWNER = "owner_supplied" @@ -108,7 +108,7 @@ class MaterialCatalog: def load_material_catalog( - public_file: str = "mat_price_public_2026-08-14.json", + public_file: str = "1_기초_자재_시설공통_나라장터_2026-08-14.json", ) -> MaterialCatalog: """관급 자재를 읽고, 사급은 **없다는 사실을 목록으로** 남긴다.""" payload = _read_json(public_file) diff --git a/B09_Estimation/B09_Estimation_MaterialPrices.py b/B09_Estimation/B09_Estimation_MaterialPrices.py index 5cfdf16c..98646339 100644 --- a/B09_Estimation/B09_Estimation_MaterialPrices.py +++ b/B09_Estimation/B09_Estimation_MaterialPrices.py @@ -119,7 +119,7 @@ def material_catalog_rows() -> dict[str, dict[str, str]]: from B09_Estimation.B09_Estimation_ResourceAxis_Join import EXT_CATALOG_FILE root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - path = os.path.join(root, "resources", "data_resource_catalog", EXT_CATALOG_FILE) + path = os.path.join(root, "resources", "master_data", "old", EXT_CATALOG_FILE) if not os.path.isfile(path): return {} with open(path, encoding="utf-8") as handle: diff --git a/B09_Estimation/B09_Estimation_Rates.py b/B09_Estimation/B09_Estimation_Rates.py index 21ea9d21..c9417756 100644 --- a/B09_Estimation/B09_Estimation_Rates.py +++ b/B09_Estimation/B09_Estimation_Rates.py @@ -27,7 +27,7 @@ _UNIT_MULTIPLIER: dict[str, int] = { "billion": 1_000_000_000, } -_RESOURCE_SUBPATH = ("resources", "data_cost_input_value") +_RESOURCE_SUBPATH = ("resources", "master_data", "old") # 라벨 문법 — 숫자 구간만 해석한다. 그 밖(`turnkey_or_alternative` 등)은 명시 선택자로 고른다. _RE_LT = re.compile(r"^lt_(\d+(?:\.\d+)?)_(million|billion)$") @@ -89,7 +89,7 @@ def _manifest_entry(file_name: str) -> dict[str, Any]: @lru_cache(maxsize=8) -def load_rate_dataset(file_name: str = "rates_2026.json") -> RateDataset: +def load_rate_dataset(file_name: str = "1_기초_제비율_토목_조달청_2026-04-13.json") -> RateDataset: """요율 파일 한 벌을 읽는다. 매니페스트의 지문·적용일을 함께 실어 재현성을 남긴다.""" entry = _manifest_entry(file_name) with open(os.path.join(_dataset_dir(), file_name), encoding="utf-8") as handle: diff --git a/B09_Estimation/B09_Estimation_ResourceAxis.py b/B09_Estimation/B09_Estimation_ResourceAxis.py index 65fc60da..b53e3259 100644 --- a/B09_Estimation/B09_Estimation_ResourceAxis.py +++ b/B09_Estimation/B09_Estimation_ResourceAxis.py @@ -44,8 +44,8 @@ NON_WORK_ITEM_FORMS = frozenset({"coefficient", "reference"}) #: 형태 판정이 안 된 표 — 값을 쓰지 않는다. UNUSABLE_FORMS = frozenset({"undetermined"}) -_MASTER_SUBPATH = ("resources", "data_work_item_master") -_CATALOG_SUBPATH = ("resources", "data_cost_input_value") +_MASTER_SUBPATH = ("resources", "master_data", "old") +_CATALOG_SUBPATH = ("resources", "master_data", "old") #: 규격이 이름 안에 붙어 있는 흔한 모양 — 「굴착기(0.7㎥)」·「덤프트럭 15톤」. _RE_SPEC = re.compile(r"[((]([^))]+)[))]|(\d+(?:\.\d+)?\s*(?:톤|ton|㎥|m3|㎡|㎜|mm|HP|kW))") diff --git a/B09_Estimation/B09_Estimation_ResourceAxis_Dump.py b/B09_Estimation/B09_Estimation_ResourceAxis_Dump.py index 3c106022..be17f9c0 100644 --- a/B09_Estimation/B09_Estimation_ResourceAxis_Dump.py +++ b/B09_Estimation/B09_Estimation_ResourceAxis_Dump.py @@ -22,7 +22,7 @@ from B09_Estimation.B09_Estimation_ResourceAxis import ( #: 자원 축 산출물이 나가는 자리 — **메인의 `data_work_item_master/` 안에 넣지 않는다.** #: 메인이 품셈을 다시 돌리면 그 폴더가 덮이므로 섞으면 사라진다. -OUTPUT_SUBPATH = ("resources", "data_cost_resource_axis") +OUTPUT_SUBPATH = ("resources", "master_data", "old") def _master_file_fingerprint(master: dict[str, Any]) -> dict[str, str]: diff --git a/B09_Estimation/B09_Estimation_ResourceAxis_Join.py b/B09_Estimation/B09_Estimation_ResourceAxis_Join.py index 3cd10d63..af5f35b0 100644 --- a/B09_Estimation/B09_Estimation_ResourceAxis_Join.py +++ b/B09_Estimation/B09_Estimation_ResourceAxis_Join.py @@ -36,8 +36,8 @@ from B09_Estimation.B09_Estimation_ResourceAxis_Sources import ( ) from common_util.common_util_aliases import AliasError, in_scope, load_aliases, parse_aliases -_EXT_SUBPATH = ("resources", "data_resource_catalog") -EXT_CATALOG_FILE = "resource_catalog_ext_2026-01-01.json" +_EXT_SUBPATH = ("resources", "master_data", "old") +EXT_CATALOG_FILE = "3_품셈_산림_자원목록보충_2026-01-01.json" #: 명세 §2 ③ — `AR--<8자리 소문자 16진>`. 종류 글자는 PriceKind 글자 그대로. _RE_AR_CODE = re.compile(r"^AR-([MLX])-[0-9a-f]{8}$") diff --git a/B09_Estimation/B09_Estimation_ResourceAxis_Sources.py b/B09_Estimation/B09_Estimation_ResourceAxis_Sources.py index f696c0c6..656bc49c 100644 --- a/B09_Estimation/B09_Estimation_ResourceAxis_Sources.py +++ b/B09_Estimation/B09_Estimation_ResourceAxis_Sources.py @@ -29,11 +29,13 @@ from B09_Estimation.B09_Estimation_ResourceAxis import ( _RE_ALTERNATIVE, ) -_CATALOG_SUBPATH = ("resources", "data_cost_input_value") -_MASTER_SUBPATH = ("resources", "data_work_item_master") +_CATALOG_SUBPATH = ("resources", "master_data", "old") +_MASTER_SUBPATH = ("resources", "master_data", "old") -def load_labor_catalog(file_name: str = "labor_const_2026-01-01.json") -> ResourceCatalog: +def load_labor_catalog( + file_name: str = "1_기초_노임_건설업_대한건설협회_2026-01-01.json", +) -> ResourceCatalog: """노임 카탈로그 132직종 + `aliases`. 코드는 `occupation_code`.""" payload = _read_json(*_CATALOG_SUBPATH, file_name) variables = payload["variables"] @@ -45,7 +47,9 @@ def load_labor_catalog(file_name: str = "labor_const_2026-01-01.json") -> Resour return ResourceCatalog(entries=entries, aliases=dict(variables.get("aliases", {}))) -def load_machine_catalog_entries(file_name: str = "mach_base_2026.json") -> list[CatalogEntry]: +def load_machine_catalog_entries( + file_name: str = "3_품셈_건설_기계경비기준_8장_2026-01-01.json", +) -> list[CatalogEntry]: """기종 카탈로그 613건을 매칭용 항목으로 편다. ⚠ **규격이 매칭의 일부**다 — 「굴착기(무한궤도)」만 23 규격이라 이름만으로는 @@ -61,7 +65,7 @@ def load_machine_catalog_entries(file_name: str = "mach_base_2026.json") -> list def load_material_catalog_entries( - file_name: str = "mat_price_public_2026-08-14.json", + file_name: str = "1_기초_자재_시설공통_나라장터_2026-08-14.json", ) -> list[CatalogEntry]: """관급 자재 6,999건을 매칭용 항목으로 편다. @@ -102,7 +106,7 @@ def load_combined_catalog() -> ResourceCatalog: def load_work_item_master( - file_name: str = "work_item_master_2026-01-01.json", + file_name: str = "2_공종_산림_마스터_2026-01-01.json", ) -> dict[str, Any]: """메인 창 산출물 — **읽기 전용**.""" return _read_json(*_MASTER_SUBPATH, file_name) diff --git a/B09_Estimation/B09_Estimation_RockLoss.py b/B09_Estimation/B09_Estimation_RockLoss.py index 756df6aa..2993517a 100644 --- a/B09_Estimation/B09_Estimation_RockLoss.py +++ b/B09_Estimation/B09_Estimation_RockLoss.py @@ -38,7 +38,7 @@ def _sources() -> tuple[dict[str, dict[str, Any]], dict[str, int]]: """(기계 코드 → 손료 성분 레코드, 규칙 이름 → 암석 가산 %).""" from B09_Estimation.B09_Estimation_MachineCost import _read_json - variables = _read_json("mach_base_2026.json")["variables"] + variables = _read_json("3_품셈_건설_기계경비기준_8장_2026-01-01.json")["variables"] records = {r["machine_code"]: r for r in variables["mach_loss_coef"]["records"]} rules = {r["machine_group"]: int(r["rock_work"]) for r in variables["mach_rock_adj"]["rules"]} return records, rules diff --git a/B09_Estimation/B09_Estimation_Router.py b/B09_Estimation/B09_Estimation_Router.py index 7aa278a3..7e30fb13 100644 --- a/B09_Estimation/B09_Estimation_Router.py +++ b/B09_Estimation/B09_Estimation_Router.py @@ -92,7 +92,7 @@ class CostRequest(BaseModel): equipment_guarantee_work_type: str = "civil_general" subcontract_guarantee_variant: str = "integrated_civil_or_industrial" - rate_file_name: str = "rates_2026.json" + rate_file_name: str = "1_기초_제비율_토목_조달청_2026-04-13.json" #: 공종별 수량 `{공종코드: 수량}`. 주면 **직접비 3분할을 여기서 만들어** 쓴다. #: ⚠ 일위대가 합계를 뭉쳐 넣지 않는다 — 밑수가 항목마다 갈린다(PLAN 8-9 규칙 2). diff --git a/B09_Estimation/B09_Estimation_UnitPrice.py b/B09_Estimation/B09_Estimation_UnitPrice.py index aed1a286..9c06a591 100644 --- a/B09_Estimation/B09_Estimation_UnitPrice.py +++ b/B09_Estimation/B09_Estimation_UnitPrice.py @@ -500,7 +500,7 @@ def _add_machine_layers( @lru_cache(maxsize=1) def load_basis_missing( - file_name: str = "basis_missing_2026-01-01.json", + file_name: str = "2_공종_산림_밑수없음_2026-01-01.json", ) -> dict[str, str]: """B08 이 낸 **밑수 못 찾은 표** 목록 — `{표 번호: 절 이름}`. @@ -512,7 +512,7 @@ def load_basis_missing( import os root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - path = os.path.join(root, "resources", "data_work_item_master", file_name) + path = os.path.join(root, "resources", "master_data", "old", file_name) if not os.path.exists(path): return {} with open(path, encoding="utf-8") as handle: diff --git a/B09_Estimation/B09_Estimation_WoodChipping.py b/B09_Estimation/B09_Estimation_WoodChipping.py index 39b0ccdc..1dc112ba 100644 --- a/B09_Estimation/B09_Estimation_WoodChipping.py +++ b/B09_Estimation/B09_Estimation_WoodChipping.py @@ -57,7 +57,9 @@ def operating_record(node: dict[str, Any] | None = None): values = _table_values(node) if values is None: return None - aliases = _read_json(*_CATALOG_SUBPATH, "labor_const_2026-01-01.json")["variables"]["aliases"] + aliases = _read_json(*_CATALOG_SUBPATH, "1_기초_노임_건설업_대한건설협회_2026-01-01.json")[ + "variables" + ]["aliases"] return OperatingRecord( machine_code=MACHINE, machine_name="이동식 임목파쇄기", diff --git a/Z01_MasterData/Z01_MasterData_BasePrices_Machine.py b/Z01_MasterData/Z01_MasterData_BasePrices_Machine.py index 350a84c8..e125e11c 100644 --- a/Z01_MasterData/Z01_MasterData_BasePrices_Machine.py +++ b/Z01_MasterData/Z01_MasterData_BasePrices_Machine.py @@ -23,7 +23,11 @@ from B09_Estimation.B09_Estimation_MachineOperating import FUEL_VARIABLES, load_ from Z01_MasterData.Z01_MasterData_Tables import RESOURCES #: B09 셈이 여는 원본 셋 — 바뀌면 캐시를 새로 읽음 -_INPUT_FILES = ("mach_base_2026.json", "pum_const_2026.json", "labor_const_2026-01-01.json") +_INPUT_FILES = ( + "3_품셈_건설_기계경비기준_8장_2026-01-01.json", + "3_품셈_건설_표전체_2026-01-01.json", + "1_기초_노임_건설업_대한건설협회_2026-01-01.json", +) EDITABLE = ["price_thousand_krw", "loss_coefficient_per_hour"] COMPUTED = ("hourly_loss_krw", "hourly_fuel_krw", "hourly_operator_krw", "hourly_total_krw") #: 조종원 식 글자 — B09 식 문자열(좌→우 차례)을 사람이 읽게만 바꿈 @@ -90,7 +94,7 @@ def _cached(_mtimes: tuple[int, ...]): def _inputs(): - folder = RESOURCES / "data_cost_input_value" + folder = RESOURCES / "master_data" / "old" return _cached(tuple((folder / name).stat().st_mtime_ns for name in _INPUT_FILES)) diff --git a/Z01_MasterData/Z01_MasterData_Tables.py b/Z01_MasterData/Z01_MasterData_Tables.py index 0bae789f..5b10d92f 100644 --- a/Z01_MasterData/Z01_MasterData_Tables.py +++ b/Z01_MasterData/Z01_MasterData_Tables.py @@ -19,7 +19,7 @@ from typing import Any ROOT = Path(__file__).resolve().parent.parent RESOURCES = ROOT / "resources" -LABEL_DIR = RESOURCES / "data_master_labels" +LABEL_DIR = RESOURCES / "master_data" / "old" DEFAULT_PAGE_SIZE = 50 MAX_PAGE_SIZE = 500 ROW_KEY = "@key" @@ -132,7 +132,7 @@ def _labels_at(path: str, _mtime_ns: int) -> dict[str, Any]: def load_labels() -> dict[str, Any]: """이름표 끝 판(이름 차례) — 없으면 빈 이름표(파일도 안 보임).""" - found = sorted(LABEL_DIR.glob("labels_*.json")) if LABEL_DIR.is_dir() else [] + found = sorted(LABEL_DIR.glob("4_화면_이름표_*.json")) if LABEL_DIR.is_dir() else [] if not found: return {"kinds": {}, "files": [], "columns": {}, "column_overrides": {}} return _labels_at(str(found[-1]), found[-1].stat().st_mtime_ns) diff --git a/Z01_MasterData/Z01_MasterData_WorkItems.py b/Z01_MasterData/Z01_MasterData_WorkItems.py index 23c8d85b..db86b9a3 100644 --- a/Z01_MasterData/Z01_MasterData_WorkItems.py +++ b/Z01_MasterData/Z01_MasterData_WorkItems.py @@ -24,7 +24,7 @@ SOURCE_OF = { "work_item_forest": "pum_forest", "work_item_const": "pum_const", } # 이름표 `work_item_axis` 와 같은 이름 -FOLDER = tables.RESOURCES / "data_work_item_master" +FOLDER = tables.RESOURCES / "master_data" / "old" #: 불변 열쇠 칸 — ⚠ 데스크탑 서브 자료가 오면 칸 이름을 맞출 것(여기 한 곳) KEY_FIELD = "work_item_key" PATH_JOIN = " › " @@ -127,7 +127,7 @@ def base_rows(kind: str) -> list[dict[str, Any]]: return rows -LINK_FOLDER = tables.RESOURCES / "data_work_item_link" +LINK_FOLDER = tables.RESOURCES / "master_data" / "old" LINKED = "연결됨" @@ -136,7 +136,7 @@ def linked_keys() -> frozenset[str]: ⚠ 목록을 코드에 안 둠 — 판정은 그 표 · 미판정은 안 이음(표의 `unconfirmed_action: do_not_link`). """ - found = sorted(LINK_FOLDER.glob("work_item_link_*.json")) if LINK_FOLDER.is_dir() else [] + found = sorted(LINK_FOLDER.glob("2_공종_산림건설_연결_*.json")) if LINK_FOLDER.is_dir() else [] if not found: return frozenset() links = _read(str(found[-1]), found[-1].stat().st_mtime_ns).get("links") or [] diff --git a/common_util/common_util_aliases.py b/common_util/common_util_aliases.py index 71484ea5..119d8aef 100644 --- a/common_util/common_util_aliases.py +++ b/common_util/common_util_aliases.py @@ -22,7 +22,11 @@ from pathlib import Path from typing import Any ALIAS_FILE = ( - Path(__file__).resolve().parents[1] / "resources" / "data_aliases" / "aliases_2026-01-01.json" + Path(__file__).resolve().parents[1] + / "resources" + / "master_data" + / "ref" + / "공종_자원별칭_실무_2026-01-01.json" ) AXES = frozenset({"resource", "variant"}) _FIELDS = ("axis", "from", "to", "scope", "pum_edition") diff --git a/common_util/common_util_node_bundle.py b/common_util/common_util_node_bundle.py index 9584ab0d..ba14dae7 100644 --- a/common_util/common_util_node_bundle.py +++ b/common_util/common_util_node_bundle.py @@ -22,7 +22,7 @@ ROOT = Path(__file__).resolve().parents[1] # 번들이 낡았는지 재는 대상 — 기하 계통이 걸쳐 있는 폴더 + 구조물도 식 풀이(B08, 2026-09-13). SOURCE_DIRS = ("B05_Profile", "B06_Section", "B08_Quantity", "common_util") # 번들에 박히는 자료(JSON) — 벽 전면 기울기 표준경사 표(2026-09-14 B5). 표만 바뀌어도 다시 빌드. -SOURCE_DATA_DIRS = ("resources/data_masonry",) +SOURCE_DATA_DIRS = ("resources/master_data/old",) # 번들 만들기·실행 상한(초). 실측 번들 실행 0.1초, 빌드 3초 수준이라 넉넉하다. BUILD_TIMEOUT_S = 300 RUN_TIMEOUT_S = 600 diff --git a/common_util/common_util_work_item_key.py b/common_util/common_util_work_item_key.py index 94ec26dd..d5e7e531 100644 --- a/common_util/common_util_work_item_key.py +++ b/common_util/common_util_work_item_key.py @@ -20,7 +20,7 @@ from functools import lru_cache from pathlib import Path from typing import Any, Iterable -MASTER_DIR = Path(__file__).resolve().parent.parent / "resources" / "data_work_item_master" +MASTER_DIR = Path(__file__).resolve().parent.parent / "resources" / "master_data" / "old" #: 우리가 세운 공종·구조물 — 난수 코드가 곧 불변 열쇠 _STABLE_CODE = re.compile(r"^AX-(?:WK|ST)-[0-9a-f]{8}$") @@ -38,7 +38,7 @@ def _read(path: str, _mtime_ns: int) -> dict[tuple[str, str], str | None]: def _keys() -> dict[tuple[str, str], str | None]: out: dict[tuple[str, str], str | None] = {} - for path in sorted(MASTER_DIR.glob("*work_item_master_*.json")): # 산림 + 건설(`const_`) + for path in sorted(MASTER_DIR.glob("2_공종_*_마스터_*.json")): # 산림 + 건설(`const_`) out.update(_read(str(path), path.stat().st_mtime_ns)) return out diff --git a/common_util/common_util_work_item_link.py b/common_util/common_util_work_item_link.py index e949ecda..a86783e6 100644 --- a/common_util/common_util_work_item_link.py +++ b/common_util/common_util_work_item_link.py @@ -19,7 +19,7 @@ from functools import lru_cache from pathlib import Path from typing import Any -FOLDER = Path(__file__).resolve().parent.parent / "resources" / "data_work_item_link" +FOLDER = Path(__file__).resolve().parent.parent / "resources" / "master_data" / "old" CONFIRMED = "확정" #: 표 `policy.both_precedence` 낱말 → 그 행의 열쇠 칸 _KEY_COLUMN = {"forest": "forest_key", "construction": "const_key"} @@ -39,7 +39,7 @@ def _read(path: str, _mtime_ns: int) -> dict[str, Any]: def _doc() -> dict[str, Any]: - found = sorted(FOLDER.glob("work_item_link_*.json")) if FOLDER.is_dir() else [] + found = sorted(FOLDER.glob("2_공종_산림건설_연결_*.json")) if FOLDER.is_dir() else [] return _read(str(found[-1]), found[-1].stat().st_mtime_ns) if found else {}