"signal is aborted without reason" 오류. 프론트 공통 타임아웃이 30초인데 등고선 하강 + 확장 루프가 33초 걸려 계산 도중 abort 됐다. - config_frontend 에 API_ANALYSIS_TIMEOUT_MS(60초) 추가. 공통 30초는 그대로 두고 분석 엔드포인트(primary-region, basins)에만 적용한다. 일반 요청까지 늘리면 장애 시 화면이 오래 멈춘다. - requestJson 에 timeoutMs 인자 추가. AbortError 원문은 원인을 알 수 없으므로 "요청이 N초 안에 끝나지 않았습니다"로 바꿔 던진다. 같이 속도도 줄였다 (33.3s -> 26.2s, 결과 동일) - 하강 방향장은 해석 영역과 무관하다 — 등고선 기하만으로 정해진다. 확장 회차마다 다시 만들 이유가 없어, 격자가 커졌을 때만 새로 만들고 아니면 재사용한다. 해석 영역은 마지막에 마스크로만 씌운다. - 1차 영역 bbox 는 영역에 딱 붙어 있어 첫 회차부터 격자를 넓혀야 했다. 시작할 때 사방에 확장폭 2배 여유를 둬 몇 회차는 격자를 안 넓히고 돈다. 검증: 적색 457,404 로 이전과 동일. 확장 3회 닫힘, 방향장 계산 4회 -> 2회. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
123 lines
4.7 KiB
TypeScript
123 lines
4.7 KiB
TypeScript
/* =============================================================================
|
|
* config_frontend.ts
|
|
* 프론트엔드 제어 및 웹 환경 설정 (API 주소, 업로드 제한, 라우트 등)
|
|
*
|
|
* 규칙:
|
|
* - 프론트엔드의 모든 제어 상수는 여기서 관리. 컴포넌트 내 하드코딩 금지.
|
|
* - API 주소, 파일 제한, WebCAD 렌더 옵션 등을 중앙 집중.
|
|
* ========================================================================== */
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* 1. API 통신
|
|
* -------------------------------------------------------------------------- */
|
|
/** 백엔드 API 기본 경로. vite proxy(/api → :8000)를 통해 FastAPI로 전달. */
|
|
export const API_BASE_URL = "/api";
|
|
|
|
/** API 요청 타임아웃 (ms) */
|
|
export const API_TIMEOUT_MS = 30_000;
|
|
|
|
/** 격자 해석처럼 수십 초가 걸리는 분석 요청용 타임아웃 (ms).
|
|
* 일반 요청에 이 값을 쓰면 장애 시 화면이 오래 멈추므로 분석 엔드포인트에만 쓴다. */
|
|
export const API_ANALYSIS_TIMEOUT_MS = 60_000;
|
|
|
|
/** B03~B09 워크플로우에서 사용할 현재 프로젝트 UUID 저장 키 */
|
|
export const CURRENT_PROJECT_ID_KEY = "frd_current_project_id";
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* 2. 파일 업로드 제한 (B03_FileInput)
|
|
* -------------------------------------------------------------------------- */
|
|
/** 단일 파일 최대 크기 (MB) */
|
|
export const UPLOAD_MAX_MB = 30 * 1024;
|
|
|
|
/** 한 요청에서 선택 가능한 최대 파일 수 */
|
|
export const UPLOAD_MAX_FILES = 5;
|
|
|
|
/** 청크 업로드 단위 (MB) */
|
|
export const UPLOAD_CHUNK_SIZE_MB = 1024;
|
|
|
|
/** 업로드 진행 UI 갱신 주기 (ms) */
|
|
export const PROGRESS_UPDATE_INTERVAL_MS = 10_000;
|
|
|
|
/** B03 업로드 Service Worker 번들 경로 */
|
|
export const SERVICE_WORKER_PATH = "/assets/B03_FileInput_ServiceWorker.js";
|
|
|
|
/** 허용 확장자 (지형/포인트클라우드/도면) */
|
|
export const UPLOAD_ALLOWED_EXT = [".las", ".laz", ".tif", ".tfw", ".prj", ".dxf"] as const;
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* 3. WebCAD / 3D 렌더링 옵션
|
|
* -------------------------------------------------------------------------- */
|
|
export const RENDER_OPTIONS = {
|
|
/** Three.js 배경색 (theme.css 변수와 별개로 캔버스 clear color) */
|
|
canvasClearColorLight: 0xf6f7fa,
|
|
canvasClearColorDark: 0x16121f,
|
|
pointColor: 0x3e0079,
|
|
gridCenterColor: 0x9491a1,
|
|
gridLineColor: 0xe6e2e3,
|
|
/** 카메라 기본 시야각 */
|
|
cameraFov: 60,
|
|
/** 카메라 near/far */
|
|
cameraNear: 0.1,
|
|
cameraFar: 100_000,
|
|
/** 안티앨리어싱 사용 여부 */
|
|
antialias: true,
|
|
/** 픽셀 비율 상한 (고DPI 성능 보호) */
|
|
maxPixelRatio: 2,
|
|
} as const;
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* 4. 라우트 상수 (해시 기반 SPA 라우팅)
|
|
* 각 페이지 폴더명과 1:1 매핑.
|
|
* -------------------------------------------------------------------------- */
|
|
export const ROUTES = {
|
|
// 로그인 전
|
|
A01_HOME: "a01-home",
|
|
A02_PROG_DETAIL: "a02-prog-detail",
|
|
A03_COMP_DETAIL: "a03-comp-detail",
|
|
A04_NEWS_HISTORY: "a04-news-history",
|
|
A05_EDU_DETAIL: "a05-edu-detail",
|
|
A06_LOGIN: "a06-login",
|
|
A07_REGISTER: "a07-register",
|
|
A08_SUPPORT: "a08-support",
|
|
A09_SECURITY: "a09-security",
|
|
// 로그인 후
|
|
B01_ACCOUNT: "b01-account",
|
|
B02_PROJ_REGISTER: "b02-proj-register",
|
|
B03_FILE_INPUT: "b03-file-input",
|
|
B04_WF1_SURFACE: "b04-wf1-surface",
|
|
B05_WF2_ROUTE: "b05-wf2-route",
|
|
B06_WF3_PROFILE_CROSS: "b06-wf3-profile-cross",
|
|
B07_WF4_DESIGN_DETAIL: "b07-wf4-design-detail",
|
|
B08_WF5_QUANTITY: "b08-wf5-quantity",
|
|
B09_WF6_ESTIMATION: "b09-wf6-estimation",
|
|
B10_PAYMENT: "b10-payment",
|
|
B11_STATUS: "b11-status",
|
|
} as const;
|
|
|
|
export type RouteKey = keyof typeof ROUTES;
|
|
export type RoutePath = (typeof ROUTES)[RouteKey];
|
|
|
|
/** 기본 진입 라우트 */
|
|
export const DEFAULT_ROUTE: RoutePath = ROUTES.A01_HOME;
|
|
|
|
/** 로그인이 필요한 라우트 (인증 가드용) */
|
|
export const PROTECTED_ROUTES: readonly RoutePath[] = [
|
|
ROUTES.B01_ACCOUNT,
|
|
ROUTES.B02_PROJ_REGISTER,
|
|
ROUTES.B03_FILE_INPUT,
|
|
ROUTES.B04_WF1_SURFACE,
|
|
ROUTES.B05_WF2_ROUTE,
|
|
ROUTES.B06_WF3_PROFILE_CROSS,
|
|
ROUTES.B07_WF4_DESIGN_DETAIL,
|
|
ROUTES.B08_WF5_QUANTITY,
|
|
ROUTES.B09_WF6_ESTIMATION,
|
|
ROUTES.B10_PAYMENT,
|
|
ROUTES.B11_STATUS,
|
|
];
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* 5. 테마 / 언어 저장 키
|
|
* -------------------------------------------------------------------------- */
|
|
export const THEME_STORAGE_KEY = "frd_theme";
|
|
export const LANG_STORAGE_KEY = "frd_lang";
|