Files
samplez/rippr-flutter-src/docs/LAUNCH.md
uhryniuk 4c634354bd Refresh the Flutter snapshot: v3 tickets V3-04 through V3-16, plus a fresh installable APK
V3-04 through V3-07, V3-10, V3-16 shipped complete; V3-11/V3-12/V3-14 shipped code-complete pending device/account verification; V3-08/V3-09 deferred behind a new V3-17 (self-hosted OSRM investigation). 316 tests passing, up from 221.

The APK is a fresh release build (debug-signed, no release signing config exists yet) with two build fixes applied: core library desugaring enabled for flutter_local_notifications, and sentry_flutter bumped to 9.27.0 (8.14.2's bundled Kotlin plugin was incompatible with this project's Kotlin 2.4.0 toolchain).
2026-08-19 13:36:04 -05:00

196 lines
8.1 KiB
Markdown
Raw 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.

# Launch
How Rippr gets from "on my phone" to "on the App Store with money coming in" — in stages,
because the jump is much bigger than it looks and most of it is not code.
**Where things stand:** the app is feature-complete on both platforms and has never
recorded a real ride. Nothing below should start before
[port/REAL-RIDE-CHECKLIST.md](port/REAL-RIDE-CHECKLIST.md) is done.
---
## Stage 0 — you and your friends *(today, free)*
What works right now, with no accounts and no stores.
### Android — genuinely easy
Send them the APK. That's it.
```bash
adb install -r rippr-flutter-1.0-debug.apk # or just message them the file
```
They tap it in Files and allow "install unknown apps". It works, it keeps working, and it
costs nothing. **For riding buddies on Android, this is a complete answer** — you may
never need the Play Store.
Worth switching to a **release build** before handing it round: the debug APK is ~172 MB
and slower. That needs a keystore, kept somewhere you will not lose it:
```bash
keytool -genkey -v -keystore ~/rippr-release.jks -keyalg RSA -keysize 2048 \
-validity 10000 -alias rippr
flutter build apk --release --split-per-abi # ~3 files, ~20 MB each
```
> **Back that keystore up.** Lose it and you can never update an app that shipped with it.
### iOS — awkward, and the awkwardness is the point
Free signing (see `INSTALL.md` in the samplez repo, alongside the APK) gives **7-day
builds**, three apps at a time, and needs your Mac every time. Fine for you. Miserable for
a friend who just wants to ride.
There is no free way around it. Apple deliberately does not allow casual iPhone
sideloading.
**If any of your friends ride with an iPhone, Stage 1 is not optional.**
---
## Stage 1 — a real group of testers *(~$99/yr + $25 once)*
This is the stage that actually fits "me and my friends", and it is a big quality-of-life
jump over Stage 0.
### TestFlight — the single best upgrade
Requires the **Apple Developer Program, $99/yr**.
- Builds last **90 days**, not 7
- **100 internal testers** and up to **10,000 external** via a public link
- Friends install the TestFlight app and tap once — no Mac, no cables, no trust dialogs
- Updates push automatically
- External testers need a light App Review pass (usually a day); internal testers do not
For a riding group this is effectively "the app store, for people I choose". Many projects
happily live here forever and never publish publicly.
### Google Play internal testing — optional
**$25, one time, forever.** Up to 100 testers, no review for the internal track. Worth it
mainly if handing out APKs starts to annoy you, or you want automatic updates on Android
too.
### What you must add before either
- **A privacy policy URL.** Both stores require one for anything touching location, even
in testing. It can be a single static page: what is collected (GPS while recording),
where it goes (nowhere — stays on the device), and how to delete it (delete the ride, or
the app).
- Switch the bundle id from `com.rippr.port` to something you own, e.g. `com.dylan.rippr`.
- A release build, on both platforms.
---
## Stage 2 — public launch
Everything in Stage 1, plus the parts that are genuinely work.
### Apple
- **Privacy nutrition labels** — Location → Precise, *not* linked to identity, App
Functionality only. Details in [port/RELEASE-IOS.md](port/RELEASE-IOS.md).
- **Expect to justify background location.** It is the most common rejection for apps like
this. Head it off with a **demo video of a real ride** in the review notes, showing the
user pressing Start.
- App name, subtitle, keywords, screenshots at several device sizes, a support URL.
- Review is typically 24–48 hours, and a rejection round is normal. Budget two weeks.
### Google
- **Data Safety form** — the Play equivalent of nutrition labels, and it must match
reality.
- Background location gets **extra scrutiny on Play**: a written justification and often a
video. Rippr's case is strong (a ride recorder is the textbook example), but it is a real
review step.
- Store listing, feature graphic, screenshots.
### Things that only matter once strangers use it
- **Crash reporting.** Currently none — the v3 backlog notes a recorder that dies mid-ride
leaves no trace beyond logcat. Sentry or Crashlytics before public launch.
- **A support address** people can actually reach.
- Whatever the real ride teaches you about battery. Strangers will not forgive what a
friend would.
---
## A positioning note, since you ride bikes *and* motorcycles
Everything user-facing currently says motorcycle, but the recording pipeline is entirely
activity-agnostic — it records positions and speeds, and nothing in it cares what you are
sitting on. `BACKLOG.md` already carries **activity type per ride** as an idea.
That matters here rather than only in the backlog, because it decides the store category,
the screenshots and who finds the app. Cyclists are a far larger audience than
motorcyclists and are already used to paying for ride apps. Deciding whether Rippr is a
motorcycle app or a ride recorder is a positioning question worth settling **before**
writing a store listing, not after.
It is also cheap: an activity column on `Trip` and a picker. It needs a real `Migration`,
since the destructive fallback is gone.
---
## Stage 3 — monetization
Only worth designing once people are actually riding with it. But the shape matters
because it changes the architecture, and it is worth knowing which door you are opening.
### The options, from least to most commitment
**Paid up front — a few dollars, once.**
Simplest possible. No servers, no accounts, no recurring obligation. Sells poorly in a
category where Strava is free, but the cost to you is nearly zero and it fits an app that
works entirely offline.
**Free, with a one-time unlock.**
Recording free forever; pay once for extras — export formats, unlimited history, themes.
No servers needed if the extras are local. Good match for Rippr as it exists today.
**Subscription for cloud features.**
The v3 backlog already points here: accounts, cloud backup, group rides. This is the only
model that justifies recurring money, because **you have recurring costs**. It is also the
biggest jump: a server, authentication, a privacy stance, and an obligation to keep
someone's ride history alive.
> Note the coupling. Cloud backup needs accounts; accounts need a privacy policy with
> teeth, GDPR-style deletion, and — on iOS — **in-app account deletion**, which Apple
> requires of any app that lets you create an account. Group rides need all of that plus
> live location sharing between people, which is a consent question, not a technical one.
### The numbers
- **Apple and Google both take 30%**, dropping to **15%** under their small-business
programmes (under $1M/yr). Enrol; it is not automatic on Apple's side.
- Apple: $99/yr. Google: $25 once.
- Server costs are yours. A modest VPS runs a group-ride backend for single-digit dollars
a month until it doesn't.
- Payments are handled by the stores for digital goods — you may not route around them for
in-app features.
### What I would actually do
Keep it free while it is you and your friends. If it grows, the honest first step is a
**one-time unlock** for local extras — no servers, no obligations, no privacy surface.
Only build the subscription once someone who is not your friend asks for cloud backup.
Paid storage of other people's location history is a commitment that outlives your
interest in maintaining it, and that is worth entering deliberately.
---
## The order of operations
1. **Ride with it.** [port/REAL-RIDE-CHECKLIST.md](port/REAL-RIDE-CHECKLIST.md). Nothing
else matters until the numbers are right — and iOS background suspension (item I3) may
still force a change of GPS engine.
2. Release builds, real bundle id, a keystore you have backed up.
3. A one-page privacy policy.
4. $99 Apple → TestFlight. Your friends stop needing your Mac.
5. Live with it for a season. Let real use decide what is missing.
6. Only then: public listings, crash reporting, and a monetization model chosen from
evidence rather than from a table like this one.