Files
Aislo/resources/tester/test_b07_confirm_keeps_design.py
eomsangdonandClaude Opus 5 419148901b fix(b07): 횡단도 [확정]은 설계 상태만 올림 — 입력 셋으로 다시 계산한 값으로 정본을 덮던 것 걷음(브레인 ②)
- 옛 길: 지반·단면·측구 쪽 셋만으로 compute_cross_design 을 돌려 설계를 통째로 update
  → 암선·절토경사·표준 횡단·구조물 트림·사용자 입력(측구 끔)이 사라짐
- 936be972 실측(읽기만): 62측점 전부 단면적 바뀜 · 절토 5,868.92 → 4,650.76㎥(−20.8%) · 성토 +5.8% · 종점 1078.01 측구 끔→켬
- 지금: patch = {status: confirmed} 뿐 · 응답 설계는 저장값 그대로 · _recompute_confirmed_design 지움
- 확인: 실제 라우터로 23장 전부 [확정] → 62측점 상태 뺀 값 차이 0 · 상태 되돌림

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
2026-09-14 23:43:58 +09:00

105 lines
3.7 KiB
Python

"""B07 횡단도 [확정]은 설계 **상태만** 올린다 — 정본 설계값을 덮지 않는다 (2026-09-14 브레인 ②).
실측(936be972 · 읽기만): 옛 [확정]은 입력 셋(지반·단면·측구 쪽)만으로 단면적을 다시 계산해
설계를 통째로 덮었다 — 62측점 전부 단면적이 바뀌고(절토 −20.8% · 성토 +5.8%) 암선·절토경사·
표준 횡단·구조물 트림이 빠졌으며, 종점 1078.01 은 **사용자가 끈 측구가 켜졌다**.
B07 CAD 에는 설계를 고치는 자리가 없으므로 덮을 값이 없다 — 「반만 계산할 거면 반만 덮는다」.
"""
from __future__ import annotations
import asyncio
from pathlib import Path
from types import SimpleNamespace
from uuid import UUID
import B07_DesignDetail.B07_DesignDetail_Router as router
from B07_DesignDetail.B07_DesignDetail_Schema import DesignDrawingConfirmRequest
STORED = {
"status": "provisional",
"ground_type": "ripping_rock",
"section_mode": "left_cut",
"ditch_side": "left",
"ditch_enabled": False,
"rock_boundary_offset_m": 0.8,
"cut_slope_ratio": 0.5,
"cut_area_m2": 48.894,
"fill_area_m2": 54.84,
}
class _Cursor:
async def __aenter__(self) -> _Cursor:
return self
async def __aexit__(self, *_: object) -> bool:
return False
class _Connection:
async def begin(self) -> None: ...
async def commit(self) -> None: ...
async def rollback(self) -> None: ...
def cursor(self) -> _Cursor:
return _Cursor()
class _Acquire:
async def __aenter__(self) -> _Connection:
return _Connection()
async def __aexit__(self, *_: object) -> bool:
return False
def test_확정은_상태만_올리고_설계값을_안_덮는다(monkeypatch, tmp_path: Path) -> None:
patches: list[dict] = []
async def source(_project_id: UUID) -> tuple[int, Path, Path, bool]:
return 182, tmp_path, tmp_path / "longitudinal.json", False
async def designs(_route_id: int) -> dict[int, dict]:
return {700: dict(STORED)}
async def merge(_connection: object, **kwargs: object) -> bool:
patches.append(dict(kwargs["patch"])) # type: ignore[arg-type]
return True
async def stage(*_: object) -> None: ...
monkeypatch.setattr(router, "_confirmed_source", source)
monkeypatch.setattr(router, "_designs_by_chainage", designs)
monkeypatch.setattr(
router, "_drawing_list", lambda *_: [SimpleNamespace(id="cross_00700m", kind="cross")]
)
monkeypatch.setattr(router, "extract_quantity_table", lambda *_: None)
monkeypatch.setattr(router, "_store_confirmed_drawing", lambda *_: False)
monkeypatch.setattr(router, "get_db_pool", lambda: SimpleNamespace(acquire=_Acquire))
monkeypatch.setattr(router, "merge_cross_section_design_by_round", merge)
monkeypatch.setattr(router, "start_stage", stage)
monkeypatch.setattr(router, "complete_stage", stage)
# 옛 길 — 입력 셋으로 다시 계산한 값(암 절토경사가 빠져 절토가 줄어든 모양)을 흉내 낸다.
monkeypatch.setattr(
router,
"_recompute_confirmed_design",
lambda *_: {**STORED, "ditch_enabled": True, "cut_area_m2": 7.527, "status": "confirmed"},
raising=False,
)
response = asyncio.run(
router.confirm_design_drawing(
UUID("936be972-11bc-46c2-8bf3-b15d8de7df0d"),
"cross_00700m",
DesignDrawingConfirmRequest(drawing={}),
)
)
# 덮는 것은 상태 하나뿐 — 단면적·사용자 입력(측구 끔)은 그대로.
assert patches == [{"status": "confirmed"}]
# 화면 정보 패널이 받는 설계도 저장값 그대로(상태만 확정).
assert response.design == {**STORED, "status": "confirmed"}