feat(공용): 프로젝트 떠남 = 물음 뒤 그 프로젝트 비움 (PLAN 572-4 · 요구 400~403)

- main.ts renderAll 첫머리 — 프로젝트 화면 → 밖이면 leaveProject(지금 프로젝트) · hashchange 가드(셋 물음)를 지난 뒤
- leaveProject 지움 = b_page_state clearSessionKeys(지움 알림) — B05 설계 가게의 미룬 쓰기(1 s)가 떠난 뒤 design-footprint 를 되살리던 흠 막음(ORCA 에서 찾음)
- test_401 — 떠남 연결 소스 대조 · 지움 알림 수

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-28 18:44:36 +09:00
co-authored by Claude Opus 5.5
parent f427aa76f6
commit aed9857714
5 changed files with 40 additions and 10 deletions
@@ -74,7 +74,7 @@ function openTab() {
currentRoute: () => router.route,
setLeaveGuard: (fn) => ((router.guard = fn), (router.sets += 1)),
});
return { win, sw };
return { win, sw, ps: load("A00_Common/b_page_state.ts") };
}
const X = "11111111-aaaa-4aaa-8aaa-000000000001";
@@ -147,8 +147,12 @@ const keys = (win) => Object.keys(win.sessionStorage.dump()).sort();
]) {
shared.idb.data.set(`${pid}|${url}`, { key: `${pid}|${url}`, projectId: pid, url });
}
const removed = [];
const stop = A.ps.onStateRemoved((key) => removed.push(key)); // 설계 가게가 미룬 쓰기를 거두는 알림
await A.sw.leaveProject(X);
stop();
out.leave = {
notified: removed.length,
keys: keys(A.win),
expected: [...keep].sort(),
entered: A.win.sessionStorage.getItem("aislo:entered-project"),
@@ -52,6 +52,7 @@ def test_떠남은_그_프로젝트_몫만_지움(out):
assert leave["local"] == ["1", "1"] # 취향 · CAD 복구본
assert leave["idb"] == [f"{Y}|u1"] # 보관함 = X 줄만 지움
assert leave["otherTabKept"] == "1" # 다른 탭 세션은 안 건드림
assert leave["notified"] == 13 # 지운 칸마다 지움 알림 — 설계 가게가 미룬 쓰기(1 s)를 거둠
def test_떠남_물음_한_번(out):
@@ -96,3 +97,12 @@ def test_떠남_취소_뒤_단계_단추_다시_맞춤():
assert "window.dispatchEvent(new Event(ROUTE_RESTORED_EVENT))" in main
help_ts = (ROOT / "ui_template/ui_template_help.ts").read_text(encoding="utf-8")
assert "window.addEventListener(ROUTE_RESTORED_EVENT, onHash);" in help_ts
def test_떠남은_물음_뒤_한_자리에서_비움():
# 572-4 — hashchange 가드(물음)를 지난 renderAll 첫머리 · 프로젝트 화면 → 밖 일 때만
main = (ROOT / "A00_Common/main.ts").read_text(encoding="utf-8")
render = main[main.index("const renderAll") : main.index("const within")]
assert "isProjectRoute(shown) && !isProjectRoute(currentRoute())" in render
assert "leaveProject(currentProjectId())" in render
assert main.index("takeLeaveGuard()") > main.index("const renderAll") # 물음은 renderAll 앞에서