rename privacy "private" → "unlisted"; enable GPS for unlisted
- "unlisted" = not shown in the public feed, but GPS track, timeseries and detail JSON are all accessible by direct URL (security by obscurity) - "private" accepted as legacy alias everywhere (backward compat with existing data on disk) - New writes from Strava sync / ZIP upload / sidecar use "unlisted" - Only "no_gps" now suppresses the GPS track - isUnlisted() helper in format.ts used by all Svelte/Astro components - SCHEMA.md and CLAUDE.md document the privacy model and the distinction between "unlisted" and "no_gps"
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
# Advice on ARCHITECTURE.md
|
||||
|
||||
Review of the mobile / offline plan in `ARCHITECTURE.md`. The two-stage extract/render pipeline, edit flow, and federation sections are accurate and clear — this document focuses on where the architectural risk lives: the mobile app and the path to fully-offline operation.
|
||||
|
||||
## What's strong
|
||||
|
||||
- **Workflow framing (1–4) is the right way to think about it.** Each workflow is a concrete user story, not an abstract capability list. Workflow 1 (record → convert → cloud) is achievable with what's already there; that's a good wedge to ship first.
|
||||
- **Honest status table** at the bottom of "Fully offline — missing pieces". An architecture doc that admits what isn't done is more useful than one that hand-waves.
|
||||
- **Incremental validation plan (§5).** Testing the service worker approach in the browser before touching native builds is the right call — cheap to run, and the failure mode is informative rather than expensive.
|
||||
|
||||
## Decision: drop `capacitor-nodejs`
|
||||
|
||||
The doc previously listed `capacitor-nodejs` as a fallback if service workers fail on iOS. We are dropping this option entirely. Reasons:
|
||||
|
||||
- It embeds a full Node runtime, meaningfully increasing app size.
|
||||
- iOS support relies on a fork of Node-mobile and has historically been spotty.
|
||||
- It introduces a long-term maintenance burden (tracking upstream Node, plugin updates, two runtimes to debug).
|
||||
- The "Hard" effort label in the original status table understated both the integration risk and the ongoing cost.
|
||||
|
||||
If service workers turn out to be blocked on iOS, the fallback should be one of:
|
||||
|
||||
1. **A data access abstraction** (see next section) that lets the app read from IndexedDB directly via a JS loader, with no `fetch('/data/*')` in the hot path at all. This sidesteps the WKWebView question entirely.
|
||||
2. **A native Swift/Kotlin micro-server** if a local HTTP origin is genuinely required.
|
||||
3. **Bundling data as static assets** and re-running `cap sync` on import — crude but boring and reliable.
|
||||
|
||||
`capacitor-nodejs` should not appear in the doc, the test plan, or the status table.
|
||||
|
||||
## Things to fix or add
|
||||
|
||||
### 1. Add a data access abstraction step *before* the service worker work
|
||||
|
||||
The doc frames the offline problem as "serve local data to the WebView at `/data/*`". That skips a prior question: does the Astro site actually need to fetch `/data/*` at runtime, or can the data layer be abstracted behind a thin loader (`loadIndex()`, `loadActivity(id)`) with two implementations?
|
||||
|
||||
- **Cloud build:** loader uses `fetch('/data/...')` as today.
|
||||
- **App build:** loader reads from IndexedDB directly.
|
||||
|
||||
This is a much smaller change than service worker interception, avoids the iOS WKWebView question entirely, and is useful even if you stay cloud-only (testability, mocking, future federation transports). It should land *before* any service worker work — at which point the SW work may turn out to be unnecessary.
|
||||
|
||||
### 2. Commit to JS for sidecar merge — do not use Pyodide
|
||||
|
||||
The "missing pieces" section lists two options for re-running `merge_all` on save: reimplement in JS (~150 lines) or call into Pyodide. Pick JS. Reasons:
|
||||
|
||||
- Pyodide is lazy-loaded by `/convert/`. It is **not** warm just because the app is open.
|
||||
- A user tapping Edit → change title → Save would trigger a multi-second Pyodide cold start (~10MB) for a one-line edit. Terrible UX, and it repeats on every cold app launch.
|
||||
- Porting `merge_all` to JS keeps the edit drawer decoupled from the convert page's machinery. The two subsystems stay independent.
|
||||
|
||||
Pyodide should remain convert-page-only.
|
||||
|
||||
### 3. The Workflow 4 diagram contradicts the test plan
|
||||
|
||||
The "Fully offline on phone" workflow shows a "Local Node server" arrow as if it were the chosen path. The §5 test plan picks service workers first. The diagram should reflect that — show the SW path as primary, and drop the Node server box entirely (per the decision above).
|
||||
|
||||
### 4. Missing: data lifecycle on device
|
||||
|
||||
Nothing in the doc covers:
|
||||
|
||||
- How much storage the app is allowed to use on iOS before the OS evicts it.
|
||||
- What happens on uninstall / reinstall.
|
||||
- Sync / conflict resolution if the same activity exists locally and on a cloud instance.
|
||||
|
||||
These don't need solutions today, but they should be acknowledged as open questions. Otherwise Workflow 4 will hit all of them at once during implementation.
|
||||
|
||||
### 5. Reconcile Pyodide payload size
|
||||
|
||||
Line 162 says "~8MB", line 335 says "~10MB". Pick one and use it consistently.
|
||||
|
||||
## Small stuff
|
||||
|
||||
- The federation diagram uses a `Note1` node that won't render as a Mermaid note — it'll appear as a regular box. Use `%%` comments or restructure.
|
||||
- The "iOS: App Store / TestFlight" cell in the PWA-vs-Capacitor table sits in the Capacitor column but reads like a downside. Clarify it's the distribution path, not a limitation relative to PWA.
|
||||
|
||||
## Bottom line
|
||||
|
||||
The plan is sound and the incremental validation approach is right. The two highest-leverage changes:
|
||||
|
||||
1. **Add a data access abstraction layer** before the service worker work. It's small, useful regardless, and may make the SW work moot.
|
||||
2. **Port `merge_all` to JS** so the edit drawer doesn't depend on Pyodide warm-up.
|
||||
|
||||
With `capacitor-nodejs` removed, the offline path is: data access abstraction → IndexedDB-backed loader → JS merge → (optionally) service worker for any remaining `fetch('/data/*')` callsites that can't be migrated to the loader.
|
||||
Reference in New Issue
Block a user