Compare commits
2 commits
8fcd7fef42
...
8b8e6622a9
| Author | SHA1 | Date | |
|---|---|---|---|
| 8b8e6622a9 | |||
| 63e7cc36ef |
1 changed files with 202 additions and 0 deletions
202
docs/mobile-app-strategy.md
Normal file
202
docs/mobile-app-strategy.md
Normal 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)
|
||||
Loading…
Add table
Add a link
Reference in a new issue