You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: emails/CATALOG.md
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,7 +13,9 @@ These are the locally configured draft journeys. This document is not a live sta
13
13
|[Teammate onboarding](https://app.loops.so/workflows/cmtvpm0ag01it0j37w02o6wav)| teammate | Day 0, Day 3 | 2 |
14
14
|[Former customer follow-up](https://app.loops.so/workflows/cmtvpm8zm01ii0j01cz7d15qr)| former | Day 14 | 1 |
15
15
16
-
All journeys require global subscription, positive Cap consent, the exact audience, lifecycle enabled and onboarding eligible. These filters continue to apply downstream. Free/former promotional flows additionally exclude teammates and require promotional eligibility. Customer and teammate flows still require marketing consent.
16
+
Completed signups reach Loops through Stripe; SSO uses a small direct fallback. Cap supplies targeting through a durable sync queue, without a separate marketing opt-in step. Existing opt-outs and suppressions take precedence. The integration is not deployed. Historical imports stay held; a new accepted invitation can start teammate help only.
17
+
18
+
Current draft journeys require global subscription, capConsent=subscribed, the exact audience, lifecycle enabled and onboarding eligible. capConsent is a legacy migration guard, not a separate consent-capture requirement for new signups. These filters continue to apply downstream. Free/former promotional flows additionally exclude teammates and require promotional eligibility.
17
19
18
20
Teammate history takes priority over paid/free classification. Ambiguous contacts receive no journey. [Audience classification and consent](../scripts/loops/README.md#audience-rules).
19
21
@@ -112,7 +114,7 @@ flowchart TD
112
114
113
115
## Campaign templates
114
116
115
-
Campaigns are manually scheduled product updates, with no automatic enrollment. Both require subscription, positive consent and their exact audience. The free template also requires promotional eligibility and excludes teammates.
117
+
Campaigns are manually scheduled product updates, with no automatic enrollment. Both require subscription, capConsent=subscribed and their exact audience. The free template also requires promotional eligibility and excludes teammates.
116
118
117
119
| Campaign | Audience | Subject and source | Loops ID |
Copy file name to clipboardExpand all lines: emails/QA.md
+9-1Lines changed: 9 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -43,7 +43,15 @@ The local suite checks consent precedence, suppression preservation, customer an
43
43
44
44
## Remaining gate before switching
45
45
46
-
The deployed Cap signup/purchase/invite/opt-out path through an enrollment dispatcher and into an inbox has not been proven. The reviewed schema is not deployed, new explicit consent capture/enrollment and retry/deduplication dispatch need implementation, and the current sync intentionally keeps contacts held. Freshness expiry and scheduler monitoring are also required: an old `capVerifiedAt` value does not automatically prevent a Loops send.
46
+
The new implementation uses native Stripe imports, a held SSO fallback, and `loops_sync_jobs` for durable enrichment. Local routing tests cover missing Stripe imports, incomplete billing bootstrap, teammate persistence, an existing account accepting a new invite, global/list opt-outs, missing list membership, replay, identity conflicts and imported holds. The full email-script, profile and lifecycle suites passed 54 tests; existing SSO and Stripe subscription suites passed another 83. Database and web TypeScript checks passed.
47
+
48
+
Five integration checks passed on an isolated PlanetScale branch: transactional rollback, overlapping claims, expired lease recovery, newer work surviving an older completion, and an indexed due query. A full `db:push` attempt hit the repository's unrelated storage prefix-index quoting bug; the exact generated Loops migration was then applied and independently checked on the empty test branch. No production schema or data changed. The owned schema-only test branch was deleted after verification.
49
+
50
+
The worker was exercised from synthetic database records through the real Loops API, including a simulated HTTP 429 followed by a successful retry, free and SSO teammate classification, a free-to-teammate transition, and a later unsubscribe surviving a billing change. Separate live checks cover imported holds and list removals. Loops omits an API-removed list from the returned map; the runtime now treats missing membership as ineligible and never re-adds lists during updates. All owned test contacts were read back held and globally unsubscribed. These checks sent no email and kept production workflows in Draft.
51
+
52
+
The native Stripe integration is connected to Cap Software, Inc. and enabled for customer creation and updates only. A new owned live Stripe customer appeared in Loops; two later name changes updated that same contact. Name import and Product updates and tips list assignment were verified, and a global unsubscribe survived the final Stripe update. No payments, subscriptions or emails were created. The test contact remains held and globally unsubscribed. Both saved event mappings were checked after reload. A separate test-mode Stripe customer did not import through this live connection, is not counted as a passing native test, and was deleted after verification.
53
+
54
+
The deployed Cap signup/purchase/invite path has not yet been proven end to end. Production schema/code deployment, recipient Preference Center list-opt-out preservation across native Stripe updates, the final Bento suppression delta, and scheduler monitoring remain cutover gates. The Cap-worker API list-removal check above does not independently prove native Stripe handling of a recipient list opt-out. The worker retries failed updates, but Loops still uses the last successfully synced values during an outage; `capVerifiedAt` is not a native expiry rule.
47
55
48
56
Follow the [cutover runbook](../scripts/loops/README.md#before-any-activation). Test that deployed path using owned inboxes, including outages and retries, before requesting production activation. Keep imported history held, preserve all opt-outs, reconcile fresh Bento changes, check Resend overlap and disable duplicate Bento automation only during the approved cutover.
0 commit comments