Skip to main content

โšก Frontend Key Features

Current routes, analysis surfaces, upload flow, and coach mode in the Flutter app.

:::tip Source of truth Routes live in lib/routing/app_router.dart; feature UI lives under lib/features/; Firebase integration lives under lib/services/. :::

The app uses go_router with a Firebase-auth refresh listener. Signed-out users may access sign-in, sign-up, password reset, privacy, and terms; other routes redirect to /sign-in.

RouteSurface
/Home
/sessionsSession history
/sessions/:idLive job state or completed analysis
/practice and /practice/:idDrills
/newRecord or upload a session
/profile, /settings, /billingAccount surfaces
/coachingPlayer-side coaching
/coach, /coach/student/:idCoach roster and student detail

Unknown routes render a non-reflective in-app 404.

Analysisโ€‹

MatchAnalysisScreen loads the job, keeps the Firestore subscription open for the screen's lifetime (the Gemini read and merged report land on the job doc after done), and loads the combined analysis once through AnalysisService. It exposes four tabs:

  • Overview โ€” includes the Coach's Read card (CoachReadView) whenever the Gemini whole-video read is usable: summary, per-player ratings, strengths / work-ons with drills, and a timestamped shot log whose chips seek the video. This is the value surface for court-free sessions where the court-derived sections are sparse.
  • Shots
  • Heatmap
  • Stats

The mini-player shares seek and playback state with the shot list, heatmap, and the Coach's Read timestamps. Per-player filters use the roster when player identity is present in the analysis.

Upload flowโ€‹

StorageService.uploadVideoWithPreprocess() is the current path:

  1. VideoPreprocessService extracts and validates metadata.
  2. The client calls requestUploadPath in europe-west1.
  3. The server creates one job and returns a user-scoped Storage path.
  4. The client uploads one file, with retry and progress reporting.
  5. If upload fails before finalization, the client calls reportUploadFailure.

Client-side physical video chunking is not shipped. The current job records retain chunkIndex: 0, totalChunks: 1, and isChunked: false for compatibility.

State and designโ€‹

  • Riverpod provides app-level state; feature screens may keep local widget state.
  • lib/ds/tokens/ and lib/ds/widgets/ implement the AceSense design system.
  • Release builds default USE_MOCK to false, so placeholder data does not ship.
  • Localization includes English, German, Spanish, French, Italian, and Swedish.

Job vocabularyโ€‹

The client accepts legacy and current intermediate states:

StateMeaning
pendingUpload path reserved; object not finalized
uploaded / queuedUpload complete or waiting for dispatch
processing / runningAnalysis in progress
doneAnalysis available
failedTerminal error

Only pre-dispatch states receive the client's 30-minute abandoned-upload timeout. The backend owns long-running processing timeouts.