- 묶음 drainage 단계 입력 지문(노선 초안 rev 뺌 · 관 id · 자리 cm) — 같은 노선 · 관으로 다시 돈 묶음은 흘려보냄(떠 있는 요청 안 끊음 · 다시 안 흐림) - 차례 번호는 요청마다 하나 · 답은 차례 + 지문이 지금과 같을 때만 받음 - 서버 답이 「낡음」(노선 [저장] 뒤 등) = 수동은 흐림 + [업데이트] · 자동은 3 s 뒤 조용히(markStale) - 시험 test_349_drainage_live_flow(가짜 DOM · 시계 · fetch 로 화면 파일 실행 — 수동 · 자동 · 제안 [적용]) · 347-2 헬퍼 새 받기 규칙 - PLAN.md 349-0b Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XWh5wNNycMkbwMpACz1rte
55 lines
2.7 KiB
TypeScript
55 lines
2.7 KiB
TypeScript
/* =============================================================================
|
|
* B05_Profile/logic/B05_Profile_Drainage_Live.ts
|
|
* 배수유역 자동/수동 다시 셈(347-2) — 순수 규칙만. 화면 · fetch 는 `B05_Profile_UI_Drainage_Live.ts`.
|
|
*
|
|
* - 대상 = 평면(노선 초안) · 관 자리만 — 종단 · 횡단 조작은 배수유역 결과를 안 바꿈(묶음 deps 와 같음).
|
|
* - 노선 초안이 없으면(저장 노선 그대로) 낡음 아님 — 관 조작은 세부 유역 나눔(0.2 s)이 바로 맞춤.
|
|
* - 자동 = 조용한 뒤 `QUIET_MS` · 수동 = 흐림 + [업데이트] · 기본 수동.
|
|
* - 묶음이 같은 입력으로 다시 돌면(입력 지문 같음) 낡음 · 떠 있는 요청을 그대로 둠.
|
|
* - 답 채택 = 보낸 차례 · 입력 지문이 지금과 같고 서버가 그만두지 않았을 때만(늦은 답 버림).
|
|
* ========================================================================== */
|
|
|
|
export type DrainageMode = "manual" | "auto";
|
|
|
|
/** 자동 모드 — 마지막 조작 뒤 이만큼 조용하면 셈(ms · 341 결정 거리 6 · 3 초). */
|
|
export const QUIET_MS = 3000;
|
|
|
|
/** 계정 화면 설정 글자 → 모드(없거나 모르는 값 = 수동). */
|
|
export const parseDrainageMode = (raw: string | null | undefined): DrainageMode =>
|
|
raw === "auto" ? "auto" : "manual";
|
|
|
|
/** 묶음 drainage 단계 입력 → 낡았는가 — 노선 초안이 있을 때만. */
|
|
export const draftMakesStale = (route: unknown): boolean => route !== null && route !== undefined;
|
|
|
|
/** 묶음 drainage 입력 지문 — 노선 초안(판 번호 rev 뺌) · 관 id · 자리(cm). */
|
|
export function inputKey(route: unknown, pipes: unknown): string {
|
|
const draft = route && typeof route === "object" ? { ...route, rev: undefined } : null;
|
|
const spots = Array.isArray(pipes)
|
|
? pipes.map((pipe) => `${pipe?.id ?? ""}@${Math.round(Number(pipe?.chainage_m) * 100)}`).sort()
|
|
: [];
|
|
return JSON.stringify([draft, spots]);
|
|
}
|
|
|
|
/** 「지금 노선으로 셈」 몸통 — 서버 `post_drainage_live`. */
|
|
export function liveRequestBody<P>(
|
|
generation: number,
|
|
route: unknown,
|
|
points: P[],
|
|
): { generation: number; route: unknown; points: P[] } {
|
|
return { generation, route: route ?? null, points };
|
|
}
|
|
|
|
/** 답을 화면에 올리는가 — 서버가 그만둔 답 · 옛 차례 · 입력이 바뀐 뒤 답은 버림. */
|
|
export function acceptLive(
|
|
response: { status?: string; generation?: number },
|
|
sent: { generation: number; key: string },
|
|
now: { generation: number; key: string },
|
|
): boolean {
|
|
return (
|
|
response.status !== "superseded" &&
|
|
sent.generation === now.generation &&
|
|
sent.key === now.key &&
|
|
(response.generation === undefined || response.generation === sent.generation)
|
|
);
|
|
}
|