stack/apps/backend/src/app/api/latest/emails
BilalG1 4f99c469fe
stack auth preview mode (#1307)
<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Preview mode: sandboxed experience with mock projects, placeholder
data, and disabled external integrations (payments, webhooks, email
rendering, session replays).
* One-click preview project creation and automatic preview sign-in for
quick access.

* **New Features — Walkthrough**
* Interactive guided walkthroughs with spotlight, animated cursor,
step-driven navigation, and targeted element hooks.

* **Style**
* UI/UX adjustments for preview: theme behavior, conditional
banners/alerts, informational alerts, and walkthrough attributes added
across pages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-08 16:57:42 -07:00
..
capacity-boost [Refactor][Feat][Fix] Rework Email Section With New Sent Page, Better Drafts Page, and Settings Page (#1221) 2026-03-11 12:01:36 -07:00
delivery-info [Refactor][Feat][Fix] Rework Email Section With New Sent Page, Better Drafts Page, and Settings Page (#1221) 2026-03-11 12:01:36 -07:00
notification-preference clickhouse new syncs and verify-data (#1304) 2026-04-08 14:43:22 -07:00
outbox clickhouse new syncs and verify-data (#1304) 2026-04-08 14:43:22 -07:00
render-email stack auth preview mode (#1307) 2026-04-08 16:57:42 -07:00
send-email [Refactor][Feat][Fix] Rework Email Section With New Sent Page, Better Drafts Page, and Settings Page (#1221) 2026-03-11 12:01:36 -07:00
unsubscribe-link clickhouse new syncs and verify-data (#1304) 2026-04-08 14:43:22 -07:00
README.md Email outbox backend (#1030) 2025-12-12 10:26:38 -08:00

Email Infrastructure Overview

This folder contains the HTTP endpoints that sit on top of the new email outbox pipeline. The pipeline is intentionally asynchronous: instead of sending mail inside request handlers we persist work items to the EmailOutbox table and let background workers render, queue, and deliver them.

Execution Flow

  1. Enqueue API endpoints (and server-side helpers) call sendEmailToMany to persist one row per recipient. Each entry captures the template source, render variables, target recipient, priority, and scheduling metadata.
  2. Render runEmailQueueStep atomically claims rows that have not been rendered. Emails are rendered via Freestyle, producing HTML/Text/Subject snapshots while capturing render errors in structured fields.
  3. Queue Rendered rows whose scheduled_at is in the past are marked as ready (isQueued = true). Capacity is calculated per tenancy based on recent delivery performance to decide how many emails can be handed off to the sender during this iteration.
  4. Send Claimed rows are processed in parallel. Before delivery we fetch the latest user data, honour notification preferences and skip users who have unsubscribed or deleted their account. Provider responses are captured in the sendServerError* fields so the dashboard can surface actionable feedback.
  5. Delivery Stats The worker updates EmailOutboxProcessingMetadata so we can derive execution deltas and expose aggregated metrics via the /emails/delivery-info endpoint.

Key Tables

  • EmailOutbox Durable queue of emails with full status history and audit data. Constraints ensure mutually exclusive sets of render/send error fields and guard against race conditions.
  • EmailOutboxProcessingMetadata Stores the last worker execution timestamp so we can compute accurate capacity budgets each run.

Mutable vs. Immutable States

Emails can only be edited, paused, retried, or deleted before startedSendingAt is set. Once sending begins, the entry becomes read-only. Retrying an email effectively resets its place in the pipeline & queue, see the Prisma schema for more details.