- B07 POST /design-drawings/reset — 저장본 확정 풂(번호 · json 남김) · B07 이 올린 측점 확정 → 잠정 · 축척 · 횡단 배치 · 평면도 종류 · 표식 파일 지움 · 새 _Router_Reset.py(main.py 물림) - B08 POST /quantity/reset — quantity 설정 구획 기본 · hydro_inputs 지움 · milestone 기본(사용자 그림 붙은 거래처 경로 줄만 남김 · to = 시점) · 1본 길이 · 그림 남김 - B09 POST /estimation/reset — 사용자 값 · 단가 책 · estimation 설정 구획 지움 · 안 쓰는 서고 사본 정리 · 견적서 남김 · 답 = GET 꼴 - 공용 reset_section(구획 하나 기본으로) · 새 시험 test_298_2_page_reset Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
103 lines
4.3 KiB
Python
103 lines
4.3 KiB
Python
"""B07 [초기화](요구 298-2 · 300 C1 · C3) — 그 페이지 사용자 값 · 설정을 지움.
|
|
|
|
POST /api/projects/{id}/design-drawings/reset 본문 없음
|
|
|
|
기준 = 저장본 없이 지금 B06 정본으로 그린 원본(떠 두지 않음 · 앞 단계 저장 = 저절로 새 기준).
|
|
지움 = 모든 저장본 확정 풂(`confirmed=False` · 도면번호 · json 남김 = [원본에서 다시 그리기] 꼴) ·
|
|
B07 이 확정으로 올린 측점 설계 → 잠정 · 설정 파일(축척 · 횡단 배치 · 표 배율 · 평면도 종류 · 표식).
|
|
M02 층(도각 · 표지)은 안 건드림. 단계 = [저장]과 같음(`mark_stage` save).
|
|
"""
|
|
|
|
import asyncio
|
|
import logging
|
|
import shutil
|
|
from pathlib import Path
|
|
from typing import Any
|
|
from uuid import UUID
|
|
|
|
from fastapi import APIRouter
|
|
from fastapi.responses import JSONResponse
|
|
|
|
from B06_Section.B06_Section_Repository import merge_cross_section_design_by_round
|
|
from B07_DesignDetail.B07_DesignDetail_Engine_Template import drawing_scales_path
|
|
from B07_DesignDetail.B07_DesignDetail_Router import _confirmed_source, _designs_by_chainage
|
|
from B07_DesignDetail.B07_DesignDetail_Router_Support import CROSS_LAYOUT_FILE
|
|
from B07_DesignDetail.B07_DesignDetail_Router_Support_Io import (
|
|
_design_root,
|
|
_read_manifest,
|
|
_write_manifest,
|
|
)
|
|
from B07_DesignDetail.B07_DesignDetail_Router_Support_Plan import _kinds_dir, _marks_path
|
|
from common_util.common_util_workflow_state import mark_stage
|
|
from config.config_db import get_db_pool
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter(prefix="/api/projects", tags=["B07 Design Detail"])
|
|
|
|
|
|
def reset_design_files(project_root: Path) -> dict[str, Any]:
|
|
"""저장본 풂 + 설정 파일 지움 → {released: 풀린 장 수, cleared: 지운 설정 이름}."""
|
|
manifest = _read_manifest(project_root)
|
|
released = 0
|
|
for entry in manifest["drawings"].values():
|
|
if entry.get("confirmed"):
|
|
entry["confirmed"] = False
|
|
released += 1
|
|
if released:
|
|
_write_manifest(project_root, manifest)
|
|
cleared = []
|
|
for path in (
|
|
drawing_scales_path(project_root),
|
|
_design_root(project_root) / CROSS_LAYOUT_FILE,
|
|
_marks_path(project_root),
|
|
):
|
|
if path.is_file():
|
|
path.unlink()
|
|
cleared.append(path.name)
|
|
if _kinds_dir(project_root).is_dir():
|
|
shutil.rmtree(_kinds_dir(project_root))
|
|
cleared.append(_kinds_dir(project_root).name)
|
|
return {"released": released, "cleared": cleared}
|
|
|
|
|
|
@router.post("/{project_id}/design-drawings/reset")
|
|
async def reset_design_drawings(project_id: UUID) -> Any:
|
|
try:
|
|
route_id, project_root, _longitudinal_path, _bypass = await _confirmed_source(project_id)
|
|
result = await asyncio.to_thread(reset_design_files, project_root)
|
|
designs = await _designs_by_chainage(route_id)
|
|
confirmed = [chainage for chainage, d in designs.items() if d.get("status") == "confirmed"]
|
|
pool = get_db_pool()
|
|
async with pool.acquire() as connection:
|
|
await connection.begin()
|
|
try:
|
|
for chainage in confirmed:
|
|
await merge_cross_section_design_by_round(
|
|
connection,
|
|
route_id=route_id,
|
|
chainage=chainage,
|
|
patch={"status": "provisional"},
|
|
)
|
|
async with connection.cursor() as cursor:
|
|
await mark_stage(str(project_id), 4, "save", cursor)
|
|
await connection.commit()
|
|
except Exception:
|
|
await connection.rollback()
|
|
raise
|
|
return {
|
|
"status": "success",
|
|
"project_id": str(project_id),
|
|
**result,
|
|
"provisional": len(confirmed),
|
|
}
|
|
except FileNotFoundError as exc:
|
|
return JSONResponse(status_code=404, content={"status": "error", "message": str(exc)})
|
|
except PermissionError as exc:
|
|
return JSONResponse(status_code=409, content={"status": "error", "message": str(exc)})
|
|
except Exception:
|
|
logger.exception("B07 초기화 실패: project_id=%s", project_id)
|
|
return JSONResponse(
|
|
status_code=500,
|
|
content={"status": "error", "message": "상세 설계를 초기화하지 못했습니다."},
|
|
)
|