T27: parity audit and handover
PARITY-AUDIT.md walks every row of the v2.0.1 feature table with the evidence behind each claim, keeping verified, implemented-but-unproven, and gap strictly apart rather than ticking boxes in bulk. Carried the durable docs forward: ARCHITECTURE.md with what changed and why, a README covering status and the parity harness, and the v3 backlog with a header noting the two items whose status changed. The native repo's README now opens with a pointer here and records both bugs the port found. All internal doc links verified. The cutover step is deliberately left undone: the application id stays com.rippr.port so both apps can be installed together, because the real-ride checklist depends on recording the same ride on both at once. That comparison is worth more than finishing tidily. The native repo is marked superseded rather than archived -- it is still the only version that has recorded a real ride. Also corrected an arithmetic slip: 175 tests, not 178. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
107
README.md
107
README.md
@@ -1,17 +1,102 @@
|
||||
# rippr
|
||||
# Rippr
|
||||
|
||||
GPS ride recorder for motorcycles
|
||||
A GPS ride recorder for motorcycles, on **Android and iOS**. Records telemetry into a
|
||||
local SQLite database, renders the traversed path on a map afterwards, and exports to
|
||||
GPX/GeoJSON.
|
||||
|
||||
## Getting Started
|
||||
Built for one specific use: **hit start, put the phone in a pocket, ride, hit stop.**
|
||||
Most of the design follows from that.
|
||||
|
||||
This project is a starting point for a Flutter application.
|
||||
This is a Flutter port of the native Android app in `~/dojo/rippr` (v1 → v2.0.1). The port
|
||||
is feature-complete; see [docs/port/PARITY-AUDIT.md](docs/port/PARITY-AUDIT.md) for
|
||||
exactly what is verified and what is not.
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
```
|
||||
Flutter 3.47 · Dart 3.13 Android minSdk 26 · iOS 12+
|
||||
~4,600 lines Dart 175 tests (171 unit/widget, 4 integration)
|
||||
```
|
||||
|
||||
- [Learn Flutter](https://docs.flutter.dev/get-started/learn-flutter)
|
||||
- [Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||
- [Flutter learning resources](https://docs.flutter.dev/reference/learning-resources)
|
||||
## Status
|
||||
|
||||
For help getting started with Flutter development, view the
|
||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
||||
| Feature | Status |
|
||||
|---|---|
|
||||
| GPS recording, foreground on Android / background mode on iOS | Implemented; **not yet ridden** |
|
||||
| Trips with pause / resume / stop / discard | Working, 50 tests |
|
||||
| Live speed + elapsed clock | Working |
|
||||
| Path on OpenStreetMap, per-segment, speed-coloured | Working; colouring unverifiable without a real ride |
|
||||
| Ride statistics + charts | Working; bit-identical to the Kotlin original |
|
||||
| Rename / delete / merge rides | Working |
|
||||
| GPX + GeoJSON export | Working; byte-identical to the Kotlin original |
|
||||
| Upload to a REST endpoint | Implemented, **no UI** (as in the native app) |
|
||||
| Notification actions (Pause/Resume in the shade) | **Absent** — the one capability lost |
|
||||
| Live map while recording · group ride | Deferred to v3 |
|
||||
|
||||
> **The port has never recorded a real ride.** No simulator produces velocity, so max
|
||||
> speed, moving time, speed colouring, elevation against real GPS error, battery, and iOS
|
||||
> stationary suspension are all unverified. That is
|
||||
> [docs/port/REAL-RIDE-CHECKLIST.md](docs/port/REAL-RIDE-CHECKLIST.md), and it is the next
|
||||
> thing that should happen.
|
||||
|
||||
## Quick start
|
||||
|
||||
Requires **JDK 17–21** for Android (AGP rejects 25) and Xcode for iOS.
|
||||
|
||||
```bash
|
||||
flutter pub get
|
||||
dart run build_runner build # Drift codegen
|
||||
flutter analyze && flutter test
|
||||
flutter test integration_test -d <device-id>
|
||||
flutter run
|
||||
```
|
||||
|
||||
**Watch the disk.** A full dual-platform build cycle costs roughly 10 GB, and the Android
|
||||
emulator needs 7.4 GB free just to boot. Run `flutter clean` before booting it.
|
||||
|
||||
## Cross-language parity
|
||||
|
||||
The strongest guarantee in this repo. It compiles the **real Kotlin sources** from the
|
||||
native app and diffs them against the Dart port across twenty fixtures:
|
||||
|
||||
```bash
|
||||
brew install kotlin
|
||||
JAVA_HOME=<jdk-21> ./tool/parity/run.sh
|
||||
```
|
||||
|
||||
Everything matches to the last digit — including the elevation accumulator at
|
||||
`38.959594555022136` and byte-identical GPX/GeoJSON. The single expected difference is
|
||||
speed-derived values, where Kotlin's 32-bit `Float` widens with artefacts Dart's uniform
|
||||
`double` does not reproduce.
|
||||
|
||||
## Documentation
|
||||
|
||||
| Document | Contents |
|
||||
|---|---|
|
||||
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | Why it is built this way, and what changed from the native app |
|
||||
| [docs/port/PLAN.md](docs/port/PLAN.md) | The 28-task migration plan |
|
||||
| [docs/port/PROGRESS.md](docs/port/PROGRESS.md) | What actually happened, including every bug found |
|
||||
| [docs/port/PARITY-AUDIT.md](docs/port/PARITY-AUDIT.md) | Feature-by-feature, with the evidence behind each claim |
|
||||
| [docs/port/REAL-RIDE-CHECKLIST.md](docs/port/REAL-RIDE-CHECKLIST.md) | **The outstanding work** |
|
||||
| [docs/port/RELEASE-IOS.md](docs/port/RELEASE-IOS.md) | App Review readiness |
|
||||
| [docs/PORT_RESEARCH.md](docs/PORT_RESEARCH.md) | The original research this plan was built on |
|
||||
|
||||
The native repo's `docs/v1/`, `docs/v2/` and `docs/v3/BACKLOG.md` remain the record of how
|
||||
the app got here and where it is going.
|
||||
|
||||
## Two bugs this port found in the native app
|
||||
|
||||
**Crash recovery measured the dead time as distance.** `restoreAfterProcessDeath` says it
|
||||
resumes into a new segment; it actually adopts the segment a crash left open, so the
|
||||
authoritative recomputation measures straight through the gap. Reproduced at **111 km** of
|
||||
phantom distance. Fixed here.
|
||||
|
||||
**The elevation regression guard passes on seed luck.** On a shared fixture the algorithm
|
||||
yields ~39 m, which would fail the native test's own 35 m bound. It passes only because
|
||||
`kotlin.random.Random(42)` happens to draw a benign sequence.
|
||||
|
||||
## Before shipping
|
||||
|
||||
- Switch the application id from `com.rippr.port` back to `com.rippr`. The suffix exists
|
||||
so the native app can be installed alongside during the port — **keep it until the real
|
||||
ride comparison is done**.
|
||||
- Replace the default Flutter app icon; the native artwork is in `~/dojo/rippr/design/`.
|
||||
- Build and test a release build. Everything so far has been debug.
|
||||
|
||||
Reference in New Issue
Block a user