Merge remote-tracking branches 'origin/main_laptop_1', 'origin/sub_desktop_1' and 'origin/sub_laptop_1' into CODEX
This commit is contained in:
@@ -47,9 +47,26 @@ export interface RowsQuery {
|
||||
sort?: SortOrder | null;
|
||||
}
|
||||
|
||||
/** 기초단가 다섯 — 고친 값은 원본이 아니라 덮개 파일에 쌓임(품셈이 갱신돼도 안 날아감). */
|
||||
/**
|
||||
* ① 기초단가 다섯 — 얼마인가. 시장이 정하고 주간~반기로 바뀜.
|
||||
* 고친 값은 원본이 아니라 덮개 파일에 쌓임(품셈이 갱신돼도 안 날아감).
|
||||
*/
|
||||
export const BASE_PRICE_KINDS = ["labor", "machine", "material", "oil", "rate"] as const;
|
||||
export type BasePriceKind = (typeof BASE_PRICE_KINDS)[number];
|
||||
|
||||
/** ② 품셈 기준 아홉 — 얼마나 드나. 품셈이 정하고 해마다 한 번 개정(2026-09-16 사용자 ①②). */
|
||||
export const SPEC_KINDS = [
|
||||
"coef",
|
||||
"material_surcharge",
|
||||
"formwork_reuse",
|
||||
"rebar_complexity",
|
||||
"timber_structure_class",
|
||||
"masonry_slope",
|
||||
"masonry_back_length",
|
||||
"stone_kind",
|
||||
"masonry_class",
|
||||
] as const;
|
||||
|
||||
export type BasePriceKind = (typeof BASE_PRICE_KINDS)[number] | (typeof SPEC_KINDS)[number];
|
||||
|
||||
async function request<T>(path: string, init: RequestInit = {}): Promise<T> {
|
||||
const response = await fetch(`${API_BASE_URL}${path}`, {
|
||||
|
||||
@@ -15,9 +15,11 @@ import {
|
||||
fetchMasterRows,
|
||||
fetchOverrides,
|
||||
type MasterGroup,
|
||||
type BasePriceKind,
|
||||
type MasterRows,
|
||||
type RowsQuery,
|
||||
saveBasePrice,
|
||||
SPEC_KINDS,
|
||||
VALUES_TABLE_ID,
|
||||
} from "./Z01_MasterData_Api_Fetch";
|
||||
import { valueWithUnit, type OverrideState } from "./Z01_MasterData_UI_Cells";
|
||||
@@ -31,25 +33,32 @@ export function buildSidePanel(groups: MasterGroup[], view: RowsView): HTMLEleme
|
||||
};
|
||||
|
||||
const baseTitle = L("Z01_MasterData_BasePrices");
|
||||
const baseGrid = el("div", { className: "z01-master__base-grid" });
|
||||
for (const kind of BASE_PRICE_KINDS) {
|
||||
const label = L(`Z01_MasterData_Base_${kind}` as const);
|
||||
const button = el("button", {
|
||||
className: "z01-master__base",
|
||||
attrs: { type: "button" },
|
||||
text: label,
|
||||
});
|
||||
button.addEventListener("click", () => {
|
||||
activate(button);
|
||||
view.show({
|
||||
title: `${baseTitle} › ${label}`,
|
||||
key: `base-prices/${kind}`,
|
||||
load: (query) => fetchBasePrices(kind, query),
|
||||
save: (rowId, values) => saveBasePrice(kind, rowId, values),
|
||||
const specTitle = L("Z01_MasterData_SpecValues");
|
||||
/** 한 상자 몫 단추들 — ①얼마인가 ②얼마나 드나 로 갈라 세움(성격도 갱신 주기도 다름). */
|
||||
const kindGrid = (boxTitle: string, kinds: readonly BasePriceKind[]): HTMLElement => {
|
||||
const grid = el("div", { className: "z01-master__base-grid" });
|
||||
for (const kind of kinds) {
|
||||
const label = L(`Z01_MasterData_Base_${kind}` as const);
|
||||
const button = el("button", {
|
||||
className: "z01-master__base",
|
||||
attrs: { type: "button" },
|
||||
text: label,
|
||||
});
|
||||
});
|
||||
baseGrid.append(button);
|
||||
}
|
||||
button.addEventListener("click", () => {
|
||||
activate(button);
|
||||
view.show({
|
||||
title: `${boxTitle} › ${label}`,
|
||||
key: `base-prices/${kind}`,
|
||||
load: (query) => fetchBasePrices(kind, query),
|
||||
save: (rowId, values) => saveBasePrice(kind, rowId, values),
|
||||
});
|
||||
});
|
||||
grid.append(button);
|
||||
}
|
||||
return grid;
|
||||
};
|
||||
const baseGrid = kindGrid(baseTitle, BASE_PRICE_KINDS);
|
||||
const specGrid = kindGrid(specTitle, SPEC_KINDS);
|
||||
const overridesButton = el("button", {
|
||||
className: "z01-master__base z01-master__base--wide",
|
||||
attrs: { type: "button" },
|
||||
@@ -113,7 +122,11 @@ export function buildSidePanel(groups: MasterGroup[], view: RowsView): HTMLEleme
|
||||
tree.append(groupBox);
|
||||
}
|
||||
|
||||
panel.append(section(baseTitle, baseGrid), section(L("Z01_MasterData_Tree"), tree));
|
||||
panel.append(
|
||||
section(baseTitle, baseGrid),
|
||||
section(specTitle, specGrid),
|
||||
section(L("Z01_MasterData_Tree"), tree),
|
||||
);
|
||||
attachCollapsible(panel);
|
||||
return panel;
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
"file": "coef_2026.json",
|
||||
"dataset_id": "coef",
|
||||
"effective_date": "2026-01-01",
|
||||
"sha256": "0bc3fe981165e8d320b7c20f4535c545f2f54415427ac60205dac4a72dbb4f19",
|
||||
"size_bytes": 29413
|
||||
"sha256": "daba170cd806374c92e086dec69f9559271c0317a7426e66e9dc841c2ca264bd",
|
||||
"size_bytes": 31715
|
||||
},
|
||||
{
|
||||
"file": "fx_2026-08-14.json",
|
||||
|
||||
@@ -787,6 +787,7 @@
|
||||
]
|
||||
},
|
||||
"surcharge_mat": {
|
||||
"used_value_at": "resources/data_material_surcharge/material_surcharge_2026-01-01.json → rates_pct — ⚠ 코드가 읽어 쓰는 값은 저기다. 이 표는 원문 보관용이라 읽는 코드가 없다(두 벌이 아니다).",
|
||||
"unit": "percent",
|
||||
"representation": "full_source_tables",
|
||||
"duplicate_application_prohibited": true,
|
||||
@@ -1108,6 +1109,8 @@
|
||||
"max": 1.45,
|
||||
"duplicate_group": "암괴나 호박돌이 섞인 점토",
|
||||
"duplicate_index": 1,
|
||||
"duplicate_same_value": true,
|
||||
"duplicate_reason": "원문 두 줄 · 값 같음 — 화면에는 한 줄로 보임. 원문은 그대로 둠(임의 보정 없음).",
|
||||
"selection": "pending"
|
||||
},
|
||||
{
|
||||
@@ -1129,6 +1132,9 @@
|
||||
"max": 1.45,
|
||||
"duplicate_group": "암괴나 호박돌이 섞인 점토",
|
||||
"duplicate_index": 2,
|
||||
"duplicate_same_value": true,
|
||||
"hidden_duplicate": true,
|
||||
"duplicate_reason": "원문 두 줄 · 값 같음 — 화면에는 한 줄로 보임. 원문은 그대로 둠(임의 보정 없음).",
|
||||
"selection": "pending"
|
||||
}
|
||||
]
|
||||
@@ -1210,6 +1216,8 @@
|
||||
"max": 0.95,
|
||||
"duplicate_group": "암괴나 호박돌이 섞인 점토",
|
||||
"duplicate_index": 1,
|
||||
"duplicate_same_value": true,
|
||||
"duplicate_reason": "원문 두 줄 · 값 같음 — 화면에는 한 줄로 보임. 원문은 그대로 둠(임의 보정 없음).",
|
||||
"selection": "pending"
|
||||
},
|
||||
{
|
||||
@@ -1231,6 +1239,9 @@
|
||||
"max": 0.95,
|
||||
"duplicate_group": "암괴나 호박돌이 섞인 점토",
|
||||
"duplicate_index": 2,
|
||||
"duplicate_same_value": true,
|
||||
"hidden_duplicate": true,
|
||||
"duplicate_reason": "원문 두 줄 · 값 같음 — 화면에는 한 줄로 보임. 원문은 그대로 둠(임의 보정 없음).",
|
||||
"selection": "pending"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
"schema_version": "1.0",
|
||||
"dataset_id": "data_master_labels",
|
||||
"effective_date": "2026-01-01",
|
||||
"generated_at": "2026-09-16T11:39:55+09:00",
|
||||
"generated_at": "2026-09-16T13:11:45+09:00",
|
||||
"note": "마스터 자료의 **사람이 읽을 이름표**. 값이 아니라 이름만 담는다 — 여기를 고쳐도 계산은 안 바뀐다. Z01 마스터 관리 화면이 표·열 이름을 여기서 읽는다.",
|
||||
"policy": {
|
||||
"labels_only": "값·수식·단가를 담지 않는다. 마스터 파일은 손대지 않는다.",
|
||||
"no_invented_meaning": "뜻을 모르는 열은 name_ko 를 비우고 unknown 에 사유를 적는다. 지어내지 않는다.",
|
||||
"unit_is_label_only": "unit 은 이름표에서만 정한다. 자료에 없는 단위를 만들어 붙이지 않는다.",
|
||||
"counting_rule": "표 = 화면이 표로 그릴 마디(줄이 여럿인 마디). 값 묶음 = 표가 아닌 마디(설명·방침·한 값짜리 요율 따위).",
|
||||
"brain_kind_table": "갈래는 2026-09-15 브레인 갈래 나눔표를 그대로 따른다(로직 17 · 기초값 9 · 부산물 4 · 씨앗 1).",
|
||||
"brain_kind_table": "갈래는 2026-09-15 브레인 갈래 나눔표에서 출발한다(로직 17 · 기초값 9 · 부산물 4 · 씨앗 1). 2026-09-16 사용자 판정으로 `structure_unit_observed`·`revetment_sabang` 둘을 **참고 사례**로 옮겼다 — 한 현장 관찰값·교본 설명 섞임이라 기초데이터가 아니다(로직 15 · 참고 사례 2).",
|
||||
"out_of_31": "폴더 지문(_manifest.json) 셋은 브레인 31 밖이다. 부산물이 아니라 **지문** 갈래로 둔다 — 계산이 남긴 기록이 아니라 어느 판으로 셈했는지 못박는 표라 「정본 아님」 딱지가 안 맞는다(2026-09-15 브레인 ②).",
|
||||
"excluded": "강우 IDF 캐시(resources/data_rainfall_idf_cache, 96 파일)는 배수용이라 뺀다.",
|
||||
"merged_tables_rule": "`merged_tables` 는 **기초단가 다섯**(노임·자재·유가·제비율·기계)을 화면이 한 표씩으로 보이려고 여러 원본 표를 모은 자리다. ⚠ **값을 옮기지 않는다** — 열 이름·단위·숨김과 `editable`(고칠 수 있나)만 담는다. `editable: false` 는 다른 값에서 나온 계산값이라 사람이 못 고친다. 기계는 한 표로 안 모이므로 `machine_cost_chain` 이 사슬을 적는다 (2026-09-15 사용자 지시 · 브레인).",
|
||||
@@ -45,6 +45,10 @@
|
||||
"name_ko": "지문",
|
||||
"summary": "어느 판으로 셈했는지 못박는 자리. 값도 규칙도 아니고 **판을 가리키는 표**다 — 고치지 않는다."
|
||||
},
|
||||
"reference": {
|
||||
"name_ko": "참고 사례",
|
||||
"summary": "한 현장·한 교본에서 본 값. ⚠ 표준이 아니다 — 근거로 보되 기초데이터처럼 갈아 끼우지 않는다."
|
||||
},
|
||||
"seed": {
|
||||
"name_ko": "씨앗",
|
||||
"summary": "앞으로 늘려 갈 첫 벌. 모양을 잡아 두려고 먼저 놓은 것이다."
|
||||
@@ -766,6 +770,433 @@
|
||||
"note": "못 채운 성분이 있으면 그 사실을 적는 자리 — 0 으로 안 때운다."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "coef",
|
||||
"name_ko": "토량환산계수",
|
||||
"summary": "판 흙이 부풀고(L) 다진 흙이 줄어드는(C) 비. 토질마다 하한·상한.",
|
||||
"sources": [
|
||||
"coef::variables/coef_soil_L/records",
|
||||
"coef::variables/coef_soil_C/records"
|
||||
],
|
||||
"rows_note": "L 16 + C 16 = 32 줄(암괴 중복 두 줄은 한 줄로 합침)",
|
||||
"columns": [
|
||||
{
|
||||
"key": "table",
|
||||
"name_ko": "어느 표",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "`coef_soil_L`(부풂) · `coef_soil_C`(다짐). ⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "soil_type",
|
||||
"name_ko": "토질",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "min",
|
||||
"name_ko": "하한",
|
||||
"unit": "",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"key": "max",
|
||||
"name_ko": "상한",
|
||||
"unit": "",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"key": "rule",
|
||||
"name_ko": "별도 규정",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "원문이 값 대신 「별도 설계」라 적은 자리."
|
||||
},
|
||||
{
|
||||
"key": "selection",
|
||||
"name_ko": "채택 여부",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "원문이 같은 토질을 두 줄로 실어 어느 줄을 쓸지 아직 안 고른 자리(`pending`)."
|
||||
},
|
||||
{
|
||||
"key": "source_rows",
|
||||
"name_ko": "원문 줄 수",
|
||||
"unit": "줄",
|
||||
"visible": true,
|
||||
"note": "⭐ 한 줄로 보이지만 원문에는 몇 줄이었나 — 암괴 중복 쌍이 `2` 다."
|
||||
},
|
||||
{
|
||||
"key": "duplicate_note",
|
||||
"name_ko": "합친 사유",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "⭐ 「원문 두 줄 · 값 같음 — 한 줄로 보임」. 원문은 그대로 두고 화면만 접었다는 뜻."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "material_surcharge",
|
||||
"name_ko": "재료 할증률",
|
||||
"summary": "자재마다 몇 %를 더 사는지. 조건이 갈리면 다른 조건 칸에 함께 둔다.",
|
||||
"sources": [
|
||||
"material_surcharge::rates_pct"
|
||||
],
|
||||
"rows_note": "19 줄",
|
||||
"columns": [
|
||||
{
|
||||
"key": "material",
|
||||
"name_ko": "자재명",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "rate",
|
||||
"name_ko": "할증률",
|
||||
"unit": "%",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"key": "condition",
|
||||
"name_ko": "조건",
|
||||
"unit": "",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"key": "alt_rate",
|
||||
"name_ko": "다른 조건 할증률",
|
||||
"unit": "%",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"key": "alt_condition",
|
||||
"name_ko": "다른 조건",
|
||||
"unit": "",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"key": "pumsem",
|
||||
"name_ko": "어느 품셈",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "`forest`(산림 · 1차) · `construction`(건설 · 보완)."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "formwork_reuse",
|
||||
"name_ko": "거푸집 사용횟수",
|
||||
"summary": "구조물 갈래마다 거푸집을 몇 번 쓰는지, 횟수마다 기준수량의 몇 %인지.",
|
||||
"sources": [
|
||||
"formwork_reuse::reuse_by_class",
|
||||
"formwork_reuse::reuse_ratio_pct",
|
||||
"formwork_reuse::euroform_type/classes"
|
||||
],
|
||||
"rows_note": "구조 갈래 4 + 사용횟수 비율 12(합판·각재 × 6) + 유로폼 갈래 3 = 19 줄",
|
||||
"columns": [
|
||||
{
|
||||
"key": "table",
|
||||
"name_ko": "어느 표",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "`reuse_by_class`(갈래별 횟수) · `reuse_ratio_pct`(횟수별 비율) · `euroform_type/classes`(유로폼 갈래). ⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "class",
|
||||
"name_ko": "구조 갈래",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "reuse_count",
|
||||
"name_ko": "사용횟수",
|
||||
"unit": "회",
|
||||
"visible": true,
|
||||
"note": "비율표에서는 ⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "examples",
|
||||
"name_ko": "원문 예시",
|
||||
"unit": "",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"key": "material",
|
||||
"name_ko": "거푸집 재료",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "`plywood`(합판) · `timber`(각재). ⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "ratio_pct",
|
||||
"name_ko": "기준수량 비율",
|
||||
"unit": "%",
|
||||
"visible": true,
|
||||
"note": "⭐ 품셈 12-4 — 그 횟수로 쓸 때 기준수량의 몇 %인지. 일위대가 재료비에 걸린다."
|
||||
},
|
||||
{
|
||||
"key": "daily_area_m2",
|
||||
"name_ko": "1일 시공량",
|
||||
"unit": "㎡",
|
||||
"visible": true,
|
||||
"note": "유로폼 설치·해체 품이 갈리는 값."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "rebar_complexity",
|
||||
"name_ko": "철근 가공·조립 갈래",
|
||||
"summary": "간단·보통·복잡·매우복잡 갈래와 갈래별 단가 참고값.",
|
||||
"sources": [
|
||||
"rebar_complexity::classes",
|
||||
"rebar_complexity::price_hint_krw_per_ton"
|
||||
],
|
||||
"rows_note": "갈래 4 + 단가 참고값 4 = 8 줄",
|
||||
"columns": [
|
||||
{
|
||||
"key": "table",
|
||||
"name_ko": "어느 표",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "`classes`(갈래) · `price_hint_krw_per_ton`(단가 참고값). ⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "class",
|
||||
"name_ko": "갈래",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "examples",
|
||||
"name_ko": "원문 예시",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "품셈 12-3 [주]① 이 든 구조물 보기."
|
||||
},
|
||||
{
|
||||
"key": "price_krw_per_ton",
|
||||
"name_ko": "단가 참고값",
|
||||
"unit": "원/ton",
|
||||
"visible": true,
|
||||
"note": "⚠ **표시 전용** — 갈래 차이를 사람이 보라고 둔 값이다. 계산에 안 들어간다."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "timber_structure_class",
|
||||
"name_ko": "목재공작물 구조 갈래",
|
||||
"summary": "갈래마다 목재 채적 1㎥ 에 드는 건축목공·보통인부.",
|
||||
"sources": [
|
||||
"timber_structure_class::classes"
|
||||
],
|
||||
"rows_note": "6 줄",
|
||||
"columns": [
|
||||
{
|
||||
"key": "class",
|
||||
"name_ko": "갈래",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "보통구조 하·중·상 · 상등구조 하·중·상. ⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "carpenter",
|
||||
"name_ko": "건축목공",
|
||||
"unit": "인/㎥",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"key": "laborer",
|
||||
"name_ko": "보통인부",
|
||||
"unit": "인/㎥",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"key": "examples",
|
||||
"name_ko": "원문 예시",
|
||||
"unit": "",
|
||||
"visible": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "masonry_slope",
|
||||
"name_ko": "돌쌓기 표준경사",
|
||||
"summary": "쌓기 방식 × 성절토 × 직고 구간마다 전면 기울기(1:n).",
|
||||
"sources": [
|
||||
"masonry_slope::table"
|
||||
],
|
||||
"rows_note": "메찰 2 × 성절토 2 × 직고 5 = 20 줄",
|
||||
"columns": [
|
||||
{
|
||||
"key": "bond",
|
||||
"name_ko": "쌓기 방식",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "메쌓기 · 찰쌓기. ⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "face",
|
||||
"name_ko": "성토·절토",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "height_bracket",
|
||||
"name_ko": "직고 구간",
|
||||
"unit": "m",
|
||||
"visible": true,
|
||||
"note": "⚠ 원문 표기 그대로(`~1.5`·`~3`·`~5`·`~7`·`7이상`) — 예쁘게 고치면 열쇠가 바뀐다. ⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "face_slope_ratio",
|
||||
"name_ko": "전면 기울기",
|
||||
"unit": "1:n",
|
||||
"visible": true,
|
||||
"note": "코드가 늘 쓰던 0.3 은 이 표의 「메쌓기·성토·~1.5」 한 칸일 뿐이었다."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "masonry_back_length",
|
||||
"name_ko": "돌쌓기 뒷길이 표준",
|
||||
"summary": "쌓기 방식 × 직고 구간마다 뒷길이 하한·상한(㎝).",
|
||||
"sources": [
|
||||
"masonry_back_length::table_cm"
|
||||
],
|
||||
"rows_note": "메찰 2 × 직고 5 = 10 줄",
|
||||
"columns": [
|
||||
{
|
||||
"key": "bond",
|
||||
"name_ko": "쌓기 방식",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "메쌓기 · 찰쌓기. ⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "height_bracket",
|
||||
"name_ko": "직고 구간",
|
||||
"unit": "m",
|
||||
"visible": true,
|
||||
"note": "⚠ 원문 표기 그대로(`~1.5`·`~3`·`~5`·`~7`·`7이상`) — 예쁘게 고치면 열쇠가 바뀐다. ⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "min_cm",
|
||||
"name_ko": "뒷길이 하한",
|
||||
"unit": "㎝",
|
||||
"visible": true,
|
||||
"note": "⭐ 안 고르면 이 값이 제안된다(범위 안에 드는 품셈 규격 중 가장 작은 것)."
|
||||
},
|
||||
{
|
||||
"key": "max_cm",
|
||||
"name_ko": "뒷길이 상한",
|
||||
"unit": "㎝",
|
||||
"visible": true,
|
||||
"note": "원문이 상한을 안 준 칸은 빈다."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "stone_kind",
|
||||
"name_ko": "돌 종류별 소요량",
|
||||
"summary": "돌 종류 × 뒷길이마다 고임돌·채움 콘크리트 원단위와 뒤채움 몫.",
|
||||
"sources": [
|
||||
"stone_kind::wedge_stone_m3_per_m2",
|
||||
"stone_kind::fill_concrete_m3_per_m2",
|
||||
"stone_kind::backfill_ratio_of_back_length",
|
||||
"stone_kind::fallback"
|
||||
],
|
||||
"rows_note": "고임돌 28 + 채움 28 + 뒤채움 몫 4 + 미지정일 때 15 = 75 줄",
|
||||
"columns": [
|
||||
{
|
||||
"key": "table",
|
||||
"name_ko": "어느 표",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "`wedge_stone_m3_per_m2`(고임돌) · `fill_concrete_m3_per_m2`(채움 콘크리트) · `backfill_ratio_of_back_length`(뒤채움 몫) · `fallback/…`(돌 종류 미지정일 때). ⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "stone_kind",
|
||||
"name_ko": "돌 종류",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "야면석·호박돌 / 깬잡석 / 깬돌 / 견치돌. 미지정 벌에는 이 칸이 없다. ⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "back_length_cm",
|
||||
"name_ko": "뒷길이",
|
||||
"unit": "㎝",
|
||||
"visible": true,
|
||||
"note": "25·30·35·45·55·60·75 일곱 규격. ⚠ 표에 없는 뒷길이를 가까운 칸으로 접지 않는다. ⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "m3_per_m2",
|
||||
"name_ko": "원단위",
|
||||
"unit": "㎥/㎡",
|
||||
"visible": true,
|
||||
"note": "고임돌·채움 콘크리트 표의 값. 원문 「-」 칸은 빈다 — 0 이 아니다."
|
||||
},
|
||||
{
|
||||
"key": "ratio",
|
||||
"name_ko": "뒤채움 몫",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "뒷길이 가운데 뒤채움이 차지하는 비. 나머지가 잡석이 된다."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "masonry_class",
|
||||
"name_ko": "돌쌓기 규격 갈래",
|
||||
"summary": "저장 제원으로 자동 판정하는 축 — 뒷길이 갈래·돌 직경 갈래·형식별 전면 기울기.",
|
||||
"sources": [
|
||||
"masonry_class::back_length/classes",
|
||||
"masonry_class::boulder_diameter",
|
||||
"masonry_class::face_slope"
|
||||
],
|
||||
"rows_note": "뒷길이 갈래 3 + 돌 직경 갈래 3 + 형식별 기울기 3 = 9 줄",
|
||||
"columns": [
|
||||
{
|
||||
"key": "table",
|
||||
"name_ko": "어느 표",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "`back_length/classes`(뒷길이 갈래) · `boulder_diameter`(돌 직경 갈래) · `face_slope`(형식별 기울기). ⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "class",
|
||||
"name_ko": "갈래",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "뒷길이는 `35cm이하` 꼴, 돌 직경은 원문 표기 `40~60` 꼴. ⚠ 원문 표기 그대로(`~1.5`·`~3`·`~5`·`~7`·`7이상`) — 예쁘게 고치면 열쇠가 바뀐다. ⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "max_cm",
|
||||
"name_ko": "상한",
|
||||
"unit": "㎝",
|
||||
"visible": true,
|
||||
"note": "뒷길이 갈래의 상한."
|
||||
},
|
||||
{
|
||||
"key": "type_id",
|
||||
"name_ko": "구조물 종류 키",
|
||||
"unit": "",
|
||||
"visible": true,
|
||||
"note": "`masonry_wet`·`masonry_dry`·`boulder_masonry`. ⚠ 줄을 가리는 축 — 못 고침. 바꾸면 고친 값이 주인을 잃는다."
|
||||
},
|
||||
{
|
||||
"key": "face_slope_ratio",
|
||||
"name_ko": "전면 기울기",
|
||||
"unit": "1:n",
|
||||
"visible": true,
|
||||
"note": "형식마다 정해진 값. 코드 기본 0.3 이 여기서 왔다."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"machine_cost_chain": {
|
||||
@@ -993,6 +1424,99 @@
|
||||
"machine_code"
|
||||
],
|
||||
"checked": "취득가 613 · 손료계수 387 · 연료 214 · 운전경비 92 **네 표 모두 기계코드 겹침 0**(전수). 취득가가 가장 넓어 뼈대가 되고 나머지가 붙는다."
|
||||
},
|
||||
{
|
||||
"table": "coef",
|
||||
"name_ko": "토량환산계수",
|
||||
"verdict": "있음(묶어야 함)",
|
||||
"key": [
|
||||
"table",
|
||||
"soil_type"
|
||||
],
|
||||
"checked": "L·C 두 표가 한 자리에 서므로 `table` 이 함께 있어야 한다. 토질 이름은 원문 그대로. 암괴 중복 두 줄은 값이 같아 한 줄로 합쳤고 `source_rows`·`duplicate_note` 가 그 사유를 든다."
|
||||
},
|
||||
{
|
||||
"table": "material_surcharge",
|
||||
"name_ko": "재료 할증률",
|
||||
"verdict": "있음",
|
||||
"key": [
|
||||
"material"
|
||||
],
|
||||
"checked": "자재명 19 줄 겹침 0(전수). 그대로 열쇠로 쓴다."
|
||||
},
|
||||
{
|
||||
"table": "formwork_reuse",
|
||||
"name_ko": "거푸집 사용횟수",
|
||||
"verdict": "있음(표마다 다름)",
|
||||
"key": [
|
||||
"table",
|
||||
"class",
|
||||
"material",
|
||||
"reuse_count"
|
||||
],
|
||||
"checked": "갈래 표는 `table+class`, 비율표는 `table+material+reuse_count` 로 가려진다. 한 표 안에서 축이 갈리므로 열쇠도 줄마다 다르다."
|
||||
},
|
||||
{
|
||||
"table": "rebar_complexity",
|
||||
"name_ko": "철근 갈래",
|
||||
"verdict": "있음(묶어야 함)",
|
||||
"key": [
|
||||
"table",
|
||||
"class"
|
||||
],
|
||||
"checked": "갈래 표와 단가 참고값 표가 같은 갈래 이름을 쓰므로 `table` 이 함께 있어야 한다."
|
||||
},
|
||||
{
|
||||
"table": "timber_structure_class",
|
||||
"name_ko": "목재 구조 갈래",
|
||||
"verdict": "있음",
|
||||
"key": [
|
||||
"class"
|
||||
],
|
||||
"checked": "갈래 6 줄 겹침 0(전수)."
|
||||
},
|
||||
{
|
||||
"table": "masonry_slope",
|
||||
"name_ko": "돌쌓기 표준경사",
|
||||
"verdict": "없음 — 축으로만 가려짐",
|
||||
"key": [
|
||||
"bond",
|
||||
"face",
|
||||
"height_bracket"
|
||||
],
|
||||
"checked": "id 칸이 없다. 쌓기 방식 × 성절토 × 직고 구간 셋으로만 줄이 가려진다. ⚠ 직고 구간은 원문 표기 `~1.5`·`~3`·`~5`·`~7`·`7이상` 그대로 — 열쇠의 몸이라 못 바꾼다."
|
||||
},
|
||||
{
|
||||
"table": "masonry_back_length",
|
||||
"name_ko": "돌쌓기 뒷길이 표준",
|
||||
"verdict": "없음 — 축으로만 가려짐",
|
||||
"key": [
|
||||
"bond",
|
||||
"height_bracket"
|
||||
],
|
||||
"checked": "id 칸이 없다. 쌓기 방식 × 직고 구간 둘로만 가려진다. 구간 표기는 위와 같다."
|
||||
},
|
||||
{
|
||||
"table": "stone_kind",
|
||||
"name_ko": "돌 종류별 소요량",
|
||||
"verdict": "없음 — 축으로만 가려짐",
|
||||
"key": [
|
||||
"table",
|
||||
"stone_kind",
|
||||
"back_length_cm"
|
||||
],
|
||||
"checked": "id 칸이 없다. 표 × 돌 종류 × 뒷길이로 가려지되 **표마다 축 수가 다르다** — 뒤채움 몫은 돌 종류까지, 미지정 벌은 뒷길이까지만 쓴다."
|
||||
},
|
||||
{
|
||||
"table": "masonry_class",
|
||||
"name_ko": "돌쌓기 규격 갈래",
|
||||
"verdict": "없음 — 축으로만 가려짐",
|
||||
"key": [
|
||||
"table",
|
||||
"class",
|
||||
"type_id"
|
||||
],
|
||||
"checked": "id 칸이 없다. 뒷길이·돌 직경 갈래는 `table+class`, 형식별 기울기는 `table+type_id`. ⚠ 돌 직경 갈래 이름은 원문 표기 `40~60` 꼴 그대로다."
|
||||
}
|
||||
],
|
||||
"null_is_real": {
|
||||
@@ -1086,15 +1610,15 @@
|
||||
}
|
||||
},
|
||||
"counts": {
|
||||
"merged_tables": 5,
|
||||
"merged_columns": 89,
|
||||
"merged_tables": 14,
|
||||
"merged_columns": 136,
|
||||
"files": 34,
|
||||
"tables": 91,
|
||||
"columns": 456,
|
||||
"value_groups": 173,
|
||||
"columns": 462,
|
||||
"value_groups": 175,
|
||||
"unknown": 0,
|
||||
"value_groups_by_kind": {
|
||||
"doc": 107,
|
||||
"doc": 109,
|
||||
"value": 66
|
||||
}
|
||||
},
|
||||
@@ -1484,6 +2008,24 @@
|
||||
"name_ko": "채택 여부",
|
||||
"unit": "",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"key": "duplicate_same_value",
|
||||
"name_ko": "값 같은 중복",
|
||||
"unit": "",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"key": "duplicate_reason",
|
||||
"name_ko": "중복 사유",
|
||||
"unit": "",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"key": "hidden_duplicate",
|
||||
"name_ko": "접힌 줄",
|
||||
"unit": "",
|
||||
"visible": false
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1529,6 +2071,24 @@
|
||||
"name_ko": "채택 여부",
|
||||
"unit": "",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"key": "duplicate_same_value",
|
||||
"name_ko": "값 같은 중복",
|
||||
"unit": "",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"key": "duplicate_reason",
|
||||
"name_ko": "중복 사유",
|
||||
"unit": "",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"key": "hidden_duplicate",
|
||||
"name_ko": "접힌 줄",
|
||||
"unit": "",
|
||||
"visible": false
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1665,6 +2225,12 @@
|
||||
"name_ko": "값 단위",
|
||||
"summary": "할증은 %다.",
|
||||
"kind": "value"
|
||||
},
|
||||
{
|
||||
"key": "variables/surcharge_mat/used_value_at",
|
||||
"name_ko": "쓰는 값이 있는 자리",
|
||||
"summary": "이 표는 원문 보관용이라 읽는 코드가 없다. 값은 `material_surcharge` 의 `rates_pct` 를 읽는다.",
|
||||
"kind": "doc"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1827,6 +2393,12 @@
|
||||
"summary": "실무 집계에서 본 할증률. 참고이지 기본값이 아니다.",
|
||||
"kind": "value"
|
||||
},
|
||||
{
|
||||
"key": "original_tables",
|
||||
"name_ko": "원문 표가 실린 자리",
|
||||
"summary": "같은 값이 `coef` 의 `surcharge_mat` 에도 있다. ⚠ 두 벌이 아니다 — 저쪽은 원문 보관이고 읽어 쓰는 정본은 여기다.",
|
||||
"kind": "doc"
|
||||
},
|
||||
{
|
||||
"key": "policy",
|
||||
"name_ko": "방침",
|
||||
@@ -2562,9 +3134,9 @@
|
||||
{
|
||||
"file_id": "revetment_sabang",
|
||||
"path": "resources/data_masonry/revetment_sabang_2026-01-01.json",
|
||||
"name_ko": "기슭막이 치수(사방)",
|
||||
"summary": "독립 기슭막이의 높이·계획비탈·둑마루 두께·뒷채움을 한 자리에 둔 벌.",
|
||||
"kind": "logic",
|
||||
"name_ko": "기슭막이 치수(사방) — 참고 사례",
|
||||
"summary": "사방기술교본 값에 설명 글이 섞인 벌. ⚠ 기초데이터가 아니다 — 표준값처럼 쓰지 말고 근거로만 본다(2026-09-16 사용자 판정).",
|
||||
"kind": "reference",
|
||||
"tables": [],
|
||||
"value_groups": [
|
||||
{
|
||||
@@ -2596,9 +3168,9 @@
|
||||
{
|
||||
"file_id": "structure_unit_observed",
|
||||
"path": "resources/data_structure_unit/structure_unit_observed_2026-01-01.json",
|
||||
"name_ko": "구조물 관측 원단위",
|
||||
"summary": "품셈에 표준 물량표가 없는 콘크리트 구조물을 실무 설계원본에서 뽑은 벌.",
|
||||
"kind": "logic",
|
||||
"name_ko": "구조물 관측 원단위 — 참고 사례",
|
||||
"summary": "울진소광 **한 현장**을 관찰한 값이다. ⚠ 기초데이터가 아니다 — 규격이 다르면 안 맞고 표준도 아니다(2026-09-16 사용자 판정).",
|
||||
"kind": "reference",
|
||||
"tables": [
|
||||
{
|
||||
"key": "double_count_rules/rules",
|
||||
@@ -6320,6 +6892,16 @@
|
||||
"unit": "",
|
||||
"visible": true
|
||||
},
|
||||
"duplicate_reason": {
|
||||
"name_ko": "중복 사유",
|
||||
"unit": "",
|
||||
"visible": true
|
||||
},
|
||||
"duplicate_same_value": {
|
||||
"name_ko": "값 같은 중복",
|
||||
"unit": "",
|
||||
"visible": true
|
||||
},
|
||||
"duration_bracket": {
|
||||
"name_ko": "공사기간 구간",
|
||||
"unit": "",
|
||||
@@ -6470,6 +7052,11 @@
|
||||
"unit": "",
|
||||
"visible": true
|
||||
},
|
||||
"hidden_duplicate": {
|
||||
"name_ko": "접힌 줄",
|
||||
"unit": "",
|
||||
"visible": false
|
||||
},
|
||||
"hours_per_day": {
|
||||
"name_ko": "1일 근로시간",
|
||||
"unit": "시간",
|
||||
@@ -7479,6 +8066,10 @@
|
||||
"name_ko": "값 단위",
|
||||
"summary": "할증은 %다."
|
||||
},
|
||||
"coef::variables/surcharge_mat/used_value_at": {
|
||||
"name_ko": "쓰는 값이 있는 자리",
|
||||
"summary": "이 표는 원문 보관용이라 읽는 코드가 없다. 값은 `material_surcharge` 의 `rates_pct` 를 읽는다."
|
||||
},
|
||||
"formwork_reuse::reuse_ratio_pct": {
|
||||
"name_ko": "사용횟수별 기준수량 비율",
|
||||
"summary": "품셈 12-4 — 일위대가 재료비에 걸린다. B08 이 곱하면 이중계상이다."
|
||||
@@ -7599,6 +8190,10 @@
|
||||
"name_ko": "실무 관측",
|
||||
"summary": "실무 집계에서 본 할증률. 참고이지 기본값이 아니다."
|
||||
},
|
||||
"material_surcharge::original_tables": {
|
||||
"name_ko": "원문 표가 실린 자리",
|
||||
"summary": "같은 값이 `coef` 의 `surcharge_mat` 에도 있다. ⚠ 두 벌이 아니다 — 저쪽은 원문 보관이고 읽어 쓰는 정본은 여기다."
|
||||
},
|
||||
"oil::variables/oil_diesel": {
|
||||
"name_ko": "경유 단가",
|
||||
"summary": "전국평균 경유 값(원/L)."
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
"schema_version": "1.0",
|
||||
"dataset_id": "data_master_sources",
|
||||
"effective_date": "2026-09-15",
|
||||
"generated_at": "2026-09-15T21:59:23+09:00",
|
||||
"generated_at": "2026-09-16T14:05:40+09:00",
|
||||
"note": "기초단가 자료가 **어디서 오고 얼마 만에 바뀌는지** 적은 표. 파일 안에는 제 판만 있고 「최신이 무엇인지·어디서 받는지」가 없어 건설 노임이 반 년 뒤처진 것을 아무도 몰랐다(2026-09-15). 그 자리를 메운다.",
|
||||
"policy": {
|
||||
"values_untouched": "값을 담지 않는다. 자료가 어디서 오는지만 담는다.",
|
||||
"our_edition_is_read": "`our_edition` 은 **실제 파일에서 읽는다**(`effective_date`, 파생본은 `derived_from.effective_date`). 손으로 적으면 갱신하고 안 고쳐 또 뒤처진다.",
|
||||
"address_found_on": "받는 자리 일곱은 2026-09-16 에 안티그래비티가 찾아 채웠다(제조노임·기계·기계 운전경비·자재·유가 전국·유가 지역·요율). 건설노임 한 줄은 그 전(2026-09-15)에 브레인이 준 것이다.",
|
||||
"no_invented_address": "받는 자리는 **받은 것만** 적는다. 모르면 빈 칸으로 두고 사유를 단다 — 주소를 지어내지 않는다.",
|
||||
"status_rule": "`latest_published` 가 `our_edition` 보다 뒤면 **뒤처짐**, 같으면 최신, 둘 가운데 하나라도 없으면 **모름**. 날마다 바뀌는 유가는 날짜 차이로 보여야 한다."
|
||||
},
|
||||
@@ -65,19 +66,18 @@
|
||||
"kind_ko": "노임",
|
||||
"name_ko": "중소제조업 직종별 임금",
|
||||
"publisher": "중소기업중앙회",
|
||||
"where_to_get": "",
|
||||
"where_to_get": "중소기업중앙회 https://www.kbiz.or.kr | [정보마당] > [조사연구통계](게시판 mnSeq=325) > 「중소제조업 직종별 임금조사보고서」 PDF",
|
||||
"cycle": "반기",
|
||||
"latest_published": "",
|
||||
"latest_basis": "",
|
||||
"our_edition": "2026-07-01",
|
||||
"our_edition_from": "effective_date",
|
||||
"status": "unknown",
|
||||
"checked_on": "2026-09-15",
|
||||
"note": "받는 자리를 아직 못 받았다 — 주소를 지어내지 않는다. 우리 판은 2026 상반기 조사(조사월 2026-03 · 공표 2026-06-30)다.",
|
||||
"checked_on": "2026-09-16",
|
||||
"note": "우리 판은 2026 상반기 조사(조사월 2026-03 · 공표 2026-06-30)다. ⚠ 게시판에 반기마다 새 보고서가 올라오므로 **최신 공표일은 게시판에서 봐야** 한다.",
|
||||
"files": [
|
||||
"resources/data_cost_input_value/labor_mfg_2026-07-01.json"
|
||||
],
|
||||
"where_to_get_missing_reason": "받는 자리를 아직 못 받았다 — 주소를 지어내지 않는다.",
|
||||
"latest_missing_reason": "수시·일별이라 최신 공표일이 한 날로 안 정해지거나, 아직 확인을 안 했다."
|
||||
},
|
||||
{
|
||||
@@ -86,19 +86,18 @@
|
||||
"kind_ko": "기계",
|
||||
"name_ko": "건설공사 표준품셈 제8장 건설기계",
|
||||
"publisher": "국토교통부",
|
||||
"where_to_get": "",
|
||||
"where_to_get": "공사비원가관리센터 https://cost.kict.re.kr | [표준품셈] (또는 CODIL https://www.codil.or.kr [건설기준정보] > [건설공사표준품셈]) > 건설공사 표준품셈 원문 PDF(공통부문 제8장 건설기계 8-3)",
|
||||
"cycle": "해마다",
|
||||
"latest_published": "2026-01-01",
|
||||
"latest_basis": "2026-09-15 브레인 쪽지",
|
||||
"our_edition": "2026-01-01",
|
||||
"our_edition_from": "effective_date",
|
||||
"status": "current",
|
||||
"checked_on": "2026-09-15",
|
||||
"checked_on": "2026-09-16",
|
||||
"note": "우리 판이 최신이다. 취득가·손료계수·연료소모량·조종원이 다 여기서 온다.",
|
||||
"files": [
|
||||
"resources/data_cost_input_value/mach_base_2026.json"
|
||||
],
|
||||
"where_to_get_missing_reason": "받는 자리를 아직 못 받았다 — 주소를 지어내지 않는다."
|
||||
]
|
||||
},
|
||||
{
|
||||
"source_id": "machine_operating",
|
||||
@@ -106,19 +105,18 @@
|
||||
"kind_ko": "기계",
|
||||
"name_ko": "건설기계 운전경비(품셈 8-4 파생본)",
|
||||
"publisher": "국토교통부",
|
||||
"where_to_get": "",
|
||||
"where_to_get": "공사비원가관리센터 https://cost.kict.re.kr | 별도 배포처 없음(위 건설공사 표준품셈 원문과 같음) > 공통부문 제8장 건설기계 「8-4 건설기계 운전경비 산정」 표",
|
||||
"cycle": "해마다 — 위 품셈을 따라간다",
|
||||
"latest_published": "2026-01-01",
|
||||
"latest_basis": "파생 원본(mach_base)의 판",
|
||||
"our_edition": "2026-01-01",
|
||||
"our_edition_from": "derived_from.effective_date",
|
||||
"status": "current",
|
||||
"checked_on": "2026-09-15",
|
||||
"checked_on": "2026-09-16",
|
||||
"note": "⚠ **판을 모르는 파일이 아니다** — 파일 안 `derived_from.effective_date` 에 2026-01-01 이 박혀 있다(건설품셈 8-4 운전경비 파생본 · 원본 지문까지 함께). `mach_fuel_rate`·`mach_operator_map` 이 다 차면 걷어낼 자리다.",
|
||||
"files": [
|
||||
"resources/data_cost_machine_operating/machine_operating_2026.json"
|
||||
],
|
||||
"where_to_get_missing_reason": "받는 자리를 아직 못 받았다 — 주소를 지어내지 않는다."
|
||||
]
|
||||
},
|
||||
{
|
||||
"source_id": "mat_price_public",
|
||||
@@ -126,19 +124,18 @@
|
||||
"kind_ko": "자재",
|
||||
"name_ko": "관급자재 단가(시설공통자재)",
|
||||
"publisher": "조달청",
|
||||
"where_to_get": "",
|
||||
"where_to_get": "나라장터 https://www.g2b.go.kr | [가격정보] > [시설공통자재] (또는 조달청 https://www.pps.go.kr [정보제공] > [업무별자료] > [시설공사]) > 시설공통자재 가격조사 엑셀",
|
||||
"cycle": "반기 + 수시",
|
||||
"latest_published": "",
|
||||
"latest_basis": "",
|
||||
"our_edition": "2026-08-14",
|
||||
"our_edition_from": "effective_date",
|
||||
"status": "unknown",
|
||||
"checked_on": "2026-09-15",
|
||||
"checked_on": "2026-09-16",
|
||||
"note": "수시 공고라 「최신 공표일」이 한 날로 안 정해진다 — 받은 날(우리 판)이 곧 기준이다. 철근·레미콘·아스콘은 이 벌에 없다(쇼핑몰 스냅숏 미확보).",
|
||||
"files": [
|
||||
"resources/data_cost_input_value/mat_price_public_2026-08-14.json"
|
||||
],
|
||||
"where_to_get_missing_reason": "받는 자리를 아직 못 받았다 — 주소를 지어내지 않는다.",
|
||||
"latest_missing_reason": "수시·일별이라 최신 공표일이 한 날로 안 정해지거나, 아직 확인을 안 했다."
|
||||
},
|
||||
{
|
||||
@@ -147,19 +144,18 @@
|
||||
"kind_ko": "유가",
|
||||
"name_ko": "유가 — 전국평균",
|
||||
"publisher": "한국석유공사(오피넷)",
|
||||
"where_to_get": "",
|
||||
"where_to_get": "오피넷 https://www.opinet.co.kr | [국내유가통계] > [주유소] > [평균판매가격] — 「전국」 탭 조회 뒤 [엑셀저장](API avgAllPrice.do)",
|
||||
"cycle": "주간 · 일별",
|
||||
"latest_published": "",
|
||||
"latest_basis": "",
|
||||
"our_edition": "2026-08-14",
|
||||
"our_edition_from": "effective_date",
|
||||
"status": "unknown",
|
||||
"checked_on": "2026-09-15",
|
||||
"checked_on": "2026-09-16",
|
||||
"note": "날마다 바뀌는 값이라 「최신」이 곧 오늘이다. **뒤처짐을 날짜 차이로 보여야 하는 자료**다. ⚠ 시도별 판과 「전국」 줄이 겹치는데 값도 기준일도 다르다(어느 쪽을 쓸지 판정 대기).",
|
||||
"files": [
|
||||
"resources/data_cost_input_value/oil_2026-08-14.json"
|
||||
],
|
||||
"where_to_get_missing_reason": "받는 자리를 아직 못 받았다 — 주소를 지어내지 않는다.",
|
||||
"latest_missing_reason": "수시·일별이라 최신 공표일이 한 날로 안 정해지거나, 아직 확인을 안 했다."
|
||||
},
|
||||
{
|
||||
@@ -168,19 +164,18 @@
|
||||
"kind_ko": "유가",
|
||||
"name_ko": "유가 — 시도별",
|
||||
"publisher": "한국석유공사(오피넷)",
|
||||
"where_to_get": "",
|
||||
"where_to_get": "오피넷 https://www.opinet.co.kr | [국내유가통계] > [주유소] > [평균판매가격] — 「지역별」 탭에서 시도를 고른 뒤 [엑셀저장](API avgSidoPrice.do)",
|
||||
"cycle": "주간 · 일별",
|
||||
"latest_published": "",
|
||||
"latest_basis": "",
|
||||
"our_edition": "2026-09-09",
|
||||
"our_edition_from": "effective_date",
|
||||
"status": "unknown",
|
||||
"checked_on": "2026-09-15",
|
||||
"checked_on": "2026-09-16",
|
||||
"note": "품셈 8-1-7 5호 「유류가격은 해당지역의 가격으로 한다」를 따르려고 둔 벌이다.",
|
||||
"files": [
|
||||
"resources/data_cost_input_value/oil_regional_2026-09-09.json"
|
||||
],
|
||||
"where_to_get_missing_reason": "받는 자리를 아직 못 받았다 — 주소를 지어내지 않는다.",
|
||||
"latest_missing_reason": "수시·일별이라 최신 공표일이 한 날로 안 정해지거나, 아직 확인을 안 했다."
|
||||
},
|
||||
{
|
||||
@@ -189,19 +184,18 @@
|
||||
"kind_ko": "요율",
|
||||
"name_ko": "토목공사 원가계산 제비율 적용기준",
|
||||
"publisher": "조달청",
|
||||
"where_to_get": "",
|
||||
"where_to_get": "조달청 https://www.pps.go.kr | [정보제공] > [업무별자료] > [시설공사] > 「시설공사 원가계산 간접공사비(제비율) 적용기준」 토목 엑셀(재게시 kseis https://www.kseis.co.kr 자료실)",
|
||||
"cycle": "해마다 + 수시(법이 바뀌면)",
|
||||
"latest_published": "2026-04-13",
|
||||
"latest_basis": "2026-09-15 브레인 쪽지",
|
||||
"our_edition": "2026-04-13",
|
||||
"our_edition_from": "effective_date",
|
||||
"status": "current",
|
||||
"checked_on": "2026-09-15",
|
||||
"checked_on": "2026-09-16",
|
||||
"note": "우리 판이 최신이다. 국민연금 요율은 국민연금법(현행 2026-06-17)을 따로 물었다. ⚠ 요율은 **법이 바뀌면 주기와 상관없이** 바뀐다 — 주기만 보고 안심하면 안 된다.",
|
||||
"files": [
|
||||
"resources/data_cost_input_value/rates_2026.json"
|
||||
],
|
||||
"where_to_get_missing_reason": "받는 자리를 아직 못 받았다 — 주소를 지어내지 않는다."
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
"files": [
|
||||
{
|
||||
"file": "material_surcharge_2026-01-01.json",
|
||||
"sha256": "30a1e11acb6f6bd52c72e0ff471c96f772917858306ea61f66ecbcb5df433c9f",
|
||||
"size_bytes": 5087
|
||||
"sha256": "1394a39be22ac0eb7476e4bc2b81c1e23c365a4ad5b915befe85d3f0f99023d5",
|
||||
"size_bytes": 5344
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"schema_version": "1.0",
|
||||
"dataset_id": "material_surcharge",
|
||||
"original_tables": "resources/data_cost_input_value/coef_2026.json → variables/surcharge_mat — 원문 표가 실린 자리. ⚠ 값이 겹치지만 이원화가 아니다: 저쪽은 원문 보관이고 읽어 쓰는 정본은 여기(rates_pct)다.",
|
||||
"effective_date": "2026-01-01",
|
||||
"source": {
|
||||
"primary": {
|
||||
|
||||
@@ -152,3 +152,60 @@ def test_단위가_붙어야_할_열에_단위가_있다(shown):
|
||||
if units.get(key) != unit:
|
||||
bad.append(f"{kind}/{key}: {units.get(key)!r} ≠ {unit!r}")
|
||||
assert not bad, bad
|
||||
|
||||
|
||||
def test_줄_열쇠가_서버_축과_같다(labels):
|
||||
"""⭐ 덮개가 줄을 붙드는 끈 — 서버가 줄마다 `@axis` 로 내는 축이 곧 열쇠다.
|
||||
|
||||
이름표가 축을 빠뜨리면 고친 값이 갱신 뒤 주인을 잃는다.
|
||||
"""
|
||||
declared = {r["table"]: set(r["key"]) for r in labels["row_keys"]}
|
||||
bad = []
|
||||
for kind in base_prices.KINDS:
|
||||
axes = set()
|
||||
for row in base_prices.rows(kind):
|
||||
axes |= set(row.get("@axis") or ())
|
||||
if not axes: # 다섯 표는 `@id` 한 칸이라 축을 안 낸다
|
||||
continue
|
||||
missing = axes - declared.get(kind, set())
|
||||
if missing:
|
||||
bad.append(f"{kind}: 이름표에 없는 축 {sorted(missing)}")
|
||||
assert not bad, bad
|
||||
|
||||
|
||||
def test_구간_이름은_원문_표기_그대로다():
|
||||
"""⚠ `~1.5`·`7이상` 을 예쁘게 고치면 줄 열쇠가 바뀌어 덮개가 주인을 잃는다."""
|
||||
for kind in ("masonry_slope", "masonry_back_length"):
|
||||
brackets = {str(r.get("height_bracket")) for r in base_prices.rows(kind)}
|
||||
assert brackets == {"~1.5", "~3", "~5", "~7", "7이상"}, (kind, sorted(brackets))
|
||||
classes = {
|
||||
str(r.get("class"))
|
||||
for r in base_prices.rows("masonry_class")
|
||||
if r.get("table") == "boulder_diameter"
|
||||
}
|
||||
assert classes == {"40~60", "60~80", "80~100"}, sorted(classes)
|
||||
|
||||
|
||||
#: ⚠ **줄마다 축이기도 값이기도 한 칸** — `formwork_reuse.reuse_count` 는
|
||||
#: `reuse_by_class` 줄에서는 **고치는 값**(갈래별 사용횟수)이고
|
||||
#: `reuse_ratio_pct` 줄에서는 **축**(몇 회째인가)이다. 서버는 열 하나에 한 판정만 내므로
|
||||
#: 지금은 고칠 수 있는 칸으로 서 있다. 비율표 줄에서 이 칸을 고치면 **다른 줄로 옮겨 간다**.
|
||||
#: 2026-09-16 크로스체크에서 드러났고 판정 대기 — 고치기 전까지 여기 예외로 적어 둔다.
|
||||
AXIS_ALSO_VALUE = {"formwork_reuse/reuse_count"}
|
||||
|
||||
|
||||
def test_축_칸은_못_고친다():
|
||||
"""축을 고치면 줄이 다른 줄이 된다 — 서버가 잠가야 한다."""
|
||||
bad = []
|
||||
for kind in base_prices.KINDS:
|
||||
rows = base_prices.rows(kind)
|
||||
axes = set()
|
||||
for row in rows:
|
||||
axes |= set(row.get("@axis") or ())
|
||||
if not axes:
|
||||
continue
|
||||
meta = base_prices.table(kind, page=1, size=1)
|
||||
for axis in axes:
|
||||
if axis in meta["editable"] and f"{kind}/{axis}" not in AXIS_ALSO_VALUE:
|
||||
bad.append(f"{kind}/{axis} 가 고칠 수 있는 칸으로 섰다")
|
||||
assert not bad, bad
|
||||
|
||||
@@ -19,7 +19,9 @@ ROOT = Path(__file__).resolve().parents[2]
|
||||
LABELS_PATH = ROOT / "resources" / "data_master_labels" / "labels_2026-01-01.json"
|
||||
|
||||
#: 브레인 갈래 나눔표(2026-09-15). 폴더 장부(_manifest)는 그 31 밖이라 따로 센다.
|
||||
BRAIN_KIND_COUNTS = {"logic": 17, "base_value": 9, "byproduct": 4, "seed": 1}
|
||||
#: 2026-09-16 사용자 판정 — `structure_unit_observed`(울진소광 한 현장 관찰값)와
|
||||
#: `revetment_sabang`(교본값에 설명 글 섞임)은 기초데이터가 아니라 **참고 사례**다.
|
||||
BRAIN_KIND_COUNTS = {"logic": 15, "base_value": 9, "byproduct": 4, "seed": 1, "reference": 2}
|
||||
MANIFEST_PREFIX = "manifest_"
|
||||
|
||||
META_KEYS = {
|
||||
@@ -449,12 +451,29 @@ def test_미결은_미판정으로_표시된다(labels):
|
||||
assert column["name_ko"] == "미판정"
|
||||
|
||||
|
||||
MERGED_KEYS = ("labor", "material", "oil", "rate", "machine")
|
||||
#: 2026-09-16 사용자 판정 — 기초데이터 아홉이 더해져 열넷.
|
||||
#: 잣대 = 계산되는 값이 아니라 **그냥 값만으로 정의되는 데이터셋**.
|
||||
MERGED_KEYS = (
|
||||
"labor",
|
||||
"material",
|
||||
"oil",
|
||||
"rate",
|
||||
"machine",
|
||||
"coef",
|
||||
"material_surcharge",
|
||||
"formwork_reuse",
|
||||
"rebar_complexity",
|
||||
"timber_structure_class",
|
||||
"masonry_slope",
|
||||
"masonry_back_length",
|
||||
"stone_kind",
|
||||
"masonry_class",
|
||||
)
|
||||
|
||||
|
||||
def test_기초단가_다섯이_다_있다(labels):
|
||||
def test_기초데이터_열넷이_다_있다(labels):
|
||||
merged = {m["key"]: m for m in labels["merged_tables"]}
|
||||
assert tuple(merged) == MERGED_KEYS
|
||||
assert set(merged) == set(MERGED_KEYS)
|
||||
for entry in merged.values():
|
||||
assert entry["name_ko"].strip()
|
||||
assert entry["summary"].strip()
|
||||
|
||||
@@ -49,7 +49,15 @@ def test_갈래는_이름표_차례_파일_34_강우_캐시는_없음(client: Te
|
||||
groups = _tree(client)["groups"]
|
||||
assert [g["key"] for g in groups] == [k for k in LABELS["kinds"]]
|
||||
counts = {g["key"]: len(g["files"]) for g in groups}
|
||||
assert counts == {"logic": 17, "base_value": 9, "byproduct": 4, "fingerprint": 3, "seed": 1}
|
||||
# 2026-09-16 사용자 판정 — 한 현장 관찰값·교본 설명 섞임 둘은 참고 사례로 옮겼다.
|
||||
assert counts == {
|
||||
"logic": 15,
|
||||
"base_value": 9,
|
||||
"byproduct": 4,
|
||||
"reference": 2,
|
||||
"fingerprint": 3,
|
||||
"seed": 1,
|
||||
}
|
||||
assert {g["key"]: g["label"] for g in groups}["base_value"] == "기초값"
|
||||
by_id = {f["file_id"]: f for f in LABELS["files"]}
|
||||
for f in (f for g in groups for f in g["files"]):
|
||||
|
||||
@@ -147,6 +147,17 @@ export const ui_locales_b3 = {
|
||||
Z01_MasterData_Base_material: ["자재단가", "Material"],
|
||||
Z01_MasterData_Base_oil: ["유가", "Fuel"],
|
||||
Z01_MasterData_Base_rate: ["요율", "Rates"],
|
||||
/* ② 품셈 기준 아홉 — 얼마나 드나(품셈이 정하고 해마다 한 번 개정) */
|
||||
Z01_MasterData_SpecValues: ["품셈 기준", "Standard rates"],
|
||||
Z01_MasterData_Base_coef: ["토량환산", "Soil conversion"],
|
||||
Z01_MasterData_Base_material_surcharge: ["자재할증", "Material surcharge"],
|
||||
Z01_MasterData_Base_formwork_reuse: ["거푸집", "Formwork reuse"],
|
||||
Z01_MasterData_Base_rebar_complexity: ["철근", "Rebar"],
|
||||
Z01_MasterData_Base_timber_structure_class: ["목구조", "Timber structure"],
|
||||
Z01_MasterData_Base_masonry_slope: ["돌쌓기 경사", "Masonry slope"],
|
||||
Z01_MasterData_Base_masonry_back_length: ["뒷길이", "Back length"],
|
||||
Z01_MasterData_Base_stone_kind: ["돌종류", "Stone kind"],
|
||||
Z01_MasterData_Base_masonry_class: ["갈래", "Masonry class"],
|
||||
Z01_MasterData_Overrides: ["고친 것 모아 보기", "Edited values"],
|
||||
Z01_MasterData_Edit_Can: [
|
||||
"고칠 수 있는 칸 — 눌러 고치고 Enter 로 저장 (Esc 취소)",
|
||||
|
||||
Reference in New Issue
Block a user