feat(notifications): P2d dispatcher cron route

POST /api/cron/notifications drains <=20 pending rows/min, sends via the
transport with the row id as Resend Idempotency-Key (overlap-safe),
marks sent or increments attempts (retryable -> stay pending, permanent
or budget-exhausted -> failed). Constant-time CRON_SECRET bearer check;
503 when unset. ~4.5/s spacing under Resend's 5/s limit. proxy.ts
whitelists /api/cron (no session; own shared secret). CRON_SECRET added
to .env.example.
This commit is contained in:
Moheeb Zara
2026-05-17 04:54:11 -07:00
parent 2c88278d13
commit 75097a601c
3 changed files with 102 additions and 0 deletions
+5
View File
@@ -44,6 +44,11 @@ RESEND_API_KEY=
# in Resend (SPF + DKIM) for production delivery. Friendly name optional.
# Example: HeatSync Labs <noreply@hackerspace.sh>
EMAIL_FROM=
# Shared secret guarding the notification dispatcher (/api/cron/notifications).
# The droplet's crontab POSTs with "Authorization: Bearer $CRON_SECRET" once a
# minute. Unset = the dispatcher returns 503 and never sends. Generate with:
# openssl rand -hex 32
CRON_SECRET=
# Docker build flag (only when building the standalone image)
# Set to "1" in the Dockerfile so next.config.mjs emits standalone output.