docs: record Cloud Functions v2 deploy follow-ups in Future.md

New "Backend — Cloud Functions v2 follow-ups" section (deployed 2026-07-08):
- launch-time quota work: raise Cloud Run CPU quota, then drop cpu:'gcf_gen1'/concurrency:1,
  revisit maxInstances, add minInstances to cold-start-sensitive callables
- ops recovery pattern for orphaned https strays from failed trigger creates
- Node 22 runtime bump before the 2026-10-30 Node 20 decommission
- RevenueCat webhook re-enable steps (secret seed, uncomment export, delete dormant v1 first)

Also refresh the npm-audit note: 9 moderates remain post v7 bump — firebase-admin transitive.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
null 2026-07-08 03:24:06 -05:00
parent 7d015e3ab9
commit 805ef9f2e7
1 changed files with 32 additions and 1 deletions

View File

@ -94,7 +94,7 @@ tokens R16, add-FAB `Color(0xFFB98AF4)`→`primary` R18.)_
- **Error-surfacing standardization** — BucketList/MessagesInbox/PlayHub/AnswerHistory/WeeklyRecap/Onboarding VMs swallow load errors (blank screens); adopt uiState.error + ErrorState for reads, _events snackbar for writes (ConversationViewModel pattern). - **Error-surfacing standardization** — BucketList/MessagesInbox/PlayHub/AnswerHistory/WeeklyRecap/Onboarding VMs swallow load errors (blank screens); adopt uiState.error + ErrorState for reads, _events snackbar for writes (ConversationViewModel pattern).
- **Retention (from ClaudeGamesReview.md):** HowWell role-swap rematch CTA · return-tomorrow beat on all results screens · per-couple seen-question memory for DS (102-item pool) + shuffle Date Match deck (deterministic first card for every couple) · exclude daily_fun_mc from HowWell prediction pool · hide Challenges day-N+1 prompt until its day · analytics: first-answer/reveal-viewed/waiting-abandoned/notif-tap events. - **Retention (from ClaudeGamesReview.md):** HowWell role-swap rematch CTA · return-tomorrow beat on all results screens · per-couple seen-question memory for DS (102-item pool) + shuffle Date Match deck (deterministic first card for every couple) · exclude daily_fun_mc from HowWell prediction pool · hide Challenges day-N+1 prompt until its day · analytics: first-answer/reveal-viewed/waiting-abandoned/notif-tap events.
- **Content retag**`daily_fun_mc` rows carry `sex='neutral'` (benign today only via the binary filter; retag to keep Desire Sync's pool clean). 48/150 sexual_preferences items are non-binary configs (Wheel-only) — intended? - **Content retag**`daily_fun_mc` rows carry `sex='neutral'` (benign today only via the binary filter; retag to keep Desire Sync's pool clean). 48/150 sexual_preferences items are non-binary configs (Wheel-only) — intended?
- **npm audit**10 moderate (retry-request/teeny-request via @google-cloud/storage transitive); revisit on next functions dependency bump. - **npm audit**9 moderate remain after the 2026-07-08 firebase-functions v7 bump (retry-request/teeny-request via @google-cloud/storage, i.e. **firebase-admin** transitive — untouched by the functions bump); revisit on the next firebase-admin major.
- **Banner lifecycle** — GamePromptController results banner should dismiss once results are viewed (BANNER-LIFE-001). - **Banner lifecycle** — GamePromptController results banner should dismiss once results are viewed (BANNER-LIFE-001).
@ -158,6 +158,37 @@ Improvement & feature ideas surfaced while QA-testing as a consumer (each works
> Artwork to generate (ChatGPT prompts, house-style-matched) lives in `ClaudeBrandingReview.md`, not here. > Artwork to generate (ChatGPT prompts, house-style-matched) lives in `ClaudeBrandingReview.md`, not here.
## Backend — Cloud Functions v2 follow-ups (migrated + deployed 2026-07-08)
All 34 functions run as **2nd gen** in `closer-app-22014` (plus `onUserDelete`, intentionally v1 — gen 2 has
no `auth.user().onDelete`). Deploy-day learnings + deferred items:
- **Restore full vCPU + concurrency at launch (quota).** The project's default **Cloud Run regional CPU quota**
can't fit ~35 services at v2's default 1 vCPU/instance — deploys failed container healthchecks with
*"Quota exceeded for total allowable CPU per project per region"*, so `functions/src/options.ts` pins
`cpu: 'gcf_gen1'` (gen1 fractional tiers, 256MiB → ⅙ vCPU), `concurrency: 1`, `maxInstances: 5`. Costless at
dev scale. **At launch:** request the Cloud Run CPU quota increase (console → IAM & Admin → Quotas,
us-central1), then drop the `cpu`/`concurrency` overrides to restore 1 vCPU + concurrency 80, revisit
`maxInstances`, and consider `minInstances: 1` on the cold-start-sensitive callables (`checkDeviceIntegrity`,
`createInviteCallable`, `acceptInviteCallable` — app startup + pairing are first impressions).
- **Deploy-failure recovery pattern (keep for ops).** A background-trigger create that fails mid-deploy (quota,
Eventarc propagation) leaves an **orphaned `https` service**; retries then error *"Changing from an HTTPS
function to a background triggered function is not allowed."* Fix: `firebase functions:delete <name>` the
stray, then redeploy it. Diagnose with `firebase functions:list` — healthy Firestore triggers show
`google.cloud.firestore.document.v1.*`, strays show `https`. (First-ever gen-2 deploy also needs Eventarc
service-agent IAM to propagate — the "retry in a few minutes" failures were this.)
- **Node runtime bump — hard deadline 2026-10-30.** Node 20 was deprecated 2026-04-30 and is **decommissioned
2026-10-30**, after which deploys fail. Bump `functions/package.json` `engines.node` to 22 (verify the gen-1
`onUserDelete` supports it), build, redeploy. Every deploy currently prints the warning.
- **RevenueCat webhook re-enable (when billing is set up).** RevenueCat has no account yet, so the migrated v2
`revenueCatWebhook` is **not deployed** — its export is commented out in `functions/src/index.ts` because
`defineSecret('REVENUECAT_SIGNING_KEY')` is validated codebase-wide at deploy (a missing secret fails *every*
function's deploy, even with `--only`). To enable: ① create the RevenueCat project + webhook, ② seed the real
Ed25519 public key — `firebase functions:secrets:set REVENUECAT_SIGNING_KEY`, ③ uncomment the export,
**delete the old dormant v1 `revenueCatWebhook` first** (still deployed; same-name v1→v2 is blocked
in-place), ⑤ `firebase deploy --only functions:revenueCatWebhook`, ⑥ point RevenueCat at the function URL and
send a test event.
## Roadmap — features & strategy (consolidated from the old `FUTURE.md`, 2026-06-28) ## Roadmap — features & strategy (consolidated from the old `FUTURE.md`, 2026-06-28)
**Unbuilt games (Play Hub is live; these remain):** **Unbuilt games (Play Hub is live; these remain):**