Help centre Families Coaches Support

Littles Baby Tracker

Help for families and coaches

Site Tools


technical:features:25_embedded_mobile_coach_app

25 — Embedded mobile coach app

Technical reference. For task-based help, see the corresponding user guide.
Documentation status: reviewed against implementation · Reviewed: 2026-07-21 · Primary users: authenticated coaches · Surfaces: coach portal, mobile web and native wrapper hand-off

Purpose

The coach portal exposes mobile-first coach workflows without asking desktop users to sign in twice. On a phone it first offers the installed native app; otherwise it hosts the mobile web coach experience in a viewport-aware iframe and hands over the current portal access token in memory.

User outcomes

Context Outcome
Desktop/tablet coach Opens the mobile coach app inside the portal at /mobile-app.
Mobile-browser coach with native app The dreamsforlittles:// scheme attempts to open the installed app.
Mobile-browser coach without native app The browser falls back to the embedded experience after approximately 1.4 seconds.
Coach following an activity alert The embedded presentation lands on the corresponding /coach/… route; the current generic native scheme does not carry that path.

Entry points

  • Coach portal navigation → Mobile web.
  • /mobile-app for the default coach dashboard.
  • /mobile-app?path=<encoded coach route> from coach activity-notification navigation.

Functional flow

1. Choose native or embedded presentation

  1. Non-mobile browsers navigate directly to /mobile-app and render the iframe.
  2. A likely iOS/Android browser clicks the dreamsforlittles:// custom scheme.
  3. A 1,400 ms timer navigates to the iframe only if the document stayed visible. Page-hide/visibility events cancel the fallback after a successful native hand-off.
  4. A scheme-launch exception triggers the iframe immediately.

2. Build a coach-only initial route

  1. The portal reads the optional path query value.
  2. Values beginning with /coach are passed as the initial mobile route; anything else becomes /coach.
  3. The hosted URL adds adminMobileWeb=1 and adminMobileWebInitialPath=….
  4. Production defaults to the portal's /mobile-web/ build; development defaults to http://localhost:5177/; VITE_MOBILE_WEB_URL can explicitly replace it.

3. Hand over authentication

  1. On iframe load and on route entry, the portal obtains its current access token.
  2. It posts littles:admin-mobile-web-auth to the iframe's exact calculated origin. The access token is in the message payload, never in the iframe URL.
  3. Mobile web enables its admin-hosted auth client only in admin-portal mode, validates the sender origin, constructs an in-memory session and uses the token for normal platform API calls.
  4. The receiver accepts its own origin in production. Development additionally permits HTTP localhost/127.0.0.1 origins.
  5. Mobile web waits up to three seconds for the hand-off. Account recovery, OAuth and password changes remain owned by the portal rather than the embedded auth client.

4. Maintain a usable viewport

  1. The portal sizes the route using visualViewport.height when available, with a 320 px minimum.
  2. Resize, orientation and visual-viewport events update the height and keep the portal at the top of the page.
  3. The iframe re-posts authentication after a load so a navigation/reload can recover its in-memory session.

Validation and user-visible states

State Behaviour
Native app opens The portal becomes hidden and the iframe fallback is cancelled.
Scheme unavailable The embedded app opens after the short fallback window.
Missing path or a value without the /coach prefix Initial route falls back to /coach.
Portal token missing No credential is posted; embedded bootstrap eventually behaves as unauthenticated/failed auth.
Message late The receiver waits three seconds and can accept a later valid message through its installed listener.
Iframe reload onLoad posts the current token again.
Backend denies a route The mobile error/denied state is shown; embedding never bypasses API authorization.

Security boundaries

  • The token is sent only with an exact postMessage target origin, and the receiver validates event.origin.
  • The URL contains mode and initial-route hints only; it must never contain an access token.
  • The current path check is a navigation guard based on the /coach prefix, not an authorization mechanism.
  • Platform endpoints still validate the JWT, actor role, organization, assignment, subscription and permission for every operation.
  • The embedded session is memory-only. The native custom-scheme attempt does not transfer the browser token to the native app.
  • The current dreamsforlittles:// launch is also pathless. A notification destination is preserved by the iframe fallback, not handed to the native app by this scheme.
Do not treat iframe origin checks or the /coach path prefix as the security boundary. Adding a new deployment origin requires deliberate sender-and-receiver configuration, and every new mobile route must remain server-authorized.

Acceptance checklist

  1. [ ] Desktop navigation renders the configured mobile-web build in the full-height portal frame.
  2. [ ] Mobile navigation attempts the native scheme and only falls back while the page remains visible.
  3. [ ] Initial values that do not begin with /coach resolve to /coach.
  4. [ ] The access token never appears in the URL, logs or persistent embedded storage.
  5. [ ] Sender target origin and receiver origin validation agree in production and development.
  6. [ ] Iframe reload re-establishes the hand-off.
  7. [ ] Activity notification links preserve an authorized /coach/… destination in the embedded presentation without claiming path hand-off through the generic native scheme.
  8. [ ] API denial remains effective inside the iframe.

Source evidence

  • Coach portal: admin-web/src/App.tsx, admin-web/src/mobile-web-build-url.ts, admin-web/src/components/AdminShell.tsx
  • Mobile web: mobile-web/src/api/admin-portal-mobile-auth.ts, mobile-web/src/webview/bridge.ts, mobile-web/src/App.tsx