- 공통 제약 기준값 확정(9-29 사용자 결정) — 후보 표 임시값 그대로 기본값, 화면에서 프로젝트마다 바꿀 수 있음 - 로직 단추 옆 제약 네 칸(비우면 placeholder 로 기본값) · 채운 칸만 POST /route/initial 몸통 criteria 로 실어 보냄 - [확인]의 initial.criteria 에도 실어 성공하면 initial_choice.json 에 겹친 칸만 남김(빈 칸은 기본값이라 안 담김) - 다시 열 때 current_initial.criteria 로 그 칸만 복원 · 캐시가 서버 갈래·비중·제약과 다르면 버림(sameBase) - 서버: generate_initial_route/_SearchGrid 가 stream_offset_m·grade_smooth_m 겹침을 받아 탐색·비교값에 반영 - 응답 criteria.pending 은 이제 늘 빈 목록 — 화면의 「후보 · 사용자 확정 대기」 글 삭제 시험: test_route_initial(+2) · test_b05_routeedit_initial(criteria 겹침·확정 표시 삭제) · test_b05_routeedit_initial_roundtrip(+1, 사본에서 계류 이격 30m 겹침 왕복) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015sCeZz8z8YnbovsKgn7HK7
65 lines
2.6 KiB
TypeScript
65 lines
2.6 KiB
TypeScript
/* =============================================================================
|
|
* B05_Profile_Api_RouteInitial.ts
|
|
* 초기노선 갈래 요청(계획서 20) — 로직 하나를 골라 서버가 새 계획노선 노드를 낸다.
|
|
*
|
|
* POST /projects/{id}/route/initial { mode, weights?, criteria? } → 노드 · 비교값 · 공통 제약 기준값
|
|
*
|
|
* 계산 자리는 **서버 단독**(CLAUDE.md 5장 ③) — 화면은 부르고, 받은 노드를 편집 캐시에 싣고,
|
|
* 받은 비교값·기준값을 보이기만 한다. 모양은 계획서 20 「API」 줄(서버 `initial_route`) —
|
|
* 답을 펴는 자리는 `normalizeRouteInitial`(`_RouteEdit_Initial_Model`) 한 곳이다.
|
|
* ========================================================================== */
|
|
|
|
import { requestJson } from "./B05_Profile_Api_Replan";
|
|
|
|
/** 갈래 셈 대기 상한 — 노선 여러 벌을 셈해 견주므로 넉넉히 잡는다. */
|
|
const INITIAL_TIMEOUT_MS = 5 * 60 * 1000;
|
|
|
|
/** 로직 이름 — 서버와 같은 낱말을 쓴다. `follow` 는 예상노선 추종(처음 초기값). */
|
|
export type RouteInitialLogic = "follow" | "earthwork" | "gentle" | "weighted";
|
|
|
|
/** 비중 계산의 세 비중(%) — 합 100. */
|
|
export interface RouteInitialWeights {
|
|
expected: number;
|
|
earthwork: number;
|
|
grade: number;
|
|
}
|
|
|
|
/** 공통 제약 겹침 값 — 화면 네 칸(계획서 20 확정). 비우면 서버가 프로젝트 기본값을 쓴다.
|
|
* 이름은 서버 몸통과 그대로(snake_case) — 변환 없이 그대로 실어 보낸다. */
|
|
export interface RouteInitialCriteria {
|
|
max_grade_pct?: number;
|
|
min_radius_m?: number;
|
|
stream_offset_m?: number;
|
|
grade_smooth_m?: number;
|
|
}
|
|
|
|
export interface RouteInitialRequest {
|
|
mode: RouteInitialLogic;
|
|
weights?: RouteInitialWeights;
|
|
criteria?: RouteInitialCriteria;
|
|
}
|
|
|
|
/** 서버 길이 아직 없다(404·405) — 화면은 이 글로 알린다. */
|
|
export const ROUTE_INITIAL_MISSING =
|
|
"초기노선 갈래 서버 길이 아직 없습니다(계획서 20 · sub3 대기).";
|
|
|
|
/** 로직 하나로 초기노선을 묻는다. 답의 모양은 `normalizeRouteInitial` 이 편다. */
|
|
export async function fetchRouteInitial(
|
|
projectId: string,
|
|
request: RouteInitialRequest,
|
|
): Promise<unknown> {
|
|
try {
|
|
return await requestJson<unknown>(
|
|
`/projects/${projectId}/route/initial`,
|
|
{ method: "POST", body: JSON.stringify(request) },
|
|
INITIAL_TIMEOUT_MS,
|
|
);
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : "";
|
|
if (/HTTP 40[45]|Not Found|Method Not Allowed/.test(message)) {
|
|
throw new Error(ROUTE_INITIAL_MISSING);
|
|
}
|
|
throw error;
|
|
}
|
|
}
|