fix(mobile): clear technical debt — real SHA-256, feed pagination, search
source_hash: BAS JSON import now computes SHA-256 via crypto.subtle.digest
instead of the '${id}-${length}' stub. No extra package — Hermes supports
Web Crypto API natively.
Feed pagination: useActivities(query, limit) accepts a LIMIT parameter.
The feed screen starts at 50, calls loadMore() via FlatList onEndReached
(threshold 0.3) to increment by 50 each time. useActivityCount(query)
drives the hasMore guard so loadMore is a no-op at the end of the list.
Feed search: compact TextInput below the header filters by title via
SQLite json_extract LIKE. Changing the query resets limit to PAGE_SIZE
so stale paginated results don't linger.
Docs: close the three resolved debt items; keep only the accepted
background-polling limitation as a known gap.
This commit is contained in:
+3
-31
@@ -985,41 +985,13 @@ and re-extracted server-side.
|
||||
This section documents mismatches between what the plan describes and what is
|
||||
actually implemented, plus features not yet in the plan.
|
||||
|
||||
### Remaining stubs
|
||||
|
||||
**`source_hash` for BAS JSON import is not SHA-256** (`mobile/app/(tabs)/import.tsx`)
|
||||
|
||||
BAS JSON import records `source_hash = "${detail.id}-${text.length}"` — a rough
|
||||
stand-in. FIT/GPX/TCX imports (via Pyodide) correctly compute SHA-256 of the file
|
||||
bytes. The BAS JSON path still uses the stub; dedup works in practice (activity IDs
|
||||
are unique) but the hash is not a real content fingerprint.
|
||||
|
||||
**`auto_import_path` only triggers on app open, not in background**
|
||||
### `auto_import_path` only triggers on app open, not in background
|
||||
|
||||
The watch-folder scan runs when the Import tab mounts and when the app comes to
|
||||
foreground (`AppState` → `'active'`). There is no true background task that fires
|
||||
while the app is closed. Full background polling would require `expo-background-fetch`
|
||||
but cannot use the Pyodide WebView (a UI component).
|
||||
|
||||
### Missing from the plan entirely
|
||||
|
||||
**Feed pagination**
|
||||
|
||||
`useActivities()` in `mobile/db/queries.ts` calls `getAllSync` with no `LIMIT`.
|
||||
This is fine for tens of activities, but will cause noticeable lag at hundreds.
|
||||
Should add cursor-based pagination or a virtual list with lazy loading.
|
||||
|
||||
**Individual activity deletion**
|
||||
|
||||
There is no way to delete a single activity, local or remote. "Reset synced data"
|
||||
nukes all remote activities at once. A long-press or swipe-to-delete gesture on
|
||||
activity cards is needed, with a server-side `DELETE /api/activity/{id}` endpoint
|
||||
for remote activities.
|
||||
|
||||
**Feed search and filter**
|
||||
|
||||
No search bar, no sport filter, no date picker. The feed is a flat reverse-
|
||||
chronological list. As the feed grows this becomes a usability problem.
|
||||
but cannot use the Pyodide WebView (a UI component). Accepted limitation — the
|
||||
on-open trigger covers the primary Karoo use case (open app after a ride).
|
||||
|
||||
**Token expiry and the reconnect flow**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user