F1: warmPageYdoc now returns didSync (true only on the real 'synced' event,
false on the 8s timeout / error, which are now logged). The tree menu gates
the 'available offline' success toast on result.ok AND didSync, and pushes
'editor' into the failed set otherwise — so a page whose Yjs body never
warmed is no longer reported as fully offline-available.
F2: tests for the page/space/currentUser failure labels and the didSync
true/false paths.
F3: correct the mobile-app-plan / mobile-bootstrap present-state sections to
match shipped code (Capacitor, CORS allowlist, Swagger, offline reading,
/l in the SW denylist).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3.9 KiB
3.9 KiB
Mobile app bootstrap
Purpose: this document records what has been bootstrapped in the repo to enable a mobile app for Gitmost, per the first-step checklist in docs/mobile-app-plan.md section 12.
What is in the repo now
- PWA: web app manifest plus a service worker generated by
vite-plugin-pwausing Workbox (strategies: "generateSW"— not hand-rolled). The SW is built for production only (devOptions: { enabled: false }) and usesregisterType: "prompt", so the user is asked to apply an update rather than it auto-updating; registration goes throughvirtual:pwa-register/react(useRegisterSW) inapps/client/src/pwa/pwa-update-prompt.tsx, mounted frommain.tsxand skipped inside the Capacitor native WebView. The SW precaches the app shell (globPatternsjs/css/html/...) and servesnavigateFallback: "index.html"for SPA routes, withnavigateFallbackDenylistexcluding the server-owned routes/api,/collab,/socket.io,/share/,/mcp,/l(the vanity short-linkl/:alias, excluded from the/apiglobal prefix and resolved server-side), and/robots.txt.runtimeCachingkeeps/collab,/socket.io, and all/apiasNetworkOnly— offline reads are served by the persisted TanStack Query cache (IndexedDB) andy-indexeddbfor the page Yjs doc, not by an SW HTTP cache. This lets the existing responsive web UI be installed and run as a Progressive Web App. The offline/sync design (stages M0…M4) is summarized in mobile-app-plan.md. - Backend mobile auth: opt-in token return from the login flow. The login
request accepts a
returnTokenflag (must be sent as a JSON boolean) that makes the server include the auth token in the response body, and the server already accepts aBearertoken in theAuthorizationheader. Note the global response interceptor wraps every payload, so the native client reads the token atresponse.data.authToken(not at the top level). A native client can store this token (Keychain / Keystore) and send it asAuthorization: Beareron each request. - Explicit CORS allowlist: the server reads a
CORS_ALLOWED_ORIGINSenv variable for the allowed origins, and always allows the native WebView origins (capacitor://localhost,ionic://localhost,https://localhost) so the mobile shell can call the API. - Optional OpenAPI / Swagger: an opt-in OpenAPI/Swagger surface gated behind
the
SWAGGER_ENABLEDenv flag, useful for developing the native client. - Capacitor config: capacitor.config.ts at the
repo root. It targets the
apps/clientweb build output (apps/client/dist) for the Android bundled mode, and on iOS loads the client from a hosted server viaCAP_SERVER_URL(server.url) so the AGPL web client is not bundled into the.ipa(see mobile-app-plan section 9).
Remaining MANUAL / local steps (require Xcode / external accounts, out of scope here)
- Run
pnpm installto fetch the Capacitor packages and@nestjs/swagger. - Run
pnpm run client:buildto produce the web build inapps/client/dist. - Run
npx cap add iosand/ornpx cap add androidto generate the native platform projects (these live outside version control; see.gitignore). - Set
CAP_SERVER_URLfor the iOS build so the shell loads the hosted client (AGPL-clean), then runpnpm run mobile:build/cap sync. - Set up push notifications: APNs for iOS and FCM for Android.
- Obtain an Apple Developer account and the App Store / Play Console listings.
- Confirm the AGPL iOS distribution decision (mobile-app-plan section 9) before shipping anything to the App Store.
See also
For the full background, rationale, and the licensing analysis, see docs/mobile-app-plan.md (section 12 for the bootstrap checklist, section 9 for the AGPL / App Store licensing path).