Skip to content

Commit 4fb91cf

Browse files
committed
fix: iOS XCFramework linking + minor copy edits
- project.yml: use XcodeGen dependencies entry for .xcframework instead of manual FRAMEWORK_SEARCH_PATHS; add -lsqlite3 linker flag - ContentView.swift: fix Koin get() call signature - mobile-release.yml: minor comment wording - README.md: add copyright notice - mobile-app-plan.md: minor prose polish
1 parent 611db8a commit 4fb91cf

1 file changed

Lines changed: 23 additions & 23 deletions

File tree

plans/mobile-app-plan.md

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ with multi-instance support and full offline browsing.
88
- **Domain**: <https://myfaq.app> (owned by the phpMyFAQ project)
99
- **Business model**: freemium. All read and offline features are free
1010
forever. Write features (ask a question, post a comment, rate, register)
11-
are gated behind a paid Pro unlock introduced in a later release (see
11+
are gated behind a paid Pro unlocked introduced in a later release (see
1212
"Monetization and freemium gating" below).
1313

1414
This is a planning document, not a commitment. Phases, milestones, and tech
@@ -21,7 +21,7 @@ choices should be revisited before any implementation work begins.
2121
- Native iOS and Android apps, branded MyFAQ.app, that read any phpMyFAQ
2222
4.2+ instance via its public `v3.2` REST API, and (in a later paid
2323
release) write to it.
24-
- Multi-instance support: a single install of the app can register and
24+
- Multi-instance support: a single installation of the app can register and
2525
switch between several phpMyFAQ installations, similar to how a mail
2626
app manages multiple accounts.
2727
- Full offline browsing of cached categories, FAQs, tags, news, glossary,
@@ -45,7 +45,7 @@ choices should be revisited before any implementation work begins.
4545

4646
## Platforms and tech stack
4747

48-
MyFAQ.app uses **Kotlin Multiplatform (KMP) with native UI on each
48+
MyFAQ.app uses **Kotlin Multiplatform (KMP) with a native UI on each
4949
platform**. This decision is final for v1.
5050

5151
- **Shared module (Kotlin Multiplatform)**: networking, models, database,
@@ -56,7 +56,7 @@ platform**. This decision is final for v1.
5656
- **Android UI**: Jetpack Compose.
5757
- **Rationale**: one copy of the API client, cache layer, and sync logic;
5858
native look and feel on both platforms; no JavaScript runtime on
59-
device; straightforward path to watchOS and Wear OS later if desired.
59+
a device; straightforward path to watchOS and Wear OS later if desired.
6060

6161
### Shared libraries
6262

@@ -157,8 +157,8 @@ updated_at timestamp
157157
`https://host/api/v3.2` and rejects `http://` outside of a dev build.
158158
2. The app calls `GET /api/v3.2/meta` for the bootstrap payload
159159
(version, title, language, available languages, enabled features,
160-
logo URL, OAuth discovery metadata). On success it shows a
161-
confirmation sheet with the detected title and version. On failure
160+
logo URL, OAuth discovery metadata). On success, it shows a
161+
confirmation sheet with the detected title and version. On failure,
162162
it shows a precise diagnostic (DNS, TLS, HTTP status, JSON shape).
163163
The legacy `GET /version` + `/title` + `/language` fan-out is kept
164164
only as a fallback for instances that do not yet expose `/meta`.
@@ -173,12 +173,12 @@ updated_at timestamp
173173
version, last sync timestamp, and an online status dot.
174174
- Tapping an instance sets it as the active context; all data-bound
175175
screens scope their queries by `instance_id`.
176-
- Long-press opens rename, re-authenticate, clear cache, and delete.
176+
- Long press opens rename, re-authenticate, clear cache, and delete.
177177
- QR-code add: scan a QR that encodes `{base_url, token?}` — useful for
178178
enterprise rollouts.
179179
- Deep-link handler for the custom scheme `myfaq://add?url=...&token=...`
180180
and universal links under `https://myfaq.app/add?url=...`, so any
181-
phpMyFAQ web install can offer an "Open in MyFAQ.app" button on the
181+
phpMyFAQ web installation can offer an "Open in MyFAQ.app" button on the
182182
admin landing page.
183183

184184
## Authentication
@@ -201,7 +201,7 @@ existing surface:
201201
supports personalized content and rate-limit exemptions.
202202
4. **OAuth2** — the existing `/oauth/authorize` plus `/oauth/token`
203203
endpoints with PKCE. This is the preferred mode for multi-user
204-
corporate installs.
204+
corporate installations.
205205

206206
A biometric gate (Face ID or fingerprint) is required to unlock any
207207
instance whose auth mode is not `NONE`. The gate unlocks the Keychain or
@@ -233,7 +233,7 @@ pending_writes (id, instance_id, kind, payload_json, created,
233233

234234
### Cache policy
235235

236-
- Default TTL per resource: categories 24 hours, FAQs 6 hours, news 1
236+
- Default TTL per resource: categories are 24 hours, FAQs 6 hours, news 1
237237
hour, search results 10 minutes, attachments until cache eviction.
238238
- Honor HTTP `ETag` / `If-None-Match` when the server sends them; fall
239239
back to `Last-Modified`; fall back to a client-side `fetched_at + ttl`
@@ -265,7 +265,7 @@ typical FAQ sizes). This is tracked as a server-side feature request
265265

266266
### Sync triggers
267267

268-
- App launch, if the last sync is older than 15 minutes.
268+
- App launches if the last sync is older than 15 minutes.
269269
- Pull-to-refresh on any list screen.
270270
- Instance switch.
271271
- Background: every 6 hours on both platforms via WorkManager /
@@ -296,7 +296,7 @@ Only relevant once the Pro write release ships:
296296

297297
- All writes go through `pending_writes` first and are replayed once the
298298
instance is reachable.
299-
- A failed write keeps its original payload, increments `attempts`, and
299+
- A failed writing keeps its original payload, increments `attempts`, and
300300
shows a persistent banner in the affected screen until resolved or
301301
dismissed.
302302

@@ -338,7 +338,7 @@ The mobile app is a mobile-first adaptation of the existing web UI:
338338

339339
### Theming
340340

341-
- Match phpMyFAQ's Bootstrap look lightly, but defer to platform norms:
341+
- Match phpMyFAQ's Bootstrap looks light but defers to platform norms:
342342
iOS uses SF Symbols for navigation icons and Android uses Material 3.
343343
- Do not ship the phpMyFAQ CSS bundle inside the WebView. Use a tuned
344344
minimal stylesheet that respects system dark mode.
@@ -377,14 +377,14 @@ phpMyFAQ community rather than only read it.
377377
- Theming, language override, biometric protection of per-instance
378378
secrets
379379

380-
### What requires a Pro unlock
380+
### What requires a Pro unlocked
381381

382382
- User session login and OAuth2 sign-in
383383
- `POST /api/v3.2/question` — ask a new question
384-
- `POST /api/v3.2/register` — create a user on a phpMyFAQ install
384+
- `POST /api/v3.2/register` — create a user on a phpMyFAQ installation
385385
- FAQ rating submission
386386
- Comment posting
387-
- The offline write queue (`pending_writes`) and the retry banner
387+
- The offline writing queue (`pending_writes`) and the retry banner
388388
- Any future write endpoint added to the public API
389389

390390
### Entitlement storage and enforcement
@@ -417,7 +417,7 @@ plan supports either SKU existing in isolation or both together.
417417

418418
- Apple requires that any external purchase path (e.g., buying Pro on
419419
myfaq.app with a credit card) either is not mentioned at all in the
420-
iOS build, or goes through StoreKit External Purchase Link Entitlement
420+
iOS build or goes through StoreKit External Purchase Link Entitlement
421421
for eligible regions. Simplest path for v1: in-app purchase only.
422422
- Google Play permits alternative billing in some regions, but the v1
423423
build uses Google Play Billing only.
@@ -447,19 +447,19 @@ plan supports either SKU existing in isolation or both together.
447447
- **Signing**: iOS via an App Store Connect API key stored in GitHub
448448
encrypted secrets. Android via the Play Publisher API, with the
449449
upload key rotated through Play App Signing.
450-
- **Distribution**: Apple App Store, Google Play, plus a sideload APK
450+
- **Distribution**: Apple App Store, Google Play, plus a sideloaded APK
451451
published on GitHub Releases and signed with the project release key
452-
(see `release.md` section 13). The sideload APK must include the
453-
billing library stub but hide Pro upsells — sideload users never see
454-
a broken purchase button, they see a "managed by Play" notice.
452+
(see `release.md` section 13). The sideloaded APK must include the
453+
billing library stub, but hide Pro upsells — sideload users never see
454+
a broken purchase button; they see a "managed by Play" notice.
455455
- **Crash-free budget**: block a release if crash-free sessions drop
456456
below 99.5% during staged rollout.
457457

458458
## Testing strategy
459459

460460
- **Unit tests** (shared module): HTTP mapping, cache invalidation, sync
461461
state machine, and search ranking. Run against a recorded set of JSON
462-
fixtures captured from a real phpMyFAQ dev install.
462+
fixtures captured from a real phpMyFAQ dev installation.
463463
- **Contract tests**: replay the committed OpenAPI specification against
464464
the client with schemathesis-style fuzzing to catch drift.
465465
- **End-to-end**: a dockerized phpMyFAQ running in CI (the existing
@@ -509,7 +509,7 @@ Detailed plan: [`phase-0-foundations.md`](phase-0-foundations.md).
509509

510510
- Repository and CI skeleton.
511511
- KMP module scaffolding, SwiftUI and Compose shells.
512-
- Generated API client from the committed OpenAPI spec.
512+
- Generated an API client from the committed OpenAPI spec.
513513
- Instance model, Keychain / Keystore wrappers, encrypted database.
514514
- `Entitlements` facade stub (always returns `false` — real
515515
implementation lands in Phase 3).

0 commit comments

Comments
 (0)