From 805ef9f2e754fcb19bfc54ddebc52f9bb2feda14 Mon Sep 17 00:00:00 2001 From: null Date: Wed, 8 Jul 2026 03:24:06 -0500 Subject: [PATCH] docs: record Cloud Functions v2 deploy follow-ups in Future.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- Future.md | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/Future.md b/Future.md index 2a3a41e9..6a546024 100644 --- a/Future.md +++ b/Future.md @@ -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). - **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? -- **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). @@ -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. +## 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 ` 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) **Unbuilt games (Play Hub is live; these remain):**