fix(B06): 유토곡선 영역 누락 — 재계산 결과와 계획선 정본이 어긋나던 것
두 곳이 같은 뿌리였음. 브라우저 재계산은 **편집이 반영된 계획고**로 횡단 설계를 만드는데 `design_profiles` 는 저장분 그대로라 두 값의 기준이 갈렸음. 1. 재계산 창구가 방금 푼 계획선을 **공유 캐시에도 얹도록** 함 (`detail.longitudinal.design_profiles`). 이게 없으면 낡음 판정이 영원히 참이 되어 B06 유토곡선이 통째로 빈 채로 남았음(사용자 보고). `profile_alignment`(base_pvi)는 건드리지 않음 — 편집 델타의 기준선이라 편집분을 구워 넣으면 이중 적용됨. 2. B06 진입 정합이 **미저장 세션 편집을 못 보고 건너뛰던** 것. 서버에서 갓 받은 저장분 끼리는 늘 일치해 「낡지 않음」이 되는데, B05가 세션에 남긴 편집은 그 안에 없음. 세션 초안이 있으면 판정을 건너뛰고 무조건 맞추도록 함 — 재계산은 브라우저 안에서 끝나 값이 쌈. 화면 검증(5174, 같은 시점 비교): 수정 전 — B05 절토 4,774.1㎥ / 성토 16,715.5㎥, B06 절토 4,515.0㎥ / 성토 14,857.5㎥ 수정 후 — 양쪽 모두 절토 4,774.1㎥ / 성토 16,690.7㎥ (일치) B06 유토곡선 영역도 곡선이 다시 그려짐(문구 없음). 전체 테스트 183건 통과, `tsc --noEmit` 통과. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -39,7 +39,7 @@ import {
|
||||
planElevationAt,
|
||||
toAlignmentBase,
|
||||
} from "../B05_Profile/B05_Profile_UI_Profile_Alignment";
|
||||
import { readAlignment } from "../B05_Profile/B05_Profile_UI_Profile_Data";
|
||||
import { readAlignment, toDesignProfile } from "../B05_Profile/B05_Profile_UI_Profile_Data";
|
||||
|
||||
/** 계획선 편집 델타 — B05 `AlignmentEdits`와 저장분 `profile_alignment.edits`가 같은 모양이다. */
|
||||
export interface CrossRefreshEdits {
|
||||
@@ -118,6 +118,15 @@ function refreshLocally(input: CrossRefreshInput): number[] | null {
|
||||
station_offsets: edits.station_offsets ?? {},
|
||||
curve_radii: edits.curve_radii ?? {},
|
||||
});
|
||||
// 방금 푼 계획선을 **공유 캐시에도 얹는다**. 여기서 만드는 횡단 설계는 편집이 반영된
|
||||
// 계획고 기준인데 `design_profiles` 만 저장분으로 남으면 두 값의 기준이 어긋나, 낡음
|
||||
// 판정이 영원히 참이 되어 유토곡선이 빈 채로 남는다(2026-09-03 사용자 보고: B05 편집 중
|
||||
// 문구만 뜸 → B06 유토곡선 영역 누락). `profile_alignment`(base_pvi)는 **건드리지 않는다**
|
||||
// — 편집 델타의 기준선이라 편집분을 구워 넣으면 다음 편집에서 이중 적용된다.
|
||||
detail.longitudinal.design_profiles = [
|
||||
toDesignProfile(alignment, detail.longitudinal.design_profiles?.[0]),
|
||||
];
|
||||
|
||||
const rockOffsets = readRockBoundarySession(projectId, input.routeId) ?? {};
|
||||
const rockDefault = readRockBoundaryDefault(projectId);
|
||||
|
||||
|
||||
@@ -289,9 +289,15 @@ export async function renderB06ProfileCross(root: HTMLElement): Promise<void> {
|
||||
*/
|
||||
async function reconcileStaleDesigns(): Promise<void> {
|
||||
if (!sectionDetail || !projectId || currentRouteId === null) return;
|
||||
const draft = readAlignmentDraft(currentRouteId);
|
||||
// 낡음 판정은 B05와 **같은 규칙** 하나뿐이다(공용 판정 — 계획고 어긋남 +
|
||||
// 옛 암 2단계 필드 누락). 조건이 갈리면 같은 데이터가 두 화면에서 다른 값이 된다.
|
||||
if (!hasStaleDesigns(sectionDetail)) return;
|
||||
//
|
||||
// 다만 **미저장 세션 편집이 있으면 판정을 건너뛰고 무조건 맞춘다**. 서버에서 갓 받은
|
||||
// 저장분끼리는 늘 일치해 「낡지 않음」으로 나오는데, B05가 세션에 남긴 편집은 그 안에
|
||||
// 없어 B06이 재계산을 통째로 건너뛰었다 — 같은 시점에 B05 절토 4,774.1㎥ ↔ B06
|
||||
// 4,515.0㎥ 로 갈렸다(2026-09-03 실측). 재계산은 브라우저 안에서 끝나 값싸다.
|
||||
if (!draft && !hasStaleDesigns(sectionDetail)) return;
|
||||
// 진입 정합은 화면을 잠그지 않는다 — 카드가 도착하는 대로 조용히 갱신된다
|
||||
// (CLAUDE.md 5장).
|
||||
try {
|
||||
@@ -303,7 +309,7 @@ export async function renderB06ProfileCross(root: HTMLElement): Promise<void> {
|
||||
};
|
||||
}
|
||||
| undefined;
|
||||
const edits = readAlignmentDraft(currentRouteId) ?? {
|
||||
const edits = draft ?? {
|
||||
station_offsets: alignment?.edits?.station_offsets ?? {},
|
||||
curve_radii: alignment?.edits?.curve_radii ?? {},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user