feat(M02): 구조물 집계표 설계값 채우기 — 펼침 열 · 측점 줄 · 관 줄 나눔 · 손 값 지킴 · 채운 표 길에 B06 관 연장 (PLAN 10-4)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015LuapLYqN1GGFD8Y1PStD5
This commit is contained in:
2026-09-25 09:46:20 +09:00
co-authored by Claude Opus 5.5
parent 9b9f3e15ba
commit ab810c4a4a
4 changed files with 667 additions and 6 deletions
@@ -10,17 +10,26 @@
from __future__ import annotations
import asyncio
import logging
from pathlib import Path
from typing import Any, Literal
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel, ConfigDict, Field
from B06_Section.B06_Section_Repository import (
get_cross_section_designs,
get_workflow_route_context,
)
from common_util.common_util_auth import verify_session
from common_util.common_util_storage import resolve_stored_project_path
from config.config_db import get_db_pool
from config.config_db import get_db_pool, run_with_connection
from M02_MasterTemplete import M02_Table_Fill as fill
from M02_MasterTemplete import M02_Template_Layers as layers
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/m02", tags=["M02 MasterTemplete Layers"])
Layer = Literal["system", "company", "personal", "project"]
@@ -103,6 +112,17 @@ async def _company_projects(company_id: int) -> list[dict[str, Any]]:
return [{"project_id": str(row[0]), "name": row[1], "storage_path": row[2]} for row in rows]
async def _cross_designs(project_id: str) -> list[dict[str, Any]]:
"""최신 노선의 B06 횡단 설계 — 못 읽으면 빈 목록(관 연장이 빈칸으로 섬 · 0 아님)."""
try:
context = await run_with_connection(get_workflow_route_context, UUID(str(project_id)))
route_id = int((context or {}).get("route_id") or 0)
return await run_with_connection(get_cross_section_designs, route_id) if route_id else []
except Exception:
logger.exception("M02 채운 표 — 횡단 설계 조회 실패: project_id=%s", project_id)
return []
# ── 권한 · 자리 ───────────────────────────────────────
@@ -397,9 +417,7 @@ async def filled_table(
name: str,
session: dict[str, Any] = Depends(verify_session),
) -> dict[str, Any]:
"""설계값을 채운 표 문서 — 저장 안 함(5장 ③ 서버 단독)."""
from M02_MasterTemplete import M02_Table_Fill as fill
"""설계값을 채운 표 문서 — 저장 안 함(5장 ③ 서버 단독) · `결과` = 계산 열(없으면 null)."""
project = await _project(session, project_id)
try:
found = await asyncio.to_thread(
@@ -413,5 +431,7 @@ async def filled_table(
raise _bad(error) from error
if found is None:
raise HTTPException(status_code=404, detail="양식을 찾을 수 없습니다.")
document = await asyncio.to_thread(fill.fill_table, project["root"], found["문서"])
return {"이름": name, "판": found["판"], "문서": document}
lengths = fill.pipe_lengths_from_designs(await _cross_designs(project_id))
document = await asyncio.to_thread(fill.fill_table, project["root"], found["문서"], lengths)
result = await asyncio.to_thread(fill.recalc, document)
return {"이름": name, "판": found["판"], "문서": document, "결과": result}