feat(M02): 구조물 도면 = 좌측 셋째 컨테이너 · 열마다 미리 만듦

- 좌측 「구조물 도면」을 「표 양식」·「도면 양식」과 같은 층 컨테이너로
- 구조물집계표 열마다 빈 구조물 도면을 서버가 미리 만들어 둠(도번 자동 · 도각 없는
  빈 CAD 문서 · 산출근거 빈 줄 셋) — 좌측 줄에 항상 도번이 붙음
- 새 열을 더해 집계표를 저장하면 그 열의 빈 구조물 도면도 서버가 같이 만듦
  (`M02_MasterTemplete_Store.write` → `backfill_missing_structures`)
- 좌측 구조물 도면 줄을 누르면 그 CAD 화면이 곧장 열림(열 머리글 · 도번을 제목에)
- 지금 있는 49개 열의 구조물 도면을 미리 만들어 커밋(`resources/master_template/structure/`)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K7JS47SacjPxZ718QsZKyr
This commit is contained in:
2026-09-27 19:17:17 +09:00
co-authored by Claude Sonnet 5
parent ef5a7e9771
commit 65f43ca083
56 changed files with 3682 additions and 87 deletions
@@ -28,6 +28,8 @@ export interface Selection {
projectId: string | null;
kind: Kind;
name: string;
/** 화면 제목에 쓸 글 — 없으면 name 그대로(구조물 도면은 열 머리글) */
label?: string;
}
interface EditorHandle {
@@ -140,14 +142,10 @@ export function createMain(isAdmin: boolean, onSaved?: () => void): MainHandle {
const made = createStructurePanel({
isAdmin,
confirmLeave,
// 같은 페이지에서 그 구조물 도면을 CAD 편집으로 엶 · 좌측 목록을 다시 받아
// 고름 표시를 옮김(`sel` 은 `open` 이 기다리기 전에 이미 새 것 · 목록은 `getOpen` 을 봄)
onEdit: (column) => {
void open({ layer: "system", projectId: null, kind: "structure", name: column });
onSaved?.();
// 같은 페이지에서 그 구조물 도면을 CAD 편집으로 엶
onEdit: (column, label) => {
void open({ layer: "system", projectId: null, kind: "structure", name: column, label });
},
// 새로 만든 뒤 — 집계표 도면 줄을 새 도번으로 다시 그림
onCreated: () => sheet?.recalc(),
});
extra.replaceChildren(made.root);
return made;
@@ -212,7 +210,7 @@ export function createMain(isAdmin: boolean, onSaved?: () => void): MainHandle {
title.textContent = L("M02_PickTemplate");
return empty("");
}
title.textContent = next.name;
title.textContent = next.label ?? next.name;
try {
const got = await readTemplate(next.layer, next.kind, next.name, next.projectId);
if (mine !== seq) return;
@@ -230,7 +228,7 @@ export function createMain(isAdmin: boolean, onSaved?: () => void): MainHandle {
// 구조물 도면은 열 id 로 열리니 머리에 도번을 함께 보임
if (next.kind === "structure") {
const number = (got.문서 as StructureDoc)?.도번;
if (number) title.textContent = `${number} · ${next.name}`;
if (number) title.textContent = `${number} · ${next.label ?? next.name}`;
}
await mount(shown, next);
} catch (error) {
@@ -246,7 +244,7 @@ export function createMain(isAdmin: boolean, onSaved?: () => void): MainHandle {
const at = sel;
try {
const edited = editor ? await editor.getDoc() : loaded;
// 구조물 도면 — CAD 는 `도면` 칸만 다룸 · 도번 · 산출근거는 읽은 그대로 둠
// 구조물 도면 저장은 `도면` 칸만 갈아 끼움 — 도번 · 산출근거는 읽은 그대로
const doc =
at.kind === "structure" && loaded
? { ...(loaded as StructureDoc), 도면: edited as StructureDoc["도면"] }