diff --git a/docs/Engineering_Reference_Manual.md b/docs/Engineering_Reference_Manual.md index df34a8be..7baf07e5 100644 --- a/docs/Engineering_Reference_Manual.md +++ b/docs/Engineering_Reference_Manual.md @@ -1458,6 +1458,8 @@ OOB code = `truncate6(SHA-256(pubkey ‖ nonce))`. **Root cause**: an orphaned `https` service (from a partial deploy or a previous attempt) is blocking the new background trigger from being created under the same name. The 2nd-gen quota was the proximate cause of the *initial* deploy failure (Cloud Run CPU quota couldn't fit ~35 services at v2's default 1 vCPU/instance; container healthchecks failed with *"Quota exceeded for total allowable CPU per project per region"*) - `functions/src/options.ts` pins `cpu: 'gcf_gen1'`, `concurrency: 1`, `maxInstances: 5` as the workaround. **Fix / deploy pattern**: when the "Changing from an HTTPS function to a background triggered function" error appears, `firebase functions:delete ` then redeploy. Diagnose with `firebase functions:list` - healthy Firestore triggers show `google.cloud.firestore.document.v1.*` in the trigger column; strays show `https`. For the Eventarc propagation race, wait 2-3 minutes and retry. **At launch**: request the Cloud Run CPU quota increase (console → IAM & Admin → Quotas, us-central1), then drop `cpu`/`concurrency` from `options.ts` to restore 1 vCPU + concurrency 80. **Re-introduction risk**: a deploy that changes a function's *type* (callable → scheduled → trigger) under the same name WILL fail. Plan the rename + 2-step delete/redeploy if you need to refactor a function's surface. + +### A-201 - Date Match premium ideas ungated (a badge is NOT a gate) **Symptom**: free users could view, like and match `isPremium` date ideas with no paywall. `DateMatchRepositoryImpl.getDateIdeas()` returned `DateIdeaSeed.all` with no entitlement filter; `DateMatchViewModel` had no `CouplePremiumChecker`; `DateMatchScreen` rendered only a cosmetic `PremiumBadge()`. (Server still blocked real premium self-grant, so only premium *content* leaked, not the entitlement.) **Fix (R12)**: `DateMatchViewModel` injects `CouplePremiumChecker`; `swipeCurrent` intercepts LOVE/MAYBE on a premium idea when neither partner is premium → emits `paywallRequired` → `DateMatchScreen` navigates to the Paywall; SKIP still passes; the deck stays on the card. Mirrors the established [gate pattern](#premium-gated-features-and-gate-pattern). **Re-introduction risk / lesson**: a feature can ship an `isPremium` content flag + a `PremiumBadge` with **no enforcement at all**. When adding premium content, wire a real `CouplePremiumChecker` gate (filter OR paywall-on-interaction) - a badge is a label, not a lock. Audit by **trying to USE premium content as a free user**, not by grepping for checker usages (which only finds the features that already have one).