Stu Mason
Stu Mason

Activity

StuMason/cleanconnect
Client SaaS
TypeScript
Pull Request Opened

PR #196 opened: feat: capture Resend email delivery events (PR8)

Logs email delivery events from Resend so we can see what was sent and how it landed — the analytics layer for the newsletter + drip.

What

  • POST /api/resend/webhook — verified with the official Resend\WebhookSignature (Svix), not hand-rolled crypto. Records events for our own sending domain only (config services.resend.tracked_domain); other domains are acked (200, no retry) + ignored.
  • email_events table + EmailEvent model — stores delivered / opened / clicked / bounced / complained, retaining the full payload (click/bounce metadata + tags/broadcast_id for future campaign segmentation).
  • Admin aggregate page /admin/emails — counts by type (last 30 days) + recent events table. New "Emails" nav item.
  • Per-user email events on the admin user screen — backfills the comms-log gap flagged in PR4a.

Fixtures — verified against the docs

tests/Fixtures/resend/*.json match the real Resend payload shape. I checked the live Resend docs: clicked + bounced exact (incl. broadcast_id, template_id, tags, click.{ipAddress,link,timestamp,userAgent}, bounce.{message,subType,type}); delivered/opened/complained share the confirmed common data structure. (Initial drafts were from memory and missing broadcast_id/template_id/tags — corrected.)

Notes

  • Opens are unreliable post-Apple-Mail-Privacy-Protection (inflated) — the UI says so; treat clicks as the real signal.
  • The resend-laravel package auto-registers an unverified /resend/webhook route that nothing listens to (harmless). Ours is the verified one your Resend webhook points at (/api/resend/webhook).
  • RESEND_WEBHOOK_SIGNING_SECRET already set on prod (Coolify). Activates on deploy.

Tests (10 new)

Real-fixture round-trip for all 5 event types, invalid-signature → 401, other-domain dropped, admin aggregate counts, non-admin forbidden.

+705
additions
-0
deletions
21
files changed