refactor(511-B B-4 기본 설계 셋 Node · preview 걷음): run_calc = 늘 떠 있는 Node(못 띄우면 새 프로세스) · 기본 설계 셋(체인 · 노선 저장 이월 · [측점 만들기] · GET 빈 측점 · B05 확정 측구 방향 역반영) = 측점 묶음 Node cross.design 한 번 · 포장 · 기울임 · 세월교 하강 = TS facilityRanges(cross.design facilities · Node 못 부르면 파이썬 구간 짝) · /cross-design/preview 걷음(창구 · 스키마 · recompute_designs_for_alignment · 화면 refreshFromServer) · crossOptions = logic/B06_Section_Cross_Save.ts(다음 단계 [저장] 횡단 한 바퀴 짝 · 아직 안 부름) · 시험 266 · 475_3 · masshaul_single_source 기대 맞춤 — 요구 320-4
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,6 @@ from fastapi import APIRouter, Depends, Request
|
||||
from fastapi.responses import JSONResponse, Response
|
||||
|
||||
from B03_FileInput.B03_FileInput_Repository import get_project_storage_relative_path
|
||||
from B05_Profile.B05_Profile_Engine_Grade_Profile import rebuild_alignment_profile
|
||||
from B05_Profile.B05_Profile_Engine_Sections import (
|
||||
cross_files_in_order,
|
||||
relabel_pipe_stations,
|
||||
@@ -35,15 +34,9 @@ from B06_Section.B06_Section_Repository import (
|
||||
insert_cross_sections,
|
||||
list_recent_company_projects,
|
||||
)
|
||||
from B06_Section.B06_Section_Router_Design import (
|
||||
PREVIEW_DESIGN_FIELDS as _PREVIEW_DESIGN_FIELDS,
|
||||
)
|
||||
from B06_Section.B06_Section_Router_Design import (
|
||||
attach_default_designs as _attach_default_designs,
|
||||
)
|
||||
from B06_Section.B06_Section_Router_Design import (
|
||||
recompute_designs_for_alignment as _recompute_designs_for_alignment,
|
||||
)
|
||||
from B06_Section.B06_Section_Router_Design import (
|
||||
stored_standard_cross_section as _stored_standard_cross_section,
|
||||
)
|
||||
@@ -55,8 +48,6 @@ from B06_Section.B06_Section_Schema import (
|
||||
CompanyStandardListResponse,
|
||||
CompanyStandardProject,
|
||||
CompanyStandardResponse,
|
||||
CrossDesignPreviewRequest,
|
||||
CrossDesignPreviewResponse,
|
||||
HaulEquipmentLimit,
|
||||
SectionContextResponse,
|
||||
SectionDetailResponse,
|
||||
@@ -482,104 +473,3 @@ async def regenerate_route_sections(
|
||||
status_code=500,
|
||||
content={"status": "error", "message": "종횡단 재생성 처리 중 오류가 발생했습니다."},
|
||||
)
|
||||
|
||||
|
||||
def _with_design_choices(
|
||||
designs: list[dict[str, Any]], choices: dict[str, dict[str, Any]] | None
|
||||
) -> list[dict[str, Any]]:
|
||||
"""카드 선택 세션값을 저장분 위에 얹은 행 목록(439) — 뒤 행이 같은 측점 앞 행을 덮음."""
|
||||
stored = {round(float(r["chainage_m"]), 3): r.get("design") or {} for r in designs}
|
||||
picked = {round(float(key), 3): choice for key, choice in (choices or {}).items()}
|
||||
return designs + [
|
||||
{"chainage_m": key, "design": {**stored.get(key, {}), **choice}}
|
||||
for key, choice in picked.items()
|
||||
]
|
||||
|
||||
|
||||
@router.post(
|
||||
"/{project_id}/sections/{route_id}/cross-design/preview",
|
||||
response_model=CrossDesignPreviewResponse,
|
||||
)
|
||||
async def preview_cross_designs(
|
||||
project_id: UUID, route_id: int, request: CrossDesignPreviewRequest
|
||||
) -> CrossDesignPreviewResponse | JSONResponse:
|
||||
"""계획선 편집 델타로 계획선과 전 측점 횡단 설계를 다시 계산해 돌려준다(저장 없음).
|
||||
|
||||
⚠ **평상시 조작 경로가 아니다**(2026-09-03 이후). 계획선을 만지는 동안의 재계산은
|
||||
브라우저가 직접 한다(`common_util/common_util_cross_design.ts`) — 조작 중 계산이
|
||||
서버로 나가면 왕복이 조작 속도를 지배하기 때문이다(사용자 확정). 이 엔드포인트는
|
||||
선형 저장분이 없어 브라우저가 계획고를 풀 수 없는 **옛 데이터 폴백**으로만 남는다
|
||||
(`B06_Section_Cross_Refresh.refreshCrossDesigns`).
|
||||
|
||||
영속화는 각 페이지의 임시저장·확정이 맡는다.
|
||||
"""
|
||||
pool = get_db_pool()
|
||||
try:
|
||||
async with pool.acquire() as connection:
|
||||
longitudinal_row = await get_longitudinal_section(connection, project_id, route_id)
|
||||
if not longitudinal_row:
|
||||
return JSONResponse(
|
||||
status_code=404,
|
||||
content={"status": "error", "message": "종횡단 상세 결과가 없습니다."},
|
||||
)
|
||||
stored_path = await get_project_storage_relative_path(connection, project_id)
|
||||
designs = await get_cross_section_designs(connection, route_id)
|
||||
source = await get_route_generation_source(connection, project_id, route_id)
|
||||
designs = _with_design_choices(designs, request.design_choices)
|
||||
project_root = Path(resolve_stored_project_path(stored_path))
|
||||
detail = await asyncio.to_thread(
|
||||
_read_section_detail,
|
||||
project_root,
|
||||
str(longitudinal_row["longitudinal_file_path"]),
|
||||
(source or {}).get("route_data_path"),
|
||||
)
|
||||
|
||||
def rebuild() -> None:
|
||||
alignment, profile = rebuild_alignment_profile(detail["longitudinal"], request.edits())
|
||||
detail["longitudinal"]["profile_alignment"] = alignment
|
||||
detail["longitudinal"]["design_profiles"] = [profile]
|
||||
_recompute_designs_for_alignment(
|
||||
detail["longitudinal"],
|
||||
detail["cross_sections"],
|
||||
designs,
|
||||
request.standard_cross_section,
|
||||
request.rock_boundary_offsets,
|
||||
project_root,
|
||||
request.berms,
|
||||
request.cut_slope_ratios,
|
||||
)
|
||||
|
||||
await asyncio.to_thread(rebuild)
|
||||
# 계획고를 끄는 동안 오가는 값이라 기본은 **유토곡선이 실제로 읽는 필드만** 싣는다.
|
||||
# 지반선 샘플·설계선 좌표(design_line)·선형 구조를 다 담으면 1MB가 넘어 편집이 굼떠진다
|
||||
# (2026-08-03 사용자 지적). 계획선 자체는 화면이 이미 같은 규칙으로 계산해 들고 있다.
|
||||
# `full_designs`(B06 진입 시 stale 일괄 재계산)일 때만 설계 전체를 1회 싣는다 —
|
||||
# 측점별 순차 호출 N번보다 왕복 1번이 훨씬 싸다(2026-08-04 사용자 확인).
|
||||
return CrossDesignPreviewResponse(
|
||||
designs=[
|
||||
{
|
||||
"chainage_m": section.get("chainage_m"),
|
||||
"design": section["design"]
|
||||
if request.full_designs
|
||||
else {
|
||||
key: section["design"].get(key)
|
||||
for key in _PREVIEW_DESIGN_FIELDS
|
||||
if key in section["design"]
|
||||
},
|
||||
}
|
||||
for section in detail["cross_sections"]
|
||||
if section.get("design")
|
||||
],
|
||||
)
|
||||
except FileNotFoundError as exc:
|
||||
return JSONResponse(status_code=404, content={"status": "error", "message": str(exc)})
|
||||
except (OSError, ValueError, json.JSONDecodeError) as exc:
|
||||
return JSONResponse(status_code=400, content={"status": "error", "message": str(exc)})
|
||||
except Exception:
|
||||
logger.exception(
|
||||
"B06 횡단 설계 프리뷰 실패: project_id=%s route_id=%s", project_id, route_id
|
||||
)
|
||||
return JSONResponse(
|
||||
status_code=500,
|
||||
content={"status": "error", "message": "횡단 설계 프리뷰 계산 중 오류가 발생했습니다."},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user