Scope
디테일 패널을 백엔드 snapshot endpoint(`GET /api/v1/dashboard/bikes/{bikeId}/snapshot`)와 연결해, 마커 클릭 시 차량 + 활성 계약 + 라이더 (+교육 요약) + 활성 보험 + 활성 장비 섹션을 모두 보여준다.
Included:
- `service-ops-api.ts` 에 snapshot 응답 타입 + `getBikeSnapshot(bikeId)` 클라이언트 메소드 + 변환 함수.
- `lib/services/dashboard-bike-snapshot-data.ts` 서버 로더 + mock fallback.
- `app/api/dashboard/bike-snapshot/[bikeId]/route.ts` Next.js route handler.
- `BikeDetailPanel` 확장: 기존 텔레메트리 섹션 + 신규 4 섹션 (라이더 / 계약 / 보험 / 장비). 단일 스크롤 형태, 섹션별 헤더 + 행.
- CSS 토큰만 활용 (palette 일관성 유지).
Excluded:
- 충전소 디테일 패널 (별도 슬라이스).
- 디바이스 설치 이력 / 차량 운영 상태 이력 (백엔드 snapshot 에 포함 안됨).
- 패널 안의 라이더 → /riders/{id} 같은 navigation 링크 (별도 슬라이스).
- 라이더 다중 계약 처리 (백엔드도 단일 활성 계약 가정).
Acceptance criteria
- 마커 클릭 시 디테일 패널이 5섹션을 모두 노출.
- 활성 계약 없으면 라이더/계약/보험 섹션이 `데이터 없음` 안내로 대체.
- 장비 0건이면 `설치된 장비 없음` 안내.
- 라이더 교육 상태 (`완료`/`미완료`/`만료`) + 최근 교육 정보 정확히 표시.
- 백엔드 미구성/세션 없음/fetch 실패 시에도 텔레메트리 섹션 + 안내 메시지.
- `npm run lint` / `npx tsc --noEmit` / `npm run build` 통과.
Trace
Concurrent work gate
Decision: allowed-with-non-overlap
Evidence:
- Open target issues: none.
- Open target PRs: none.
- Active branches: dev, main.
Reason: front-admin-web 만 변경.
Scope
디테일 패널을 백엔드 snapshot endpoint(`GET /api/v1/dashboard/bikes/{bikeId}/snapshot`)와 연결해, 마커 클릭 시 차량 + 활성 계약 + 라이더 (+교육 요약) + 활성 보험 + 활성 장비 섹션을 모두 보여준다.
Included:
Excluded:
Acceptance criteria
Trace
Concurrent work gate
Decision: allowed-with-non-overlap
Evidence:
Reason: front-admin-web 만 변경.