fix(B06): 횡단 카드 버튼이 서버에 바로 저장하던 것을 캐시로 바꿈
사용자 확정(2026-09-06): 조작은 캐시에 쌓이고 [저장]·[확정]에서만 영구저장소에 나간다. 카드 버튼(지반유형·단면유형·측구·포장·2단 비탈)은 누를 때마다 POST cross-design 이 나가 서버가 계산하고 바로 저장하고 있었다. - 세션 초안 crossdesign 신설(B06_Section_Cross_Design_Session) — 선택값만 담는다. - 계산은 브라우저 재계산 창구 하나로 돌린다(B05·B06 공용). - 재계산 때 세션 선택이 정본보다 우선 — 새로고침 뒤에도 고른 값이 남는다. - [저장]·[확정] patch 에 선택값 + 전 측점 면적을 실어 보낸다. 카드 버튼을 바꾸면 구조물이 없는 측점 면적도 달라지므로 구조물 측점만 보내면 수량이 어긋난다. - 구조물 목록 주석 정정(이미 초안 방식인데 옛 주석만 남아 있었다). 검증: tsc --noEmit 통과, pytest 389 passed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,7 @@ import type { StandardCrossSectionSpec } from "@util/common_util_cross_design";
|
||||
import { previewCrossDesigns } from "./B06_Section_Api_Fetch";
|
||||
import type { CrossSection, SectionDetailResponse } from "./B06_Section_Api_Fetch";
|
||||
import { readRockBoundarySession } from "./B06_Section_UI_Page_Persist";
|
||||
import { crossDesignChoices } from "./B06_Section_Cross_Design_Session";
|
||||
import {
|
||||
effectiveStandardCross,
|
||||
readRockBoundaryDefault,
|
||||
@@ -153,6 +154,10 @@ function refreshLocally(input: CrossRefreshInput): number[] | null {
|
||||
|
||||
const rockOffsets = readRockOffsets(projectId, input.routeId);
|
||||
const rockDefault = readRockBoundaryDefault(projectId);
|
||||
// 카드 버튼 선택은 세션 초안이 정본보다 새것이다 — 새로고침 뒤에도 고른 값이 남는다
|
||||
// (2026-09-06 사용자 확정: 조작은 캐시, 저장은 [저장]·[확정]).
|
||||
const choices = crossDesignChoices(projectId, input.routeId);
|
||||
const choiceAt = (chainageM: number) => choices.get(Math.round(chainageM * 100) / 100);
|
||||
|
||||
const updated: number[] = [];
|
||||
for (const section of detail.cross_sections) {
|
||||
@@ -169,22 +174,32 @@ function refreshLocally(input: CrossRefreshInput): number[] | null {
|
||||
: typeof storedOffset === "number"
|
||||
? storedOffset
|
||||
: rockDefault;
|
||||
const choice = choiceAt(section.chainage_m);
|
||||
let next;
|
||||
try {
|
||||
next = computeCrossDesign(
|
||||
section.samples ?? [],
|
||||
planElevationAt(alignment, section.chainage_m),
|
||||
{
|
||||
groundType: typeof design.ground_type === "string" ? design.ground_type : "ripping_rock",
|
||||
sectionMode: typeof design.section_mode === "string" ? design.section_mode : "left_cut",
|
||||
ditchSide: typeof design.ditch_side === "string" ? design.ditch_side : null,
|
||||
groundType:
|
||||
choice?.ground_type ??
|
||||
(typeof design.ground_type === "string" ? design.ground_type : "ripping_rock"),
|
||||
sectionMode:
|
||||
choice?.section_mode ??
|
||||
(typeof design.section_mode === "string" ? design.section_mode : "left_cut"),
|
||||
ditchSide:
|
||||
choice?.ditch_side ??
|
||||
(typeof design.ditch_side === "string" ? design.ditch_side : null),
|
||||
// 저장분은 측구가 없으면 `ditch_type: null` 이다 — 서버와 같이 기본형으로 되돌린다.
|
||||
ditchType: typeof design.ditch_type === "string" ? design.ditch_type : "standard",
|
||||
paved: Boolean(design.paved),
|
||||
ditchType:
|
||||
choice?.ditch_type ??
|
||||
(typeof design.ditch_type === "string" ? design.ditch_type : "standard"),
|
||||
paved: choice?.paved ?? Boolean(design.paved),
|
||||
standard,
|
||||
rockBoundaryOffsetM,
|
||||
twoStageSlope:
|
||||
design.two_stage_slope === undefined ? true : Boolean(design.two_stage_slope),
|
||||
choice?.two_stage_slope ??
|
||||
(design.two_stage_slope === undefined ? true : Boolean(design.two_stage_slope)),
|
||||
ditchEnabled: typeof design.ditch_enabled === "boolean" ? design.ditch_enabled : null,
|
||||
// 세월교 월류 하강은 계획선 편집으로 바뀌지 않는다 — 저장분 값을 그대로 잇는다.
|
||||
surfaceDropM: typeof design.surface_drop_m === "number" ? design.surface_drop_m : 0,
|
||||
|
||||
Reference in New Issue
Block a user