knowledge(마스터): 인력 열 한 벌 정리 — 조사 → 구분 · 상세구분 · 상태 · 일시간 · 준용 공통 칸

- 인력.json 392 줄이 같은 열 한 벌(키 · 원문번호 · 구분 · 상세구분 · 이름 · 규격 · 단위 · 값 · 출처 · 일시간 · 상태 · 옛이름 · 비고 · 준용)
- 건설업 미공표 14 는 4-라 산정값을 값에 · 상태 「산정」 · 근거는 비고 한 줄 · 산정·신뢰도·업종·부문·환산비·후보 등 열두 칸 없앰
- 머리 「구분」 에 원문 · 기관 · 판 · 공표일 · 원천 · 상세구분 등록 — 새 조사는 한 항목 더하고 줄만 붙이면 끝
- 엔진은 준용이 있으면 그 직종 값 · 없으면 값 · check_master 인력 열 검사 · M01 구분·상세구분 거름과 구분 목록 API · 빌더도 새 열

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JgUhN55Z3BCYhUJTjwTNfj
This commit is contained in:
2026-09-20 15:12:54 +09:00
co-authored by Claude Opus 5
parent cfd8f67471
commit 1447750e89
17 changed files with 775 additions and 653 deletions
+34 -5
View File
@@ -70,7 +70,25 @@ ROW_KEYS = {
"품셈재료": ("", "원문번호", "이름", "규격", "단위", "요구절", "연결"),
}
# 한 테이블 파일 — 줄의 갈래 칸 · 머리의 갈래 묶음
MERGED = {"인력": "조사", "기계": "세부분류"}
MERGED = {"인력": "구분", "기계": "세부분류"}
# 인력 줄 — 모든 줄이 같은 열 한 벌 · 상태 값
LABOR_COLS = (
"",
"원문번호",
"구분",
"상세구분",
"이름",
"규격",
"단위",
"",
"출처",
"일시간",
"상태",
"옛이름",
"비고",
"준용",
)
LABOR_STATUS = ("공표", "산정", "미공표", "미확보")
def load(names: list[str] | None = None, folder: Path = MASTER) -> dict[str, dict]:
@@ -168,6 +186,8 @@ def check_form(name: str, data: dict) -> list[str]:
out.append(f"{where} · 칸 「{need}」 없음")
if "출처" in row and not _source_ok(row["출처"]):
out.append(f"{where} · 출처 모양 「{row['출처']}")
if data.get("그룹") == "인력":
out += _check_labor(where, row)
if kind == "품셈재료":
out += _check_linked(where, row)
if kind == "요소" and isinstance(row.get(""), dict):
@@ -181,6 +201,18 @@ def check_form(name: str, data: dict) -> list[str]:
return out
def _check_labor(where: str, row: dict) -> list[str]:
"""인력 줄 — 열 한 벌(차례까지 같음) · 상태 값 · 옛이름 목록."""
out = []
if tuple(row) != LABOR_COLS:
out.append(f"{where} · 열이 한 벌이 아님 — 「{' · '.join(LABOR_COLS)}")
if row.get("상태") not in LABOR_STATUS:
out.append(f"{where} · 상태 「{row.get('상태')}」 — {' · '.join(LABOR_STATUS)} 아님")
if not isinstance(row.get("옛이름"), list):
out.append(f"{where} · 옛이름 목록 아님 「{row.get('옛이름')}")
return out
def _check_linked(where: str, row: dict) -> list[str]:
"""품셈재료 — 값 칸 없음 · 요구절은 출처 모양 · 연결 = 시중물가 키 · 후보 조건 · null."""
out = [f"{where} · 값 칸을 두지 않음"] if "" in row else []
@@ -200,7 +232,7 @@ def _check_linked(where: str, row: dict) -> list[str]:
def check_links(whole: mf.Master) -> list[str]:
"""끊긴 키 — 품셈재료 연결 · 시중물가 조달 연결 · 인력 준용·후보가 가리키는 줄."""
"""끊긴 키 — 품셈재료 연결 · 시중물가 조달 연결 · 인력 준용 가리키는 줄."""
out = []
for key, row in whole.index.get("MP", {}).items():
link = row.get("연결")
@@ -211,9 +243,6 @@ def check_links(whole: mf.Master) -> list[str]:
ref = row.get(col)
if ref not in (None, "") and str(ref) not in whole.index.get("LB", {}):
out.append(f"{whole.label(key)} · {col}{ref}」 없는 인력 키")
for ref in mk.KEY.findall(str(row.get("후보") or "")):
if ref not in whole.index.get("LB", {}):
out.append(f"{whole.label(key)} · 후보 「{ref}」 없는 인력 키")
nara = whole.index.get("MN", {})
for key, row in whole.index.get("MT", {}).items():
source = str(row[""]["조달"].get("출처") or "")