chore(요구): 요구 400 조사 — 프로젝트 떠날 때 세션 비우기

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-28 13:53:32 +09:00
co-authored by Claude Opus 5.5
parent 3908e110e9
commit 975673758b
@@ -0,0 +1,163 @@
# 요구 400 — 프로젝트를 떠날 때 세션 비우기 조사
읽기 전용 조사 · 구현 없음 · 근거 = 파일:줄.
## 0. 결론 한 줄
- 지금 비우기 = 다른 프로젝트로 **들어가기 직전**(같은 프로젝트로 돌아오면 안 비움) · 다만 판별이 B 등록표 키 위주라 **D02 · E 캐시 7칸이 빠짐**(남고 쌓이고 확인창도 없음).
- 떠남 자리는 이미 한 곳 — `main.ts` hashchange(가드 뒤 `renderAll`) · 로그아웃 · 탭 닫기만 밖이고 둘 다 이미 전부 비움.
- 추천 = (나) 두 단계 — ① D02 · E 캐시를 등록표로 옮김 ② 떠남 한 자리에서 프로젝트 칸 비움 · 그 앞에 가드 없는 페이지(B08 · B09 · D04 · E03 · E05 · E06)에 「떠나기 전 저장」.
## 1. 지금 비우는 자리
| 무엇 | 자리 | 언제 | 지우는 것 |
| --- | --- | --- | --- |
| 프로젝트 들어감 | `A00_Common/b_project_switch.ts:100-123` `enterProject` | 탭 표식 `aislo:entered-project`(:17) ≠ 들어갈 id 일 때만(:105) | 등록표 키 머리 + 옛 키 머리로 주인 가름(:23-35 · :54-59) → 다른 프로젝트 칸 지움(:117) · 3D 지형 IndexedDB(:119) |
| 부르는 곳 | `A00_Common/b_workflow_nav.ts:102-108` `goToWorkflowStage` | 대시보드 진입 전부(`B01_Dashboard_UI_Home_Cards.ts:70` · `_ProjectList_Parts.ts:106` · `_Projects.ts:81` · `_ProjectDetail.ts:166` · `_View_Assigned.ts:46` · `_PlanLink.ts:76`) · B 단계 이동(`b_page_scaffold.ts:129` · `moveStage` :179) | 위와 같음 |
| 확인창 | `b_project_switch.ts:108-116` | 다른 프로젝트 draft 칸이 채워져 있으면 「지우고 열기 / 남기기」 | 「남기기」= 그 프로젝트 초안만 둠 |
| 계정 떠남 | `b_project_switch.ts:132-140` `wipeAccountCache` | 로그아웃 `app_shell.ts:53-73`(가드 먼저) · `B01_Dashboard_UI_Shell.ts:60-66` · 계정 바뀜 `A06_Login_Api_Fetch.ts:71` | `sessionStorage.clear()` 전부 · 현재 프로젝트 id · IndexedDB 전부 · pref(localStorage)는 남김 |
| 3D 지형만 | `B11_Status_UI_Loading.ts:87` · `B04_PreProcess_UI_Page.ts:98` · `design_view_profile.ts:100` | 그 페이지 열 때 | IndexedDB 다른 프로젝트 |
비우기를 **안 거치는** 길:
- 새 프로젝트 등록 — `B02_ProjRegister_UI_Page.ts:270` · `group_workflow.ts:117`(D01 · E01) = localStorage 현재 프로젝트만 바꾸고 `navigateTo` · 앞 프로젝트 칸은 다음 `goToWorkflowStage` 까지 남음.
- 새로고침 · 주소 직접 입력 — 라우터는 `dropGoneProject` 만(`router.ts:225-234`).
- D · E 단계 아이콘 · [<] [>] — `group_workflow.ts:81-84` `navigateTo`(같은 프로젝트라 문제 없음).
판별의 구멍(`b_project_switch.ts:60-62 · 77`):
- 「다른 프로젝트」 집합 = **등록표 키에서만** 모음 · 등록표 밖 키는 `:` 마디가 그 집합에 들 때만 지움.
- E 페이지는 등록표를 안 씀 → E 프로젝트 id 가 집합에 안 들어감 → E 캐시는 진입 비우기에 **안 걸림**.
- D02 `d02_points_{pid}` = 밑줄 이음 → `:` 마디가 아님 → **안 걸림**.
## 2. 세션 칸 목록
### 프로젝트 칸 (session · 모두 pid 를 품음 → 섞임 위험은 낮음)
| 무리 | 키 | 자리 | 지금 진입 비우기 |
| --- | --- | --- | --- |
| B 초안 | `aislo:draft:{이름}:{pid}[:{노선}]` — structures · plus-stations · uphill · pipes · structure-pick · pipe-ids · pipe-option-queue · selection · structure-type-cache · kindreset · std-cross · pagesettings · route-draft · route-draft-hold · 노선 범위 칸 21(crossw · alignment-draft 등) · b08-materials/hydro/options/milestone · b09-estimation | `b_page_state.ts:115-216` | 걸림 |
| B 결과 | `aislo:result:{이름}:{pid}` — latest · section-context · section-detail · std-cross-default · rock-boundary-default · routeedit-initial · design-stations/profile/footprint | `b_page_state.ts:218-245` | 걸림 |
| D | `aislo:draft:d03-plan:{pid}` · `aislo:draft:d04-assignees:{pid}` | `b_page_state.ts:202 · 216` | 걸림 |
| D | `d02_points_{pid}` | `D02_PlanBase_UI_Page.ts:49` | **안 걸림** |
| E | `e02_ground_cache:{pid}` · `e03_prob_cache:{pid}` · `e04_settings:{pid}` · `e05_report_cache:{pid}` · `e06_rock_cache:{pid}` · `e07_settings:{pid}` | `E02:63` · `E03_UI_Prob:79` · `E04:73` · `E05:54` · `E06:64` · `E07:90` | **안 걸림** · 확인창 없음 |
| 공용 | `aislo:entered-project` · `frd_preloaded_signature`(값에 pid) · `frd_preload_target` | `b_project_switch.ts:17` · `b_asset_cache.ts:355-356` | 표식 · 준비 화면용 |
### 프로젝트 밖 칸 (session · 떠날 때 지우면 안 됨)
- 로그인 OTP 대기 `a06:otp-pending`(`A06_Login_UI_Auth_Page.ts:23`).
- 시스템 관리자 고른 회사 `aislo.adminCompany`(`B01_Dashboard_UI_Legacy.ts:31` · `M02_MasterTemplete_Layer.ts:74`).
- 화면 표식 — `aislo.provenance.tint`(`ui_template_provenance.ts:50`) · `frd_touch_hint_shown` · `aislo-ss-notified-no-formula`.
- M01 · M02 관리자 미저장 초안 — `m01_master_draft` · `m01_logic_drafts_lab` · `m01.view.*` · `m01.logic.pending` · M01 Side 고름 칸 · `m02-hopyo-check:*` · `m02-hopyo-ledger:*`.
→ `sessionStorage.clear()` 통째는 안 됨(로그아웃만 예외) · 지울 칸을 골라야 함.
### localStorage (세션 비우기와 무관 · 남김)
- 로그인 = 서버 쿠키(`credentials: "include"`) · 브라우저 저장소에 토큰 없음.
- `frd_current_project_id`(탭 공유) · `aislo:pref:*`(계정 동기화 · 프로젝트 범위 pref = routeedit-view/locks/snap-step) · `aislo:owner` · `frd_theme` · `frd_lang` · `frd_touch_mode` · `aislo.b01.homeLayout` · `m02.dfpanel.*` · `aislo-ss-recent-units`.
- B07 CAD 자동백업 `OPEN_WEB_CAD__RECOVERY__{pid·도면}`(`B07_DesignDetail_UI_Save.ts:190-212`) — B07 고침은 세션이 아니라 여기라 세션 비우기 영향 없음.
## 3. 「프로젝트를 떠남」의 길
| 떠남 | 코드 | 지나는 자리 |
| --- | --- | --- |
| 좌측 위 집(대시보드) | `ui_template_workflow_layout.ts:105` | hashchange |
| 머리 메뉴 · M01 · M02 · 홈 | `app_shell.ts:128 · 154 · 282` · `m_settings_nav.ts:104` | hashchange |
| 다른 무리 프로젝트 | 대시보드 거쳐 `goToWorkflowStage` | hashchange + `enterProject` |
| 뒤로 가기 · 주소창 해시 | 브라우저 | hashchange |
| 로그아웃 | `app_shell.ts:53-73`(가드 → 지움 → 새로고침) | 밖 · 이미 전부 지움 |
| 탭 닫기 | 브라우저 | 밖 · 세션이 탭과 함께 사라짐 · beforeunload 물음 = B05·B06(`design_leave.ts:107-112`) · M02(`M02_MasterTemplete_UI_Main.ts:218-223`)만 |
| 새로고침 | — | 떠남 아님 · 세션 남음 |
한 자리 = `A00_Common/main.ts:89-100` hashchange → 가드 통과 → `renderAll`(:73-86).
- 「프로젝트 화면」 판별은 이미 있음 — `router.ts:108-117` `PROJECT_ROUTES` + 초안 길 `project: true`(D02~D04 · E02~E07 · b09-print) · `router.ts:225` 가 같은 판별을 씀.
- 떠남 = 직전 화면(`shown`)이 프로젝트 화면 · 다음 화면이 아님.
## 4. 떠날 때 비우면 생기는 위험 · 고쳐지는 흠
### 페이지별 떠남 가드 (세션 칸이 고침을 품는 곳)
| 페이지 | 세션 고침 칸 | 지금 가드 | 떠날 때 비우면 |
| --- | --- | --- | --- |
| B05 · B06 | 설계 초안 | `design_leave.ts:102-128` [취소][폐기][저장] | 안전 |
| B08 | b08-* | 단계 이동(`moveStage` · `B08_Quantity_UI_Page.ts:169`)만 저장 · 집 · 머리 메뉴 · 뒤로 = 저장 없이 떠남 | **말없이 사라짐** |
| B09 | b09-estimation | 같음(`B09_Estimation_UI_Shell.ts:355-370` · [저장] 단추 없음) | **말없이 사라짐** |
| D02 · D03 | d02_points · d03-plan | `beforeLeave` 저장(`D02:90` · `D03:168`) | 안전 |
| D04 | d04-assignees | 없음 | **말없이 사라짐** |
| E02 | e02_ground_cache | `beforeLeave` 저장(`E02:146`) | 안전 |
| E03 | e03_prob_cache | 없음 | **사라짐** |
| E05 | e05_report_cache | 없음([저장] 있음) | **사라짐** |
| E06 | e06_rock_cache | 없음([해석] 때 저장) | **사라짐** |
| E04 · E07 | 탐색 설정 · 조건 | 없음 · 저장 대상 아님(E04 = 없으면 저장된 결과의 설정) | 설정만 처음으로 |
- 지금은 이 칸들이 대시보드에 다녀와도 남아 「이어서」가 됨 → 떠남 비우기를 먼저 넣으면 위 표 굵은 칸이 말없이 사라짐 → **가드가 먼저**.
### 그 밖 위험
- 되돌아올 때 느려짐 — result 칸(section-detail 한 칸 1.5 M 자 · 386-0)까지 지우면 같은 프로젝트로 돌아올 때 다시 받고 셈(B05 열기 7.5 s = 386-0 측정 · 386-2 뒤 줄었을 수 있음).
- 3D 지형 — IndexedDB + `frd_preloaded_signature` 를 떠날 때 지우면 같은 프로젝트로 돌아와도 준비 화면(B11)이 다시 돎 · 「대시보드 다녀오면 건너뜀」(`b_asset_cache.ts:345-352` · 08-01 사용자 지시)과 어긋남 → 떠날 때는 남김이 맞음.
- 여러 탭 — 세션은 탭마다 → 떠남 비우기는 그 탭만 · 현재 프로젝트 id 는 localStorage(탭 공유) → 다른 탭이 바꾸면 이 탭 새로고침이 다른 프로젝트를 열고 앞 초안이 세션에 남음(`enterProject` 안 거침 · B05·B06 만 `pinDraftProject` 로 막음 · `design_store.ts:83-98`) → 떠남 비우기로 못 고침 · 들어갈 때 그물(`enterProject`)은 남겨야 함.
### 고쳐지는 흠 (구체)
1. E 캐시 6칸 · D02 캐시가 진입 비우기에 안 걸려 탭이 살아 있는 동안 쌓임 · 저장 안 한 E 고침이 확인창 없이 숨음. 세션 넘침 처리(`b_page_state.ts:446-466`)도 result 칸만 비워 이 칸은 못 비움.
2. 새 프로젝트 등록 직후(B02 · D01 · E01) 앞 프로젝트 칸이 남음 — 등록은 대시보드 [+]에서 시작하므로 떠남 비우기가 먼저 지움.
3. 헛 확인창 — B05·B06 은 [저장] 뒤에도 횡단 초안 · 고름 · 관 id 칸이 세션에 남음(`design_leave.ts:8-9` · `design_save.ts:289-307`) · `planProjectPurge` 는 채워진 draft 칸 전부를 「저장 안 한 고침」으로 봄(`b_project_switch.ts:63-68`) → 저장 끝난 프로젝트에서 다른 프로젝트로 갈 때도 확인창이 뜰 수 있음. 떠날 때 페이지 가드 뒤 바로 지우면 사라짐.
4. 실제 섞임 사례는 옛 키뿐 — 프로젝트 없는 `b05-profile-alignment-draft:{노선}`(387-1 · `b_page_state.ts:205-206`) · 지금 키는 모두 pid 를 품어 충돌보다 「남음 · 쌓임 · 묻지 않고 숨음」이 흠.
## 5. 넷째 무리
- 사방설계 `EROSION` — 새 프로젝트 고르기 「준비 중」(`B01_Dashboard_UI_NewProject.ts:74`) · 종류 칩(`B01_Dashboard_UI_ProjectList_Parts.ts:19`) · DB 주석(`db_management/020_project_groups.sql:11`) · 단계 묶음 없음(`group_workflow.ts:28-46` 은 PLAN · STABILITY 둘).
- 같은 틀(`mountGroupStep` · 초안 길 `project: true` · 등록표 칸)을 쓰면 떠남 비우기가 저절로 걸림.
## 6. 제안
| 갈래 | 내용 | 장점 | 단점 |
| --- | --- | --- | --- |
| (가) | 떠남 한 자리에서 비움 · 키는 그대로 · pid 마디로 판별 | 고칠 파일 적음 | D02 밑줄 키 못 잡음 · E 칸은 확인창 대상 밖 · 키 꼴마다 예외 |
| **(나) 추천** | 프로젝트 칸 전부 등록표로(D02 1 · E 6) + 떠남 한 자리에서 비움 | 무리가 늘어도 표 한 줄 · 진입 비우기 · 확인창 · 세션 넘침이 모두 같은 표를 봄 · 사방 무리도 저절로 | 페이지 손질(키 · 가드) |
| (다) | 그대로 | 손댈 것 없음 | 흠 1~3 남음 |
(다)로 가더라도 ① 단계(등록표 옮김)만은 흠 고침으로 값어치 있음.
### 떠남 비우기 규칙 (나)
- 자리 — `main.ts` `renderAll` 첫머리 · 직전 화면이 프로젝트 화면 · 다음이 아님 → `leaveProject()`(가드 통과 뒤라 다시 안 물음).
- 지움 — 세션의 프로젝트 칸 전부(등록표 draft · result · 옛 키 머리 · 모든 프로젝트) + `aislo:entered-project`. `planProjectPurge(session, "")` 의 `doomed` 를 그대로 씀(빈 id = 모두 「다른 프로젝트」).
- 남김 — pref(localStorage) · 2장 「프로젝트 밖 칸」 · `frd_current_project_id` · IndexedDB 3D · `frd_preloaded_signature`(다른 프로젝트 들 때 `enterProject` 가 지움 · 지금 그대로).
- `enterProject` — 그물로 남김(새로고침 · 다른 탭 · 등록 직후).
### 고칠 파일 · 창 나눔 (파일 겹침 없음)
| 창 | 파일 | 일 |
| --- | --- | --- |
| 창1 (A00 공용) | `A00_Common/b_page_state.ts` | 등록표 7줄(d02-points · e02-ground · e03-prob · e04-settings · e05-report · e06-rock · e07-settings · draft · project) — **먼저 커밋** |
| 창1 | `A00_Common/design/design_leave.ts` | `OTHER_PAGE`(:37) 를 `^(b0[89]|d0\d|e0\d)-` 로 — B05 고침 지문에 D · E 칸 안 섞임 |
| 창1 | `A00_Common/b_project_switch.ts` | `leaveProject()` 추가(지금 155줄) |
| 창1 | `A00_Common/router.ts` | `isProjectRoute(route)` 내보냄(:108-117 + `draft.project` 한 판별) |
| 창1 | `A00_Common/main.ts` | `renderAll` 에서 떠남이면 `leaveProject()` — **창2 · 창3 합친 뒤 마지막** |
| 창2 (D · E) | `D02_PlanBase_UI_Page.ts` · `E02` · `E03_StabSection_UI_Prob.ts` · `E04` · `E05` · `E06` · `E07` `_UI_Page.ts` | 직접 `sessionStorage` → `readState` · `writeState` · `clearState` |
| 창2 | `D04_PlanConfirm_UI_Page.ts` · `E03_StabSection_UI_Page.ts`(629줄 · 늘면 쪼갬) · `E05` · `E06` | `mountGroupStep` `beforeLeave`(그 페이지 저장 함수 · 실패 = 머묾) |
| 창3 (B08 · B09) | `B08_Quantity_UI_Page.ts` · `B09_Estimation_UI_Shell.ts` | 단계 이동 저장 steps 를 `setLeaveGuard` 로도(`root.isConnected` 거짓이면 참 · `group_workflow.ts:71` 꼴) |
차례 = 창1 등록표 → 창2 · 창3 병행 → 창1 떠남 연결. 떠남 연결이 가드보다 먼저 들어가면 4장 굵은 칸이 말없이 사라짐.
### 더할 시험 (`resources/tester`)
- `test_400_leave_clear.py` + `helper_400_leave_clear.cjs`(`helper_290_1` 꼴) — B · D · E 칸 + 프로젝트 밖 칸(OTP · adminCompany · M01 · M02 초안 · tint · 준비 표식) 심고 `leaveProject()` → 프로젝트 칸 0 · 밖 칸 그대로 · `aislo:entered-project` 없음 · IndexedDB 지우기 안 부름 · pref 그대로.
- 같은 시험 — `main.ts` 가 가드 뒤 `renderAll` 에서 `isProjectRoute` 두 번 · `leaveProject(` 부름(소스 대조 · `test_290_1:62` 꼴).
- `test_384_1_session_keys.py` 넓힘 — D0* · E0* `_UI_*.ts` 코드에 직접 `sessionStorage` 0.
- `test_290_1_project_purge.py` 시드 보강 — E · D02 칸이 진입 비우기 · 확인창에 걸림.
- `test_560_4_leave_save.py` 보강 — D04 · E03 · E05 · E06 `beforeLeave:` · B08 · B09 `setLeaveGuard(`.
- 화면(ORCA) — B05 고침 → 대시보드 → 가드 [저장] → 세션 프로젝트 칸 0 · 같은 프로젝트 재진입 시 B11 건너뜀 · E05 고침 → 집 → 저장 물음 · M02 초안은 프로젝트 오가도 남음.
## 갈래 갈리는 결정
1. 떠날 때 **계산 결과(result)** 도 지울지 — 지움(세션 가벼움 · 돌아오면 다시 받고 셈 · B05 열기 7.5 s = 386-0 측정) / 남김(초안만 지우고 결과는 다른 프로젝트 들 때 지움 · 지금 그대로).
2. **3D 지형 보관함(IndexedDB)** — 떠날 때 남김(제안 · 같은 프로젝트로 돌아오면 준비 화면 건너뜀 · 08-01 지시) / 같이 지움.
3. **E04 탐색 설정 · E07 조건** 칸의 통 — draft(세션 · 떠나면 지움 · 확인창 대상) / pref + project(localStorage · 계정 동기화 · 남음 · routeedit-view 선례).
4. **가드 없는 페이지** — 페이지마다 「떠나기 전 저장」(제안 · D02 · E02 방식) / 떠남 자리 공용 확인창 하나(「지우고 나가기 / 머묾」 · 페이지 손질 적음 · 저장은 사용자가 따로).
5. **떠남 범위** — 프로젝트 밖 모든 화면(대시보드 · M01 · M02 · 홈 · 등록 · 제안) / 대시보드만.
6. **현재 프로젝트 id(localStorage)** — 떠나도 남김(제안 · 다른 탭 · 대시보드 표시 무관) / 지움.