Architecture Overview

Sendoka is a single Next.js 16 App Router application. All API surface, dashboard UI, and background handlers run as route handlers in one deployable unit.

Layers

┌─────────────────────────────────────────────────────────┐
│  Dashboard UI (src/app/overview/**)                    │
│  React Server Components — NextAuth session gated       │
└────────────┬────────────────────────────────────────────┘
             │ fetch
┌────────────▼────────────────────────────────────────────┐
│  Internal API (src/app/api/internal/**)                 │
│  Session-auth'd CRUD for dashboard                      │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│  Public API v1 (src/app/api/v1/**)                      │
│  API-key auth'd send endpoints                          │
└────────────┬────────────────────────────────────────────┘
             │
┌────────────▼─────────────┬──────────────────────────────┐
│ withApiAuth middleware   │  • Bearer key → org/env     │
│ (src/lib/api/middleware) │  • Rate limit (Upstash)     │
└────────────┬─────────────┴──────────────────────────────┘
             │
┌────────────▼────────────────────────────────────────────┐
│  Providers (src/lib/providers/**)                       │
│  AWS SES v2 (email) · AWS SNS (SMS) · SES domain ID    │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│  Inbound Webhooks (src/app/api/webhooks/**)             │
│  SES → SNS HTTP · Stripe signed events                  │
└────────────┬────────────────────────────────────────────┘
             │
┌────────────▼────────────────────────────────────────────┐
│  Webhook fan-out → customer endpoints                   │
│  (src/lib/api/webhook-fanout.ts)                        │
└─────────────────────────────────────────────────────────┘

Data: Neon Postgres (Drizzle ORM). Cache/RL: Upstash Redis.

Key modules

  • src/app/api/v1/* — public REST API (email/SMS send, list, retrieve, batch).
  • src/app/api/internal/* — session-auth'd dashboard CRUD (keys, domains, webhooks, templates, team, org, billing, audit, two-factor).
  • src/app/api/auth/* — NextAuth + user registration + email verify + password reset.
  • src/app/api/webhooks/* — inbound from SES (status events), SNS SMS (delivery), Stripe.
  • src/app/api/cron/* — scheduled jobs (send-scheduled, retry-webhooks, cleanup-idempotency, report-overage).
  • src/lib/api/* — cross-cutting: auth middleware, errors, idempotency, cursor pagination, rate limit (per-plan), usage metering, webhook fan-out + delivery log, audit log, SNS signature verification, template rendering.
  • src/lib/auth/* — NextAuth options, API-key generate/validate, TOTP, email-verification helper, active-org cookie resolver.
  • src/lib/billing/* — Stripe client + plan definitions.
  • src/lib/providers/* — AWS SES (simple + raw MIME) / SNS wrappers, domain identity management.
  • src/lib/db/* — Drizzle connection + 16 tables.
  • src/components/ui/* — toast, skeleton, confirm dialog, error boundary.

Request authentication modes

Surface Auth Implementation
/overview/* NextAuth JWT middleware.ts
/api/internal/* getServerSession route-level checks
/api/v1/* Bearer API key withApiAuth wrapper
/api/webhooks/stripe Stripe signature stripe.webhooks.constructEvent
/api/webhooks/ses SNS signature (RSA-SHA1/SHA256 against SigningCertURL) src/lib/api/sns-verify.ts
/api/webhooks/sns-sms SNS signature same module
/api/cron/* Bearer CRON_SECRET per-handler authorized()
/api/auth/* public (register, NextAuth) n/a