Commit Graph

11 Commits

Author SHA1 Message Date
null 3ab76fbcdf feat(mobile): go fully native — native Tracker home over the JSON API (no WebView)
Replace the WebView SPA handoff with the app's own native screens that call the
same JSON API — hitting the on-device server in local mode or the remote server
in server mode (same code, base URL switches). Uses the api.ts client built earlier.

- api.ts: typed getTracker/toggleBillPaid/createBill/logout + a shared authed
  mutate() helper (fetches + echoes the CSRF token); SessionUser type.
- TrackerScreen.tsx: native monthly Tracker — month header, Paid/Needs-action/Bills/
  Remaining stat tiles, prev/next month nav, and bill rows with a one-tap mark-paid
  toggle that re-fetches. Loading/error/empty states. Currency + dates via Intl in
  the WebView (Chromium — full ICU, unlike the embedded server).
- MainApp.tsx + app.css: native app shell (top bar + avatar) and a bottom tab bar
  (Tracker built; Calendar/Insights/Account are placeholders/account for now).
- App.tsx: renders MainApp instead of window.location.replace to the SPA; native
  auth for both modes (local login shows 'this device'); 401 bounces to login.

Verified on the x86_64 emulator: two-doors setup -> native login -> native Tracker
with live bills -> tap to mark paid -> tiles + row update. No WebView.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 14:41:04 -05:00
null 27a76e92b8 feat(mobile): Seamless brand reskin + two-doors setup on a design-token system
Bring the native shell up to the web app's brand so the setup->app handoff is
seamless, and make it token-driven instead of hard-coded hex.

- src/theme.css: design tokens as the single source of truth — a primitive brand
  ramp (the greens from the web app's mark.svg) mapped to semantic roles
  (--color-*, --radius-*, --space-*). Change the brand in one place; every screen
  follows. index.css now references only tokens (no raw hex).
- src/LogoMark.tsx: shared brand mark component (the real bar-chart+checkmark),
  replacing the indigo crosshair and de-duplicating inline SVG.
- SetupScreen rebuilt as a two-doors chooser for ease of use: 'Run on this phone'
  (private/offline, one tap) and 'Connect to a server' (reveals the URL field only
  when chosen), keeping the insecure-http warning.
- De-hardcoded the rest: App splash + biometric/loading/lock screens now use
  classes and the accent token instead of inline styles and #6366f1.

Verified on the x86_64 emulator: new setup renders in-brand, 'Connect to a server'
reveals the field, 'Run on this phone' boots the local server and loads the app.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 14:22:41 -05:00
null 7f7c0ef7b0 feat(mobile): warn on insecure http:// server URLs before native login
SetupScreen now flags a plain http:// address (to anything but loopback) — the
native login POST would send the password in cleartext — and requires an explicit
second tap ("Connect anyway") to proceed, with an override for trusted LAN setups.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 10:51:35 -05:00
null c1523ece1a feat(mobile): shared api/config layer, server-mode CSRF fix, robustness + update-safe DB (batch 10)
Unify the native shell and harden it:

- src/config.ts: single source for local host/port, preference keys, secure-storage
  key, timeouts, and CSRF constants (dedupes LOCAL_URL etc. across App/LoadingScreen).
- src/api.ts: one HTTP client — credentials mode, AbortController timeouts, and error
  normalization into user-facing messages (network/timeout/401/403/429/5xx), with typed
  auth responses.
- Batch 10 CSRF fix: /api/auth/totp/challenge is not CSRF-exempt, so the native TOTP
  step now fetches GET /api/auth/csrf-token and echoes it as x-csrf-token (mirrors the
  web client); TOTP login no longer breaks for 2FA users.
- Error-handling / boot robustness: LoadingScreen gets a health-poll timeout and
  surfaces main.js's {type:'serverError'} channel messages instead of spinning forever;
  App.tsx bootstrap and the encryption-key fetch now .catch to a visible state; crypto.ts
  reports secure-storage failures.
- Data safety: move the SQLite DB, backups, and tmp OUT of nodejs-project into the app's
  filesDir (bt-data). nodejs-mobile re-copies nodejs-project on every app update, which was
  silently wiping local-mode data. Verified on the emulator: create data -> bump versionCode
  -> reinstall -> migrations skipped, no re-seed, data persists.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 10:48:23 -05:00
null 2c29ec45bd feat(mobile): run the TypeScript backend on Node 18 in local mode (batch 7-9)
The web app migrated its server to TypeScript (server.cts) on Express 5 /
openid-client 6 / kysely, none of which ran on the old embedded Node 12.19.
Rebuild the local-mode pipeline for Node 18:

- sync-nodejs-project.sh: sync server.cts + .cts/.mts + setup/ + seed data.
- transpile-node18.js (replaces transpile-node12.js): esbuild TS->CJS in place,
  keeping .cts/.mts filenames (Node 18's CJS loader loads unknown extensions via
  the .js handler, so the explicit-extension require() graph keeps resolving).
- prepare-local-mode-deps.js: bundle ESM-only kysely to CJS, stub openid-client
  (unused on-device), and rewrite path-to-regexp's \p{} regexes to ASCII (the
  no-ICU Node 18 build can't compile unicode-property escapes).
- build-better-sqlite3-node18.sh (replaces the Node-12 build/fix scripts):
  cross-compile for all three ABIs against the Node 18 ABI, injecting libnode.so
  as a NEEDED entry so V8 symbols resolve at dlopen.
- main.js: entry -> server.cts; drop the now-native randomUUID/hkdfSync polyfills
  (keep the Intl shim); add TMPDIR + a startup-error relay to the WebView.
- nodejs-project/package.json: server dep set matched to the web app.

Verified end-to-end on the x86_64 emulator: boot -> migrations -> seed -> login
-> create bill -> force-stop -> relaunch -> data persists. arm64/armv7 prebuilds
are built and link-verified; a physical-device run is still pending.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 09:42:53 -05:00
null 3e115dd349 feat(mobile): Node 18.20.4 embedded runtime + cordova-bridge fix (batch 6/6.5)
Swap the abandoned nodejs-mobile Node 12.19 runtime for the nodejs-mobile core
Node 18.20.4 Android build, staged into the plugin by install-node18-runtime.sh
(the cordova fork's Android side is still Node 12). Re-register the cordova-bridge
linked binding via explicit napi_module_register(NM_F_LINKED), since Node 18's
NAPI_MODULE_X macro drops the flag and process._linkedBinding could no longer
find it. Verified on the x86_64 emulator: process.version=v18.20.4 and a full
native<->node channel round-trip (device encryption key delivered).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 09:42:34 -05:00
null 0c58b7a4a5 feat: better-sqlite3 ARM prebuilds for real Android devices (batch 3) 2026-06-14 18:27:03 -05:00
null d55e73120c feat: server-mode login, biometric unlock, CapacitorHttp native auth (batch 4.5) 2026-06-14 18:08:01 -05:00
null 5a8135fcd0 feat: prepare-android-assets, nodejs project sync, loading screen, capacitor config updates, better-sqlite3 android fix script 2026-06-14 13:10:14 -05:00
null e1f63a8215 feat: add encryption key bridge for nodejs-mobile local mode
- Add src/crypto.ts: generates 48-byte hex key, stores via capacitor-secure-storage-plugin (Android Keystore / iOS Keychain)
- Add nodejs-assets/nodejs-project/main.js: waits for encryption key from WebView before starting server
- Update LoadingScreen.tsx: sends encryption key to embedded Node process over nodejs-mobile-cordova channel
- Add capacitor-secure-storage-plugin dependency
- Update vite-env.d.ts with channel types for nodejs
- Add private docs to .gitignore (PROJECT.md, PLAN.md, etc.)
2026-06-13 20:13:12 -05:00
null 186d651862 feat: initial mobile app extracted from bill-tracker repo
- Capacitor + React + Vite app for Android
- SetupScreen for server URL connection or local mode
- LoadingScreen with nodejs-mobile health polling
- sync-nodejs-project.sh: --source flag (defaults to ../bill-tracker)
- transpile-node12.js: uses own esbuild devDependency
- prepare-android-assets.js: nodejs-mobile cordova asset packaging
2026-06-13 20:00:05 -05:00