MOB-05 — Navigation, app shells & system states
go_router with auth guard, bottom-navigation shells for both apps, deep-link routes, splash/version check, offline/maintenance/forced-update/error/empty states.
| Field | Details |
|---|---|
| Task code | MOB-05 |
| Phase | P0 — Foundations (cadrage, UX/UI, architecture & contract) |
| Product scope | V1 |
| Status | Planned |
| Start | Mon 26 Oct 2026 |
| Due | Tue 27 Oct 2026 |
| Responsible | Imad — Mobile developer (Flutter) |
| Co-responsible | — |
| Effort | 0.75 person-day(s) planned · 3 from scratch · size S |
| Area · app | Mobile foundation · mobile |
| Depends on | MOB-04 |
| Unblocks | MOB-06, MOB-10 |
| Milestones | — |
Summary
go_router with auth guard, bottom-navigation shells for both apps, deep-link routes, splash/version check, offline/maintenance/forced-update/error/empty states.
Description
Both apps need one routing model so auth state, guest browsing, deep links from push and invitation links and system states behave identically and are testable. Scope: go_router with a redirect driven by the session state (unknown, guest, signed-in with account status), the bottom-navigation shells of both apps, the deep-link route registry, the splash with version check (appConfig.get) and the shared system states — offline, maintenance, forced update, error, empty (RA-01, RA-36, DA-01). Auth screens themselves are MOB-06. It needs appConfig.get and me.get in the contract (SRV-03) and Akram's DES-06/DES-10/DES-11 system-state frames. MOB-06, MOB-08 (push routing) and MRA-09 (app links) plug their routes into this registry.
Subtasks
| # | Subtask | Owner |
|---|---|---|
| 1 | AppRouter per app (go_router + go_router_builder typed routes) with a single pure redirect function over SessionState (unknown, guest, signedIn(PENDING_VALIDATION | ACTIVE | SUSPENDED | DISABLED)) | Imad |
| 2 | SplashScreen RA-01 / DA-01: session restore and appConfig.get?app=RESELLER_APP|DELEGATE_APP&platform=android in parallel, 5 s timeout, last policy cached for offline starts | Imad |
| 3 | VersionPolicy evaluator (minVersion, latestVersion, forced, maintenance) and ForcedUpdateScreen (Play Store link via url_launcher), SoftUpdateBanner, MaintenanceScreen with details.until | Imad |
| 4 | Reseller shell (StatefulShellRoute): « Accueil », « Catalogue », « Panier » (badge), « Commandes », « Compte »; catalog branches open to guests, the others redirect guests to the sign-up prompt | Imad |
| 5 | Delegate shell with the DES-11 tab set (« Accueil », « Tournée », « Prospects », « Messages », « Compte »); all routes require a delegate session | Imad |
| 6 | Deep-link registry shared with MOB-08 and MRA-09: /products/:id, /orders/:id, /promotions/:id, /tickets/:id, /returns/:id, /notifications, /i/:code (reseller); /tours/:id, /visits/:id, /resellers/:id, /tasks, /sync (delegate); pending deep link replayed after sign-in | Imad |
| 7 | System-state widgets RA-36 / DA-28 (forced update part): OfflineBanner, ErrorState with retry and requestId, EmptyState variants, NotFound route | Imad |
| 8 | Android back behaviour: pop within a branch, return to the first tab, exit confirmation on the root | Imad |
Deliverables
- apps/reseller/lib/src/app/router.dart and shell.dart
- apps/delegate/lib/src/app/router.dart and shell.dart
- packages/hoco_core/lib/src/app_config/version_policy.dart
- packages/hoco_ui/lib/src/system_states/
Acceptance criteria
- An app below minVersion shows the forced-update screen and cannot go further; maintenance mode shows the maintenance screen (ADM-07)
- A 426 UPGRADE_REQUIRED received mid-session also routes to the forced-update screen
- Offline at launch with a stored session opens the last shell from cache (delegate: today's tour) instead of blocking
- A deep link /orders/{id} opened while signed out goes through sign-in and lands on that order
- A guest can open « Accueil » and « Catalogue » but « Commandes » and « Panier » show the sign-up prompt
Requirements covered
| Requirement | Title | Release |
|---|---|---|
| AUTH-09 | Device registration for push and minimum-app-version enforcement | V1 |
| ADM-07 | Mobile app versions: minimum and latest version, forced update, maintenance mode | V1 |
Screens
| Screen | Name | App |
|---|---|---|
| RA-01 | Splash & version check | RA |
| RA-36 | System states (offline, maintenance, forced update, errors, empty) | RA |
| DA-01 | Splash & version check | DA |
API surface
| Endpoint group | Operations |
|---|---|
| Me, devices, app config & reference data | 9 |
Test measures
- Unit tests of VersionPolicy and of the redirect function for every SessionState
- Widget tests of the shells (tab switching keeps branch state, badges)
- integration_test launching with a mocked appConfig returning forced=true and maintenance=true
Risks
- Redirect loops between splash, auth and deep links — keep all redirect logic in one tested pure function
KPI
- Delivered by Tue 27 Oct 2026 within 0.75 person-day(s).
- Every acceptance criterion above demonstrated before hand-off; linked requirements' acceptance criteria pass.
- Zero open critical defects, permission gaps or data-integrity regressions at sign-off.
Generated from content/plan/tasks.json by scripts/generate-team-tasks.mjs. Dates are computed by the scheduler (Sunday–Thursday weeks, holidays excluded) — change the plan, not this page.
MOB-03 — API client from the OpenAPI contract + mock server workflow
hoco_api generated from openapi.json (models + dio client), regeneration script, Prism mock server for local development, contract version pinned.
MOB-06 — Authentication flows (both apps)
Guest mode (browse without prices), reseller welcome, sign-up with OTP, customer type and account claim, pending-validation screen, sign-in, forgot password; delegate sign-in and reset; session restore and status gating.