Commit Graph

3 Commits

Author SHA1 Message Date
null a63bf350b1 fix(crash): LocalDate.ofInstant crashes on API<34 + add Lint/R8 CI gates
Adding Android Lint to CI immediately caught two real crash bugs invisible to
all emulator QA (the fixture emulators run API 34+):

- SettingsViewModel + YourProgressViewModel called LocalDate.ofInstant, which
  was only added in API 34 — but minSdk is 26. On every device running Android
  8-13 (the bulk of the install base) these throw NoSuchMethodError and crash
  the Settings and Your Progress screens. Fixed with the API-26-safe equivalent
  Instant.atZone(zone).toLocalDate() (same result).

The other two Lint errors were false positives (ProduceStateDoesNotAssignValue
on two EncryptedChatImage composables that DO assign value inside the producer —
the check misfires on a suspend/?.let RHS) — explicitly @Suppress'd with a note,
so Lint reaches 0 errors legitimately rather than via a blanket baseline.

CI (android-ci.yml) gains two jobs:
- android-lint: ./gradlew :app:lintDebug (fails on error-severity; 113 existing
  warnings are non-fatal and left for a separate burndown).
- release-build: first-ever R8 gate — builds :app:bundleRelease with a throwaway
  keystore + dummy RC_API_KEY (satisfies the release guards; AAB not distributed),
  so the minify/shrink/sign toolchain can never silently rot. Verified locally:
  bundleRelease SUCCEEDS today (95MB AAB). A green build proves the toolchain,
  not runtime survival of reflectively-loaded classes (Tink) — that stays a
  release-APK QA item.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 18:41:04 -05:00
null 3cd3195e3f build(functions): bump runtime Node 20 → 22 (Node 20 decommissioned 2026-10-30)
Node 20 was deprecated 2026-04-30 and deploys are blocked after 2026-10-30. nodejs22 is GA
for BOTH gens (deprecation 2027-04-30) — required because the runtime is codebase-wide and
onUserDelete stays gen1. nodejs24 was checked per plan and rejected: 2nd-gen only.

- functions/package.json engines.node 20 → 22 (the deploy-facing change; dist unaffected)
- .github/workflows/backend-ci.yml: both setup-node pins 20 → 22 so CI matches prod

Verified pre-deploy: tsc clean, 70 tests green, emulator discovery loads all 35 / 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 03:42:18 -05:00
null 55699e17ed feat: security hardening, CI, analytics, invite deep links, solo mode, weekly recap
Roadmap phases 0-3.1 (see plan). Verified: unit tests, functions tests,
firestore rules 119/119, live emulator smokes.

Security + CI:
- Move App Check debug token out of committed build.gradle.kts to
  local.properties (secret() resolver: local.properties -> -P -> env);
  admin service-account key relocated outside the repo.
- Add GitHub Actions (android unit/scan/gitleaks, backend functions +
  rules emulator via emulators:exec) with a CI google-services.json stub
  and a reviewed .gitleaksignore baseline.
- Fix firestore rules tests to the current deployed contract (was 108/118,
  now 119/119).

Analytics + consent:
- FirebaseRetentionAnalytics behind a fail-safe composite sink, single-
  sourced hashing (AnalyticsHashing), Settings -> Privacy opt-out toggle
  gating Firebase + the sink, and the ~11 missing event call sites.
- NoPlaintextInAnalyticsTest guards the content-free rule at build time.

Funnel:
- Invite deep links (https App Link + closer:// fallback), JoinLink parser,
  PendingJoinCodeStore, prefilled/already-paired pairing, richer share text.
- Solo pre-pairing: UnpairedLockedCard on Play, SoloAnswerMigrator + consent
  dialog moving pre-pairing answers into Couple Lore.

Weekly recap:
- WeeklyRecapScreen driven by the existing generator from local answer data,
  Home card rewired, content-free shareable card.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 20:33:38 -05:00