/* ============================================================================= * B06_Section_Cross_Design_Session.ts * 횡단 카드 버튼(지반유형·단면유형·측구·포장·2단 비탈) 선택의 **세션 보관소**. * * 왜 생겼나(2026-09-06 사용자 확정) — 예전에는 버튼을 누를 때마다 * `POST …/sections/{route}/cross-design` 이 나가 서버가 계산하고 **바로 저장**했다. * 조작은 캐시에 쌓이고 [저장]·[확정]에서만 정본으로 나가야 한다는 규칙에 어긋난다. * 계산은 브라우저가 하고(`common_util_cross_design.ts`), 선택값은 여기 담긴다. * * 담는 것은 **사용자가 고른 것만**이다 — 계산 결과(면적·설계선)는 담지 않는다. * ========================================================================== */ import { readState, writeState } from "../A00_Common/b_page_state"; /** 카드에서 고를 수 있는 값 한 벌 — 서버 `CrossDesignRequest` 와 같은 이름을 쓴다. */ export interface CrossDesignChoice { ground_type: string; section_mode: string; ditch_side?: string | null; ditch_type?: string | null; paved?: boolean; two_stage_slope?: boolean; /** 측구를 둘지 **사용자가 정한 선택**(`null` = 자동 판정). 결과(`ditch_enabled`)가 아니다. * ⚠ 이 칸이 없으면 측구 토글이 눌려도 캐시에 안 담겨 **화면에서 안 돈다**(2026-09-09). */ ditch_choice?: boolean | null; } type ChoiceMap = Record; /** 측점 키 — 암 경계선 저장소와 같은 규칙(0.01m 단위). */ const keyOf = (chainageM: number): string => chainageM.toFixed(2); function readAll(projectId: string, routeId: number): ChoiceMap { return readState("crossdesign", projectId, routeId) ?? {}; } /** 이 측점의 선택값(없으면 null). */ export function readCrossDesignChoice( projectId: string, routeId: number, chainageM: number, ): CrossDesignChoice | null { return readAll(projectId, routeId)[keyOf(chainageM)] ?? null; } /** 선택값을 세션에 담는다. 같은 측점의 앞선 값은 덮어쓴다. */ export function writeCrossDesignChoice( projectId: string, routeId: number, chainageM: number, choice: CrossDesignChoice, ): void { const all = readAll(projectId, routeId); all[keyOf(chainageM)] = choice; writeState("crossdesign", all, projectId, routeId); } /** [저장]·[확정]이 patch 로 실을 목록 — 누가거리(숫자) → 선택값. */ export function crossDesignChoices( projectId: string | null, routeId: number | null, ): Map { const choices = new Map(); if (!projectId || routeId === null) return choices; for (const [key, value] of Object.entries(readAll(projectId, routeId))) { const chainage = Number(key); if (Number.isFinite(chainage) && value) choices.set(chainage, value); } return choices; }