fix(B05): 시설 속성은 측점이 같은 관에만 붙임 · 옛 관 이동 예약 적용 제거

- 원인: 화면 attach · 서버 carry_facility_attributes 가 거리 제한 없이 가장 가까운 관에 속성을 붙여, 관 수 > 속성 수이거나 관을 이웃 쪽으로 옮기면 BOX · 세월교가 옆 관 측점으로 넘어감
- 고침: 화면 carryIndices ↔ 서버 carry_indices 짝 — 허용 오차 0.05m 안 가장 가까운 원본만 · 한 원본 한 번 · 못 붙인 관은 속성 없음(추천은 기존대로 빈칸에만) · 두 파일 머리에 짝 표기
- 관을 옮기면 속성이 따라감: 지도 끌기(onMove → move) · 되돌리기 · 구조물 폼(follow — 사라진 관 하나 · 새 관 하나일 때)
- B06 옛 「관 이동 예약」(culvertmove): 저장 때 읽지도 적용하지도 않음 — flushCulvertOptions · createCulvertOptionWriter 에서 이동 키 제거
- 시험: 거울 시험 test_b05_facility_carry(화면 · 서버 같은 답 · 끌기 · 되돌리기) · 옛 최근접 · 이동 예약 적용 시험을 새 규칙으로 고침
- 확인: ORCA 5180 랩탑_보조 — 세월교(173.09) 8m 앞 165m 에 옵션 없는 관 추가 → 저장 → pipe_points.json 165 = 속성 없음 · 173.09 = ford_bridge · 나머지 11건 전후 같음

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RrQ65VtGZbae2VKgYVMhmc
This commit is contained in:
2026-09-29 09:51:55 +09:00
co-authored by Claude Opus 5.5
parent c48ed4c309
commit 2a9b343e2e
10 changed files with 264 additions and 84 deletions
@@ -7,8 +7,8 @@ B05 는 관 목록 전체를 세션 스냅샷(`pipes`)으로 담고, B06 은 바
여기서 지키는 것은 둘이다.
① 저장기(`createCulvertOptionWriter`)에는 **관을 넣고 빼는 길이 없다** — 남아 있으면
관 목록을 담는 자리가 다시 둘이 된다.
② 옛 세션에 남아 있던 **이동 예약은 저장 때 흘려보낸다** — 합치기 전에 만들어 둔
예약이 조용히 사라지면 안 된다.
② 옛 세션에 남아 있던 **이동 예약은 저장 때 안 씀** — 관 위치는 스냅샷으로만 옮김
(적용하면 관이 이웃 측점으로 튀어 BOX · 세월교 속성이 넘어감).
실제 화면 코드를 그대로 컴파일해 Node 로 돌린다(다단 하한 시험과 같은 방식).
"""
@@ -62,21 +62,17 @@ global.window = {
};
const api = require(process.argv[3]);
const writer = api.createCulvertOptionWriter(
() => "p1",
() => "opt",
undefined,
() => "move",
);
const writer = api.createCulvertOptionWriter(() => "p1", () => "opt", undefined);
// ① 관을 넣고 빼는 길이 저장기에 남아 있으면 안 된다.
const methods = Object.keys(writer).sort();
// ② 합치기 전 세션에 남아 있던 이동 예약은 저장 때 흘려보낸다.
// ② 옛 세션의 이동 예약은 남아 있어도 안 씀 — 구간값만 제 측점에 나감.
store.set("move", JSON.stringify({ "120.00": 135 }));
store.set("opt", JSON.stringify({ "120.00": { pipe_count: 2 } }));
api
.flushCulvertOptions("p1", "opt", "move")
.flushCulvertOptions("p1", "opt")
.then(() => {
writeFileSync(
process.argv[2],
@@ -134,6 +130,5 @@ def test_관_목록을_담는_자리는_하나뿐이다(tmp_path: Path) -> None:
# ① 저장기에는 구간값 예약과 내보내기만 있다 — 관을 넣고 빼는 길은 스냅샷 한 곳뿐이다.
assert result["methods"] == ["flush", "queue"]
# ② 옛 세션의 이동 예약은 저장 때 반영되고 비워진다.
assert result["savedChainages"] == [135, 200]
assert result["moveLeft"] is None
# ② 옛 세션의 이동 예약은 저장 때 안 씀 — 관은 제 측점 그대로.
assert result["savedChainages"] == [120, 200]