fix(B05): 구조물 목록 배관 중복 — 확정 복원 유령 정밀 제거

경로확정 직후 같은 배관이 2개씩 뜨던 문제(2026-08-06 사용자 보고):
확정 시 종단 정본에 병합된 배관이 페이지 진입 복원(restoreSections)으로
목록에 들어오는데, 복원 항목은 structureType이 없어 isPipeStation 판정을
빠져나가 관 정본 투영(setPipeStations) 때 걷히지 않았다. 정본 연동 항목과
비연동 유령이 공존 — 로드 순서(배수유역 관 vs 종단 복원) 레이스라 서버
재시작 여부에 따라 재현이 갈렸다.

setPipeStations에서 투영되는 관과 같은 자리(±0.5m)의 종류 없는 복원
항목만 제거. 종류를 갖춘 사용자 추가 구조물은 자리가 겹쳐도 보존.

실측: 재진입 후 목록 관 4개 각 1건(중복 소멸), 콘솔 에러 0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-06 18:11:43 +09:00
co-authored by Claude Fable 5
parent 7a4326e339
commit 1b48ab3732
@@ -461,8 +461,19 @@ export function createIrregularStationsSection(
// 배관 항목은 통째로 갈아 끼운다 — 정본은 배수유역도의 관 목록이다.
// 단, 사용자가 관종·직경을 손으로 바꾼 항목(userSized)은 같은 자리에 다시 올 때 유지한다.
const previousPipes = stations.filter(isPipeStation);
const incomingChainages = pipes.map((pipe) =>
typeof pipe === "number" ? pipe : pipe.chainage_m,
);
for (let index = stations.length - 1; index >= 0; index -= 1) {
if (isPipeStation(stations[index])) stations.splice(index, 1);
const entry = stations[index];
// 경로확정 정본(종단 병합분)에서 복원된 항목은 구조물 종류(structureType)가 없다.
// 그 중 정본 관과 같은 자리(±0.5m)인 것은 관의 **복원 유령**이다 — 지금 투영되는
// 정본 관이 진짜이므로 걷어낸다. 같은 배관이 목록에 2개씩 뜨던 원인(2026-08-06
// 사용자 보고). 종류를 갖춘 사용자 추가 항목은 자리가 겹쳐도 건드리지 않는다.
const restoredGhost =
entry.structureType === undefined &&
incomingChainages.some((chainage) => Math.abs(entry.chainage_m - chainage) < 0.51);
if (isPipeStation(entry) || restoredGhost) stations.splice(index, 1);
}
pipes.forEach((pipe) => {
const chainage = typeof pipe === "number" ? pipe : pipe.chainage_m;