Roadmap — Legacy App Replacement

This track has a single, finite goal: replace the legacy Flutter app with our new native apps at full feature parity, and migrate existing users’ data — so today’s free Range Day users can move over without losing anything. A migrating user lives entirely in the new native app.

Only once parity ships do we expand into new surfaces and the paid layer — all of that lives in Roadmap — Pro & New Features. This file also holds the shared platform foundation the parity app (and everything after) builds on. Each work item links to its full spec in items/.

Target customer segment: church security teams. See Product Overview and Customer Segments.

Shared Foundation

Platform the parity app — and everything after — builds on.

Foundation

These block everything else. No feature work starts until the skeleton is in place.

  • Monorepo Scaffold — Cargo workspace, directory structure, CI skeleton
  • Core Crate — models, validation, scoring profiles, sync protocol, offline queue
  • Proto Definitions — ConnectRPC service and message .proto files, buf config
  • DB Schema — Postgres migrations for all entities

Auth & Identity

Infrastructure

  • Deployment Pipeline — CI/CD, container builds, tagged releases
  • Observability Setup — tracing, logging, metrics, Grafana stack
  • File Storage — DO Spaces setup for user-uploaded media
  • Push Infrastructure — APNs certificates, push delivery service setup
  • Spaces CORS Config — repo-checked bucket CORS applied by workflow (browser presigned-PUTs; staging hand-applied 2026-07-13, prod on the cutover checklist)
  • Push Service — push notification delivery (APNs + platform push), event/challenge/social notifications

Platform & Verification

Per-deployment configuration and store-readiness foundation (accepted decisions, not yet scheduled).

  • Native App Platform Configuration — bundle ID revert to com.range.day, permissions, targetSdk 36, Firebase, deep-link infra (in-place update of the ~70k-user listings)
  • Instance Verification & Licensing — user-configurable server URL + signed GetInstanceInfo handshake; the per-deployment config channel (branding, capabilities, web_origin) and white-label DRM foundation

Feature Parity

Match the existing free Flutter app, feature for feature, in the new native apps.

Server APIs

  • Score API — ConnectRPC service for score submission, querying, live streaming
  • Drill API — ConnectRPC service for drill CRUD, visibility, copying, favorites
  • User API — ConnectRPC service for user profiles, friends, social graph, user search
  • Challenge API — ConnectRPC service for challenge CRUD, invitations, results
  • Leaderboard API — ConnectRPC service for per-drill, per-org, friends leaderboards
  • Achievement API — ConnectRPC service for badge definitions, user achievement tracking
  • Achievement Triggers — server-side achievement evaluation on score submission, idempotent award
  • Achievement Drill ID Criteria — migrate achievement criteria from drill-name keys to drill_id (drill renames break unlocks)
  • Media API — ConnectRPC service for file upload/download, presigned URLs (DO Spaces)
  • Media Multi-Upload — lift one-per-kind constraint, allow n-number photos/videos per score
  • Location API — ConnectRPC service for reusable locations (ranges, facilities), org/user/public visibility
  • Range Bag API — ConnectRPC service for gear/equipment tracking
  • Content Feed API — ConnectRPC service for dynamic content/announcements, read tracking
  • Dry Fire Score Submission — submit dry fire timer sessions as scores so dry_fire_drill_count achievement can unlock
  • Personal Range Day Sharing — allow personal range days to be shared with friends via roster

Mobile (iOS + Android)

  • UniFFI Setup — Swift + Kotlin binding generation pipeline
  • Mobile Auth — login, registration, password reset UI
  • On-Range Scoringsingle-shooter, single-drill score entry, offline queue, foreground sync (multi-shooter + course scoring were deferred at MVP build — re-opened as parity gaps under “Scoring & Calculator Parity” below)
  • Event View — view event details, drills, roster (read-only event visibility is part of the replacement app; event creation/admin/org workflows are Pro — see Roadmap — Pro & New Features)
  • Score History — personal score history across orgs (trend chart + grouping parity → score-history-trends)
  • Friends & Social — friend requests, friends list, user search
  • Challenges — create, complete, and compare challenges with friends
  • Leaderboards — per-drill and friends hit factor rankings
  • Range Bag — gear/equipment tracking
  • Achievements — badge display, progress tracking
  • Favorites — bookmark drills and courses
  • Media Capture — photos/videos attached to scores
  • Push Notifications — receive and display event/challenge/social notifications
  • Dry Fire Training — dry fire drill browsing, recommended par times, built-in par timer
  • Personal Scheduled Range Days — personal range day planning with date, time, location, and drill selection
  • Content Feed — server-driven announcements, tips, and content without app store updates

Friend Discovery (parity follow-ups)

Parity gaps kept alive by the Friend Discovery Parity decision — follow-ups, not cutover blockers.

Scoring & Calculator Parity (re-opened by the 2026-06-15 parity audit)

Legacy scoring features the new app deferred at MVP build (see 2026-06-15-mvp-parity-audit). The server already supports N-shooter scoring; the gaps are the entry UI (web + native) + course-run grouping + the deferred leaderboards.

  • Squad Scoring Entry — instructor/RO scores N shooters against one drill in a batch, on every surface (PWA + dashboard + iOS + Android), org-member or event-roster sourced. Closes the mobile-scoring multi-shooter deferral (all-surfaces close-out 2026-07-12).
  • Course Scoring — multi-stage course run + aggregate standing on every surface (PWA + iOS + Android: live run, squad run, past-run browsing, resume); the one piece that needed new schema/proto (course-run grouping + ListCourseRuns). Migrated legacy runs browse-able, recorder-owned by design (all-surfaces close-out 2026-07-13).
  • MSD & Course Leaderboards — rank squad-recorded scores + course standings (lifts the leaderboard-api deferrals). Closed 2026-07-13: squad scores verified already ranking (verify-only); per-drill boards reworked to legacy parity (self-recorded scores rank, public boards world-visible, friends boards cross-org) with migrated scores carved from All-Users boards; course boards decided-against — within-run standings (shipped with course-scoring) are the legacy parity bar, cross-run boards parked on ROADMAP-PRO.
  • Hit-Factor Calculator + Log — rebuild the USPSA calculator and the saved performance log on the Training hub, and migrate the 26,380 legacy hit_factors entries 1:1 into hit_factor_entries (Scope B, Decision #3). PWA shipped 2026-06-20; native → mobile-track.

Authoring & Content Creation Parity (re-opened by the 2026-06-15 parity audit)

Legacy let any shooter create content from their phone; the new app only authors on the dashboard. See 2026-06-15-mvp-parity-audit.

  • Shooter-Side Drill Authoring — let shooters create/edit custom drills (with photo stage-image) on PWA + native, not just the dashboard (~16k legacy custom drills).
  • Stage-Diagram Builder — rebuild the legacy vector stage editor (templated targets, drag/rotate/resize, undo/redo); backup-verified 2,362 drills / 990 authors drew vector designs (~5× the flat-photo path). MVP-vs-fast-follow is an open scope call; vector-only storage means these don’t display without a renderer.

Media Display Parity (migration-media client follow-ups)

Avatar + drill-image display on the clients — the user-facing side of migration-media (PR-4 shipped the web/dashboard surfaces).

Round-2 Parity Gaps (filed from the 2026-06-15 forensic sweep)

Gaps surfaced by the 2026-06-15-mvp-parity-audit round-2 sweep, triaged with fresh per-gap agents and filed 2026-06-25. The remaining F-gaps were dispositioned as already-deferred or not-a-gap (recorded in the audit note, not re-filed).

Migration (from the existing app)

  • Migration ETL — one-time Supabase to new Postgres data migration
  • ⚠️ Migration Completeness Audit (2026-06-22) — source-exhaustive pre-cutover audit of the ETL: 82 gaps (7 high-severity silent drops), the skip-list/spec corrected in place, 10 product decisions owed. Cutover-readiness gate for migration-etl.
  • One-Way Sync — Supabase to new DB listener during coexistence period
  • Migration: Media — Supabase Storage → DO Spaces; new-system support for avatars + drill images (build complete — PR-1…5; the live transfer + sync forwarding are creds-gated)
  • Migration: No-Shoot Zone — carry legacy no-shoot counts into migrated score breakdowns (re-grades migration-etl finding #6; done #103)
  • Staging E2E Test Suite + Shared API Client — API-level migration validation against deployed staging, via a shared rangeday-api-client crate the apps and tests both consume (suite live + armed deploy-smoke proven green 2026-07-12)