fix(M02): 도면 양식 저장이 빈 {} 로 덮이던 흠 — getDoc 을 await · 서버는 뼈대 없는 문서를 400 으로 거절

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148XFUpPfpiuTjxF1EK9c95
This commit is contained in:
2026-09-25 12:43:03 +09:00
co-authored by Claude Sonnet 5
parent dd60b6a1cb
commit 9bf3258509
3 changed files with 28 additions and 5 deletions
@@ -65,9 +65,17 @@ def read(kind: str, name: str) -> dict[str, Any]:
return {"종류": kind, "이름": name, "판": version_of(raw), "문서": json.loads(raw)}
def _check_skeleton(kind: str, doc: Any) -> None:
"""빈 문서·뼈대 없는 문서는 거절 — 표는 열 목록 · 도면은 entities 목록."""
key = "열" if kind == "table" else "entities"
if not isinstance(doc, dict) or not isinstance(doc.get(key), list):
raise StoreError(400, f"양식 문서에 「{key}」 목록이 없음 — 저장하지 않음")
def write(kind: str, name: str, version: str, doc: Any) -> dict[str, Any]:
"""`version` 이 빈 글이면 새로 만듦(이미 있으면 409) · 아니면 그 판일 때만 덮어씀."""
path = _path(kind, name)
_check_skeleton(kind, doc)
with _LOCK:
have = version_of(path.read_bytes()) if path.is_file() else ""
if have != (version or ""):
@@ -23,7 +23,7 @@ export interface Selection {
}
interface EditorHandle {
getDoc: () => unknown;
getDoc: () => unknown | Promise<unknown>;
destroy: () => void;
}
@@ -162,7 +162,7 @@ export function createMain(isAdmin: boolean): MainHandle {
if (!sel) return;
const at = sel;
try {
const doc = editor ? editor.getDoc() : loaded;
const doc = editor ? await editor.getDoc() : loaded;
const info = await saveTemplate(at.layer, at.kind, at.name, at.projectId, version, doc);
version = info.판;
loaded = doc;