fix(472 덧 관 지움 ↶): 갈아끼움 — 지금 상세에 없던 측점이 정본 자리로 돌아오면 정본 설계(빈 기본 설계 아님)

- 관 지움 ↶ = 351 측점이 새로 서며 freshDesign(잠정 status · 포장 권장 pavement_suggested 빠짐 → 성토 경고 안내가 달라짐) → 같은 자리 정본 행이 있으면 그 설계 사본
- 지금 상세에 같은 자리 측점이 있으면(격자에 구조물 놓기 등) 옛 규칙 그대로 · 노선 초안 차례 그대로
- 시험 test_272_swap_keeps_canon 관 지움 되돌림(옛 코드 실패)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-19 11:34:51 +09:00
co-authored by Claude Opus 5.5
parent 789bd9ce09
commit ff21ef21b7
3 changed files with 43 additions and 3 deletions
+13 -2
View File
@@ -193,7 +193,7 @@ export function swapCrossSections(
oldKeys: ReadonlyArray<string>,
intervalM: number | null,
routeDraft = false,
saved: ReadonlyArray<Partial<CanonPlace>> = [],
saved: ReadonlyArray<Partial<CanonPlace & Pick<CrossSection, "design">>> = [],
): StationSwap {
const byKey = new Map(detail.cross_sections.map((section, i) => [oldKeys[i], section]));
const used = new Set<CrossSection>();
@@ -301,7 +301,18 @@ export function swapCrossSections(
: fresh
? uphillSide(station)
: (prior?.uphill_side ?? null);
if (!prior) return { ...place, uphill_side: uphill, samples, design: freshDesign(uphill) };
// 지금 상세에 없던 측점이 정본 자리로 돌아옴(관 지움 ↶ 등) = 정본 설계(472 덧 · 지우기 전과 같음)
const restored =
!prior && !routeDraft && !detail.cross_sections.some(atPlace)
? saved.find((row): boolean => atPlace(row))
: undefined;
if (!prior)
return {
...place,
uphill_side: uphill,
samples,
design: restored?.design ? { ...restored.design } : freshDesign(uphill),
};
const reseed =
(station.kind === "pipe" || station.kind === "structure") &&
Math.abs(prior.chainage_m - station.chainageM) > FACILITY_RESEED_M;
@@ -212,6 +212,26 @@ const out = {};
out.pipeGone.canon = report(after)["40.00"].same;
}
/* 1-5. 관 지움 → 되돌림(472 덧) — 지금 상세에 없던 측점이 정본 자리로 = 정본 설계(빈 기본 설계 아님) */
{
const all = stationsAt(45);
const without = all.filter((s) => s.key !== "pipe:p1");
const gone = m.swapCrossSections(canonDetail(), without, KEYS, 20, false);
const saved = canonDetail().cross_sections;
const back = m.swapCrossSections(gone.detail, all, keysOf(without), 20, false, saved);
const at45 = back.detail.cross_sections.find((s) => s.chainage_m === 45);
const bare = m
.swapCrossSections(gone.detail, all, keysOf(without), 20, false)
.detail.cross_sections.find((s) => s.chainage_m === 45);
out.pipeRestore = {
design: json(at45.design) === json(canonOf.get(45).design),
copy: at45.design !== saved.find((s) => s.chainage_m === 45).design,
place: report(back.detail)["45.00"].same,
bytes: bytesSame(back.detail, [45]),
bareFresh: bare.design?.mark === undefined, // 정본 없음 = 기본 설계 그대로
};
}
/* 2. 가게 길(swapSectionStations) — 가게 routeDraft 로 가름: 없음 · 있음 · 초안 버린 직후 */
const seed = (P, R) => {
m.writeState("section-detail", canonDetail(), P, R);
+10 -1
View File
@@ -114,7 +114,9 @@ def test_가게_길_초안_있음_버린_직후(out):
for at in STRAIGHT: # 초안 차례 = 옛 규칙(기하 새 틀 · 표본 앞 값)
assert not s["draft"][at]["same"] and not s["draft"][at]["browser"], at
dropped = s["dropped"]
for at in CURVES: # 버린 뒤 = 저장 정본 자리 · 표본(초안 3 cm 자리 표본이 안 남음 · 467 덧 정본 물러섬)
for at in (
CURVES
): # 버린 뒤 = 저장 정본 자리 · 표본(초안 3 cm 자리 표본이 안 남음 · 467 덧 정본 물러섬)
assert dropped[at]["same"] and not dropped[at]["browser"], at
for at in STRAIGHT: # 초안이 안 옮긴 측점 = 앞 횡단 표본(서버) 그대로
assert not dropped[at]["browser"], at
@@ -133,3 +135,10 @@ def test_일반_측점_자리_관_지움_다른_목록(out):
assert g["sameUntouched"] is True # 일반 측점 그대로 = 같은 목록
assert g["culvertLeft"] is False and g["kind"] == "regular" # 관 카드 안 남음
assert g["canon"] # 그 자리 정본 표본 · 기하
def test_관_지움_되돌림_정본_설계(out):
r = out["pipeRestore"]
assert r["design"] and r["copy"] # 지우기 전 설계(정본 사본) — 빈 기본 설계 아님(472 덧)
assert r["place"] and r["bytes"]
assert r["bareFresh"]