โก 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/.
:::
Navigationโ
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.
| Route | Surface |
|---|---|
/ | Home |
/sessions | Session history |
/sessions/:id | Live job state or completed analysis |
/practice and /practice/:id | Drills |
/new | Record or upload a session |
/profile, /settings, /billing | Account surfaces |
/coaching | Player-side coaching |
/coach, /coach/student/:id | Coach 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:
VideoPreprocessServiceextracts and validates metadata.- The client calls
requestUploadPathineurope-west1. - The server creates one job and returns a user-scoped Storage path.
- The client uploads one file, with retry and progress reporting.
- 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/andlib/ds/widgets/implement the AceSense design system.- Release builds default
USE_MOCKto 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:
| State | Meaning |
|---|---|
pending | Upload path reserved; object not finalized |
uploaded / queued | Upload complete or waiting for dispatch |
processing / running | Analysis in progress |
done | Analysis available |
failed | Terminal error |
Only pre-dispatch states receive the client's 30-minute abandoned-upload timeout. The backend owns long-running processing timeouts.