Closer/Future.md

12 KiB
Raw Blame History

Future — ideas & improvements backlog

Non-blocking ideas: things that work today but could be better, plus feature ideas. Actual bugs (broken/incorrect behavior) live in ClaudeReport.md, not here.

UI

(No open UI defects. The P0 onboarding/auth crash filed here 2026-06-28 was fixed + verified live and moved to ClaudeReport.md as O-ONBOARD-001 — root cause was painterResource on the <bitmap> ic_launcher_foreground (not the background, as originally guessed); fixed both OnboardingScreen.CtaSlide + AuthVisuals.AuthLogoMark to use the raster closer_launcher_foreground. The "Add to Bucket List mixed dark/light" item is also fully resolved — dialog tokens R16, add-FAB Color(0xFFB98AF4)primary R18.)

QA

Improvement & feature ideas surfaced while QA-testing as a consumer (each works today — none are defects).

  • Tier 3: Compose screenshot diff for visual regression. The static scanner in scripts/theme-scan.sh catches ~80% of light/dark theme mismatches, but it cannot detect compositional failures: a theme-token color used on the wrong surface, a gradient with hardcoded light stops, or subtle contrast collapse. Implement a screenshot pipeline with Roborazzi / Shot / papAROS that renders every AppRoute in both light and dark, pixel-diffs them, and fails on unexpected white backgrounds or invisible text. When done, run it in CI against every UI PR.

  • 🟡 STARTED (R20) — Instrumented / on-device test coverage (was 0 androidTest). First cut shipped: app/src/androidTest/.../ui/FirstRunRenderSmokeTest.kt — an on-device Compose render smoke of the first-run screens (CtaSlide + AuthLogoMark, light + dark), the exact painterResource logo sites that crashed every fresh install in O-ONBOARD-001. It's the net for the "composes fine, crashes on first paint" class the JVM unit tests + static scanners structurally can't catch. Proven (R20): passes green on-device, and FAILS with the original IllegalArgumentException: Only VectorDrawables… when the bug is reintroduced. Infra added: testInstrumentationRunner

    • ui-test-junit4 (build.gradle.kts); also un-blocked the androidTest source set (the stale CanonicalVectorCaptureInstrumentTest couldn't compile against private deriveKey → made it @VisibleForTesting internal). Run: ./gradlew :app:connectedDebugAndroidTest. Still to grow: it's Hilt-/Firebase-free leaf-composable rendering only — extend toward a fuller sign-in → pair → answer daily Q → open a game → send a message flow (needs a Hilt test runner + fakes), and wire connectedDebugAndroidTest into the per-round gate / CI alongside qa/entrypoint_smoke.sh. Prompted by: the QA-plan render-coverage gap (O-ONBOARD-001 escaped because nothing rendered a composable).
  • DONE — Consistent brand glyphs across game cards + waiting surfaces. G-set + G2 (17 glyphs) in res/drawable-nodpi/glyph_*.xml; 13 wired + verified live: every Play-hub card (This or That, How Well, Desire Sync, Connection Challenges, Memory Lane, Date Match, Plan Date, Question Packs, Bucket List, Past Games — Spin the Wheel keeps its full illustration), WaitingForPartner per-game glyph, and Settings (Subscription/Security/Privacy/ Delete). 4 unused have no clean slot (notif uses ic_notification_closer; Today uses hero art; quiet-hours uses its illustration; no export-data row exists). Full map in ClaudeBrandingReview.md. (This-or-That backdrop redesign is Codex C-DARK-UI-001.)

  • Minor proactive-notification gaps (low priority). No push when a partner joins your active game (partner_joined_game)BUILT (2026-06-28, pending deploy): the non-starter opening an active session writes joinedByUsers (rule-gated), onGameSessionUpdate notifies the starter " joined your game" with the joiner's avatar (one-time joinNotifiedAt); foreground shows the standardized in-app banner. Still open: no push when a partner ends/abandons a game (game_ended/game_abandoned) — the other partner sees it in-session / on WaitingForPartner, so nothing's broken, just less proactive. Prompted by: Pass E (R8) inventory.

  • Clarify Connection Challenges day-progress when partners are out of step. If one partner catches up a missed day ("Pick it back up") while the other doesn't, the two devices show different "Day N of 7" (seen R10: QA Day 4 vs Sam Day 3) even though the 🔥 streak stays in sync on both. Not broken (plausibly individual-pace-through-the-series by design), but two people in the same shared challenge seeing different day numbers is confusing — consider a shared "you're on Day N together" framing or a clearer caught-up/ahead indicator. Prompted by: Pass B (R10) Connection Challenges playthrough.

Security hardening (defense-in-depth — not vulnerabilities; rules already hold)

  • Enforce App Check on Firestore (currently OFF). Round 7 raw-API test: an authenticated request with no App Check token (raw Firestore REST) returned 200 for a member — so rules are the sole gate. Rules correctly deny non-members/cross-couple (all 403), so this is not a live hole, but enabling App Check enforcement on Firestore would block non-app clients entirely (defense-in-depth). Prompted by: R7 D3 raw-API angle.
  • Biometric app-lock re-locks on cold-start/process-death but maybe not plain background→resume. R15 code review: MainActivity gates AppNavigation behind BiometricLockScreen when biometricLoginEnabled and sessionVerified is false; sessionVerified is a remember{} that resets on Activity recreation (cold-start, process death) — so the lock re-arms there — but a plain background→foreground without recreation keeps sessionVerified = true, so it may not re-prompt. Architecturally sound (no compose-tree bypass; content isn't composed until unlocked), but consider re-locking on ON_STOP/timeout so a picked-up unlocked phone re-prompts. Prompted by: R15 Pass M code audit (not live-tested — emulator has no enrolled biometric).

Artwork to generate (ChatGPT prompts, house-style-matched) lives in ClaudeBrandingReview.md, not here.

Roadmap — features & strategy (consolidated from the old FUTURE.md, 2026-06-28)

Unbuilt games (Play Hub is live; these remain):

  • Would You Rather / Truth or Dare — tiered sweet→spicy, consent-gated; reuses the deck + match engine. Strong premium "spicy" tier lever.
  • Daily Sync / Rose-Bud-Thorn — one-tap emotional check-in, see partner's; small/new, free retention driver.

"2026, not 2019" differentiators (strategic):

  • AI-personalized prompts — server-side (latest Claude) generate/weight prompts from the couple's history/season/unexplored topics; add a generatePrompts callable (Cloud Functions already in place). Biggest modern lever; pairs with content-metadata routing below.
  • Async + real-time hybrid — partner-presence ("they're here now") for live co-play, everything still async-friendly (long-distance).
  • Multi-modal answers — voice/photo answers (esp. Memory Lane + daily check-ins).
  • Home/lock-screen widgets / live updates — glanceable today's-prompt + partner status (Glance/Wear surface).
  • Gentle gamification — forgiving "gentle streaks" (grace days) + shared wins, not loss-aversion/guilt.
  • Consent-first spicy content — Intimacy/Dare tiers opt-in, double-confirmed, reveal-only-on-overlap.

Cross-platform: Android-first is fine for MVP; iOS is the strategic gap (couples split devices). Decision + plan live in ClaudeiOSPlan.md — don't start before release/trust polish.

Product polish (consolidated from the old FUTURE.md)

  • Skeleton/loading states over bare spinners (P8). LoadingState exists but many screens still use a bare CircularProgressIndicator. Add skeletons for question lists, game histories, home modules, paywall offerings, sync/reveal waits. Acceptance: no primary route shows an isolated spinner on an otherwise blank screen.
  • Paywall / store value framing (P12). Paywall has benefits/restore/legal/RevenueCat; needs stronger value framing, real offering/trial clarity, screenshots/previews, and test coverage before release. (Overlaps Pass K/O.)
  • Content metadata & personalization (P13). The bank is clean; the next leap is routing, not more questions — tag mood/depth/relationship-stage/conflict-safe/intimacy-level/time-needed and extend the selection APIs so prompts adapt to skipped topics, relationship length, and recent answers.

Release / pre-ship (consolidated + re-verified 2026-06-28)

  • Real release config before any store submission. Confirmed still open: app/build.gradle.kts versionCode = 1 / versionName = "0.1.0" and core/navigation/ExternalLinks.kt legal URLs are placeholder TODOs (https://closer.app/privacy|terms|subscription-terms). Already done: a release-blocking Gradle check now fails the build if RC_API_KEY is unset/placeholder (build.gradle.kts:106110), so the old "add a gradle guard" sub-item is closed. Remaining: set real version, real legal/support URLs, real RC key + verify offerings/purchase/restore on internal testing. (Tracked by Pass O release-readiness.)

Help & support surface (consolidated — old "Notes to Consider")

A future Help/Support screen could include: contact support · report a bug · send feedback · FAQ · subscription/billing help · pairing help · recovery-phrase/account help · app version + build number · optional "copy diagnostics" button.