Files
samplez/rippr-src/docs/v2/18-verification.md
uhryniuk 280fd7f988 Add Rippr source snapshot and full-history bundle
Two copies for two jobs. rippr-src/ is a browsable git archive export of
the tracked tree at 2f76983 - no build outputs, no local.properties, no
nested .git - which is convenient to read in gitea but carries no history
and will drift.

rippr-full-history.bundle is the real backup: all 18 commits, verified as
"records a complete history" and test-cloned before committing. This
matters because ~/dojo/rippr has no git remote and otherwise exists only
on one machine.

rippr-src/SNAPSHOT.md explains the difference and how to restore.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 08:30:25 -05:00

119 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# T18 — End-to-end verification + remove destructive migration
**Phase** 7 · **Depends on** all · **Status** Done (automated); real-ride checklist outstanding
## Goal
Prove v2 works end to end, and close the one deliberate time bomb left in the schema.
Done when the full suite is green, a synthetic paused ride verifies correctly on the
emulator, the real-ride checklist passes, and `fallbackToDestructiveMigration()` is gone.
## Context
v1's verification harness is proven and should be reused rather than reinvented — it
caught real problems and produced the coordinate-exactness check that confirmed the
pipeline end to end.
Two lessons from that round, both of which cost time:
- **Wait for the UI, do not sleep.** A cold start took 8.7 s; a 4 s sleep produced a
silently-missed tap and a false "the service didn't start" conclusion. Poll
`uiautomator dump` for the expected text.
- **The emulator cannot produce velocity.** `adb emu geo fix` teleports, so
`Location.speed` is always 0 and every recorded `speedKmh` is 0.00. Anything
speed-derived — max speed, moving time, average moving speed, speed colouring — is
**unverifiable on the emulator** and must be checked on a real ride.
## The destructive migration — remove it
`AppDatabase` carries `fallbackToDestructiveMigration()` from T02. It was correct: v1 data
was a test and Dylan explicitly authorised nuking it.
It is **not** correct once real rides are being kept. Left in place, the next schema
change silently deletes every ride with no warning and no recovery. This is the single
most dangerous line in the v2 codebase.
Removal:
1. Delete the `fallbackToDestructiveMigration()` call.
2. Confirm `app/schemas/com.rippr.data.AppDatabase/2.json` is committed — it is the baseline
every future migration is written against.
3. Add a short note to `docs/v2/README.md` recording that migrations are now mandatory.
4. Verify a fresh install still creates the database correctly.
## Verification
### Automated
```bash
./gradlew assembleDebug testDebugUnitTest lintDebug connectedDebugAndroidTest
```
Expected coverage by this point: geo maths, statistics with the noisy-altitude regression
case, GPX/GeoJSON structure and escaping, uploader behaviour, DAO relations and CASCADE,
trip lifecycle transitions, merge correctness.
### Emulator end-to-end
```bash
emulator -avd Medium_Phone_API_35 -no-window -no-audio -no-boot-anim -gpu swiftshader_indirect
adb install -r app/build/outputs/apk/debug/app-debug.apk
for p in ACCESS_FINE_LOCATION ACCESS_COARSE_LOCATION POST_NOTIFICATIONS; do
adb shell pm grant com.rippr android.permission.$p
done
```
Drive the UI (the service is `exported=false`, so `am start-foreground-service` is
correctly refused). Feed a ride, pause partway, feed more, stop. Then:
```bash
adb exec-out run-as com.rippr cat databases/rippr_db > /tmp/check.db # plus -wal
```
Assert: one Trip; two Segments; contiguous point ids; distance non-zero; no point in a
closed segment; the rendered path shows a visible gap at the pause.
### Real-ride checklist
The only way to validate anything speed-derived:
1. Start, pocket the phone, ride, stop — matching actual usage
2. Max speed plausible (this worked in v1 and must not regress)
3. Distance plausible against the bike's odometer
4. Moving time excludes stops
5. Elevation gain plausible — **not** thousands of metres on flat ground, the classic
hysteresis failure
6. Path renders with no straight-line artefact across pauses
7. Speed colouring visibly varies
8. GPX export opens correctly in Google Earth or Strava
9. Battery drain over a multi-hour ride acceptable
10. Pause/resume survives a screen-off stretch
## Outstanding work inherited from earlier tasks
- **Compose UI tests for all four screens (T08–T11).** None exist. Verification there was
manual screenshots plus the unit/instrumented suites. Needed: navigation
record→trips→detail→back, rotation state retention, empty state, `NotFound`, and chart
degradation below two points.
## Acceptance criteria
- [x] `fallbackToDestructiveMigration()` removed
- [x] `2.json` committed as the migration baseline
- [x] Full gradle verification green
- [x] Emulator paused-ride assertions pass
- [ ] Real-ride checklist complete
- [ ] Compose UI tests written for T08–T11 screens
- [ ] Debug APK copied to `~/dojo/samplez` and committed (matching the v1 handoff)
## Risks / gotchas
- **Forgetting the migration removal** is the failure this task exists to prevent. Do it
first, not last.
- **Do not claim speed-derived features verified from emulator runs.** State plainly what
the emulator cannot test.
- **Elevation gain is the most likely silent bug.** Flat ground must read near zero.
## Out of scope
v3+ work: live map, group ride view, settings UI for the upload endpoint.