From 92441eb8c9b254eab6a296ba1b70ada549f193e1 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Fri, 4 Sep 2026 17:02:07 +0900 Subject: [PATCH] =?UTF-8?q?fix(B05):=20=EC=B4=88=EA=B8=B0=ED=99=94=20?= =?UTF-8?q?=ED=9B=84=20=EA=B3=84=ED=9A=8D=EC=84=A0=EC=9D=B4=20=EC=9B=90?= =?UTF-8?q?=EC=A7=80=EB=B0=98=EA=B3=BC=20=EC=96=B4=EA=B8=8B=EB=82=98?= =?UTF-8?q?=EB=8D=98=20=EB=AC=B8=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 브라우저 세션에 남은 계획선 편집 초안이 초기값 위에 다시 얹혀, 초기화 직후에는 멀쩡하다가 새로고침 한 번에 계획선이 측점에서 떨어짐 (실측: 측점 66개 중 25개가 10cm 초과, 최대 6.0m). - [초기화]가 `b05-profile-alignment-draft:*` 세션 초안을 전부 제거 - 노선번호 없는 초안 키(`:none`) 폐지 — 어느 노선에나 되붙어 초기화로도 떨어지지 않던 구멍 Co-Authored-By: Claude Opus 5 (1M context) --- B05_Profile/B05_Profile_UI_Page_Actions.ts | 4 +++ B05_Profile/B05_Profile_UI_Profile_Edit.ts | 32 +++++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/B05_Profile/B05_Profile_UI_Page_Actions.ts b/B05_Profile/B05_Profile_UI_Page_Actions.ts index d54c74d5..0b4b0424 100644 --- a/B05_Profile/B05_Profile_UI_Page_Actions.ts +++ b/B05_Profile/B05_Profile_UI_Page_Actions.ts @@ -32,6 +32,7 @@ import { import { clearStandardCrossSession } from "../B06_Section/B06_Section_UI_Standard_Panel"; import { saveCorridorIfDirty } from "./B05_Profile_UI_Corridor"; import { circlePoint, routePoint } from "./B05_Profile_UI_Page_Helpers"; +import { clearAlignmentDrafts } from "./B05_Profile_UI_Profile_Edit"; import type { createRoutePanel } from "./B05_Profile_UI_Panel"; import type { createRouteProfilePanel } from "./B05_Profile_UI_Profile_Panel"; import type { createStructuresBridge } from "./B05_Profile_UI_Page_Structures"; @@ -206,6 +207,9 @@ export async function resetDesignAction(ctx: PageActionContext): Promise { ctx.uphillOverrides.clear(); ctx.persistUphillOverrides(); clearStandardCrossSession(ctx.projectId); + // 계획선 편집 초안도 함께 버린다 — 남기면 초기값 위에 옛 편집이 다시 얹혀 계획선이 + // 측점에서 원지반선과 만나지 않는다(2026-09-04 실측: 새로고침 후 최대 6.0m 어긋남). + clearAlignmentDrafts(); showToast(L("B05_Route_Reset_Success"), "success"); navigateTo(ROUTES.B05_PROFILE); } catch (error) { diff --git a/B05_Profile/B05_Profile_UI_Profile_Edit.ts b/B05_Profile/B05_Profile_UI_Profile_Edit.ts index 0b6ce3e4..e2fba671 100644 --- a/B05_Profile/B05_Profile_UI_Profile_Edit.ts +++ b/B05_Profile/B05_Profile_UI_Profile_Edit.ts @@ -86,7 +86,27 @@ export interface ProfileEditStore { * 쓰면 초안 편집분이 B06에서 되돌아간 것처럼 보인다. */ export function readAlignmentDraft(routeId: number | null): AlignmentEdits | null { - return readDraft(`${DRAFT_KEY_PREFIX}:${routeId ?? "none"}`); + return routeId === null ? null : readDraft(`${DRAFT_KEY_PREFIX}:${routeId}`); +} + +/** + * 계획선 편집 초안을 모두 버린다 — [초기화]가 부른다. + * + * 초기화는 서버 값을 초기 스냅샷으로 되돌리는데, 이 초안이 남아 있으면 화면이 그 위에 + * 옛 편집 델타를 다시 얹어 계획선이 측점에서 원지반선과 만나지 않는다(2026-09-04 실측: + * 초기화 직후에는 멀쩡하다가 새로고침 한 번에 최대 6.0m 어긋남). + */ +export function clearAlignmentDrafts(): void { + try { + const keys: string[] = []; + for (let index = 0; index < sessionStorage.length; index += 1) { + const key = sessionStorage.key(index); + if (key?.startsWith(`${DRAFT_KEY_PREFIX}:`)) keys.push(key); + } + keys.forEach((key) => sessionStorage.removeItem(key)); + } catch { + // 세션 저장소를 못 쓰는 환경이면 남길 초안도 없다. + } } function readDraft(storageKey: string): AlignmentEdits | null { @@ -109,14 +129,17 @@ function readDraft(storageKey: string): AlignmentEdits | null { * 초기값은 **서버에 저장된 편집분**이고, 세션 초안이 남아 있으면(= 확정 없이 * 새로고침한 경우) 초안을 우선 채택하고 미저장 상태로 표시한다. routeId가 바뀌면 * 초안 키도 바뀌어 이전 노선의 편집이 새 노선에 잘못 얹히지 않는다. + * + * routeId가 아직 없으면 **초안을 두지 않는다**(2026-09-04). 노선 없는 키(`:none`)에 + * 쌓인 초안은 어느 노선에나 되붙어 초기화로도 떨어지지 않았다. */ export function createProfileEditStore( routeId: number | null, saved: AlignmentEdits, onChange: () => void, ): ProfileEditStore { - const storageKey = `${DRAFT_KEY_PREFIX}:${routeId ?? "none"}`; - const draft = readDraft(storageKey); + const storageKey = routeId === null ? null : `${DRAFT_KEY_PREFIX}:${routeId}`; + const draft = storageKey ? readDraft(storageKey) : null; let current = draft ?? saved; let unsaved = draft !== null; /** @@ -127,6 +150,7 @@ export function createProfileEditStore( let savedBaseline = saved; function dropDraft(): void { + if (!storageKey) return; try { sessionStorage.removeItem(storageKey); } catch { @@ -138,7 +162,7 @@ export function createProfileEditStore( current = next; unsaved = true; try { - sessionStorage.setItem(storageKey, JSON.stringify(current)); + if (storageKey) sessionStorage.setItem(storageKey, JSON.stringify(current)); } catch { // 초안 보관 실패는 편집을 막지 않는다. }