단계 게이트 · 로드맵
techspec roadmap.md의 서술형 로드맵을 측정 가능한 단계 게이트(GATE-P0 / P1 / P2)로 형식화한다. 각 게이트는 진입(entry)·종료(exit) DoD를 산출물·측정 기준으로 못박고, 각 마일스톤을 functional 페이지가 소유한 FR-* 요구사항 ID로 연결하며, purpose-scope의 "지금 안 함"(비목표)이 언제·무엇으로 풀리는지 해제 매핑을 고정한다. 핵심 불변식: 제휴(Phase 0)는 하드 게이트 — 미확보 시 Phase 1 착수를 보류한다(R1). 본 페이지가 인용하는 모든 목표 수치는 운영 데이터가 없는 진입 단계의 초기 확정치(설계)이며 운영 베이스라인으로 분기별 조정한다 — 달성치(achieved)는 기재하지 않는다.
1. 로드맵 개요 — 제휴부터 시작하는 단계
로드맵은 코드가 아니라 제휴(Phase 0)부터 시작한다. Research/implications-for-us에서 cold-start가 강하게 검증된 최대 장벽(가설 H3)이기 때문이다 — 제휴 없는 MVP는 시드 데이터가 없어 작동하지 않는다(strategy.md 전략 3). 따라서 단계 순서는 Phase 0(제휴·기반) → Phase 1(MVP) → Phase 2(확장)이며, 각 전이는 앞 게이트의 종료 DoD가 충족될 때만 발생한다.
- Phase 0 제휴·기반 (Pre-build). 사업 전제(제휴)를 확보하고 데이터 품질의 분기점을 미리 깐다. 코드 비중 최소, 계약·데이터 정의 중심.
- Phase 1 MVP. 페인 한 개를 제휴 파트너 1곳에서 확실히 푼다(purpose-scope MVP 범위). 백엔드 코어·수집·실시간·드라이버앱·console 대시보드·룰 ETA·규제 출력 v1·알림.
- Phase 2 확장. 가시성 커버리지·ETA 정확도·테넌트 확장. 텔레매틱스·ML ETA·Leg 모델·멀티테넌트 3PL·물류×금융.
| 단계 | 목표 | 핵심 산출물 | 게이트 | 전이 조건 |
|---|---|---|---|---|
| Phase 0 | 제휴·데이터 기반 | 파트너 1곳, 거점 지오펜스 100~200, 규제 항목 정의, event_code_map 시드, Cloudflare 프로비저닝 |
GATE-P0 | 제휴 합의 + 거점 지오펜스 + 규제 항목 정의 + 시드 완료 |
| Phase 1 | 페인 1개 해결(MVP) | 백엔드 코어·수집·실시간·드라이버앱·console 대시보드·룰 ETA·규제 출력 v1·알림 | GATE-P1 | Tracking Rate ≥ 85% · 荷待ち 리포트 협상 사용 · 규제 출력 수기 대체 · 무료 티어 · STUB 5종 해소 |
| Phase 2 | 가시성·정확도·확장 | 텔레매틱스·ML ETA·Leg 모델·멀티테넌트 3PL·물류×금융 | GATE-P2 | 각 비목표 해제 트리거 충족(레인별 ≥ 3,000 등) |
2. GATE-P0 — 제휴·기반 (진입/종료 DoD)
Phase 0의 게이트는 코드 산출이 아니라 계약·데이터 정의·인프라 프로비저닝으로 측정한다. 각 종료 조건은 산출물과 측정 기준이 명시되어야 한다.
| DoD 항목 | 산출물 | 측정 기준 | 근거 |
|---|---|---|---|
| 제휴 PoC 서명 | 대형 화주(特定第一種荷主, 연 9만 톤 이상) 또는 대형 운송사 1곳과 PoC 합의 문서 | 서명된 PoC 계약 1건 존재(실제 운행 데이터 접근 약정 포함) | strategy.md 전략 3 · R1 · monetization-gtm(제휴 플레이북) |
| 거점 폴리곤 지오펜스 | 주요 DC·납품처 폴리곤(KV 캐시 + D1 멤버십) | 100~200개소 폴리곤 등록, H3 해상도 정책(FR-GEO-H3RES-001) 준수, boundary 셀 비율 <30% | model.md · engine.md |
| 規制 데이터 항목 정의 | 実運送体制管理簿 기재 항목 정의 + 荷待ち 기록 포맷 확정 | 항목 스키마 동결(컬럼 카탈로그). 공식 법정 포맷 확정은 법무 서명 대기 → RR-LEGAL-001 플래그 추정 | delivery.md · regulatory |
event_code_map 대형 운송사 시드 |
대형 운송사 코드 → canonical 이벤트 매핑 시드 | ヤマト・佐川・NX・セイノー 4사 raw_code 매핑 시드 적재, canonical enum(DM-EVT-ENUM-001) 정합, 정밀도(DM-EVT-PREC-001) 동결 | model.md |
| Cloudflare 리소스 프로비저닝 | D1·KV·R2·Queues·DO·Cron 실제 리소스 생성 + wrangler ID 확정/리네임 | placeholder ID(0000…000a) 전부 실제 ID로 치환, 환경 3종(dev/stg/prod) 분리. 추적: OD-005 · OD-002(가칭→정식명) |
cost-model.md · pipeline-ops |
요구. Phase 1(MVP) 빌드 착수는 위 5개 DoD 항목이 모두 충족된 후에만 승인되어야 한다(MUST). 특히 제휴 PoC 서명은 다른 4개 항목의 충족 여부와 무관하게 하드 차단 조건이다 — 미서명 시 Phase 1을 착수하지 않는다(R1).
수용기준
- Given Phase 1 착수 결재 요청, When 제휴 PoC 서명 문서가 부재, Then 게이트는 FAIL이며 Phase 1 빌드를 시작하지 않는다(다른 산출물 완료와 무관).
- Given 거점 폴리곤 등록 현황, When 등록 개소 수를 집계, Then 100~200 범위 내이고 각 폴리곤이 FR-GEO-H3RES-001 해상도 정책으로 셀 커버되며 boundary 셀 비율 <30%다.
- Given
event_code_map시드, When ヤマト・佐川・NX・セイノー 4사 raw_code를 조회, Then 각 코드가 DM-EVT-ENUM-001 canonical enum으로 해결되고 미매핑이 0이다. - Given wrangler 설정, When 바인딩 ID를 검사, Then placeholder
0000…000a가 하나도 남아 있지 않고 dev/stg/prod 3환경이 분리되어 있다(OD-005). - Given 실運送体制管理簿 항목 정의, When 공식 법정 포맷 확정 여부를 확인, Then 법무 서명이 없으면 RR-LEGAL-001 플래그가 활성 상태로 산출물에 표기된다.
3. GATE-P1 — MVP (마일스톤 + exit 기준)
Phase 1은 페인 한 개를 제휴 파트너 1곳에서 확실히 푼다는 단일 목표를 갖는다(purpose-scope MVP 범위). 각 마일스톤을 functional 페이지가 소유한 FR-* ID로 연결한다.
SHIPPER_VIEWER 읽기전용 + CustomerTrack로 커버한다. Flutter는 드라이버 앱 전용(+선택적 최소 화주 모바일 뷰). 실시간 전송 분리: Flutter 단일-shipment 뷰=WebSocket(NFR-PERF-003 p95 ≤ 1.5s), console 플릿 개요=6s 폴링(NFR-PERF-003b: >60s stale, >300s drop). 상세: architecture-baseline · OD-001.
3.1 MVP 마일스톤 → FR 매핑
| 마일스톤 | 산출물 | 연결 FR-* (functional 소유) | as-built 상태 |
|---|---|---|---|
| 백엔드 코어 | API Worker(Hono) — shipment/stop/event, 인증, 멀티테넌시 | FR-AUTH-001 · DM-SCHEMA-001 | 인증·테넌트 격리 DONE · POST /v1/shipments 등록 STUB(500) |
| 수집 파이프라인 | Ingest Worker → Queues → Consumer(정규화·중복제거·지오펜스) | FR-ACQ-API-001 · FR-INGEST-001 · DM-DEDUP-001 · FR-GEO-DEBOUNCE-001 | ingest→DO→queue→R2 + 지오펜스 히스테리시스 엔진 DONE |
| 실시간 | Shipment Durable Object + WebSocket fan-out | FR-DLV-WS-001 · NFR-PERF-003 | ShipmentDO DONE · Flutter ShipmentWsClient STUB |
| 드라이버 앱 | Flutter — 案件 수신·자동 공유·지오펜스 자동 이벤트·완료 보고·증빙 사진(R2) | FR-ACQ-GPS-001 · FR-ACQ-AUTOSHARE-001 · FR-ACQ-CONSENT-001 · FR-ACQ-OFFLINE-001 | scaffold stub만(TransistorLocationService 100% 주석, token 하드코딩) STUB/ABSENT — 계약 동결 대기 |
| console 대시보드 | 실시간 플릿 맵·shipments·荷待ち/규제 리포트(Astro+Svelte, ADR-0010) | FR-DLV-TRACK-001(GET /v1/shipments/tracking 6s 폴링) · NFR-PERF-003b |
FleetMap/ShipmentsTable/Reports DONE(동작) · 거버닝 ADR/README 없음→ADR-0010 |
| 룰 기반 ETA | 거리+구간 평균 속도, "추정치"(eta_is_estimate=1) 표기 | FR-ENG-ETA-001(80/30/50 km/h, dwell 30min) | handleEtaBatch ack-only STUB(룰 미구현) · KV CONFIG 시드됐으나 런타임 미read(OD-007) |
| 규제 출력 v1 | 荷待ち 기록 CSV/PDF(R2 + Cron). 実運送体制管理簿는 항목 정의부터 | FR-RPT-NIMACHI-001 · FR-RPT-RANGE-001 · FR-ENG-EXC-002(荷待ち >120min) | 荷待ち/NIMACHI CSV end-to-end DONE · GET /v1/reports/jitsuunso STUB(501) |
| 알림 | 예외(지연·荷待ち 초과·추적 손실) → LINE/이메일/웹훅 | FR-DLV-NOTIFY-001 · FR-DLV-WH-001 · FR-ENG-EXC-001 | handleNotifyBatch ack-only STUB(구독 테이블·HMAC POST·전달상태 없음) |
3.2 MVP exit 기준
purpose-scope MVP 성공 기준을 측정 가능한 게이트로 확정한다. 추가로, MVP 코어 흐름을 막는 5개 STUB의 해소를 exit에 포함한다(껍데기만 있는 기능은 "운행 1개를 확실히 푼다"를 증명할 수 없다).
| exit 조건 | 측정 기준 설계 | 연결 ID |
|---|---|---|
| Tracking Rate floor | 제휴 파트너 실제 운행에서 추적 커버리지 ≥ 85%(MVP exit floor; 정상상태 지향 ≥ 92%). 100%는 비현실(스마트폰 GPS 한계)로 정직 노출 | KPI-TRACK-001 / SLO S4 |
| 荷待ち 리포트 협상 사용 | 실제 거점 데이터로 생성된 荷待ち 리포트가 화주의 개선 협상에 사용됨(파트너 확인서/사용 증빙 1건) | FR-RPT-NIMACHI-001 · KPI-DWELL-001 |
| 규제 출력 수기 대체 | 規制 출력 v1(荷待ち CSV/PDF)이 수기 작성을 대체. 공식 포맷은 RR-LEGAL-001 법무 서명 후 확정 | FR-RPT-RANGE-001 · regulatory |
| 무료 티어 유지 | 인프라 비용이 무료 티어 내(추정: Workers ~10만 req/일, D1 읽기 500만행·쓰기 10만행·5GB, KV 읽기 10만/일, R2 10GB·egress 0). 비용 가드레일(NFR-COST-001) 알람 미발화 | NFR-COST-001 · cost-model.md |
| STUB 해소 #1 — 웹훅 전달 | handleNotifyBatch ack-only → 실제 전달: 구독 테이블(0004 마이그레이션)·endpoint_secret·HMAC-SHA256 POST·재시도 래더 [0,60,300,1800,7200,21600,43200,86400]s·전달상태 |
FR-DLV-WH-001 · NFR-RELY-001(≥ 99.0%/28일) |
| STUB 해소 #2 — ETA | handleEtaBatch ack-only → 룰 ETA 구현(80/30/50 km/h, dwell 30min, KV CONFIG 런타임 read) |
FR-ENG-ETA-001 · OD-007 |
| STUB 해소 #3 — tracking-loss sweep | cron sweepActive 빈 구현 → 마지막 유효 핑 후 45min → TRACKING_LOST(Cron */5 sweep). 오경보율 <5% |
FR-ENG-EXC-003 |
| STUB 해소 #4 — rate limit | 레이트리밋 부재(에러맵엔 RATE_LIMITED/429 존재) → 적용: API Key당 600 req/min 지속·버스트 100/10s·리포트 10 req/min·인제스트 1200 req/min·429+Retry-After | security-privacy / NFR-SEC-RL-001 |
| STUB 해소 #5 — consent gate | consentGate()가 lib에 존재하나 ingest 경로 미호출(APPI 갭) → ingest 경로에서 동의 검증 호출 배선 |
FR-ACQ-CONSENT-001 · SR-APPI-CONSENT-001 |
요구. Phase 2 착수는 위 exit 조건 4종(Tracking Rate floor·荷待ち 협상 사용·규제 수기 대체·무료 티어)과 STUB 해소 5종이 모두 충족된 후에만 승인되어야 한다(MUST). exit 수치는 초기 확정 목표(설계)이며 운영 베이스라인으로 조정한다 — 달성치로 사전 기재하지 않는다.
수용기준
- Given 제휴 파트너 28일 운행 데이터, When Tracking Rate를
received_pings/expected_pings로 집계, Then ≥ 85%이고 그 값이 숨김 없이 console에 노출된다(KPI-TRACK-001). - Given 거점 운행 데이터, When 荷待ち 리포트(CSV/PDF)를 생성, Then 실제 거점 데이터로 채워지고 화주 개선 협상에 사용되었다는 증빙이 1건 이상 존재한다.
- Given 5종 STUB, When 해당 경로에 통합 테스트를 실행, Then webhook 실제 전달(2xx + HMAC 서명 검증)·룰 ETA 산출(eta_is_estimate=1)·45min tracking-loss 발화·429 레이트리밋·ingest consentGate 거부가 각각 통과한다.
- Given 28일 운영, When 비용 가드레일을 점검, Then D1 쓰기 <70% 일 예산·R2 <80% 티어로 NFR-COST-001 알람이 발화하지 않는다(무료 티어 유지).
4. GATE-P2 — 확장 (트리거 기반)
Phase 2는 일정이 아니라 데이터·테넌트 트리거로 진입한다("복잡도 적기 구매" 원칙). 각 마일스톤은 명시적 해제 조건을 갖는다.
| 마일스톤 | 산출물 | 해제 트리거 | 근거 |
|---|---|---|---|
| 텔레매틱스 연동 | OEM·通信型デジタコ 벤더 API(source_type=TELEMATICS) |
스마트폰 GPS 연속성 갭(R3)을 보강할 파트너 차량 비중 확보 시 | acquisition.md · ADR-0006 |
| ML ETA 전환 | R2 아카이브 학습 → XGBoost+LSTM, Workers AI 추론 | 레인-클래스별 누적 ≥ 3,000 완료 운행 AND 룰-MAPE > 20% | FR-ENG-ETA-002 · ADR-0007 · KPI-ETA-001(ML 후 ≤ 15%) |
| Leg 다중구간 모델 | 복합운송 구간 지원(3계층 Shipment→Stop→Event → +Leg) | 구간 1~2개를 넘는 복합운송 수요 발생 시(국내 트럭 가정 탈피) | ADR-0005 · DM-SCHEMA-001 |
| 멀티테넌트 3PL | 세분 권한·캐리어 데이터 공유 제어 | 3PL 테넌트 도입 + 캐리어 간 데이터 공유 통제 요구 발생 시 | delivery.md · SR-AUTHZ-001/SR-TENANT-001 |
| 実運送体制管理簿 완성 | 청부 계층 + 실시간 검증 결합(화이트스페이스) | Phase 0 항목 정의 + 법무 포맷 확정(RR-LEGAL-001) 후 | strategy.md · RR-JITSUUNSO-001 |
| 물류 × 금융 탐색 | 운임 결제·정산·팩토링 PoC(위치 = 운행 완료의 객관적 증거) | 위치 데이터의 "운행 증거" 신뢰도가 운임 정산에 쓸 수준으로 검증된 후(monetization-gtm 금융 게이트) | strategy.md · Research/implications-for-us |
요구. Phase 2의 각 마일스톤(텔레매틱스·ML ETA·Leg 모델·멀티테넌트 3PL·実運送体制管理簿 완성·물류×금융)은 일정이 아니라 명시적 해제 트리거가 충족될 때만 착수되어야 한다(MUST). 트리거 미충족 시 해당 마일스톤은 비목표로 유지된다 — "복잡도는 필요할 때만 산다".
수용기준
- Given 레인-클래스별 운행 누적과 룰 ETA 정확도, When ML 전환 게이트를 평가, Then 누적 ≥ 3,000 완료 운행 AND 룰-MAPE > 20%의 AND 조건이 모두 참일 때만 ML 전환을 승인한다(FR-ENG-ETA-002). 한 조건만 참이면 게이트는 FAIL이다.
- Given 동시 활성 DO 카운트, When 스케일 트리거를 점검, Then 활성 DO > 5,000(또는 월 active-wall-time 임계 초과) 시 종료 화물을 D1 60s 폴링으로 분할한다(NFR-SCALE-001).
- Given 텔레매틱스/Leg/3PL/금융 마일스톤, When 각 해제 트리거(GPS 연속성 보강 수요·복합운송 구간 >2·3PL 테넌트 도입·위치=운행 증거 신뢰도 검증)를 확인, Then 해당 트리거가 충족되지 않은 마일스톤은 착수하지 않는다(비목표 유지).
- Given 実運送体制管理簿 완성 착수, When 선행 조건을 확인, Then Phase 0 항목 정의 완료 및 공식 법정 포맷 법무 서명(RR-LEGAL-001 해제)이 모두 완료된 후에만 착수한다.
5. 비목표 해제 매핑
purpose-scope의 "지금 안 함"(비목표)이 언제·무엇으로 풀리는지 고정한다. 모든 해제는 단계 게이트 또는 명시적 트리거에 묶인다 — 일정만으로 자동 해제되지 않는다.
| 비목표 (지금 안 함) | 해제 단계 | 해제 트리거 / 연결 ID |
|---|---|---|
| 자체 ML ETA 모델 | P1 후반~P2 | 레인별 누적 ≥ 3,000 AND 룰-MAPE > 20% — FR-ENG-ETA-002 |
| 복합운송 다중 Leg 모델 | Phase 2 | 구간 >2 복합운송 수요 — ADR-0005 · DM-SCHEMA-001 |
| 텔레매틱스 / 通信型デジタコ | Phase 2 | R3 GPS 연속성 보강 수요 — acquisition.md · ADR-0006 |
| 멀티테넌트 3PL 세분 권한 | Phase 2 | 3PL 테넌트 + 캐리어 데이터 공유 통제 — SR-AUTHZ-001 |
| 물류 × 금융(결제·정산·팩토링) | Phase 2+ | 위치=운행 증거 신뢰도 검증 후 — monetization-gtm 금융 게이트 |
| 자체 IoT 하드웨어 트래커 | Phase 2+ | 특수 화물 한정 검토(스마트폰 우선 ADR-0006 유지) |
6. 단계 간 의존성 — Phase 0이 Phase 1을 unblock
Phase 0 산출물이 Phase 1의 어느 요구사항을 풀어주는지 고정한다. 특히 API/WS 계약 동결이 Flutter app stub의 단일 차단 해소 조건이다.
| Phase 0 산출물 | unblock하는 Phase 1 요구사항 | 왜 차단이었나 (as-built) |
|---|---|---|
API/WS 계약 동결(OpenAPI 단일원 + @loginippon/contract + AsyncAPI) |
Flutter 드라이버 앱 전부 — FR-ACQ-GPS-001·FR-ACQ-AUTOSHARE-001·FR-DLV-WS-001 | app은 "Pre-implementation"; 서버 데이터 의존 기능 전부 계약 동결 대기. ShipmentWsClient stub(auth/reconnect 없음)·AuthController.signIn 상태만 토글(HTTP 없음)·JobsRepository 빈 배열. unblock 산출물이 곧 API/WS 계약(api-contracts IR-API-001/IR-WS-001) |
| 거점 폴리곤 지오펜스 100~200 | 지오펜스 자동 이벤트 — FR-GEO-DEBOUNCE-001 · FR-ENG-EXC-002(荷待ち) | 엔진(geofence-engine.ts)은 DONE이나 평가할 폴리곤 데이터가 없으면 자동 도착/이탈·荷待ち 시계가 작동 불가 |
event_code_map 4사 시드 |
이벤트 정규화 — DM-NORM-001 · DM-EVT-ENUM-001 | 매핑 시드 없이는 캐리어 raw_code → canonical 해결 불가(KPI-NORM-001 ≥ 99% 측정 불능) |
| 規制 항목 정의(実運送体制管理簿·荷待ち 포맷) | 규제 출력 v1 — FR-RPT-NIMACHI-001 · FR-RPT-JITSUUNSO-001 | 컬럼 정의 없이는 CSV/PDF 산출 불가. 공식 포맷은 RR-LEGAL-001 법무 서명 후 |
| Cloudflare 리소스 프로비저닝(OD-005) | 전 백엔드·실시간·수집 — placeholder ID(0000…000a) 치환 전엔 배포 불가 |
wrangler 바인딩이 placeholder·미프로비저닝 → dev/stg/prod 어떤 환경도 배포 불능(pipeline-ops 리소스 체크리스트) |
7. 횡단 원칙 (전 단계 적용)
- 제휴가 게이트. Phase 0 제휴 미확보 시 Phase 1 착수 보류 — 하드 불변식(R1). 해자는 소프트웨어가 아니라 네트워크.
- 데이터 정직성. 콜드 스타트 동안 ETA는 "추정치"(eta_is_estimate=1)로 표기하고, Tracking Rate를 숨기지 않는다 — 100%가 비현실임을 정직하게 노출(KPI-TRACK-001). 달성치 날조 금지.
- 복잡도 적기 구매. Kafka·외부 웨어하우스·ML은 트리거가 충족될 때만 도입한다. ML 전환은 ≥ 3,000 AND MAPE > 20%의 AND 조건(FR-ENG-ETA-002)으로 게이트된다. DO 활성 > 5,000 시 종료 화물은 D1 60s 폴링으로 분할(NFR-SCALE-001) — 단계 게이트와 동형의 트리거 사고.
근거·상호참조
- techspec: roadmap.md — Phase 0/1/2 마일스톤·exit·비목표 해제·횡단 원칙(제휴 게이트·데이터 정직성·복잡도 적기 구매)
- techspec: 00-overview/goals-nongoals.md — 목표·비목표·MVP 범위(In/Out)·MVP 성공 기준
- techspec: 06-product/strategy.md — 전략 3(cold-start 제휴 1순위)·두 갈래 제휴 경로(特定第一種荷主/대형 운송사)·리스크 R1~R5·물류×금융 확장
- techspec: 02-data-model/model.md(
event_code_map·청부 계층) · 04-tracking-engine/engine.md(지오펜스·荷待ち·룰 ETA) · 05-delivery-layer/delivery.md(규제 출력·웹훅) · 03-data-acquisition/acquisition.md(텔레매틱스) · cost-model.md(무료 티어) - Research: implications-for-us(H3 cold-start 강검증→제휴 1순위·물류×금융) · japan-market(規制 의무화·960h 상한)
- code: server —
src/lib/geofence-engine.ts/geofence.ts/h3.ts(지오펜스 DONE) ·src/lib/reports.ts(荷待ち CSV DONE) ·src/consumers/queue.ts(handleNotifyBatch/handleEtaBatchack-only STUB) ·src/consumers/cron.ts(sweepActive빈 구현) ·src/routes/shipments.ts(POST /v1/shipments500 stub) ·src/routes/reports.ts(jitsuunso501) ·src/ingest/positions.ts(consentGate 미호출) · wrangler(placeholder ID 미프로비저닝) - code: console(FleetMap 6s 폴링·Reports DONE, ADR-0010) · app(Flutter pre-implementation·
ShipmentWsClientstub·계약 동결 대기) - TRD 내부: functional(FR-* 소유) · data-model(DM-* 소유) · api-contracts(IR-* 계약 동결) · nonfunctional(NFR-* 소유) · north-star-kpi(KPI-* 소유) · strategy-risk(R1) · monetization-gtm(제휴 플레이북·금융 게이트) · slo-catalog · acceptance-traceability · regulatory(RR-LEGAL-001) · security-privacy · architecture-baseline(ADR-0010) · pipeline-ops · open-decisions-rfc(OD-001/005/007)