"""B08 토적표 조회 라우터 (일감 2 · PLAN 8-4b). 값은 어디서 오나 측점별 단면적은 **B06 이 이미 낸 정본**이다(`cross_sections.data.design` 의 `cut_soil_area_m2`·`cut_rock_area_m2`·`fill_area_m2`·`ditch_area_m2`). B08 은 그것을 다시 재지 않고 **평균단면적법으로 체적화만** 한다. 계산 자리 (CLAUDE.md 5장) 초기값은 서버가 한 번 계산해 영구저장한다. 여기서는 저장된 단면적을 읽어 표를 만든다 — 새 수량을 낳지 않으므로 캐시·조작 경로가 따로 필요 없다. """ from __future__ import annotations import logging from typing import Any from uuid import UUID from fastapi import APIRouter from fastapi.responses import JSONResponse from B06_Section.B06_Section_Repository import ( get_cross_section_designs, get_workflow_route_context, ) from B08_Quantity.B08_Quantity_Engine_EarthworkTable import StationArea, build_table from config.config_db import run_with_connection logger = logging.getLogger(__name__) router = APIRouter(prefix="/api/projects", tags=["B08 Quantity"]) def _stations(designs: list[dict[str, Any]]) -> list[StationArea]: return [ StationArea.from_design(item["chainage_m"], item.get("design") or {}) for item in designs ] @router.get("/{project_id}/quantity/{route_id}/earthwork-table") async def get_earthwork_table(project_id: UUID, route_id: int) -> JSONResponse: """토적표 — 측점별 단면적을 평균단면적법으로 체적화한 표.""" try: designs = await run_with_connection(get_cross_section_designs, route_id) except Exception: logger.exception("B08 토적표 조회 실패: project_id=%s route_id=%s", project_id, route_id) return JSONResponse( status_code=500, content={"status": "error", "message": "토적표를 만들지 못했습니다."}, ) table = build_table(_stations(designs)) table["route_id"] = route_id return JSONResponse(content=table) @router.get("/{project_id}/quantity/earthwork-table") async def get_earthwork_table_for_current_route(project_id: UUID) -> JSONResponse: """경로를 안 주면 워크플로가 보고 있는 경로로 낸다 — 화면이 route_id 를 모를 때 쓴다.""" context = await run_with_connection(get_workflow_route_context, project_id) if not context or not context.get("route_id"): return JSONResponse( status_code=404, content={"status": "error", "message": "이 프로젝트에 확정된 노선이 없습니다."}, ) return await get_earthwork_table(project_id, int(context["route_id"]))