feat(815-2): M01 요소 표 「별칭」 한 열 · 마스터 기계 별칭 다섯 옮김

- 인력 · 기계 · 재료 자재 · 유가전력 표에 비고 앞 「별칭」 열 — 눌러 고침 · 콤마로 여러 개 · 빈 글이면 칸 없음
- 저장 길 = 그대로 `/api/m01/save`(서버가 앞뒤 빈칸 뗌 · 빈 글 = 칸 지움 · 그 줄만 다시 씀)
- check_master — 요소 줄 열 한 벌 밖 덧칸 `별칭` 허용(빈 글 · 글 아님은 흠)
- 마스터 기계 별칭 다섯(맞춤.json) → 기계 줄 15 개 `별칭` · 옛 마스터 장부 파일 걷음
- M01 로직 1,513 셈 지문 전후 같음
- 새 시험 test_815_2_alias_column.py

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-11 14:20:09 +09:00
co-authored by Claude Opus 5.5
parent afb3fcff8d
commit 4549e28fa5
6 changed files with 179 additions and 165 deletions
@@ -149,6 +149,11 @@ COLS = {
),
}
COLS["한국은행환율"] = COLS["유가전력"]
ALIAS = "별칭" # 요소 줄 덧칸(815-2) — 열 한 벌 밖 · 있으면 빈 글 아님
def _cols_of(row: dict) -> tuple:
return tuple(k for k in row if k != ALIAS)
def _detail(name: str) -> str:
@@ -310,7 +315,9 @@ def check_form(name: str, data: dict) -> list[str]:
out.append(f"{where} · 출처 모양 「{row['출처']}」")
if data.get("그룹") == "인력":
out += _check_labor(where, row)
if cols and tuple(row) != cols:
if ALIAS in row and not (isinstance(row[ALIAS], str) and row[ALIAS].strip()):
out.append(f"{where} · 「{ALIAS}」 이 빈 글 · 글 아님(빈 칸이면 칸을 두지 않음)")
if cols and _cols_of(row) != cols:
out.append(f"{where} · 열이 한 벌이 아님 — 「{' · '.join(cols)}」")
if kind == "품셈재료":
out += _check_linked(where, row)
@@ -328,7 +335,7 @@ def check_form(name: str, data: dict) -> list[str]:
def _check_labor(where: str, row: dict) -> list[str]:
"""인력 줄 — 열 한 벌(차례까지 같음) · 상태 값 · 옛이름 목록."""
out = []
if tuple(row) != LABOR_COLS:
if _cols_of(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)} 아님")