- Service worker (vite-plugin-pwa/Workbox): add /share/, /mcp, and /robots.txt to navigateFallbackDenylist so the SPA app-shell never shadows those server-rendered routes (they mirror the server static-serve exclude list — the share SEO/OG HTML, the MCP endpoint, and robots.txt must come from the server). - Remove the dead /api GET NetworkFirst Workbox rule (api-get-cache): offline reads are served by the persisted TanStack Query cache (IndexedDB) + y-indexeddb, never by an SW HTTP cache, so caching GET /api only risked stale responses. All /api is now NetworkOnly. clearOfflineCache still deletes any legacy api-get-cache defensively (comment updated to note it is no longer created). - CORS: drop the cleartext 'http://localhost' native-WebView origin. The Capacitor shell uses the secure scheme (capacitor.config cleartext:false, default Android scheme https, iOS hosted via CAP_SERVER_URL), so no native client uses it; allowing it only widened the credentialed-CORS surface. Keeps capacitor://, ionic://, and https://localhost. - docs/mobile-bootstrap.md: replace the inaccurate 'hand-rolled service worker' description with the real Workbox generateSW setup (prompt registration via virtual:pwa-register, production-only, denylist, NetworkOnly, RQ/y-indexeddb offline reads) and drop http://localhost from the CORS origins list. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.7 KiB
3.7 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, 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. See docs/offline-sync-plan.md for the full offline/sync design. - 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).