feat(M02): 면적 값 고침이 저장 전 도면 패널 표에 바로 비침 · 이름 · 보내기 취소는 [저장] 때 서버가 기록(112-1·112-2)

- 112-1 면적 표 변환을 공용 파일(spreadsheet_area_table.ts)로 빼 서버 Node 와 브라우저가 한 벌로 씀 · 도면 패널이 칸 고침마다(값 바뀐 표만 · 펼친 동안만) CAD 연결 표 갈기를 보기 전용 갈음(preview)으로 보냄
- 112-2 보낸 범위 이름은 도면 [저장] 요청 안에서 서버가 면적 문서에 둠(놓기만 하고 저장 안 하면 안 생김) · [보내기 취소]는 화면에서만 빼고 면적 [저장] 때 서버가 연결표 줄 · 이름을 뺌 · /name · /unlink 길 삭제

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MgChuAcyBqUkhHMTXomQC7
This commit is contained in:
2026-10-08 17:36:44 +09:00
co-authored by Claude Sonnet 5.5
parent 2a830980c7
commit 5638bd5101
17 changed files with 797 additions and 322 deletions
+22 -5
View File
@@ -150,8 +150,15 @@ def write(kind: str, name: str, version: str, doc: Any, screen: bool = False) ->
표 열의 `본뜬열`(분류 더하기로 복사한 새 열)은 적지 않음 — 집계표면 아직 파일이 없는 새 열이
원본 열의 일위대가 키와 세 파일 내용을 받음(새 번호 · 그 뒤로는 열마다 따로).
`screen` = 화면 표 [저장](PLAN 26-7e) — 있던 항목의 경로 · 층 이름 · 빈 폴더는 저장본 그대로
(정본 = 나무 · 머리는 경로에서 다시 만듦 · `tree.keep_paths`)."""
(정본 = 나무 · 머리는 경로에서 다시 만듦 · `tree.keep_paths`).
도면↔면적(112-2) — 구조물 도면 저장 때 새 연결 줄의 보낸 범위 이름을 같은 요청 안에서 면적 문서에 두고 ·
면적 저장 문서의 `보내기취소[]` 연결은 도면 연결표 줄 · 이름을 뺌."""
path = _path(kind, name)
cancels: list[str] = []
if kind == "area":
from M02_MasterTemplete import M02_Area_Table as area_table
doc, cancels = area_table.apply_cancels(name, doc)
_check_skeleton(kind, doc)
if kind in layers.LIBRARY_KINDS: # 서고 문서 키 = 파일 이름(50-3)
doc = {**doc, "키": name}
@@ -159,10 +166,15 @@ def write(kind: str, name: str, version: str, doc: Any, screen: bool = False) ->
if kind == "table" and name == STRUCTURE_TABLE:
doc = tree.normalize_table(doc) # 경로 · 머리 줄 수 · 빈 폴더(표 저장 · 나무 고침 한 줄기)
doc = _server(kind, doc)
fresh: list[dict[str, Any]] = []
with _LOCK:
have = version_of(path.read_bytes()) if path.is_file() else ""
if have != (version or ""):
raise StoreError(409, {"stale": [name], "판": have})
if kind == "structure":
from M02_MasterTemplete import M02_Area_Table as area_table
fresh = area_table.fresh_names(path, doc)
if screen and have and kind == "table" and name == STRUCTURE_TABLE:
doc = tree.normalize_table(tree.keep_paths(doc, json.loads(path.read_bytes())))
if have and kind in _KEY:
@@ -172,7 +184,11 @@ def write(kind: str, name: str, version: str, doc: Any, screen: bool = False) ->
info = _info(kind, path)
if kind == "area":
_refresh_labor(name) # 면적 칸 값이 바뀌면 일위대가 계산값(목록 합계)도
_refresh_drawing(name) # 도면 연결표 칸 글도(41-1)
_refresh_drawing(name, cancels) # 도면 연결표 칸 글도(41-1) · 보내기 취소 줄 뺌(112-2)
if fresh:
from M02_MasterTemplete import M02_Area_Table as area_table
area_table.define_names(name, fresh) # 새 연결 줄의 보낸 범위 이름(112-2)
if kind == "table" and name == STRUCTURE_TABLE:
for column, source in origins.items(): # 빈 파일 채우기 앞 — 원본 내용으로 만듦
for part in _KEY:
@@ -562,11 +578,12 @@ def _server(kind: str, doc: Any, source: Path | None = None) -> Any:
return doc
def _refresh_drawing(column: str) -> None:
"""그 열 도면의 면적 연결표 칸 글을 지금 면적 값으로(`M02_Area_Table` · 41-1)."""
def _refresh_drawing(column: str, unlink: list[str] | tuple[()] = ()) -> None:
"""그 열 도면의 면적 연결표 칸 글을 지금 면적 값으로(`M02_Area_Table` · 41-1) ·
`unlink` = 보내기 취소 줄."""
from M02_MasterTemplete import M02_Area_Table as area_table
area_table.refresh_drawing(column)
area_table.refresh_drawing(column, unlink)
def _refresh_labor(column: str) -> None: