fix(388-2 보안): [확정] 면적 · 관 길이 = 서버 셈만 · 재계산 실패 경고

- 화면 [저장] · [확정]이 면적 · 관 길이 9칸을 안 보냄
- 서버가 받아도 _AREA_KEYS 걷음(옛 화면 · 위조 값 정본에 안 남음)
- 서버 재계산 실패(상세 못 받음 · Node 실패)를 삼키지 않음 → 응답 recomputed:false
- 화면 경고 한 줄(저장은 됨 · 옛 서버 값 남음 · 다시 [저장])
- 새 test_384_s_area_keys · 옛 시험 셋 새 동작에 맞춤

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VmC34fsxxbweEG3RUjs3Mn
This commit is contained in:
2026-10-17 17:21:38 +09:00
co-authored by Claude Opus 5.5
parent 1b327b3613
commit 23c6645839
12 changed files with 191 additions and 55 deletions
@@ -17,7 +17,7 @@
으로 감싸 그대로 돌린다. 파이썬으로 포팅하면 같은 기하가 두 벌이 되어 「그림은 이런데
수량은 저렇다」가 생긴다.
실패는 비치명적이다 — 보정 전(표준) 값이 그대로 남고 화면은 예전처럼 스스로 고친다.
실패는 던진다 — 부르는 쪽([저장] · [확정])이 `recomputed: false` 로 화면에 알린다(388-2).
"""
from __future__ import annotations
@@ -258,9 +258,8 @@ async def _recompute(project_id: UUID | str, route_id: int) -> int:
)
marks.append(("종횡단 상세+DB 조회(병렬)", time.perf_counter()))
payload = getattr(response, "model_dump", None)
if payload is None: # JSONResponse = 실패
logger.warning("서버 재계산: 종횡단 상세를 못 받음 (route_id=%s)", route_id)
return 0
if payload is None: # JSONResponse = 실패 — 삼키지 않음(388-2)
raise RuntimeError(f"서버 재계산: 종횡단 상세를 못 받음 (route_id={route_id})")
detail = payload(mode="json")
sections = detail.get("cross_sections") or []
project_root = Path(resolve_stored_project_path(stored_path))
@@ -307,8 +306,8 @@ async def _recompute(project_id: UUID | str, route_id: int) -> int:
},
)
marks.append(("Node 번들(면적·유토곡선)", time.perf_counter()))
if not isinstance(output, dict):
output = {}
if not isinstance(output, dict): # Node 실패 — 삼키지 않음(388-2)
raise RuntimeError(f"서버 재계산: Node 면적 · 유토곡선 실패 (route_id={route_id})")
rows = output.get("areas")
mass_haul = output.get("mass_haul")
# 선 다단 벽 목록(④) — 목록째 얹음(수가 아니라 `_AREA_KEYS` 로는 못 거름). 주인 측점엔 빈 목록도.