# Rippr v2 — Task Index Trips, path rendering, and export. Full rationale lives in the plan; this directory holds one document per task, each self-contained enough to implement from. ## Why v2 v1 records GPS telemetry reliably — a real ride confirmed the whole pipeline including `speedKmh`. What it lacks is *structure*: `track_points` is one unbounded append-only table with no boundary between rides. "No reset", "no pause", and "no trips" are all the same missing concept. Path data is **already captured** (`latitude`, `longitude`, `altitudeM`, `bearingDeg` at 1–2 Hz). v2 adds rendering, not capture. ## Decisions | Decision | Choice | |---|---| | Map library | osmdroid — Apache-2.0, no API key, no billing | | Trip lifecycle | Manual only — explicit Start/Stop | | Reset | Discard current trip, behind a confirm | | Live map | None. Phone rides in a pocket; the map is a post-ride artifact | | Map visibility | Behind a toggle, trip detail only, never touched by the service | | v1 data | Nuked — v1 was a test, so no migration | | Trip management | Rename, delete, merge | | Group ride view | Deferred to v3+ | ## Tasks | # | Task | Phase | Depends | Status | |---|---|---|---|---| | [T01](01-baseline.md) | Repo + dependency baseline | 0 | — | **Done** | | [T02](02-schema.md) | Schema v2 entities + DAOs | 1 | T01 | **Done** | | [T03](03-repository.md) | Trip repository + reactive state | 1 | T02 | **Done** | | [T04](04-geo.md) | Geo utilities | 2 | T01 | **Done** | | [T05](05-stats.md) | Ride statistics | 2 | T04 | **Done** | | [T06](06-service-lifecycle.md) | Trip lifecycle in the service | 3 | T03 | **Done** | | [T07](07-aggregates.md) | Live aggregate accumulation | 3 | T04, T06 | **Done** | | [T08](08-nav-shell.md) | Navigation shell + ViewModels | 4 | T01 | **Done** | | [T09](09-record-screen.md) | Record screen v2 | 4 | T06, T08 | **Done** | | [T10](10-trips-list.md) | Trips list | 4 | T02, T08 | **Done** | | [T11](11-trip-detail.md) | Trip detail (stats only) | 4 | T05, T08 | **Done** | | [T12](12-trip-management.md) | Rename / delete / merge | 4 | T10, T11 | **Done** | | [T13](13-map-integration.md) | osmdroid integration + toggle | 5 | T11 | **Done** | | [T14](14-path-rendering.md) | Path rendering | 5 | T04, T13 | **Done** | | [T15](15-export-format.md) | GPX + GeoJSON writers | 6 | T04 | **Done** | | [T16](16-export-ui.md) | Export UI | 6 | T15 | **Done** | | [T17](17-uploader.md) | Uploader trip-awareness | 7 | T02 | **Done** | | [T18](18-verification.md) | Verification + remove destructive migration | 7 | all | **Done** (real-ride checklist outstanding) | ## Dependency graph ``` T01 ──┬─► T02 ──► T03 ──► T06 ──► T07 ──┐ │ ├─────────► T10 ──┐ │ │ └─────────► T17 │ │ ├─► T04 ──► T05 ──► T11├─► T12 │ │ └──────────► T14│ │ └─► T08 ──► T09 ───────┘ │ T11 ──► T13 ──► T14 │ T04 ──► T15 ──► T16 ▼ T18 ``` Critical path: **T01 → T02 → T03 → T06 → T07 → T09 → T18**. T04/T05, T08, and T15 are parallelisable early wins requiring no device. Progress log with per-task outcomes and hiccups: [PROGRESS.md](PROGRESS.md). ## Conventions - **Package layout**: `data/`, `geo/`, `stats/`, `export/`, `ui/` under `com.rippr` - **Pure logic stays Android-free** so it is JVM-unit-testable — the pattern `Telemetry.kt` already follows - **Comments explain why, not what**, matching the existing codebase - Each task ends green: `./gradlew assembleDebug testDebugUnitTest lintDebug` ## Standing constraints - **minSdk 26 ⇒ SQLite 3.18 ⇒ no window functions.** Consecutive-point maths cannot be done in SQL; it is accumulated in Kotlin. - **Migrations are now mandatory.** The destructive fallback was removed in T18. Any schema change must ship a `Migration` against `schemas/com.rippr.data.AppDatabase/2.json`. - **Decimation is render-only.** Storage and export always use raw points.