document mobile app strategy

This commit is contained in:
Yisroel Baum 2026-08-16 11:28:36 +03:00
parent 8fcd7fef42
commit 63e7cc36ef
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9

202
docs/mobile-app-strategy.md Normal file
View file

@ -0,0 +1,202 @@
# Mobile App Strategy
## Recommendation
Attainly should keep one Vue application, make it properly mobile-first, and
package it for iOS and Android with Capacitor.
Capacitor can be added to an existing Vue and Vite project. It generates real
Xcode and Android Studio projects while allowing the application to continue
using its Vue views, router, Pinia stores, Zod schemas, and Laravel API.
This is a better fit than rewriting the frontend in Flutter or React Native.
Attainly's main interactions are forms, lists, schedules, and assignment
completion controls. A native rewrite would introduce another UI codebase
without providing a proportionate product benefit.
A Progressive Web App can be offered as an interim installation option, but
Capacitor should be the App Store and Google Play distribution strategy.
## Why the Existing Architecture Is a Good Fit
Attainly already has the important separation needed for this approach:
- The Vue and Vite frontend is independent from Laravel.
- Laravel exposes a JSON API.
- Pinia owns shared client state and API boundaries.
- Zod validates responses received from the backend.
- Existing screens include responsive breakpoints.
Capacitor should be added to the existing frontend rather than creating a
second Vue application. The resulting layout would be similar to:
```text
frontend/website/
|-- src/ shared Vue application
|-- capacitor.config.ts
|-- ios/ Xcode project
`-- android/ Android Studio project
```
The built Vue assets should be bundled inside each native release. The native
application should not simply open the deployed website remotely.
## Mobile Experience
### Navigation
The desktop dashboard currently combines today's work, schedules, and
available sets into one long page. The mobile layout should separate the core
areas with bottom navigation:
- Today
- Plans
- Library
- Settings
The web and native applications can use the same underlying Vue components and
stores while presenting navigation appropriate to each form factor.
### Native Capabilities
The first store release should provide useful mobile behavior beyond a website
wrapper:
- Daily assignment reminders
- Deep links from confirmation emails and notifications
- An application badge for unfinished work
- Cached access to today's assignments during a temporary network outage
- Safe-area, keyboard, status-bar, and Android back-button handling
- Optional haptic feedback when an assignment is completed
Reminders directly support Attainly's daily-use purpose. Capacitor provides
native push-notification support through Apple Push Notification service on
iOS and Firebase Cloud Messaging on Android.
Universal Links on iOS and App Links on Android should use Attainly's HTTPS
domain. A confirmation or schedule link can then open the installed app at the
correct Vue route and fall back to the website when the app is not installed.
## Authentication
The website currently uses an HttpOnly session cookie and sends API requests
with browser credentials. That remains a good security model for the website,
but a native WebView should not depend on a cross-origin cookie. In particular,
iOS restricts third-party cookies in WebViews.
The native application should use an opaque bearer session token:
1. A mobile login endpoint authenticates the user and creates a server-side
session.
2. Laravel returns the opaque token to the native application.
3. The application stores the token in iOS Keychain or Android Keystore using
a maintained secure-storage plugin.
4. The native API client sends the token in the `Authorization` header.
5. The browser API client continues using the HttpOnly cookie.
The token must not be stored in `localStorage`. The existing session domain and
repository can likely be extended to support both transports without changing
the rest of the protected API.
A shared API client should hide the platform difference from Pinia stores:
```text
Vue views and Pinia stores
|
shared API client
/ \
browser transport native transport
HttpOnly cookie secure bearer token
\ /
Laravel API
```
All production traffic must use HTTPS. Native application bundles must not
contain backend secrets or privileged API keys.
## Store Readiness
### Account and Privacy Requirements
Attainly supports account creation, so it must add the following before store
submission:
- An account-deletion action in Settings
- A backend endpoint and policy for deleting the account and associated data
- A public web resource through which former users can request deletion
- An accessible privacy policy and terms of use
- Accurate Apple App Privacy and Google Play Data Safety declarations
- An iOS privacy manifest covering the application and relevant SDKs
Apple requires applications that support account creation to offer account
deletion within the application. Google Play requires an in-app deletion path
and a web deletion resource that remains available after the application is
uninstalled.
### Application Quality
Apple expects an application to provide functionality and UI beyond a
repackaged website. The daily reminders, deep links, offline state, mobile
navigation, and device-appropriate behavior help make Attainly useful and
app-like.
The submitted build must be stable and complete. The production backend must
remain available during review, and the reviewer must receive a working demo
account or a fully featured demo mode.
### Platform Tooling
The iOS project is built and submitted with Xcode on macOS. The Android project
is built and submitted through Android Studio or its command-line tooling.
As of August 2026, Google Play states that new applications and updates must
target Android 16, API level 36, or higher. Store SDK and tool requirements
change regularly and must be checked again immediately before implementation
and each release.
## Suggested Delivery Sequence
1. Finish and production-harden the core web product.
2. Refactor the Vue interface into responsive Today, Plans, Library, and
Settings screens.
3. Introduce the shared API client and native authentication transport.
4. Add Capacitor and generate the iOS and Android projects.
5. Implement Universal Links, App Links, and daily reminders.
6. Add offline caching for today's assignments and queued completion updates.
7. Add account deletion, privacy documents, and store disclosures.
8. Test through TestFlight and Google Play internal testing on real devices.
9. Prepare icons, splash screens, screenshots, review credentials, and store
metadata.
10. Submit to Google Play and the App Store.
Existing Cypress coverage should continue to verify the shared browser-facing
behavior. Native releases also need smoke testing on real iOS and Android
devices, particularly for authentication, deep links, notifications, offline
recovery, keyboard behavior, and operating-system navigation.
## Expected Effort
A basic Capacitor wrapper could be made to run in a few days. A polished,
secure, and review-ready mobile MVP is more realistically four to six weeks of
focused work, assuming the core web product and production backend are ready.
The largest pieces are not generating the native projects. They are mobile
authentication, mobile navigation, notifications, deep links, offline
behavior, account deletion, device testing, and store compliance.
## References
The following requirements were reviewed on August 16, 2026:
- [Capacitor documentation](https://capacitorjs.com/docs)
- [Capacitor iOS documentation](https://capacitorjs.com/docs/ios)
- [Capacitor Android documentation](https://capacitorjs.com/docs/android)
- [Capacitor security guidance](https://capacitorjs.com/docs/guides/security)
- [Capacitor cookie behavior](https://capacitorjs.com/docs/apis/cookies)
- [Capacitor deep links](https://capacitorjs.com/docs/guides/deep-links)
- [Capacitor push notifications](https://capacitorjs.com/docs/apis/push-notifications)
- [Apple App Review Guidelines](https://developer.apple.com/app-store/review/guidelines/)
- [Apple account-deletion guidance](https://developer.apple.com/support/offering-account-deletion-in-your-app/)
- [Apple app privacy management](https://developer.apple.com/help/app-store-connect/manage-app-information/manage-app-privacy/)
- [Google Play account-deletion requirements](https://support.google.com/googleplay/android-developer/answer/13327111?hl=en-EN)
- [Google Play target API requirements](https://support.google.com/googleplay/android-developer/answer/11926878?hl=en)