chore(broadcast): wire mana-mail into env pipeline + push schema

The three final pre-dogfood items:

1. drizzle.config: schemaFilter now includes 'broadcast' alongside
   'mail'. Without this, `bun run db:push` skipped the broadcast
   tables — schema existed in code but not in Postgres. Tested via
   db:push + psql \dt (3 tables created: campaigns, events, sends).

2. .env.development: new MANA-MAIL SERVICE section with Stalwart
   knobs + broadcast config (tracking secret, rate limits, send
   throttle). DEV secret is explicitly labelled non-production —
   prod rotates via env.

3. generate-env.mjs: new block writes services/mana-mail/.env on
   `pnpm setup:env`. Mirrors the invoices / research / events
   pattern. All 16 broadcast/mail vars flow through from SSOT.

Verified end-to-end:
- pnpm setup:env → services/mana-mail/.env contains
  BROADCAST_TRACKING_SECRET + rate limits
- bun run src/index.ts → /health returns 200 with the new config
- psql → broadcast.campaigns / events / sends are materialised

Broadcast module is now fully ready to send real mail — nothing
else required before the first dogfood campaign.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-21 16:21:57 +02:00
parent 3357e88a1c
commit 1861e89d45
3 changed files with 62 additions and 1 deletions

View file

@ -122,6 +122,32 @@ const APP_CONFIGS = [
},
},
// Mana Mail Service (Hono + Bun, Port 3042)
// Stalwart proxy + 1:1 send via JMAP + broadcast (newsletter) via bulk-send.
{
path: 'services/mana-mail/.env',
vars: {
PORT: (env) => env.MANA_MAIL_PORT || '3042',
DATABASE_URL: (env) =>
env.MANA_MAIL_DATABASE_URL || 'postgresql://mana:devpassword@localhost:5432/mana_platform',
MANA_AUTH_URL: (env) => env.MANA_AUTH_URL || 'http://localhost:3001',
MANA_SERVICE_KEY: (env) => env.MANA_SERVICE_KEY || 'dev-service-key',
BASE_URL: (env) => env.MANA_MAIL_BASE_URL || 'http://localhost:3042',
CORS_ORIGINS: (env) => env.CORS_ORIGINS || 'http://localhost:5173',
STALWART_JMAP_URL: (env) => env.STALWART_JMAP_URL || 'http://localhost:8080',
STALWART_ADMIN_USER: (env) => env.STALWART_ADMIN_USER || 'admin',
STALWART_ADMIN_PASSWORD: (env) => env.STALWART_ADMIN_PASSWORD || 'ChangeMe123!',
MAIL_DOMAIN: (env) => env.MAIL_DOMAIN || 'mana.how',
// Broadcast / newsletter config — generated secrets rotate at deploy.
BROADCAST_TRACKING_SECRET: (env) =>
env.BROADCAST_TRACKING_SECRET || 'dev-broadcast-tracking-secret-NOT-for-prod',
BROADCAST_MAX_RECIPIENTS_PER_CAMPAIGN: (env) =>
env.BROADCAST_MAX_RECIPIENTS_PER_CAMPAIGN || '5000',
BROADCAST_MAX_RECIPIENTS_PER_HOUR: (env) => env.BROADCAST_MAX_RECIPIENTS_PER_HOUR || '500',
BROADCAST_SEND_THROTTLE_MS: (env) => env.BROADCAST_SEND_THROTTLE_MS || '150',
},
},
// Chat Server (Hono/Bun)
{
path: 'apps/chat/apps/server/.env',