Files
rippr/docs/v3/V3-12-crash-reporting.md
Dylan 342a8f8382 Break v3 into 16 tickets
One file per feature, in the v2 shape that worked: goal, context, design,
implementation, acceptance criteria, tests, risks, out of scope -- written before
implementing so the risks are on paper rather than walked into.

Three carry more weight than their size suggests. V3-01 ships the port's first
real migration, and since the destructive fallback is gone, getting addColumn and
a v1-database test right matters more than the feature. V3-08 forces a
routing-engine decision with ongoing cost, so it sits behind a RoutingService
interface mirroring what LocationSource did for GPS. V3-13 is not code at all --
it answers the three questions open since v2, and V3-15 may close unbuilt as a
result, which is a legitimate outcome.

Several tickets record constraints that are easy to lose: no activity picker in
front of Start, because the founding premise is press-and-go with gloves; the
Route-to-Trip foreign key must not cascade, or deleting an old plan deletes the
ride; V3-14 will deliberately break the parity harness by adding GPX <type>, and
that expectation should be updated rather than the check dropped; and V3-16 must
not regress the explicit text colours that exist because of the black-on-black bug.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 10:41:35 -05:00

2.0 KiB

V3-12 — Crash reporting

Phase Quality · Depends on nothing · Size S · Status Not started

Goal

Know when the app dies mid-ride.

Context

There is none. A recorder that crashes during a ride currently leaves no trace beyond logcat, which nobody reads — and the failure mode that matters most (recording stopping silently) is exactly the one the user cannot report usefully.

Becomes important the moment anyone who is not Dylan uses it.

Design

Sentry or Firebase Crashlytics. Sentry is the better fit: it is not tied to Google services, works identically on both platforms, and its free tier is ample here.

A crash reporter in a location app is a privacy surface. Configure it deliberately:

  • No location data in breadcrumbs or context, ever
  • No device id, no ride contents
  • Explicit opt-out in settings, and disclosed in the privacy policy
  • Debug builds report nowhere

Beyond crashes, one custom event is worth having: recording ended unexpectedly — the engine stopping without a user stop. That is the failure the app exists to avoid.

Implementation

  1. Add sentry_flutter, initialised in main() behind a config flag
  2. Scrub: no coordinates, no ids, no trip contents in any payload
  3. Breadcrumbs for lifecycle transitions only
  4. A custom event when a recording ends without a user action
  5. Settings toggle, defaulting off until a privacy policy exists

Acceptance criteria

  • A forced crash appears in Sentry from a release build
  • No coordinate ever appears in a payload — inspect a real one
  • The toggle genuinely disables reporting
  • Debug builds send nothing

Tests

  • The scrubber strips coordinates from a representative payload
  • Reporting disabled means the client is never initialised
  • Manual: force a crash in a release build and check it lands

Risks

Leaking location through breadcrumbs or a stack frame's captured state. Inspect a real payload rather than assuming the scrubber works.

Out of scope

Analytics or usage tracking. Different purpose, different consent.