# 기능: StationBar 완전 폴더-구동화 (하드코딩/Mock 제거)
## 목표
StationBar(영상 하단 측점 바)가 표시하는 **모든 데이터를 선택한 폴더의 파일에서** 가져오게 한다. 코드에 노선 데이터를 하드코딩하지 않는다. 폴더 CSV에 없는 정보(노선명·방향·시종점 역명·구조물)는 폴더 내 보조 파일 `.route.json`(없으면 `route.json`)에서 읽는다.
## 사용자 보고 / 현상
- 빈 화면에서도 mock 노선("신탄진"~"대전", `158k700`)이 보였음 → StationBar 폴더 로드 전 숨김으로 1차 처리 완료.
- 잔여: 폴더 로드 후에도 터미널명·이정(mileage) 배지가 **mock**(ROUTE_LEGS 픽셀 앵커, Timeline 하드코딩)에서 나옴.
## 현재 소스 (감사 결과 요약)
| 표시 요소 | 현재 소스 | 분류 |
|----------|----------|------|
| 트랙 px 경계/스케일/transform | mocks/route.ts | LAYOUT(유지) |
| 방향 구간색·이정 라벨(kmLabels) | geoStore frames+stations 계산 | 이미 폴더-구동 |
| 커서 이정 배지 텍스트 | `formatMileage(mileageAtPx(cursorPx))` = mock ROUTE_LEGS | ROUTE DATA → 폴더 |
| 터미널명 신탄진/대전 | Timeline.tsx 하드코딩 | ROUTE DATA → route.json |
| 노선명/방향/길이/시간 | mocks/routeInfo.ts (대부분 미사용) | ROUTE DATA → route.json |
| 구조물(교량/터널) | mocks/segments.ts(미사용) / POI category | ROUTE DATA → route.json + POI |
> mocks/{routeInfo,segments,timeline,mileage}.ts 의 다수 export는 현재 **미사용(dead)**. route.ts 의 ROUTE_LEGS만 mileage.ts 경유로 커서 배지에 실사용.
## 보조 파일 `route.json` (이미 생성: samplevideo/하행)회덕-대전조차장.route.json)
```json
{
"routeInfo": { "name","direction","lengthKm","durationSec","startStationName","endStationName" },
"structures": [ { "id","type":"bridge|tunnel","name","startMileage","endMileage" } ]
}
```
- 위치: 영상과 같은 폴더 루트. 파일명 `.route.json` 우선, 없으면 `route.json`. UTF-8.
- 모든 필드 optional. 없으면 폴더 CSV에서 유도(터미널명=첫/끝 측점 title) 또는 미표시.
## 변경 설계 (To-Be)
1. **types/geo.ts**: `RouteMeta`(routeInfo + structures) 추가, `FolderGeoData`·store shape에 `routeMeta: RouteMeta | null`.
2. **utils/geoData.ts**: `parseRouteMeta(files)` — `.route.json`/`route.json` 탐색 → `await file.text()` → `JSON.parse`. `loadFolderGeoData` 반환에 `routeMeta` 추가.
3. **store/geoStore.ts**: `routeMeta` 상태 + `loadFromFolder`에서 set, `clear()`에서 null.
4. **stationbar/StationBar.tsx**:
- 커서 이정 배지: mock `mileageAtPx(cursorPx)` 대신 **폴더 데이터 기반 실제 km**(viewedRef의 km = 드론GPS 최근접 측점, 이미 계산됨) 사용.
- 구조물 마커: `routeMeta.structures`(mileage→최근접 프레임 시간→px)로 생성. (POI category 보조는 유지 가능)
- Timeline에 `startStationName/endStationName` 전달: `routeMeta.routeInfo` 우선, 없으면 첫/끝 측점 title.
5. **stationbar/components/Timeline/Timeline.tsx**: 하드코딩 "신탄진"/"대전" 제거 → props로 수신(없으면 빈 문자열/미표시).
6. **mocks**: 미사용 dead export는 그대로 두되(삭제 안 함), 실사용 ROUTE_LEGS 의존(커서 배지)은 4번으로 제거. LAYOUT 기하 상수는 UI 레이아웃이므로 유지.
## 완료 기준
- `npm run build -w client` 통과(타입 에러 0).
- 폴더 선택 시: 커서 배지 이정·터미널명·구조물이 **route.json + 폴더 CSV**에서 나온다. mock ROUTE_LEGS/하드코딩 신탄진·대전 미사용.
- route.json 없는 폴더: 크래시 없이 측점 title 기반 폴백(터미널명=첫/끝 측점) 또는 미표시.
- 영상명/노선 비의존.
## 토큰 사용 기록
> 추정치(k=1,000). 측정 합계 = subagent 총 토큰.
| 단계 | 에이전트 | 입력(추정) | 출력(추정) | 측정 합계 |
|------|----------|-----------|-----------|----------|
| ①조사 | Explore 감사(StationBar mock 매핑) | ~55k | ~7k | ~80k |
| ①설계 | 본 문서 + route.json 작성 | 오케스트레이터 | — | — |
| ②구현 | DEV (geoData/geoStore/types + StationBar/Timeline) | ~50k | ~5k | 55.5k |
| ③검수 | 오케스트레이터 직접(빌드+grep 검증) | — | — | — |
## 구현 결과 (완료)
- ✅ `route.json` 보조 파일 로딩(`.route.json`→`route.json`), geoStore `routeMeta`.
- ✅ 커서 이정 배지: 폴더 데이터(viewedRef.km, 드론 GPS 최근접 측점) 기반. mock `mileageAtPx`(ROUTE_LEGS) 런타임 의존 제거(주석만 잔존).
- ✅ 터미널명: route.json `routeInfo` → 폴백 첫/끝 측점 title. Timeline 하드코딩 신탄진/대전 제거(props 전환).
- ✅ 구조물: route.json `structures`(mileage→시간→px), 없으면 POI category 폴백.
- ✅ `npm run build -w client` 통과. mock 파일/dead export는 보존(삭제 안 함), LAYOUT 기하 상수 유지.