feat(M02): 좌측 「실무문서」 — 옛 마스터 일위대가 조합 목록 · 상세 읽기만 · 통째 지우기(39-2)

- 새 M02_MasterTemplete_Practice.ts — 구조물 조합 밖 · 도면 양식 아래 · 마스터 층 · 시스템 관리자만
- [통째 지우기] = 물음 두 번 → DELETE /api/m02/practice(시스템 관리자 문 is_system_admin · 판 · 쓰는 곳 0 확인 · 줄을 비움)
- Combo_Store.drop_practice · 시험 test_m02_practice.py(임시 사본)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BVPp2o6Mh2FZJr72yW3ofZ
This commit is contained in:
2026-10-04 17:36:51 +09:00
co-authored by Claude Opus 5.5
parent 80a635d3b9
commit 0e28b5be4a
8 changed files with 400 additions and 8 deletions
@@ -289,6 +289,21 @@ def edit(key: str, row: Any, version: str) -> dict[str, Any]:
return {"키": key, "판": _save(doc, version), "combo": fixed}
def drop_practice(version: str) -> dict[str, Any]:
"""실무문서(마스터 조합 표 = 옛 일위대가 조합 · PLAN 39-2) 통째 지우기 — 줄을 모두 비움 ·
구조물이 쓰는 조합이 있으면 409(아무것도 안 지움) · 판 다르면 409 · 마스터 층에서만."""
if heads()[-1] != MASTER:
raise store.StoreError(400, "실무문서는 마스터 층에만 있음")
doc, have = _load()
if have != (version or ""):
raise store.StoreError(409, {"stale": [FILE], "판": have})
keys = [str(r.get("키")) for r in doc.get("줄") or []]
_refuse_used(keys)
if keys:
_m01(combo_store._write, [{"op": "delete", "key": k} for k in keys], have)
return {**listing(), "지운조합": keys}
def delete(key: str, version: str) -> dict[str, Any]:
"""지우기 — 이 층 구조물 조합이 쓰면 409 + 항목 이름들(지우지 않음)."""
if heads()[-1] == MASTER: