fix(B05): 54-22 H1 · H2 경로 넘기 막음 — 구조물 id 안전 이름 · 지면 필터 · 표현 허용 목록

- H1: 구조물 저장 structure_id 를 안전 이름 규칙(FOLDER_PATTERN 과 한 벌)으로 검사 · 어기면 422
- H1: 복사본 맞춤에서 한 번 더 — 규칙 밖 · base 밖 폴더는 지우기 · 쓰기 건너뜀(못만듦)
- H2: filter_key · method 를 허용 목록(Literal)으로 · 파일 이름 만드는 곳(표고 sampler · 비용면 · 스켈레톤)에서 한 번 더
- 시험: test_54_22_security 26 통과 · 관 간격 시험 가짜 필터 이름을 허용 값으로

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYJJRCfHfdCGNhmXTjQKV7
This commit is contained in:
2026-10-06 12:22:08 +09:00
co-authored by Claude Opus 5.5
parent 976c9b2816
commit c8ca79063c
8 changed files with 158 additions and 11 deletions
+12 -1
View File
@@ -13,11 +13,21 @@ common_util로 옮겼다 — 두 화면의 종단 Z가 갈라지면 세부유역
from collections.abc import Callable
from dataclasses import dataclass
from pathlib import Path
from typing import Protocol
from typing import Literal, Protocol, get_args
import numpy as np
from scipy.interpolate import RegularGridInterpolator
#: 지면 필터 · 지표면 표현 허용 목록 — 파일 이름에 들어감(B04 `_FILTERS` · `MODEL_METHODS`)
SurfaceFilter = Literal["classification", "grid_min_z", "csf", "pmf", "ransac"]
SurfaceMethod = Literal["dtm", "tin", "nurbs", "implicit", "meshfree"]
def check_surface_keys(filter_key: str, method: str = "dtm") -> None:
"""파일 이름 만들기 전 검사 — 허용 목록 밖이면 ValueError(경로 넘기 막음)."""
if filter_key not in get_args(SurfaceFilter) or method not in get_args(SurfaceMethod):
raise ValueError(f"지면 필터 · 표현 이름이 허용 목록 밖: {filter_key!r} · {method!r}")
class SurfaceElevationSampler(Protocol):
"""종·횡단 생성기가 의존하는 최소 표고 조회 인터페이스."""
@@ -129,6 +139,7 @@ def build_surface_sampler(
models_dir: Path | str, source_filter: str, method: str, smooth: bool
) -> SurfaceElevationSampler:
"""1단계 확정 모델을 종·횡단용 일괄 XY 표고 sampler로 연다."""
check_surface_keys(source_filter, method)
models_dir = Path(models_dir)
smooth_suffix = "_smooth" if smooth and method in {"dtm", "tin"} else ""
dtm_smooth = models_dir / f"dtm_{source_filter}_smooth.npz"