fix(388-1 · 388-3 보안): 로그아웃 · 계정 바뀜 지움 · 세션 넘침 · 탭 프로젝트 고정

- 로그아웃 = 떠남 확인 먼저 → 서버 로그아웃 → 세션 전부 · 현재 프로젝트 · 3D 지형 지움 → 홈 새로고침
- 계정 바뀜(저장한 주인 ≠ 지금 사용자) = 같은 지움 뒤 새로고침 · 열쇠에 계정 안 섞음
- 세션 한도 넘침 = 결과 칸 비우고 한 번 다시 · 그래도 넘치면 「저장 공간 부족」 안내
- B05 · B06 이 연 프로젝트 고정 — 다른 탭이 바꿔도 이 탭 초안 칸 그대로
- 새 test_384_s_logout_wipe

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VmC34fsxxbweEG3RUjs3Mn
This commit is contained in:
2026-10-17 17:21:38 +09:00
co-authored by Claude Opus 5.5
parent 23c6645839
commit 3e312b68d7
8 changed files with 281 additions and 5 deletions
+2
View File
@@ -31,6 +31,7 @@ import type { DesignView } from "./design_dock";
import { saveSharedDesign, type DesignPageShared } from "./design_shared";
import { guardDesignLeave } from "./design_leave";
import { usePipeIds } from "./design_pipe_ids";
import { pinDraftProject } from "./design_store";
import { setRouteShiftOpener } from "../../B06_Section/B06_Section_UI_Cross_Center";
import { reconcilePagePipeline } from "./design_pipeline_page";
import "./design_page.css";
@@ -109,6 +110,7 @@ export function renderDesignPage(root: HTMLElement): MountedPage {
page.className = "design-page";
root.replaceChildren(page);
const projectId = localStorage.getItem(CURRENT_PROJECT_ID_KEY) ?? "";
pinDraftProject(projectId); // 연 프로젝트 고정(388-3) — 다른 탭이 바꿔도 이 탭 초안 칸 그대로
usePipeIds(projectId || null); // 관 세션 id 장부 = 이 프로젝트(323-5 · 카드 · 알약 · 종단 · 3D 같은 id)
// 한 벌 틀 — 좌측 자리 · 가운데(위 칸 + 아래 종단도). 진행 단계 틀은 단계 상태가 오면 감싼다.
+8 -1
View File
@@ -76,10 +76,17 @@ export interface DesignStore {
/** 옛 계획고 초안 키 — 위 머리 주석 참조(남은 옛 값을 쓸어 낼 때만 쓴다). */
export const ALIGNMENT_DRAFT_KEY_PREFIX = "b05-profile-alignment-draft";
/** 계획고 초안 칸의 프로젝트 — 부르는 쪽이 모르면 지금 연 프로젝트, 그것도 없으면 `-`
/** 이 탭 페이지가 연 프로젝트(388-3) — 다른 탭이 현재 프로젝트를 바꿔도 이 탭 초안이 안 섞임. */
let openedProjectId: string | null = null;
export function pinDraftProject(projectId: string | null): void {
openedProjectId = projectId || null;
}
/** 계획고 초안 칸의 프로젝트 — 부르는 쪽이 모르면 이 탭이 연 프로젝트, 그것도 없으면 `-`
* (노선 번호는 프로젝트를 건너 겹치지 않는다). */
export function draftProjectId(projectId: string | null = null): string {
if (projectId) return projectId;
if (openedProjectId) return openedProjectId;
try {
return window.localStorage.getItem(CURRENT_PROJECT_ID_KEY) || "-";
} catch {