Skip to content

feat: cross-promo block in the credits purchase receipt email - #445

Merged
ralyodio merged 1 commit into
masterfrom
feat/cross-promo
Nov 11, 2026
Merged

ralyodio merged 1 commit into
masterfrom
feat/cross-promo

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Adds the shared `@profullstack/cross-promo` block to the credits purchase receipt (`sendPurchaseReceiptEmail` in `lib/email.ts`).

  • `receiptPromo(to)`: audience `publishers`, site `crawlproof.com` (never promoted), seeded by recipient, themed to the dark email shell (accent #6ee7b7).
  • `purchaseReceiptEmailHtml` takes an optional `promoHtml`, rendered as a row after "View billing" / the PDF note and above the footer note. Without it the receipt is unchanged.
  • Dependency added with bun (`bun.lock` updated).
  • `tests/email-cross-promo.test.ts`: promo excludes crawlproof.com, the sent receipt contains the block after the billing link (CROSS_PROMO=bundled, emailer mocked). Full vitest 3062 pass, tsc clean.

🤖 Generated with Claude Code

Uses @profullstack/cross-promo (live catalog, bundled fallback, never throws):
audience publishers, site crawlproof.com (never promotes itself), themed to
the dark email shell, placed after the billing link and above the footer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​profullstack/​cross-promo@​0.1.0751008990100

View full report

@ralyodio

Copy link
Copy Markdown
Contributor Author

The profullstack org's GitHub Actions queue is backed up (about 400 runs queued across the org, crawlproof jobs waiting since 09:07), so I ran the CI gate locally on this head: bun install --frozen-lockfile, root + worker tsc --noEmit clean, bun run test 257 files / 3062 tests pass, gitleaks clean, threatcrush clean on lib/email.ts. Merging, then deploying with deploy-app.sh on dev2 the same way deploy-dev2.yml does, since that workflow is stuck in the same queue.

@ralyodio
ralyodio merged commit 2de0db1 into master Nov 11, 2026
8 checks passed
@github-actions

Copy link
Copy Markdown

ThreatCrush Security Scan

50 finding(s)

HIGH/CRITICAL: 2 | MEDIUM: 30 | LOW: 18

Severity Rule Location
HIGH tls-verification-disabled lib/onion.ts:50
HIGH secret-generic-credential lib/sp/platforms/facebook.ts:32
MEDIUM js-unescaped-html-sink app/(app)/dashboard/admin/email-broadcast/EmailBroadcastForm.tsx:125
MEDIUM js-unescaped-html-sink app/(app)/dashboard/projects/[id]/autoblog/articles/[articleId]/page.tsx:214
MEDIUM js-unescaped-html-sink app/(marketing)/blog/[slug]/page.tsx:74
MEDIUM js-unescaped-html-sink app/(marketing)/blog/[slug]/page.tsx:102
MEDIUM js-unescaped-html-sink app/(marketing)/recent/page.tsx:177
MEDIUM js-unescaped-html-sink app/(marketing)/recent/page.tsx:181
MEDIUM js-unescaped-html-sink app/c/[project]/[slug]/page.tsx:76
MEDIUM js-unescaped-html-sink app/c/[project]/page.tsx:58
MEDIUM js-unescaped-html-sink app/careers.js/route.ts:228
MEDIUM js-unescaped-html-sink app/careers.js/route.ts:285
MEDIUM js-unescaped-html-sink app/layout.tsx:129
MEDIUM js-open-redirect app/login/form.tsx:40
MEDIUM js-unescaped-html-sink app/r/[token]/page.tsx:164
MEDIUM js-open-redirect app/signup/form.tsx:65
MEDIUM js-unescaped-html-sink app/surveys/[slug]/invite/page.tsx:68
MEDIUM js-unescaped-html-sink components/json-ld.tsx:8
MEDIUM js-unescaped-html-sink components/pit-footer.tsx:17
MEDIUM js-unescaped-html-sink components/report/markdown-view.tsx:16
MEDIUM js-unescaped-html-sink lib/careers/page-templates.ts:198
MEDIUM js-dynamic-code-execution lib/crawl-limits.ts:67
MEDIUM redos-nested-quantifier lib/emailMarkdown.ts:41
MEDIUM redos-nested-quantifier lib/emailMarkdown.ts:324
MEDIUM redos-nested-quantifier lib/lx/articleGen.ts:100
MEDIUM redos-nested-quantifier lib/tracker/agent-gate.ts:61
MEDIUM sh-predictable-temp-path ops/selfhost/server/setup-supabase.sh:218
MEDIUM sql-template-interpolation scripts/detect-slot-themes.ts:31
MEDIUM sql-template-interpolation scripts/purge-constructed-keywords.ts:163
MEDIUM sql-template-interpolation scripts/purge-offniche-keywords.ts:124
MEDIUM js-dynamic-code-execution scripts/test-crawl-limits.mjs:14
MEDIUM js-dynamic-code-execution scripts/test-crawl-limits.mjs:24
LOW secret-generic-credential app/(marketing)/docs/autoblog-webhook/page.tsx:156
LOW secret-generic-credential lib/sealed/migrate.ts:38
LOW secret-generic-credential lib/sp/platforms/linkedin.ts:25
LOW secret-generic-api-key tests/ads-generator-agent.test.ts:160
LOW secret-generic-api-key tests/ads-generator-agent.test.ts:187
LOW js-dynamic-code-execution tests/careers-page-templates.test.ts:21
LOW js-dynamic-code-execution tests/careers-widget-script.test.ts:19
LOW js-dynamic-code-execution tests/careers-widget-script.test.ts:69
LOW js-dynamic-code-execution tests/contract/ad-visitor-id.test.ts:51
LOW js-dynamic-code-execution tests/contract/ad-visitor-id.test.ts:52
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:20
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:24
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:25
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:26
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:31
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:35
LOW secret-generic-credential tests/contract/posthog-integration.test.ts:13
LOW secret-generic-credential tests/lead-campaign.test.ts:16

Snippets are redacted; ThreatCrush never prints matched credential material.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant