"""B05 · B06 한 본문 저장 진행(PLAN 520-4) — 지금 도는 차례 이름 · n/N · 지난 초를 메모리에. `B06_Section_Router_DesignSave._run_steps` 가 차례마다 `mark` · 끝에 `end` · 화면 잠금판이 1 s 마다 `GET /design/save/progress`(창구는 `B06_Section_Router_DesignSave`)로 물음 (페이지 넘김 `moveStage` 단계의 progress 칸). """ from __future__ import annotations import time from typing import Any from uuid import UUID # ponytail: 프로세스 메모리 한 벌 — 서버 일꾼이 여럿이면 다른 일꾼 진행은 안 보임(그때 파일 · DB 로) _PROGRESS: dict[str, dict[str, Any]] = {} def begin(project_id: UUID, planned: list[str]) -> None: """저장 한 번 시작 — 차례 이름 목록(N)을 적음.""" _PROGRESS[str(project_id)] = {"planned": planned, "step": None, "started": time.monotonic()} def mark(project_id: UUID, name: str) -> None: """차례 들어감 — 목록 밖 이름(배수유역 다시 셈 등)은 앞 차례 자리 그대로.""" entry = _PROGRESS.get(str(project_id)) if entry is not None: entry["step"] = name def end(project_id: UUID) -> None: _PROGRESS.pop(str(project_id), None) def snapshot(project_id: UUID) -> dict[str, Any]: """지금 진행 — 안 돌면 active 거짓.""" entry = _PROGRESS.get(str(project_id)) if entry is None or entry["step"] is None: return {"active": False} planned: list[str] = entry["planned"] step = entry["step"] # 배수유역 다시 셈 = 관 차례 안 · 자리는 관 seat = "pipes" if step == "basins" else step index = planned.index(seat) + 1 if seat in planned else len(planned) return { "active": True, "step": step, "index": index, "total": len(planned), "elapsed_s": round(time.monotonic() - entry["started"], 1), }