"""B05 설계 지형 바꿈(PLAN 626-1 · 765-4 · 요구 530 · 605 · 606-1) — 평면 도구줄 지형 칩. `POST /api/projects/{id}/route/design-terrain` 본문 `{terrain: "las" | "sheet", force}` - 칩 = 맞바꿈(`common_util_design_sets.swap_design_set`) — 지금 벌(노선 · 종단 · 횡단 · 배수 · 토공 · 수량 · 초기값)을 묶음으로 떠 두고 전처리가 미리 지은 고른 지형 벌을 꺼내 끼움 · 떠난 벌의 [저장] 고침은 묶음에 살아 돌아오면 그대로 · 묶음 없음 · 지문 어긋남 = 그 자리에서 한 번 지음 · 실패 = 통째 되돌림 · 같은 지형 = 바꿀 것 없음. - `force` = LAS 나중 올리기 뒤 전처리 다시(765-5) — 고른 지형을 설계 지형으로 · B05~B09 초기화 · 두 벌 다시(`run_surface_change_chain`). [저장]과 같은 프로젝트 잠금(`common_util_save_guard`). 계산 자리 = ③ 서버 단독. """ import logging from typing import Literal from uuid import UUID from fastapi.responses import JSONResponse from pydantic import BaseModel from B05_Profile.B05_Profile_Router_Terrain import router from config.config_db import get_db_pool logger = logging.getLogger(__name__) class DesignTerrainRequest(BaseModel): terrain: Literal["las", "sheet"] #: 전처리 다시(B05~B09 초기화 · 두 벌) — LAS 나중 올리기 뒤(765-5) force: bool = False @router.post("/{project_id}/route/design-terrain", response_model=None) async def switch_route_design_terrain( project_id: UUID, body: DesignTerrainRequest ) -> dict | JSONResponse: """설계 지형 벌 맞바꿈 · `force` = 전처리 다시.""" from B03_FileInput.B03_FileInput_Service_SurfaceChange import run_surface_change_chain from B05_Profile.B05_Profile_Router_Replan import _PROJECT_PATH_MISSING, _project_paths from common_util import common_util_design_sets as sets from common_util import common_util_save_guard as guard async with guard.project_lock(str(project_id)): paths = await _project_paths(project_id) if paths is None: return JSONResponse(status_code=404, content=_PROJECT_PATH_MISSING) try: if body.force: async with get_db_pool().acquire() as connection: model_id = await sets.switch_terrain(connection, project_id, body.terrain) await run_surface_change_chain(project_id, model_id) result = {"changed": True, "design": body.terrain, "preprocessed": True} else: result = await sets.swap_design_set(project_id, paths[0], body.terrain) except (LookupError, RuntimeError) as exc: return JSONResponse(status_code=409, content={"status": "error", "message": str(exc)}) logger.info("설계 지형 바꿈: project_id=%s %s", project_id, result) return {"status": "success", **result}