mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-04-25 17:14:57 +02:00
* refactor(emails): refresh Pro welcome email — surface WM Analyst, Widgets, MCP
The Pro welcome email rendered a stale 4-card 2×2 grid (Near-Real-Time,
AI Analyst, Multi-Channel Alerts, "10 Dashboards") that missed three of
the release's signature differentiators and carried a wrong stat ("10
Dashboards" — the actual Pro surface is 50+ panels per the pricing
table). Net effect: paying users got a welcome email that undersold what
they bought and didn't point at the highest-retention action (the brief).
This commit rewrites the Pro path of userWelcomeHtml + featureCardsHtml
to the "signature-first" 2×3 grid designed via the playground at
docs/plans/pro-welcome-email-playground.html:
WM Analyst 🤖 Create Custom Widgets 🧩
MCP Integration 🔌 Daily AI Brief ☀️
Multi-Channel 50+ Pro Panels 📐
Delivery 📬
Other shifts on the Pro path:
- Headline: "Welcome to {planName}!" → "Welcome to {planName} — your
intel, delivered." — parameterized so pro_annual/pro_monthly both read
correctly.
- CTA: "Open Dashboard" (→ /) → "Open My Brief" (→ /brief). The brief
is the single highest-retention action for a new Pro.
- New "Invite your team" referral block above the CTA.
- New support contact line under the CTA, pointing at ADMIN_EMAIL so
replies route correctly.
API-plan path (api_starter/api_starter_annual/api_business/enterprise)
preserved byte-for-byte — same 4 cards, same "Welcome to {planName}!"
headline, same "Open Dashboard" CTA, no referral, no support line. A
follow-up will refresh that variant with its own MCP / Webhooks / API
lead after this ships.
Size: 6.4 KB rendered (was ~4 KB; Gmail clips at ~102 KB).
Playground (for future refreshes): docs/plans/pro-welcome-email-playground.html
* fix(emails): allowlist Pro plans + drop referral block pending Phase 9
Addresses two P1 review comments from @greptile-apps on #3300.
1. `isPro` was a deny-list (`!API_PLANS.has(planKey)`) — every plan key
outside API_PLANS fell into the Pro branch, including `free` (already
in PLAN_DISPLAY) and any future tier (e.g. `pro_team`) added to
PLAN_DISPLAY without a matching API_PLANS update. Switched to an
explicit allowlist: `PRO_PLANS = Set(['pro_monthly','pro_annual'])`.
Anything outside falls back to the neutral "Welcome to {planName}!"
shell + "Open Dashboard" CTA.
2. The "Invite your team — earn a month free" referral block linked to
`https://worldmonitor.app/referrals`, but that page isn't mounted and
`src/services/referral.ts` is still flagged "Phase 9 / Todo #223".
Shipping the block today would send paying users to a 404 and promise
a credit the backend can't grant. Removed the block entirely;
reinstate in a follow-up PR once the referral endpoint + credit logic
ship.
Playground (`docs/plans/pro-welcome-email-playground.html`) remains the
source of truth for future refreshes.
* fix(emails): align card gate with shell gate + wire reply_to for support line
Addresses two more review findings on #3300.
1. `featureCardsHtml()` still branched on `API_PLANS.has(planKey)`, so
every non-API plan (including `free` and any future tier added to
PLAN_DISPLAY without a matching PRO_PLANS update) got the 6-card Pro
marketing grid even though the shell gate (`userWelcomeHtml`) now
allowlists Pro correctly. Result: `free` or unknown-tier users saw
"Welcome to Free!" + "Open Dashboard" but still received "WM Analyst",
"Create Custom Widgets", "MCP Integration", etc. card content.
Fixed by parallel-allowlisting on `!PRO_PLANS.has(planKey)` — falls
through to the 4-card generic grid (same cards the API variant shows)
for anyone who isn't on pro_monthly / pro_annual. The generic grid is
safe for unknown tiers: no Pro-only claims, no specific promises.
2. The Pro support line reads "Questions? Reply to this email or ping
elie@worldmonitor.app" but FROM is `noreply@worldmonitor.app` and the
Resend payload omitted reply_to — replies would bounce.
Added an optional `replyTo` param to `sendEmail()` and thread
ADMIN_EMAIL through on the user welcome call. Gmail and every other
major client honour Reply-To over From when both are present.
The admin notification intentionally passes no replyTo to avoid
routing replies back to ADMIN_EMAIL (self-loop).