refactor(M02): 자재 조합 표를 마스터 템플릿으로 옮김 · M02 좌측 「자재 조합」 컨테이너

- 표 resources/master_data/자재조합.json → resources/master_template/자재조합.json(git mv) · 키 UM 은 표 안 「다음」 번호 · _키대장 · master_keys 의 UM 뺌 · check_master 틀이 새 자리를 같이 봄
- 서버: M01 /api/m01/matset* 뺌 · M02 저장소 M02_MasterTemplete_Matset.py(목록 · 새로 · 고치기 · 지우기 · 쓰는 열 검사) · 길 GET/POST /api/m02/material-combos · PUT/DELETE /api/m02/material-combos/{키} · 갈라 내기(branchMaterialCombo)도 이 저장소로
- 화면: M01 좌측 「자재 조합」 컨테이너 뺌 · M02 좌측 「자재 조합」 컨테이너(찾기 · 키 맨 앞 목록 · 새로 · 본떠 만들기 · 지우기) · 메인 칸 상세(이름 · 비고 · 본뜬키 · 담은 자재 표 · 자재 더하기 · 빼기 · 저장) · 쓰는 열이 있으면 지우기는 확인 창 없이 알림
- 시험: test_m01_matset → test_m02_matset · test_m02_combo_branch 사본 자리 · 실제 자재 코드

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VwJQ5eRrCKf3nH9EFeKvJz
This commit is contained in:
2026-09-28 22:25:30 +09:00
co-authored by Claude Opus 5.5
parent 6606ef167a
commit 4abfc5b265
28 changed files with 753 additions and 882 deletions
@@ -11,6 +11,7 @@ from fastapi import APIRouter, HTTPException, Query
from pydantic import BaseModel
from M02_MasterTemplete import M02_MasterTemplete_Branch as branch
from M02_MasterTemplete import M02_MasterTemplete_Matset as matset
from M02_MasterTemplete import M02_MasterTemplete_Store as store
router = APIRouter(prefix="/api/m02", tags=["M02 MasterTemplete"])
@@ -35,6 +36,11 @@ class MaterialBranchBody(BaseModel):
판: str = ""
class MatsetBody(BaseModel):
판: str = "" # 자재 조합 표 판 — 어긋나면 409
줄: dict[str, Any]
def _call(fn, *args):
try:
return fn(*args)
@@ -78,12 +84,37 @@ def post_structure_material_combo(column: str, body: MaterialBranchBody) -> dict
)
# 자재 조합 표(마스터 템플릿 `자재조합.json` · 키 UM) — 좌측 「자재 조합」 컨테이너
@router.get("/material-combos")
def get_material_combos() -> dict:
"""표 통째 — `{판, 줄}`(줄마다 담은 자재 포함)."""
return _call(matset.listing)
@router.get("/material-combos/{key}")
def get_material_combo(key: str) -> dict:
"""자재 조합 한 줄(키 UM) — 키 · 이름 · 담은자재 · 본뜬키 · 소유 · 비고."""
return _call(branch.material_combo, key)
@router.post("/material-combos")
def post_material_combo(body: MatsetBody) -> dict:
"""새로 · 본떠 만들기(`줄.본뜬키`) — 키는 표 「다음」 번호 · `{키, 판, 줄}`."""
return _call(matset.create, body.줄, body.판)
@router.put("/material-combos/{key}")
def put_material_combo(key: str, body: MatsetBody) -> dict:
"""고치기 — 이름 · 비고 · 담은자재(본뜬키 · 소유는 있던 것)."""
return _call(matset.edit, key, body.줄, body.판)
@router.delete("/material-combos/{key}")
def delete_material_combo(key: str, 판: str = "") -> dict:
"""지우기 — 구조물 열이 쓰면 409 `{errors, users}`."""
return _call(matset.delete, key, 판)
# 복사 가져오기 — 다른 열(`from`) 내용을 받는 열로 · 번호 · 열은 받는 쪽 그대로
@router.post("/structures/{column}/copy")
def post_structure_copy(column: str, source: str = Query(alias="from")) -> dict: