fix(B06): 재계산이 다단 구간값을 지우던 것 — 사용자 조작값 목록을 한 벌로

같은 「사용자 조작값」 목록이 세 곳에 흩어져 있었고 서로 달랐음.
브라우저(B06_Section_Cross_Refresh.ts PRESERVED_KEYS)는 extra_spans 를
살렸는데 서버 두 곳은 안 살렸음 —

  - B06_Section_Router_Design._USER_TOUCHED_KEYS (포장 강제 재계산 ·
    세월교 노면 하강 재계산이 씀)
  - B06_Section_Router 안의 인라인 사본 (단측점 설계 갱신)

그래서 포장 구간이나 세월교가 앉은 측점이 다시 계산되면 사용자가 넣은
다단 구간값이 조용히 사라졌음.

_USER_TOUCHED_KEYS 를 공개 이름 USER_TOUCHED_KEYS 로 바꾸고 extra_spans 를
넣음. 라우터의 인라인 사본을 지우고 그 한 벌을 씀.

시험 tmp/tests/test_b06_user_touched_keys.py 3건 신설 — 서버 목록에
extra_spans 가 있는지, 서버와 브라우저 목록이 같은지(status ·
pavement_suggested 는 부르는 쪽이 붙이므로 제외), 라우터에 사본이
남지 않았는지. 목록이 다시 갈라지면 시험이 깨짐.

pytest 412 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-07 04:50:43 +09:00
co-authored by Claude Opus 5
parent 9317ad3175
commit b6941bd28d
2 changed files with 21 additions and 18 deletions
+8 -14
View File
@@ -40,12 +40,13 @@ 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 (
USER_TOUCHED_KEYS,
ford_drop_at,
ford_surface_drops,
)
from B06_Section.B06_Section_Router_Design import (
attach_default_designs as _attach_default_designs,
)
from B06_Section.B06_Section_Router_Design import (
read_cross_design_inputs as _read_cross_design_inputs,
)
@@ -629,17 +630,10 @@ async def compute_cross_section_design(
if abs(float(record["chainage_m"]) - request.chainage_m) < 0.01:
stored_design = record.get("design")
if isinstance(stored_design, dict):
for key in (
"display_half_width_m",
"inlet_structure",
"basin_adjust",
"ford_adjust",
"box_adjust",
"revet_adjust",
"extra_wall_counts",
"revet_link_detached",
"revet_follow_grade",
):
# 목록을 여기 다시 적지 않는다 — 서버의 한 벌은
# `B06_Section_Router_Design.USER_TOUCHED_KEYS` 다(2026-09-07).
# 예전에는 여기에 따로 적어 두어 `extra_spans` 가 빠져 있었다.
for key in USER_TOUCHED_KEYS:
if stored_design.get(key) is not None:
design[key] = stored_design[key]
break
+13 -4
View File
@@ -112,8 +112,16 @@ def paved_at(chainage_m: float, ranges: list[tuple[float, float]], stored: Any =
return bool(stored) if isinstance(stored, bool) else False
# 사용자 조작값 — 포장 강제로 다시 계산해도 그대로 승계한다.
_USER_TOUCHED_KEYS = (
# 사용자 조작값 — 다시 계산해도 그대로 승계한다. **이 목록이 서버의 유일한 한 벌이다.**
#
# 브라우저 쪽 짝은 `B06_Section_Cross_Refresh.ts` 의 `PRESERVED_KEYS` 다(+ `status`·
# `pavement_suggested`, 이 둘은 부르는 쪽이 따로 붙인다). 새 사용자 조작값을 만들면
# **두 곳 모두**에 넣을 것 — 빠뜨리면 재계산이 조용히 지운다.
#
# ⚠ `extra_spans`(다단 구간값)가 실제로 그렇게 빠져 있었다(2026-09-07 발견). 브라우저는
# 살렸는데 서버 두 경로(포장 강제·세월교 노면 하강)와 단측점 갱신은 안 살려, 그 측점이
# 다시 계산되면 사용자가 넣은 단별 구간값이 사라졌다.
USER_TOUCHED_KEYS = (
"display_half_width_m",
"inlet_structure",
"basin_adjust",
@@ -121,6 +129,7 @@ _USER_TOUCHED_KEYS = (
"ford_adjust",
"box_adjust",
"extra_wall_counts",
"extra_spans",
"revet_link_detached",
"revet_follow_grade",
)
@@ -182,7 +191,7 @@ def enforce_pavement_ranges(
)
except (ValueError, KeyError):
continue
for key in ("status", "pavement_suggested", *_USER_TOUCHED_KEYS):
for key in ("status", "pavement_suggested", *USER_TOUCHED_KEYS):
if design.get(key) is not None:
recomputed[key] = design[key]
section["design"] = recomputed
@@ -233,7 +242,7 @@ def enforce_ford_surface_drops(
)
except (ValueError, KeyError):
continue
for key in ("status", "pavement_suggested", *_USER_TOUCHED_KEYS):
for key in ("status", "pavement_suggested", *USER_TOUCHED_KEYS):
if design.get(key) is not None:
recomputed[key] = design[key]
section["design"] = recomputed