mailery 0.1.2 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server/adapters/mongo.ts","../src/server/providers/sendgrid.ts","../src/shared/schemas.ts","../src/server/config.ts","../src/server/models/index.ts","../src/server/events.ts","../src/server/tokens.ts","../src/server/queues/index.ts","../src/server/runner/triggers.ts","../src/server/runner/predicate.ts","../src/server/templates/render.ts","../src/server/runner/suppression.ts","../src/server/runner/health.ts","../src/server/runner/send.ts","../src/server/runner/step.ts","../src/server/runner/sweep.ts","../src/server/runner/broadcasts.ts","../src/server/runner/bounce-promotion.ts","../src/server/runner/tick.ts","../src/server/runner/webhook.ts","../src/server/mailer.ts","../src/server/index.ts","../src/server/providers/null.ts","../src/server/api/admin.ts","../src/server/api/public.ts","../src/shared/options.ts"],"names":["MongoContactAdapter","ObjectId","SendGridProvider","sgMail","crypto","z","IORedis","Queue","Worker","mjml2html","htmlToText","Handlebars","counter","processScheduledBroadcasts","ObjectIdCtor","__filename","fileURLToPath","__dirname","path","Router","express","fs"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * MongoContactAdapter — reads contacts directly from the host's `users`\n * collection (read-mostly; optional narrow tag writes). Mailer never\n * duplicates identity data — the host is the source of truth.\n */\n\nimport type { Collection, Db, Filter } from 'mongodb'\nimport { ObjectId } from 'mongodb'\n\nimport type {\n AdapterFilter,\n Contact,\n ContactAdapter,\n} from '../../shared/types.js'\n\nexport interface MongoContactAdapterOptions {\n db: Db\n collection: string\n emailField?: string\n idField?: string\n /** Path to the tags array on the user document. */\n tagsField?: string\n /** When true, mailer writes tags via `$addToSet` / `$pull` on the user doc. */\n tagsWritable?: boolean\n /** 'strings' = ['vip','beta'], 'objects' = [{ name: 'vip' }]. */\n tagsArrayShape?: 'strings' | 'objects'\n /** Customize the projection mailer sees. Defaults pick up email + tags + a few common fields. */\n toContact?: (userDoc: any) => Contact\n /** Customize how AdapterFilter becomes a Mongo query. */\n translateFilter?: (filter: AdapterFilter) => Filter<any>\n /** Per-call default for query() limit. */\n batchSize?: number\n}\n\nexport class MongoContactAdapter implements ContactAdapter {\n private readonly col: Collection<any>\n private readonly emailField: string\n private readonly idField: string\n private readonly tagsField: string | null\n private readonly tagsWritable: boolean\n private readonly tagsArrayShape: 'strings' | 'objects'\n private readonly toContactFn: (doc: any) => Contact\n private readonly translateFilterFn: (filter: AdapterFilter) => Filter<any>\n private readonly batchSize: number\n\n constructor(opts: MongoContactAdapterOptions) {\n this.col = opts.db.collection(opts.collection)\n this.emailField = opts.emailField ?? 'email'\n this.idField = opts.idField ?? '_id'\n this.tagsField = opts.tagsField ?? null\n this.tagsWritable = !!opts.tagsWritable\n this.tagsArrayShape = opts.tagsArrayShape ?? 'strings'\n this.toContactFn = opts.toContact ?? this.defaultToContact.bind(this)\n this.translateFilterFn = opts.translateFilter ?? this.defaultTranslateFilter.bind(this)\n this.batchSize = opts.batchSize ?? 500\n\n // Only expose tag write methods if the host opted in.\n if (this.tagsWritable && this.tagsField) {\n this.addTags = this.addTagsImpl.bind(this)\n this.removeTags = this.removeTagsImpl.bind(this)\n }\n }\n\n async getById(externalId: string): Promise<Contact | null> {\n const filter = this.idFilter(externalId)\n const doc = await this.col.findOne(filter)\n return doc ? this.toContactFn(doc) : null\n }\n\n async getByEmail(email: string): Promise<Contact | null> {\n const doc = await this.col.findOne({ [this.emailField]: email.toLowerCase() })\n return doc ? this.toContactFn(doc) : null\n }\n\n async getBatch(externalIds: string[]): Promise<Map<string, Contact>> {\n if (externalIds.length === 0) return new Map()\n const tryObjectId = externalIds.every(canBeObjectId)\n const ids: any[] = tryObjectId ? externalIds.map((s) => new ObjectId(s)) : externalIds\n const docs = await this.col.find({ [this.idField]: { $in: ids } }).toArray()\n const out = new Map<string, Contact>()\n for (const doc of docs) {\n const c = this.toContactFn(doc)\n out.set(c.externalId, c)\n }\n return out\n }\n\n async query(\n filter: AdapterFilter,\n opts: { limit: number; cursor?: string },\n ): Promise<{ contacts: Contact[]; nextCursor?: string }> {\n const query = this.translateFilterFn(filter)\n const limit = Math.min(opts.limit, this.batchSize)\n\n // Cursor is an ObjectId-or-externalId encoded as a string; we use it as a >\n // bound on the idField for stable pagination ordered by id.\n if (opts.cursor) {\n const cursorVal = canBeObjectId(opts.cursor) ? new ObjectId(opts.cursor) : opts.cursor\n ;(query as any)[this.idField] = { ...((query as any)[this.idField] ?? {}), $gt: cursorVal }\n }\n\n const docs = await this.col\n .find(query)\n .sort({ [this.idField]: 1 })\n .limit(limit + 1)\n .toArray()\n\n const hasMore = docs.length > limit\n const slice = hasMore ? docs.slice(0, limit) : docs\n const contacts = slice.map((d) => this.toContactFn(d))\n const last = slice[slice.length - 1]\n const nextCursor = hasMore && last ? String((last as any)[this.idField]) : undefined\n return { contacts, nextCursor }\n }\n\n async count(filter: AdapterFilter): Promise<number> {\n const query = this.translateFilterFn(filter)\n return await this.col.countDocuments(query)\n }\n\n addTags?: (externalId: string, tags: string[]) => Promise<void>\n removeTags?: (externalId: string, tags: string[]) => Promise<void>\n\n // -------------------------------------------------------------------------\n // Private helpers\n // -------------------------------------------------------------------------\n\n private idFilter(externalId: string): Filter<any> {\n if (this.idField === '_id' && canBeObjectId(externalId)) {\n return { _id: new ObjectId(externalId) } as Filter<any>\n }\n return { [this.idField]: externalId }\n }\n\n private defaultToContact(doc: any): Contact {\n const tagsRaw = this.tagsField ? doc[this.tagsField] ?? [] : []\n const tags: string[] =\n this.tagsArrayShape === 'objects'\n ? (Array.isArray(tagsRaw) ? tagsRaw : []).map((t: any) => String(t.name ?? t))\n : (Array.isArray(tagsRaw) ? tagsRaw : []).map((t: any) => String(t))\n\n const externalId = String(doc[this.idField] ?? '')\n const email = String(doc[this.emailField] ?? '').toLowerCase()\n\n // Default projection: everything that's not _id / email / tags becomes a field.\n const fields: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(doc)) {\n if (k === this.idField || k === this.emailField || k === this.tagsField) continue\n fields[k] = v\n }\n\n return {\n externalId,\n email,\n tags,\n fields,\n timezone: typeof doc.timezone === 'string' ? doc.timezone : undefined,\n locale: typeof doc.locale === 'string' ? doc.locale : undefined,\n }\n }\n\n private defaultTranslateFilter(filter: AdapterFilter): Filter<any> {\n const q: Record<string, unknown> = {}\n\n if (filter.emailIn && filter.emailIn.length > 0) {\n q[this.emailField] = { $in: filter.emailIn.map((e) => e.toLowerCase()) }\n }\n if (filter.externalIdIn && filter.externalIdIn.length > 0) {\n const tryObjectId = filter.externalIdIn.every(canBeObjectId)\n q[this.idField] = {\n $in: tryObjectId ? filter.externalIdIn.map((s) => new ObjectId(s)) : filter.externalIdIn,\n }\n }\n if (filter.fieldEquals) {\n q[filter.fieldEquals.field] = filter.fieldEquals.value\n }\n if (filter.fieldIn) {\n q[filter.fieldIn.field] = { $in: filter.fieldIn.values }\n }\n if (filter.fieldExists) {\n q[filter.fieldExists] = { $exists: true }\n }\n if (filter.createdAfter || filter.createdBefore) {\n const r: any = {}\n if (filter.createdAfter) r.$gte = filter.createdAfter\n if (filter.createdBefore) r.$lte = filter.createdBefore\n q.createdAt = r\n }\n if (this.tagsField) {\n if (filter.hasTag) {\n q[this.tagsField] = filter.hasTag\n }\n if (filter.hasTagIn && filter.hasTagIn.length > 0) {\n q[this.tagsField] = { $in: filter.hasTagIn }\n }\n }\n return q\n }\n\n private async addTagsImpl(externalId: string, tags: string[]): Promise<void> {\n if (!this.tagsField || tags.length === 0) return\n const value =\n this.tagsArrayShape === 'objects'\n ? tags.map((name) => ({ name }))\n : tags\n await this.col.updateOne(this.idFilter(externalId), {\n $addToSet: { [this.tagsField]: { $each: value } } as any,\n })\n }\n\n private async removeTagsImpl(externalId: string, tags: string[]): Promise<void> {\n if (!this.tagsField || tags.length === 0) return\n const value =\n this.tagsArrayShape === 'objects'\n ? { $in: tags.map((name) => ({ name })) }\n : { $in: tags }\n await this.col.updateOne(this.idFilter(externalId), {\n $pull: { [this.tagsField]: value } as any,\n })\n }\n}\n\nfunction canBeObjectId(s: string): boolean {\n return typeof s === 'string' && /^[a-f0-9]{24}$/i.test(s)\n}\n","/**\n * SendGridProvider — sends mail through @sendgrid/mail, verifies the Event\n * Webhook signature with the ECDSA public key configured in SendGrid, and\n * normalizes inbound event payloads into our shared shape.\n *\n * Setup steps required on the SendGrid side (one-time):\n * 1. Authenticate sender domain (SPF, DKIM, DMARC).\n * 2. Configure event webhook → POST to https://your.host/m/webhooks/sendgrid\n * 3. Enable: delivered, open, click, bounce, dropped, spamreport, unsubscribe\n * 4. Generate Signed Event Webhook key → store as webhookVerificationKey\n */\n\nimport crypto from 'node:crypto'\nimport sgMail from '@sendgrid/mail'\n\nimport type {\n MailProvider,\n NormalizedEvent,\n SendArgs,\n SendResult,\n} from '../../shared/types.js'\n\nexport interface SendGridProviderOptions {\n apiKey: string\n /** ECDSA public key (PEM) from SendGrid → Settings → Mail Settings → Signed Event Webhook. */\n webhookVerificationKey?: string\n /** Send-rate cap per second (BullMQ group limiter consults this). */\n sendRatePerSecond?: number\n /** Sandbox mode bypasses actual delivery — useful in dev/test. */\n sandbox?: boolean\n}\n\nconst SG_SIG_HEADER = 'x-twilio-email-event-webhook-signature'\nconst SG_TS_HEADER = 'x-twilio-email-event-webhook-timestamp'\n\nexport class SendGridProvider implements MailProvider {\n readonly name = 'sendgrid'\n readonly sendRatePerSecond: number\n\n constructor(private readonly opts: SendGridProviderOptions) {\n sgMail.setApiKey(opts.apiKey)\n this.sendRatePerSecond = opts.sendRatePerSecond ?? 10\n }\n\n async send(args: SendArgs): Promise<SendResult> {\n const msg: sgMail.MailDataRequired = {\n to: args.to,\n from: { name: args.fromName, email: args.fromEmail },\n replyTo: args.replyTo,\n subject: args.subject,\n text: args.text,\n html: args.html,\n headers: args.headers,\n customArgs: args.messageMeta,\n trackingSettings: {\n // We do our own click/open tracking — let provider stay out of it.\n clickTracking: { enable: false, enableText: false },\n openTracking: { enable: false },\n },\n mailSettings: {\n sandboxMode: { enable: this.opts.sandbox ?? false },\n },\n }\n\n const [response] = await sgMail.send(msg)\n const providerId =\n (response.headers['x-message-id'] as string | undefined) ?? `sg-${Date.now()}`\n return {\n providerId,\n status: response.statusCode < 300 ? 'accepted' : 'rejected',\n raw: response,\n }\n }\n\n async verifyWebhook(rawBody: Buffer, headers: Record<string, string>): Promise<boolean> {\n if (!this.opts.webhookVerificationKey) return false\n const sig = headers[SG_SIG_HEADER]\n const ts = headers[SG_TS_HEADER]\n if (!sig || !ts) return false\n\n const payload = Buffer.concat([Buffer.from(ts, 'utf8'), rawBody])\n try {\n const verifier = crypto.createVerify('sha256')\n verifier.update(payload)\n return verifier.verify(this.opts.webhookVerificationKey, sig, 'base64')\n } catch {\n return false\n }\n }\n\n parseWebhookEvents(payload: unknown): NormalizedEvent[] {\n if (!Array.isArray(payload)) return []\n return payload\n .map((raw) => normalizeSendGridEvent(raw))\n .filter((e): e is NormalizedEvent => e !== null)\n }\n}\n\nfunction normalizeSendGridEvent(e: any): NormalizedEvent | null {\n const type = mapEventType(e.event)\n if (!type) return null\n return {\n type,\n providerEventId: String(e.sg_event_id ?? e['smtp-id'] ?? `${e.event}-${e.timestamp}-${e.email}`),\n providerMessageId: String(e.sg_message_id ?? e['smtp-id'] ?? ''),\n email: String(e.email ?? '').toLowerCase(),\n occurredAt: new Date(Number(e.timestamp) * 1000),\n details: {\n bounceType:\n e.event === 'bounce' ? (e.type === 'bounce' ? 'hard' : 'soft') : undefined,\n bounceReason: e.reason,\n clickedUrl: e.url,\n userAgent: e.useragent,\n ipAddress: e.ip,\n },\n }\n}\n\nfunction mapEventType(sgEvent: string): NormalizedEvent['type'] | null {\n switch (sgEvent) {\n case 'delivered':\n return 'delivered'\n case 'open':\n return 'open'\n case 'click':\n return 'click'\n case 'bounce':\n case 'dropped':\n return 'bounce'\n case 'spamreport':\n return 'spam_report'\n case 'unsubscribe':\n case 'group_unsubscribe':\n return 'unsubscribe'\n default:\n return null\n }\n}\n","/**\n * Zod schemas for runtime validation at write boundaries — public API entry\n * points (fire, upsertSubscription, suppress, sendOneOff, scheduleBroadcast)\n * and REST handler bodies.\n *\n * Domain TypeScript types live in `./types.ts`; these schemas overlap with\n * those types deliberately so we get both compile-time and runtime checking\n * at the surfaces that need it.\n */\n\nimport { z } from 'zod'\n\n// ---------------------------------------------------------------------------\n// Primitive helpers\n// ---------------------------------------------------------------------------\n\nexport const externalIdSchema = z.string().min(1).max(256)\nexport const emailSchema = z.string().email().toLowerCase().trim()\nexport const slugSchema = z\n .string()\n .min(1)\n .max(128)\n .regex(/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/, 'must be kebab-case slug')\n\n// ---------------------------------------------------------------------------\n// Public API inputs\n// ---------------------------------------------------------------------------\n\nexport const fireInputSchema = z.object({\n eventName: z.string().min(1).max(128),\n externalId: externalIdSchema,\n properties: z.record(z.string(), z.unknown()).optional(),\n dedupeKey: z.string().min(1).max(512).optional(),\n})\nexport type FireInput = z.infer<typeof fireInputSchema>\n\nexport const registerEventSchema = z.object({\n name: z.string().min(1).max(128),\n dedupePolicy: z.enum(['once-per-contact', 'once-per-day', 'every-time']),\n})\nexport type RegisterEventInput = z.infer<typeof registerEventSchema>\n\nexport const upsertSubscriptionSchema = z.object({\n externalId: externalIdSchema,\n source: z.string().min(1).max(256),\n consentTimestamp: z.date().optional(),\n consentIp: z.string().optional(),\n consentUserAgent: z.string().optional(),\n})\nexport type UpsertSubscriptionInput = z.infer<typeof upsertSubscriptionSchema>\n\nexport const unsubscribeScopeSchema = z.enum(['all', 'marketing', 'transactional'])\nexport const unsubscribeReasonSchema = z.enum([\n 'user_request',\n 'hard_bounce',\n 'complaint',\n 'manual',\n 'gdpr_forget',\n 'list_cleaning',\n])\n\nexport const unsubscribeInputSchema = z.object({\n email: emailSchema,\n scope: unsubscribeScopeSchema,\n reason: unsubscribeReasonSchema.default('user_request'),\n source: z.string().max(256).default('manual'),\n notes: z.string().max(1024).optional(),\n})\nexport type UnsubscribeInput = z.infer<typeof unsubscribeInputSchema>\n\nexport const suppressInputSchema = z.object({\n email: emailSchema,\n scope: unsubscribeScopeSchema,\n reason: z.enum(['unsubscribed', 'hard_bounce', 'complaint', 'manual', 'list_cleaning', 'gdpr_forget']),\n source: z.string().max(256).default('manual'),\n notes: z.string().max(1024).optional(),\n expiresAt: z.date().optional(),\n})\nexport type SuppressInput = z.infer<typeof suppressInputSchema>\n\nexport const tagInputSchema = z.object({\n externalId: externalIdSchema,\n tag: z.string().min(1).max(128),\n})\nexport type TagInput = z.infer<typeof tagInputSchema>\n\nexport const sendOneOffInputSchema = z.object({\n templateSlug: slugSchema,\n externalId: externalIdSchema,\n vars: z.record(z.string(), z.unknown()).optional(),\n providerOverride: z.string().optional(),\n dedupeKey: z.string().min(1).max(512),\n})\nexport type SendOneOffInput = z.infer<typeof sendOneOffInputSchema>\n\n// ---------------------------------------------------------------------------\n// Flow step + predicate schemas (mirror types.ts)\n// ---------------------------------------------------------------------------\n\nexport const flowStepSchema: z.ZodType<unknown> = z.lazy(() =>\n z.discriminatedUnion('type', [\n z.object({\n type: z.literal('wait'),\n value: z.number().int().positive(),\n unit: z.enum(['minutes', 'hours', 'days', 'weeks']),\n }),\n z.object({\n type: z.literal('condition'),\n test: predicateSchema,\n ifFalse: z.enum(['continue', 'exit']),\n }),\n z.object({\n type: z.literal('branch'),\n test: predicateSchema,\n ifTrueSteps: z.array(flowStepSchema),\n ifFalseSteps: z.array(flowStepSchema),\n }),\n z.object({\n type: z.literal('send'),\n templateSlug: slugSchema,\n providerOverride: z.string().optional(),\n vars: z.record(z.string(), z.unknown()).optional(),\n }),\n z.object({\n type: z.literal('tag'),\n addTags: z.array(z.string()).optional(),\n removeTags: z.array(z.string()).optional(),\n }),\n z.object({\n type: z.literal('fire_event'),\n eventName: z.string().min(1).max(128),\n properties: z.record(z.string(), z.unknown()).optional(),\n }),\n z.object({\n type: z.literal('webhook'),\n url: z.string().url(),\n method: z.enum(['POST', 'PUT']).optional(),\n payload: z.record(z.string(), z.unknown()).optional(),\n failureMode: z.enum(['soft', 'fail_run']).optional(),\n }),\n z.object({\n type: z.literal('exit'),\n reason: z.string().optional(),\n }),\n ]),\n)\n\nexport const predicateSchema: z.ZodType<unknown> = z.lazy(() =>\n z.union([\n z.object({ hasTag: z.string() }),\n z.object({ notHasTag: z.string() }),\n z.object({ fieldEquals: z.object({ field: z.string(), value: z.unknown() }) }),\n z.object({ fieldExists: z.string() }),\n z.object({\n hasFiredEvent: z.string(),\n sinceFlowStart: z.boolean().optional(),\n withinDays: z.number().int().positive().optional(),\n }),\n z.object({\n notHasFiredEvent: z.string(),\n withinDays: z.number().int().positive().optional(),\n }),\n z.object({\n subscriptionStatus: z.enum(['subscribed', 'unsubscribed', 'pending_doi', 'bounced', 'complained']),\n }),\n z.object({\n hasOpened: z.object({\n templateSlug: slugSchema.optional(),\n sinceFlowStart: z.boolean().optional(),\n withinDays: z.number().int().positive().optional(),\n }),\n }),\n z.object({\n hasClicked: z.object({\n templateSlug: slugSchema.optional(),\n sinceFlowStart: z.boolean().optional(),\n withinDays: z.number().int().positive().optional(),\n }),\n }),\n z.object({\n hasOpenedExcludingBots: z.object({\n templateSlug: slugSchema.optional(),\n sinceFlowStart: z.boolean().optional(),\n withinDays: z.number().int().positive().optional(),\n }),\n }),\n z.object({\n hasClickedExcludingBots: z.object({\n templateSlug: slugSchema.optional(),\n sinceFlowStart: z.boolean().optional(),\n withinDays: z.number().int().positive().optional(),\n }),\n }),\n z.object({\n openedAtLeastN: z.object({ count: z.number().int().positive(), withinDays: z.number().int().positive() }),\n }),\n z.object({\n clickedAtLeastN: z.object({ count: z.number().int().positive(), withinDays: z.number().int().positive() }),\n }),\n z.object({ all: z.array(predicateSchema) }),\n z.object({ any: z.array(predicateSchema) }),\n z.object({ not: predicateSchema }),\n ]),\n)\n","/**\n * Mailer configuration shape. Required + optional surfaces with sane defaults.\n */\n\nimport type { Db } from 'mongodb'\nimport type IORedis from 'ioredis'\nimport type Handlebars from 'handlebars'\nimport type {\n ContactAdapter,\n MailProvider,\n} from '../shared/types.js'\n\nexport interface RedisOptions {\n host?: string\n port?: number\n password?: string\n url?: string\n db?: number\n username?: string\n tls?: boolean\n}\n\nexport interface CircuitBreakerThresholds {\n /** Trip when last-hour hard-bounce rate >= this percent (e.g. 2 = 2%). */\n hardBounceRatePctTrip: number\n complaintRatePctTrip: number\n combinedBounceRatePctTrip: number\n failedToSendRatePctDegrade: number\n windowMinutes: number\n minSendsBeforeEval: number\n}\n\nexport interface MailerConfig {\n // ---- Storage --------------------------------------------------------------\n db: Db\n collectionPrefix?: string\n adapter: ContactAdapter\n\n // ---- Queue ----------------------------------------------------------------\n /**\n * Connection options, a pre-built ioredis instance, or `null` to opt out of\n * BullMQ entirely (synchronous-only mode — used by tests).\n */\n redis: RedisOptions | IORedis | null\n\n // ---- Providers ------------------------------------------------------------\n providers: Record<string, MailProvider>\n defaultProvider: string\n defaultTransactionalProvider?: string\n\n // ---- Identity / URLs ------------------------------------------------------\n publicUrl: string\n unsubscribeSecret: string\n senderAddress?: string\n fromDefaults?: { name: string; email: string }\n transactionalFromDefaults?: { name: string; email: string }\n\n // ---- Compliance -----------------------------------------------------------\n requireDoubleOptIn?: boolean\n unsubscribeTokenLifetimeDays?: number\n transactionalRespectUnsubscribe?: boolean\n /** Slug of the transactional template sent for DOI confirmation. Defaults to 'doi-confirmation'. */\n doiTemplateSlug?: string\n /** How long the DOI token stays valid. Default 7 days. */\n doiTokenLifetimeDays?: number\n\n // ---- Circuit breaker ------------------------------------------------------\n circuitBreaker?: Partial<CircuitBreakerThresholds>\n\n // ---- Broadcast safety + throughput ---------------------------------------\n broadcastConfirmationThreshold?: number\n broadcastEnqueueBatchSize?: number\n broadcastEnqueueMaxWaiting?: number\n\n // ---- Worker behavior ------------------------------------------------------\n workerless?: boolean\n tickIntervalSeconds?: number\n sendConcurrency?: number\n sendRatePerSecond?: number\n softBouncePromotionThreshold?: number\n softBouncePromotionWindowDays?: number\n webhookRetryAttempts?: number\n sendRetryAttempts?: number\n\n // ---- Tracking -------------------------------------------------------------\n trackOpens?: boolean\n trackClicks?: boolean\n storeTrackingIp?: boolean\n storeRenderedBody?: boolean\n\n // ---- Hooks ----------------------------------------------------------------\n getAdminActor?: (req: any) => string\n onCircuitBreakerTrip?: (info: { reason: string; rates: Record<string, number> }) => Promise<void> | void\n onSendFailure?: (info: { send: any; error: Error }) => Promise<void> | void\n handlebarsHelpers?: Record<string, Handlebars.HelperDelegate>\n}\n\nexport type ResolvedConfig = Required<\n Pick<\n MailerConfig,\n | 'collectionPrefix'\n | 'requireDoubleOptIn'\n | 'unsubscribeTokenLifetimeDays'\n | 'transactionalRespectUnsubscribe'\n | 'doiTemplateSlug'\n | 'doiTokenLifetimeDays'\n | 'broadcastConfirmationThreshold'\n | 'broadcastEnqueueBatchSize'\n | 'broadcastEnqueueMaxWaiting'\n | 'workerless'\n | 'tickIntervalSeconds'\n | 'sendConcurrency'\n | 'sendRatePerSecond'\n | 'softBouncePromotionThreshold'\n | 'softBouncePromotionWindowDays'\n | 'webhookRetryAttempts'\n | 'sendRetryAttempts'\n | 'trackOpens'\n | 'trackClicks'\n | 'storeTrackingIp'\n | 'storeRenderedBody'\n >\n> & {\n circuitBreaker: CircuitBreakerThresholds\n} & MailerConfig\n\nexport const DEFAULTS = {\n collectionPrefix: 'mailer_',\n requireDoubleOptIn: false,\n unsubscribeTokenLifetimeDays: 90,\n transactionalRespectUnsubscribe: false,\n doiTemplateSlug: 'doi-confirmation',\n doiTokenLifetimeDays: 7,\n broadcastConfirmationThreshold: 1000,\n broadcastEnqueueBatchSize: 1000,\n broadcastEnqueueMaxWaiting: 5000,\n workerless: false,\n tickIntervalSeconds: 60,\n sendConcurrency: 5,\n sendRatePerSecond: 10,\n softBouncePromotionThreshold: 3,\n softBouncePromotionWindowDays: 30,\n webhookRetryAttempts: 3,\n sendRetryAttempts: 4,\n trackOpens: true,\n trackClicks: true,\n storeTrackingIp: false,\n storeRenderedBody: false,\n} as const\n\nexport const CIRCUIT_BREAKER_DEFAULTS: CircuitBreakerThresholds = {\n hardBounceRatePctTrip: 2,\n complaintRatePctTrip: 0.3,\n combinedBounceRatePctTrip: 5,\n failedToSendRatePctDegrade: 10,\n windowMinutes: 60,\n minSendsBeforeEval: 100,\n}\n\nexport function resolveConfig(c: MailerConfig): ResolvedConfig {\n return {\n ...c,\n collectionPrefix: c.collectionPrefix ?? DEFAULTS.collectionPrefix,\n requireDoubleOptIn: c.requireDoubleOptIn ?? DEFAULTS.requireDoubleOptIn,\n unsubscribeTokenLifetimeDays: c.unsubscribeTokenLifetimeDays ?? DEFAULTS.unsubscribeTokenLifetimeDays,\n transactionalRespectUnsubscribe: c.transactionalRespectUnsubscribe ?? DEFAULTS.transactionalRespectUnsubscribe,\n doiTemplateSlug: c.doiTemplateSlug ?? DEFAULTS.doiTemplateSlug,\n doiTokenLifetimeDays: c.doiTokenLifetimeDays ?? DEFAULTS.doiTokenLifetimeDays,\n broadcastConfirmationThreshold: c.broadcastConfirmationThreshold ?? DEFAULTS.broadcastConfirmationThreshold,\n broadcastEnqueueBatchSize: c.broadcastEnqueueBatchSize ?? DEFAULTS.broadcastEnqueueBatchSize,\n broadcastEnqueueMaxWaiting: c.broadcastEnqueueMaxWaiting ?? DEFAULTS.broadcastEnqueueMaxWaiting,\n workerless: c.workerless ?? DEFAULTS.workerless,\n tickIntervalSeconds: c.tickIntervalSeconds ?? DEFAULTS.tickIntervalSeconds,\n sendConcurrency: c.sendConcurrency ?? DEFAULTS.sendConcurrency,\n sendRatePerSecond: c.sendRatePerSecond ?? DEFAULTS.sendRatePerSecond,\n softBouncePromotionThreshold: c.softBouncePromotionThreshold ?? DEFAULTS.softBouncePromotionThreshold,\n softBouncePromotionWindowDays: c.softBouncePromotionWindowDays ?? DEFAULTS.softBouncePromotionWindowDays,\n webhookRetryAttempts: c.webhookRetryAttempts ?? DEFAULTS.webhookRetryAttempts,\n sendRetryAttempts: c.sendRetryAttempts ?? DEFAULTS.sendRetryAttempts,\n trackOpens: c.trackOpens ?? DEFAULTS.trackOpens,\n trackClicks: c.trackClicks ?? DEFAULTS.trackClicks,\n storeTrackingIp: c.storeTrackingIp ?? DEFAULTS.storeTrackingIp,\n storeRenderedBody: c.storeRenderedBody ?? DEFAULTS.storeRenderedBody,\n circuitBreaker: { ...CIRCUIT_BREAKER_DEFAULTS, ...(c.circuitBreaker ?? {}) },\n }\n}\n","/**\n * Mongo collection helpers + indexes for every mailer-owned collection.\n *\n * The single source of truth for `mailer_*` schemas lives in\n * `plans/02-data-model.md`. The TS interfaces here track that doc.\n *\n * const collections = getCollections(db)\n * await ensureIndexes(db)\n * await collections.events.insertOne({ ... })\n */\n\nimport type { Db, Collection, ObjectId } from 'mongodb'\n\nimport type {\n SubscriptionStatus,\n SendStatus,\n TemplateKind,\n SuppressionScope,\n SuppressionReason,\n FlowRunStatus,\n BroadcastStatus,\n HealthStatus,\n FlowGoal,\n} from '../../shared/enums.js'\nimport type { FlowStep, SegmentDefinition } from '../../shared/types.js'\n\n// ---------------------------------------------------------------------------\n// Document interfaces (per collection)\n// ---------------------------------------------------------------------------\n\nexport interface SubscriptionDoc {\n _id?: ObjectId\n externalId: string\n status: SubscriptionStatus\n subscribedAt: Date | null\n unsubscribedAt: Date | null\n unsubscribeReason: string | null\n doiTokenHash: string | null\n doiRequestedAt: Date | null\n doiConfirmedAt: Date | null\n doiIp: string | null\n doiUserAgent: string | null\n source: string\n emailAtSubscribe: string\n createdAt: Date\n updatedAt: Date\n}\n\nexport interface LeadDoc {\n _id?: ObjectId\n email: string\n source: string\n capturedFields: Record<string, unknown>\n status: 'lead' | 'promoted' | 'rejected'\n promotedToExternalId: string | null\n promotedAt: Date | null\n consentedAt: Date | null\n consentIp: string | null\n unsubscribedAt: Date | null\n createdAt: Date\n updatedAt: Date\n}\n\nexport interface EventDoc {\n _id?: ObjectId\n externalId: string\n name: string\n properties: Record<string, unknown>\n dedupeKey: string\n occurredAt: Date\n createdAt: Date\n}\n\nexport interface FlowTrigger {\n type: 'event' | 'segment_enter' | 'cron'\n eventName?: string\n segmentDefinition?: SegmentDefinition\n cronExpression?: string\n once: boolean\n}\n\nexport interface FlowDraft {\n steps: FlowStep[]\n notes: string\n lastModifiedBy: string\n lastModifiedAt: Date\n}\n\nexport interface FlowDoc {\n _id?: ObjectId\n slug: string\n name: string\n description: string\n trigger: FlowTrigger\n enabled: boolean\n steps: FlowStep[]\n version: number\n draft: FlowDraft | null\n goal: FlowGoal\n audience: string\n expectedVolumePerWeek: number | null\n stats: {\n activeRuns: number\n completedRuns: number\n sendsTotal: number\n sendsLast7Days: number\n }\n lastTriggerScanAt: Date | null\n publishedAt: Date | null\n publishedBy: string | null\n createdAt: Date\n updatedAt: Date\n}\n\nexport interface FlowVersionDoc {\n _id?: ObjectId\n flowId: ObjectId\n version: number\n steps: FlowStep[]\n trigger: FlowTrigger\n publishedAt: Date\n publishedBy: string\n}\n\nexport interface FlowRunHistoryEntry {\n stepIndex: number\n action:\n | 'entered'\n | 'wait_started'\n | 'wait_completed'\n | 'condition_evaluated'\n | 'branch_taken'\n | 'sent'\n | 'send_skipped'\n | 'tagged'\n | 'event_fired'\n | 'webhook_called'\n | 'exited'\n | 'failed'\n at: Date\n details?: Record<string, unknown>\n}\n\nexport interface FlowRunDoc {\n _id?: ObjectId\n externalId: string\n flowId: ObjectId\n flowSlug: string\n flowVersion: number\n emailAtEntry: string\n enteredAt: Date\n status: FlowRunStatus\n currentStepIndex: number\n currentBranchPath: Array<number | 'true' | 'false'>\n nextActionAt: Date\n attemptsForCurrentStep: number\n history: FlowRunHistoryEntry[]\n exitedAt: Date | null\n exitReason: string | null\n createdAt: Date\n updatedAt: Date\n}\n\nexport interface TemplateDraft {\n subject: string\n preheader: string\n /** MJML source (when template is authored as MJML). Empty string if Maily-authored. */\n mjml: string\n /** Maily editor JSON (when template is authored via the WYSIWYG editor). null otherwise. */\n editorJson: Record<string, unknown> | null\n notes: string\n lastModifiedBy: string\n lastModifiedAt: Date\n}\n\nexport interface TemplateDoc {\n _id?: ObjectId\n slug: string\n name: string\n description: string\n kind: TemplateKind\n fromName: string\n fromEmail: string\n replyTo: string | null\n providerOverride: string | null\n subject: string\n preheader: string\n body: {\n /** MJML source (set when published from MJML). */\n mjml: string\n /** Maily editor JSON (set when published from the WYSIWYG editor). null otherwise. */\n editorJson: Record<string, unknown> | null\n html: string\n plainText: string\n compiledAt: Date | null\n }\n variablesSchema: Record<\n string,\n {\n type: 'string' | 'number' | 'boolean' | 'date' | 'url'\n required: boolean\n description?: string\n defaultValue?: unknown\n }\n >\n draft: TemplateDraft | null\n tags: string[]\n trackOpens: boolean\n trackClicks: boolean\n stats: {\n sent: number\n delivered: number\n opened: number\n clicked: number\n bounced: number\n complained: number\n unsubscribed: number\n lastSentAt: Date | null\n }\n publishedAt: Date | null\n publishedBy: string | null\n createdAt: Date\n updatedAt: Date\n}\n\nexport interface TemplateVersionDoc {\n _id?: ObjectId\n templateId: ObjectId\n version: number\n mjml: string\n html: string\n plainText: string\n subject: string\n preheader: string\n publishedAt: Date\n publishedBy: string\n}\n\nexport interface SendDoc {\n _id?: ObjectId\n dedupeKey: string\n externalId: string\n emailAtSend: string\n templateId: ObjectId\n templateSlug: string\n flowRunId: ObjectId | null\n broadcastId: ObjectId | null\n manualSendBy: string | null\n kind: TemplateKind\n provider: string\n providerMessageId: string | null\n fromName: string\n fromEmail: string\n subject: string\n bodyHash: string\n status: SendStatus\n errorMessage: string | null\n bounceType: 'hard' | 'soft' | null\n bounceReason: string | null\n /** Pre-send map: every rewritten link's linkId → original URL. Lookup target on click. */\n links: Array<{ linkId: string; url: string }>\n /** Render-time vars from the flow step or one-off send. Re-applied at dispatch. */\n vars: Record<string, unknown>\n openedAt: Date | null\n openCount: number\n firstClickAt: Date | null\n clickCount: number\n /** History of actual clicks (a linkId may appear multiple times). */\n clickedLinks: Array<{ url: string; linkId: string; clickedAt: Date }>\n unsubscribedAt: Date | null\n complainedAt: Date | null\n queuedAt: Date\n sentAt: Date | null\n deliveredAt: Date | null\n}\n\nexport interface SuppressionDoc {\n _id?: ObjectId\n email: string | null\n emailHash: string\n scope: SuppressionScope\n reason: SuppressionReason\n source: string\n notes: string | null\n addedAt: Date\n expiresAt: Date | null\n}\n\nexport interface BroadcastDoc {\n _id?: ObjectId\n slug: string\n name: string\n templateSlug: string\n segmentDefinition: SegmentDefinition\n status: BroadcastStatus\n scheduledAt: Date | null\n startedAt: Date | null\n completedAt: Date | null\n confirmationRequired: boolean\n confirmedCount: number | null\n confirmedAt: Date | null\n confirmedBy: string | null\n recipientCount: number | null\n /** When true, dispatch fires each recipient at their local-timezone equivalent of `scheduledAt`. */\n respectRecipientTimezone?: boolean\n stats: {\n sent: number\n delivered: number\n opened: number\n clicked: number\n bounced: number\n complained: number\n unsubscribed: number\n }\n createdAt: Date\n createdBy: string\n updatedAt: Date\n}\n\nexport interface OutboxDoc {\n _id?: ObjectId\n payload: {\n type: 'event' | 'upsert_subscription' | 'unsubscribe'\n data: Record<string, unknown>\n dedupeKey: string\n }\n status: 'pending' | 'processed' | 'failed' | 'duplicate'\n attempts: number\n lastAttemptAt: Date | null\n lastError: string | null\n enqueuedAt: Date\n processedAt: Date | null\n}\n\nexport interface AuditLogDoc {\n _id?: ObjectId\n actor: string\n action: string\n resource: { collection: string; id?: ObjectId | string; slug?: string }\n before: Record<string, unknown> | null\n after: Record<string, unknown> | null\n diffSummary: string | null\n ip: string | null\n userAgent: string | null\n requestId: string | null\n occurredAt: Date\n}\n\nexport interface WebhookEventDoc {\n _id?: ObjectId\n provider: string\n providerEventId: string\n eventType: string\n normalizedType: 'delivered' | 'open' | 'click' | 'bounce' | 'complaint' | 'unsubscribe' | 'spam_report'\n providerMessageId: string\n email: string\n occurredAt: Date\n receivedAt: Date\n processed: boolean\n raw: unknown\n}\n\nexport interface HealthDoc {\n _id: 'singleton'\n windowStartedAt: Date\n windowDurationMs: number\n counters: {\n sent: number\n delivered: number\n bounced: number\n hardBounced: number\n softBounced: number\n complained: number\n failedToSend: number\n }\n rates: {\n bounceRate: number\n hardBounceRate: number\n complaintRate: number\n failureRate: number\n }\n status: HealthStatus\n trippedAt: Date | null\n trippedReason: string | null\n manuallyResumedAt: Date | null\n updatedAt: Date\n}\n\nexport interface ContactTagDoc {\n _id?: ObjectId\n externalId: string\n tag: string\n appliedBy: 'flow' | 'admin' | 'script' | 'import'\n appliedAt: Date\n}\n\n// ---------------------------------------------------------------------------\n// Collection factory\n// ---------------------------------------------------------------------------\n\nexport interface Collections {\n subscriptions: Collection<SubscriptionDoc>\n leads: Collection<LeadDoc>\n events: Collection<EventDoc>\n flows: Collection<FlowDoc>\n flowVersions: Collection<FlowVersionDoc>\n flowRuns: Collection<FlowRunDoc>\n templates: Collection<TemplateDoc>\n templateVersions: Collection<TemplateVersionDoc>\n sends: Collection<SendDoc>\n suppressions: Collection<SuppressionDoc>\n broadcasts: Collection<BroadcastDoc>\n outbox: Collection<OutboxDoc>\n auditLog: Collection<AuditLogDoc>\n webhookEvents: Collection<WebhookEventDoc>\n health: Collection<HealthDoc>\n contactTags: Collection<ContactTagDoc>\n}\n\nexport function getCollections(db: Db, prefix = 'mailer_'): Collections {\n return {\n subscriptions: db.collection<SubscriptionDoc>(`${prefix}subscriptions`),\n leads: db.collection<LeadDoc>(`${prefix}leads`),\n events: db.collection<EventDoc>(`${prefix}events`),\n flows: db.collection<FlowDoc>(`${prefix}flows`),\n flowVersions: db.collection<FlowVersionDoc>(`${prefix}flow_versions`),\n flowRuns: db.collection<FlowRunDoc>(`${prefix}flow_runs`),\n templates: db.collection<TemplateDoc>(`${prefix}templates`),\n templateVersions: db.collection<TemplateVersionDoc>(`${prefix}template_versions`),\n sends: db.collection<SendDoc>(`${prefix}sends`),\n suppressions: db.collection<SuppressionDoc>(`${prefix}suppressions`),\n broadcasts: db.collection<BroadcastDoc>(`${prefix}broadcasts`),\n outbox: db.collection<OutboxDoc>(`${prefix}outbox`),\n auditLog: db.collection<AuditLogDoc>(`${prefix}audit_log`),\n webhookEvents: db.collection<WebhookEventDoc>(`${prefix}webhook_events`),\n health: db.collection<HealthDoc>(`${prefix}health`),\n contactTags: db.collection<ContactTagDoc>(`${prefix}contact_tags`),\n }\n}\n\n// ---------------------------------------------------------------------------\n// Index ensurer\n// ---------------------------------------------------------------------------\n\nexport async function ensureIndexes(db: Db, prefix = 'mailer_'): Promise<void> {\n const c = getCollections(db, prefix)\n\n await Promise.all([\n c.subscriptions.createIndexes([\n { key: { externalId: 1 }, unique: true },\n { key: { status: 1, unsubscribedAt: -1 } },\n ]),\n c.leads.createIndexes([\n { key: { email: 1 }, unique: true },\n { key: { status: 1, createdAt: -1 } },\n ]),\n c.events.createIndexes([\n { key: { dedupeKey: 1 }, unique: true },\n { key: { externalId: 1, occurredAt: -1 } },\n { key: { name: 1, occurredAt: -1 } },\n { key: { externalId: 1, name: 1 } },\n ]),\n c.flows.createIndexes([\n { key: { slug: 1 }, unique: true },\n { key: { enabled: 1, 'trigger.type': 1, 'trigger.eventName': 1 } },\n ]),\n c.flowVersions.createIndexes([{ key: { flowId: 1, version: 1 }, unique: true }]),\n c.flowRuns.createIndexes([\n { key: { status: 1, nextActionAt: 1 } },\n { key: { externalId: 1, flowId: 1 } },\n { key: { flowId: 1, status: 1 } },\n ]),\n c.templates.createIndexes([\n { key: { slug: 1 }, unique: true },\n { key: { tags: 1 } },\n { key: { kind: 1 } },\n ]),\n c.templateVersions.createIndexes([{ key: { templateId: 1, version: 1 }, unique: true }]),\n c.sends.createIndexes([\n { key: { dedupeKey: 1 }, unique: true },\n { key: { externalId: 1, sentAt: -1 } },\n { key: { templateId: 1, sentAt: -1 } },\n { key: { flowRunId: 1 }, sparse: true },\n { key: { broadcastId: 1 }, sparse: true },\n { key: { providerMessageId: 1 }, sparse: true },\n { key: { status: 1, queuedAt: 1 } },\n ]),\n c.suppressions.createIndexes([\n { key: { email: 1, scope: 1 }, unique: true, partialFilterExpression: { email: { $type: 'string' } } },\n { key: { emailHash: 1 } },\n { key: { addedAt: -1 } },\n ]),\n c.broadcasts.createIndexes([\n { key: { slug: 1 }, unique: true },\n { key: { status: 1, scheduledAt: 1 } },\n ]),\n c.outbox.createIndexes([\n { key: { status: 1, enqueuedAt: 1 } },\n { key: { 'payload.dedupeKey': 1 }, unique: true },\n ]),\n c.auditLog.createIndexes([\n { key: { occurredAt: -1 } },\n { key: { 'resource.collection': 1, 'resource.id': 1, occurredAt: -1 } },\n { key: { actor: 1, occurredAt: -1 } },\n ]),\n c.webhookEvents.createIndexes([\n { key: { provider: 1, providerEventId: 1 }, unique: true },\n { key: { providerMessageId: 1 } },\n { key: { processed: 1, receivedAt: 1 } },\n ]),\n c.contactTags.createIndexes([\n { key: { externalId: 1, tag: 1 }, unique: true },\n { key: { tag: 1 } },\n ]),\n ])\n}\n","/**\n * Event registry + dedupe-key policy. INVARIANT 1: every `mailer_events` row\n * has a unique dedupeKey. Callers either pass one or `mailer.registerEvent`\n * declares a policy and we derive it.\n */\n\nimport crypto from 'node:crypto'\n\nexport type DedupePolicy = 'once-per-contact' | 'once-per-day' | 'every-time'\n\nexport interface EventRegistration {\n name: string\n dedupePolicy: DedupePolicy\n}\n\nexport class EventRegistry {\n private readonly policies = new Map<string, DedupePolicy>()\n\n register(reg: EventRegistration): void {\n this.policies.set(reg.name, reg.dedupePolicy)\n }\n\n has(name: string): boolean {\n return this.policies.has(name)\n }\n\n policy(name: string): DedupePolicy | undefined {\n return this.policies.get(name)\n }\n\n /**\n * Derive a dedupeKey for an event call. Returns null when no policy is\n * registered AND no key was passed — caller should throw.\n */\n deriveKey(\n name: string,\n externalId: string,\n passedKey: string | undefined,\n now: Date,\n ): string | null {\n if (passedKey) return passedKey\n const policy = this.policies.get(name)\n if (!policy) return null\n\n switch (policy) {\n case 'once-per-contact':\n return `${externalId}:${name}`\n case 'once-per-day':\n return `${externalId}:${name}:${isoDay(now)}`\n case 'every-time':\n return `${externalId}:${name}:${randomId()}`\n }\n }\n}\n\nfunction isoDay(d: Date): string {\n return d.toISOString().slice(0, 10)\n}\n\nfunction randomId(): string {\n return crypto.randomBytes(8).toString('hex')\n}\n","/**\n * HMAC-signed tokens for unsubscribe + preference-center URLs.\n *\n * Format: base64url(payload) '.' base64url(hmac)\n * payload = JSON.stringify({ e: email, s: scope, x: expiresAtMs })\n * hmac = HMAC-SHA256(secret, payload)\n *\n * Tokens expire because long-lived signed URLs are a liability.\n */\n\nimport crypto from 'node:crypto'\nimport type { SuppressionScope } from '../shared/enums.js'\n\nexport interface UnsubscribeTokenPayload {\n email: string\n scope: SuppressionScope\n expiresAt: Date\n}\n\nexport function signUnsubscribeToken(\n payload: UnsubscribeTokenPayload,\n secret: string,\n): string {\n const body = JSON.stringify({\n e: payload.email.toLowerCase(),\n s: payload.scope,\n x: payload.expiresAt.getTime(),\n })\n const bodyB64 = b64url(Buffer.from(body, 'utf8'))\n const hmac = crypto.createHmac('sha256', secret).update(bodyB64).digest()\n return `${bodyB64}.${b64url(hmac)}`\n}\n\nexport function verifyUnsubscribeToken(\n token: string,\n secret: string,\n now: Date = new Date(),\n): UnsubscribeTokenPayload | null {\n const parts = token.split('.')\n if (parts.length !== 2) return null\n const [bodyB64, sigB64] = parts as [string, string]\n\n const expected = crypto.createHmac('sha256', secret).update(bodyB64).digest()\n let actual: Buffer\n try {\n actual = b64urlDecode(sigB64)\n } catch {\n return null\n }\n if (expected.length !== actual.length) return null\n if (!crypto.timingSafeEqual(expected, actual)) return null\n\n let body: { e?: string; s?: string; x?: number }\n try {\n body = JSON.parse(b64urlDecode(bodyB64).toString('utf8'))\n } catch {\n return null\n }\n if (!body.e || !body.s || typeof body.x !== 'number') return null\n if (body.x < now.getTime()) return null\n if (body.s !== 'all' && body.s !== 'marketing' && body.s !== 'transactional') return null\n\n return {\n email: body.e,\n scope: body.s,\n expiresAt: new Date(body.x),\n }\n}\n\nfunction b64url(buf: Buffer): string {\n return buf.toString('base64').replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\nfunction b64urlDecode(s: string): Buffer {\n const padded = s.replace(/-/g, '+').replace(/_/g, '/') + '==='.slice((s.length + 3) % 4)\n return Buffer.from(padded, 'base64')\n}\n\n/**\n * sha256 hex digest, used for storing email hashes (GDPR forget) and dedup helpers.\n */\nexport function sha256Hex(input: string): string {\n return crypto.createHash('sha256').update(input).digest('hex')\n}\n\n// ---------------------------------------------------------------------------\n// Double opt-in tokens\n// ---------------------------------------------------------------------------\n\nexport interface DoiTokenPayload {\n externalId: string\n expiresAt: Date\n}\n\n/**\n * Sign a DOI confirmation token. Same shape as the unsubscribe token, but\n * scoped to \"this externalId confirmed their subscription.\"\n */\nexport function signDoiToken(payload: DoiTokenPayload, secret: string): string {\n const body = JSON.stringify({\n i: payload.externalId,\n x: payload.expiresAt.getTime(),\n k: 'doi',\n })\n const bodyB64 = b64url(Buffer.from(body, 'utf8'))\n const hmac = crypto.createHmac('sha256', secret).update(bodyB64).digest()\n return `${bodyB64}.${b64url(hmac)}`\n}\n\nexport function verifyDoiToken(token: string, secret: string, now: Date = new Date()): DoiTokenPayload | null {\n const parts = token.split('.')\n if (parts.length !== 2) return null\n const [bodyB64, sigB64] = parts as [string, string]\n\n const expected = crypto.createHmac('sha256', secret).update(bodyB64).digest()\n let actual: Buffer\n try {\n actual = b64urlDecode(sigB64)\n } catch {\n return null\n }\n if (expected.length !== actual.length) return null\n if (!crypto.timingSafeEqual(expected, actual)) return null\n\n let body: { i?: string; x?: number; k?: string }\n try {\n body = JSON.parse(b64urlDecode(bodyB64).toString('utf8'))\n } catch {\n return null\n }\n if (!body.i || typeof body.x !== 'number' || body.k !== 'doi') return null\n if (body.x < now.getTime()) return null\n\n return { externalId: body.i, expiresAt: new Date(body.x) }\n}\n","/**\n * BullMQ wiring: four queues + the corresponding worker factories.\n *\n * mailer:tick → recovery sweep + event-trigger scan + scheduled broadcasts + outbox drain\n * mailer:advance → per-flow_run wakeup at nextActionAt (delayed jobs)\n * mailer:send → provider dispatch for a single send row\n * mailer:webhook → async normalization + apply of inbound provider events\n *\n * The Mailer class instantiates queues at init() and workers at startWorkers().\n * Job handlers themselves live in `runner/` and `api/webhook-processor.ts`.\n */\n\nimport { Queue, Worker, type QueueOptions, type WorkerOptions } from 'bullmq'\nimport IORedis, { type RedisOptions as IORedisOptions } from 'ioredis'\n\nimport type { RedisOptions } from '../config.js'\n\n/**\n * Minimal queue surface the runner depends on. Production wraps BullMQ; tests\n * can supply a no-op implementation.\n */\nexport interface QueueAPI {\n add(name: string, data: unknown, opts?: { delay?: number; attempts?: number; backoff?: { type: 'exponential'; delay: number }; jobId?: string }): Promise<unknown>\n getWaitingCount(): Promise<number>\n close(): Promise<void>\n}\n\nexport interface Queues {\n tick: QueueAPI\n advance: QueueAPI\n send: QueueAPI\n webhook: QueueAPI\n}\n\nfunction adaptBullQueue(q: Queue): QueueAPI {\n return {\n add: (name, data, opts) => q.add(name, data, opts),\n getWaitingCount: () => q.getWaitingCount(),\n close: () => q.close(),\n }\n}\n\nexport function noopQueueAPI(): QueueAPI {\n return {\n add: async () => undefined,\n getWaitingCount: async () => 0,\n close: async () => undefined,\n }\n}\n\nexport function noopQueues(): Queues {\n return {\n tick: noopQueueAPI(),\n advance: noopQueueAPI(),\n send: noopQueueAPI(),\n webhook: noopQueueAPI(),\n }\n}\n\nexport interface QueueNames {\n tick: string\n advance: string\n send: string\n webhook: string\n}\n\nexport function namespacedQueueNames(prefix: string): QueueNames {\n // BullMQ disallows `:` in queue names; use dashes for the namespace.\n void prefix\n return {\n tick: 'mailer-tick',\n advance: 'mailer-advance',\n send: 'mailer-send',\n webhook: 'mailer-webhook',\n }\n}\n\nexport function makeRedis(opts: RedisOptions | IORedis): IORedis {\n // Pre-built instance — used by tests with ioredis-mock and by hosts that\n // want to share a connection with other parts of their app.\n if (isRedisLike(opts)) return opts\n\n const config: IORedisOptions = {\n maxRetriesPerRequest: null, // BullMQ requirement\n enableReadyCheck: false,\n }\n if (opts.url) {\n return new IORedis(opts.url, config)\n }\n return new IORedis({\n ...config,\n host: opts.host ?? '127.0.0.1',\n port: opts.port ?? 6379,\n password: opts.password,\n db: opts.db,\n username: opts.username,\n tls: opts.tls ? {} : undefined,\n })\n}\n\nfunction isRedisLike(x: unknown): x is IORedis {\n return !!x && typeof x === 'object' && typeof (x as any).get === 'function' && typeof (x as any).set === 'function'\n}\n\nexport function createQueues(redis: IORedis): { queues: Queues; bullQueues: BullQueues } {\n const names = namespacedQueueNames('')\n const qOpts: QueueOptions = { connection: redis }\n const bullQueues: BullQueues = {\n tick: new Queue(names.tick, qOpts),\n advance: new Queue(names.advance, qOpts),\n send: new Queue(names.send, qOpts),\n webhook: new Queue(names.webhook, qOpts),\n }\n return {\n queues: {\n tick: adaptBullQueue(bullQueues.tick),\n advance: adaptBullQueue(bullQueues.advance),\n send: adaptBullQueue(bullQueues.send),\n webhook: adaptBullQueue(bullQueues.webhook),\n },\n bullQueues,\n }\n}\n\nexport interface BullQueues {\n tick: Queue\n advance: Queue\n send: Queue\n webhook: Queue\n}\n\n/** Register the repeating mailer-tick job. Idempotent (BullMQ dedupes by jobId). */\nexport async function scheduleTick(bullQueues: BullQueues, intervalSeconds: number): Promise<void> {\n await bullQueues.tick.upsertJobScheduler(\n 'mailer-tick-repeat',\n { every: intervalSeconds * 1000 },\n { name: 'tick', data: {} },\n )\n}\n\nexport interface CreateWorkersInput {\n redis: IORedis\n concurrency: { send: number }\n sendRateLimit?: { max: number; durationMs: number }\n handlers: {\n tick: (data: unknown) => Promise<void>\n advance: (data: { flowRunId: string }) => Promise<void>\n send: (data: { sendId: string }) => Promise<void>\n webhook: (data: { provider: string }) => Promise<void>\n }\n}\n\nexport interface Workers {\n tick: Worker\n advance: Worker\n send: Worker\n webhook: Worker\n}\n\nexport function createWorkers(input: CreateWorkersInput): Workers {\n const names = namespacedQueueNames('')\n const base: WorkerOptions = { connection: input.redis }\n\n const tick = new Worker(names.tick, async (job) => input.handlers.tick(job.data), {\n ...base,\n concurrency: 1, // single tick driver per worker process\n })\n\n const advance = new Worker(\n names.advance,\n async (job) => input.handlers.advance(job.data as any),\n { ...base, concurrency: 10 },\n )\n\n const sendOpts: WorkerOptions = {\n ...base,\n concurrency: input.concurrency.send,\n limiter: input.sendRateLimit\n ? { max: input.sendRateLimit.max, duration: input.sendRateLimit.durationMs }\n : undefined,\n }\n const send = new Worker(names.send, async (job) => input.handlers.send(job.data as any), sendOpts)\n\n const webhook = new Worker(\n names.webhook,\n async (job) => input.handlers.webhook(job.data as any),\n { ...base, concurrency: 4 },\n )\n\n return { tick, advance, send, webhook }\n}\n\nexport async function closeQueues(queues: Queues): Promise<void> {\n await Promise.all([queues.tick.close(), queues.advance.close(), queues.send.close(), queues.webhook.close()])\n}\n\nexport async function closeBullQueues(b: BullQueues): Promise<void> {\n await Promise.all([b.tick.close(), b.advance.close(), b.send.close(), b.webhook.close()])\n}\n\nexport async function closeWorkers(workers: Workers): Promise<void> {\n await Promise.all([workers.tick.close(), workers.advance.close(), workers.send.close(), workers.webhook.close()])\n}\n","/**\n * Event-trigger scan. Finds new event firings since each flow's\n * lastTriggerScanAt watermark, creates flow_runs for matching contacts,\n * enqueues immediate-advance jobs.\n */\n\nimport type { RunnerContext } from './index.js'\nimport type { FlowDoc, EventDoc } from '../models/index.js'\n\nconst BATCH_SIZE = 1000\n\nexport async function processNewlyFiredEventTriggers(ctx: RunnerContext): Promise<void> {\n const flows = await ctx.collections.flows.find({ enabled: true, 'trigger.type': 'event' }).toArray()\n for (const flow of flows) {\n await processFlowTriggers(flow, ctx)\n }\n}\n\nasync function processFlowTriggers(flow: FlowDoc, ctx: RunnerContext): Promise<void> {\n const eventName = flow.trigger.eventName\n if (!eventName) return\n const since = flow.lastTriggerScanAt ?? flow.createdAt\n\n const events = await ctx.collections.events\n .find({ name: eventName, occurredAt: { $gt: since } })\n .sort({ occurredAt: 1 })\n .limit(BATCH_SIZE)\n .toArray()\n\n if (events.length === 0) return\n\n for (const event of events) {\n await tryEnterFlow(flow, event, ctx)\n }\n\n const newestOccurredAt = events[events.length - 1]!.occurredAt\n await ctx.collections.flows.updateOne(\n { _id: flow._id },\n { $set: { lastTriggerScanAt: newestOccurredAt, updatedAt: new Date() } },\n )\n}\n\nasync function tryEnterFlow(flow: FlowDoc, event: EventDoc, ctx: RunnerContext): Promise<void> {\n if (flow.trigger.once) {\n const existing = await ctx.collections.flowRuns.findOne(\n { externalId: event.externalId, flowId: flow._id },\n { projection: { _id: 1 } },\n )\n if (existing) return\n }\n\n const sub = await ctx.collections.subscriptions.findOne({ externalId: event.externalId })\n if (!sub || sub.status !== 'subscribed') return\n\n const result = await ctx.collections.flowRuns.insertOne({\n externalId: event.externalId,\n flowId: flow._id!,\n flowSlug: flow.slug,\n flowVersion: flow.version,\n emailAtEntry: sub.emailAtSubscribe,\n enteredAt: new Date(),\n status: 'active',\n currentStepIndex: 0,\n currentBranchPath: [],\n nextActionAt: new Date(),\n attemptsForCurrentStep: 0,\n history: [{ stepIndex: -1, action: 'entered', at: new Date(), details: { eventDedupeKey: event.dedupeKey } }],\n exitedAt: null,\n exitReason: null,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n\n await ctx.queues.advance.add('advance', { flowRunId: String(result.insertedId) })\n}\n","/**\n * Predicate evaluator. Resolves all Predicate variants from `shared/types.ts`\n * against a Contact (host-side fields/tags) + mailer state (events, sends,\n * subscription).\n *\n * Network calls hit Mongo. Cache the Contact at the call site if you evaluate\n * many predicates in a row.\n */\n\nimport type { Contact, Predicate } from '../../shared/types.js'\nimport type { Collections, FlowRunDoc, SendDoc } from '../models/index.js'\n\nexport interface PredicateContext {\n contact: Contact\n run: FlowRunDoc\n collections: Collections\n now?: Date\n}\n\nconst BOT_UA_RE = /Mimecast|SafeLinks|proofpoint|HeadlessChrome|Googlebot|bingbot/i\n\nexport async function evaluatePredicate(\n predicate: Predicate,\n ctx: PredicateContext,\n): Promise<boolean> {\n const p = predicate as any\n\n if ('hasTag' in p) return ctx.contact.tags.includes(p.hasTag)\n if ('notHasTag' in p) return !ctx.contact.tags.includes(p.notHasTag)\n\n if ('fieldEquals' in p) {\n return ctx.contact.fields[p.fieldEquals.field] === p.fieldEquals.value\n }\n if ('fieldExists' in p) {\n return ctx.contact.fields[p.fieldExists] !== undefined\n }\n\n if ('subscriptionStatus' in p) {\n const sub = await ctx.collections.subscriptions.findOne({ externalId: ctx.contact.externalId })\n return sub?.status === p.subscriptionStatus\n }\n\n if ('hasFiredEvent' in p) {\n return hasEvent(ctx, p.hasFiredEvent, { sinceFlowStart: p.sinceFlowStart, withinDays: p.withinDays })\n }\n if ('notHasFiredEvent' in p) {\n return !(await hasEvent(ctx, p.notHasFiredEvent, { withinDays: p.withinDays }))\n }\n\n if ('hasOpened' in p) return await openOrClickCount(ctx, 'opened', p.hasOpened, false) > 0\n if ('hasClicked' in p) return await openOrClickCount(ctx, 'clicked', p.hasClicked, false) > 0\n if ('hasOpenedExcludingBots' in p) return await openOrClickCount(ctx, 'opened', p.hasOpenedExcludingBots, true) > 0\n if ('hasClickedExcludingBots' in p) return await openOrClickCount(ctx, 'clicked', p.hasClickedExcludingBots, true) > 0\n if ('openedAtLeastN' in p) return await openOrClickCount(ctx, 'opened', p.openedAtLeastN, true) >= p.openedAtLeastN.count\n if ('clickedAtLeastN' in p) return await openOrClickCount(ctx, 'clicked', p.clickedAtLeastN, true) >= p.clickedAtLeastN.count\n\n if ('all' in p) {\n for (const sub of p.all) {\n if (!(await evaluatePredicate(sub, ctx))) return false\n }\n return true\n }\n if ('any' in p) {\n for (const sub of p.any) {\n if (await evaluatePredicate(sub, ctx)) return true\n }\n return false\n }\n if ('not' in p) {\n return !(await evaluatePredicate(p.not, ctx))\n }\n\n return false\n}\n\nasync function hasEvent(\n ctx: PredicateContext,\n name: string,\n opts: { sinceFlowStart?: boolean; withinDays?: number },\n): Promise<boolean> {\n const filter: any = { externalId: ctx.contact.externalId, name }\n const lower = effectiveLowerBound(ctx, opts)\n if (lower) filter.occurredAt = { $gt: lower }\n const found = await ctx.collections.events.findOne(filter, { projection: { _id: 1 } })\n return !!found\n}\n\nasync function openOrClickCount(\n ctx: PredicateContext,\n kind: 'opened' | 'clicked',\n opts: { templateSlug?: string; sinceFlowStart?: boolean; withinDays?: number },\n excludeBots: boolean,\n): Promise<number> {\n const filter: any = { externalId: ctx.contact.externalId }\n if (opts.templateSlug) filter.templateSlug = opts.templateSlug\n if (kind === 'opened') filter.openedAt = { $ne: null }\n if (kind === 'clicked') filter.firstClickAt = { $ne: null }\n const lower = effectiveLowerBound(ctx, opts)\n if (lower) filter[kind === 'opened' ? 'openedAt' : 'firstClickAt'] = { $gt: lower }\n\n if (!excludeBots) {\n return await ctx.collections.sends.countDocuments(filter)\n }\n\n // Bot filter is best-effort: we only know UA for clicks (open pixel hits don't reliably carry one)\n const docs = await ctx.collections.sends.find(filter).limit(1000).toArray()\n let n = 0\n for (const s of docs) {\n if (kind === 'opened') {\n n++\n continue\n }\n const hasHumanClick = (s as SendDoc).clickedLinks?.some((c: any) => !c.userAgent || !BOT_UA_RE.test(c.userAgent))\n if (hasHumanClick) n++\n }\n return n\n}\n\nfunction effectiveLowerBound(ctx: PredicateContext, opts: { sinceFlowStart?: boolean; withinDays?: number }): Date | null {\n const now = ctx.now ?? new Date()\n if (opts.sinceFlowStart) return ctx.run.enteredAt\n if (opts.withinDays && opts.withinDays > 0) {\n return new Date(now.getTime() - opts.withinDays * 24 * 60 * 60 * 1000)\n }\n return null\n}\n","/**\n * Template render pipeline.\n *\n * authorMjml + handlebarsContext\n * ↓ Handlebars render → MJML with substituted vars\n * ↓ mjml-core compile → HTML\n * ↓ html-to-text derive → plain text alternative\n * ↓ applyTracking(sendId) → tracked HTML with rewritten links + open pixel\n *\n * Subject and preheader run through Handlebars too. Plain text is auto-derived\n * unless the template explicitly overrides it.\n */\n\nimport crypto from 'node:crypto'\nimport Handlebars from 'handlebars'\nimport { convert as htmlToText } from 'html-to-text'\nimport mjml2html from 'mjml'\n\nimport type { Contact } from '../../shared/types.js'\nimport type { TemplateDoc } from '../models/index.js'\n\n// ---------------------------------------------------------------------------\n// Compile (publish-time)\n// ---------------------------------------------------------------------------\n\nexport interface CompileResult {\n html: string\n plainText: string\n errors: Array<{ line?: number; message: string; tagName?: string; formattedMessage?: string }>\n}\n\n/** Compile MJML → HTML, then derive plain text. Called at template publish time. */\nexport async function compileTemplate(mjml: string): Promise<CompileResult> {\n const out = await mjml2html(mjml, { validationLevel: 'soft', minify: false })\n const plainText = derivePlaintext(out.html)\n return { html: out.html, plainText, errors: out.errors ?? [] }\n}\n\n/**\n * Compile Maily editor JSON (Tiptap-shape) → HTML via `@maily-to/render`, then\n * derive plain text. Called at template publish time when the template was\n * authored via the WYSIWYG editor.\n */\nexport async function compileMailyTemplate(content: unknown): Promise<CompileResult> {\n const { render } = await import('@maily-to/render')\n const html = await render(content as any)\n const plainText = derivePlaintext(html)\n return { html, plainText, errors: [] }\n}\n\n/** Auto-derive plain text from compiled HTML. */\nexport function derivePlaintext(html: string): string {\n return htmlToText(html, {\n wordwrap: 80,\n selectors: [\n { selector: 'img', format: 'skip' },\n { selector: 'a', options: { hideLinkHrefIfSameAsText: true } },\n ],\n }).trim()\n}\n\n// ---------------------------------------------------------------------------\n// Render (send-time)\n// ---------------------------------------------------------------------------\n\nexport interface RenderContext {\n contact: Contact\n vars: Record<string, unknown>\n /** URL the recipient hits to one-click unsubscribe. */\n unsubscribeUrl: string\n /** URL to view this email in a browser (when implemented). */\n viewInBrowserUrl?: string\n /** URL for the preference center (when implemented). */\n preferenceCenterUrl?: string\n /** Configured sender postal address (CAN-SPAM). */\n senderAddress?: string\n}\n\nexport interface RenderedTemplate {\n subject: string\n preheader: string\n html: string\n plainText: string\n fromName: string\n fromEmail: string\n replyTo: string | null\n}\n\nexport interface RenderOptions {\n /** Extra Handlebars helpers contributed by the host. */\n helpers?: Record<string, Handlebars.HelperDelegate>\n}\n\n/**\n * Render a published template against a contact + vars context. Returns the\n * substituted subject/preheader/html/plainText. Tracking is NOT applied here —\n * that step needs the send id and runs separately via `applyTracking`.\n */\nexport async function renderTemplate(\n template: TemplateDoc,\n ctx: RenderContext,\n opts: RenderOptions = {},\n): Promise<RenderedTemplate> {\n const hb = makeHandlebars(opts.helpers)\n\n const subject = hb.compile(template.subject)(ctx)\n const preheader = hb.compile(template.preheader)(ctx)\n\n // Prefer the compiled HTML if present; fall back to compiling MJML on the fly.\n let html: string\n if (template.body.html) {\n html = hb.compile(template.body.html)(ctx)\n } else {\n const compiled = await compileTemplate(template.body.mjml)\n html = hb.compile(compiled.html)(ctx)\n }\n\n const plainText = template.body.plainText\n ? hb.compile(template.body.plainText)(ctx)\n : derivePlaintext(html)\n\n return {\n subject,\n preheader,\n html,\n plainText,\n fromName: template.fromName,\n fromEmail: template.fromEmail,\n replyTo: template.replyTo,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Tracking application\n// ---------------------------------------------------------------------------\n\nexport interface TrackingOptions {\n sendId: string\n publicUrl: string\n trackOpens: boolean\n trackClicks: boolean\n /** URL that must NOT be rewritten (e.g. the resolved unsubscribe URL). */\n preserveUrls?: string[]\n}\n\nexport interface TrackingResult {\n html: string\n /** linkId → original URL map; persist on `mailer_sends.links` for click resolution. */\n links: Array<{ linkId: string; url: string }>\n}\n\n/**\n * Rewrite `<a href>` in `html` to /m/click/<sendId>/<linkId>?... and append an\n * open pixel. Returns the modified HTML plus the link map to persist on the\n * send document.\n */\nexport function applyTracking(html: string, opts: TrackingOptions): TrackingResult {\n const preserve = new Set((opts.preserveUrls ?? []).map((u) => u.trim()))\n const links: Array<{ linkId: string; url: string }> = []\n const seen = new Map<string, string>() // url → linkId\n\n let out = html\n\n if (opts.trackClicks) {\n out = out.replace(/<a\\b([^>]*?)\\bhref=([\"'])([^\"']+)\\2([^>]*)>/gi, (full, pre, _q, url, post) => {\n if (shouldSkipClickRewrite(url, preserve, full)) return full\n let linkId = seen.get(url)\n if (!linkId) {\n linkId = shortHash(`${opts.sendId}:${url}:${links.length}`)\n seen.set(url, linkId)\n links.push({ linkId, url })\n }\n const newHref = `${opts.publicUrl}/m/click/${opts.sendId}/${linkId}`\n return `<a${pre}href=\"${newHref}\"${post}>`\n })\n }\n\n if (opts.trackOpens) {\n const pixel = `<img src=\"${opts.publicUrl}/m/open/${opts.sendId}.png\" width=\"1\" height=\"1\" alt=\"\" style=\"display:block;border:0\" />`\n if (/<\\/body>/i.test(out)) {\n out = out.replace(/<\\/body>/i, `${pixel}</body>`)\n } else {\n out = out + pixel\n }\n }\n\n return { html: out, links }\n}\n\nfunction shouldSkipClickRewrite(url: string, preserve: Set<string>, fullTag: string): boolean {\n if (!url) return true\n if (url.startsWith('mailto:')) return true\n if (url.startsWith('tel:')) return true\n if (url.startsWith('#')) return true\n if (url.startsWith('{{') || url.startsWith('{')) return true // unrendered handlebars\n if (preserve.has(url.trim())) return true\n if (/data-mailer-notrack=[\"']true[\"']/.test(fullTag)) return true\n return false\n}\n\nfunction shortHash(input: string): string {\n return crypto.createHash('sha256').update(input).digest('hex').slice(0, 12)\n}\n\n// ---------------------------------------------------------------------------\n// Handlebars instance + helpers\n// ---------------------------------------------------------------------------\n\nfunction makeHandlebars(extra?: Record<string, Handlebars.HelperDelegate>): typeof Handlebars {\n const hb = Handlebars.create()\n\n hb.registerHelper('eq', (a: unknown, b: unknown) => a === b)\n hb.registerHelper('ne', (a: unknown, b: unknown) => a !== b)\n hb.registerHelper('gt', (a: any, b: any) => a > b)\n hb.registerHelper('lt', (a: any, b: any) => a < b)\n hb.registerHelper('gte', (a: any, b: any) => a >= b)\n hb.registerHelper('lte', (a: any, b: any) => a <= b)\n hb.registerHelper('and', (...args: any[]) => args.slice(0, -1).every(Boolean))\n hb.registerHelper('or', (...args: any[]) => args.slice(0, -1).some(Boolean))\n hb.registerHelper('not', (a: unknown) => !a)\n\n hb.registerHelper('formatDate', (value: unknown, fmt?: string) => {\n if (!value) return ''\n const d = value instanceof Date ? value : new Date(String(value))\n if (Number.isNaN(d.getTime())) return ''\n if (fmt === 'long') return d.toLocaleDateString('en-US', { dateStyle: 'long' })\n if (fmt === 'short') return d.toLocaleDateString('en-US', { dateStyle: 'short' })\n return d.toISOString().slice(0, 10)\n })\n\n hb.registerHelper('formatNumber', (n: unknown) => {\n const v = Number(n)\n return Number.isFinite(v) ? v.toLocaleString('en-US') : ''\n })\n\n hb.registerHelper('formatCurrency', (cents: unknown, currency: string = 'usd') => {\n const v = Number(cents)\n if (!Number.isFinite(v)) return ''\n return new Intl.NumberFormat('en-US', { style: 'currency', currency }).format(v / 100)\n })\n\n hb.registerHelper('pluralize', (n: unknown, one: string, many: string) =>\n Number(n) === 1 ? one : many,\n )\n\n if (extra) {\n for (const [name, fn] of Object.entries(extra)) {\n hb.registerHelper(name, fn)\n }\n }\n\n return hb\n}\n\nexport { makeHandlebars }\n","/**\n * Suppression checks. INVARIANT 3: re-checked at send time, never trusted\n * from enqueue time. INVARIANT 9: hashed-suppression records (GDPR forget)\n * block sends without retaining the plaintext email.\n */\n\nimport type { Collections } from '../models/index.js'\nimport type { SuppressionScope, TemplateKind } from '../../shared/enums.js'\nimport { sha256Hex } from '../tokens.js'\n\nexport interface SuppressionResult {\n suppressed: boolean\n scope?: string\n reason?: string\n}\n\nconst SCOPES_BY_KIND: Record<TemplateKind, SuppressionScope[]> = {\n marketing: ['all', 'marketing'],\n transactional: ['all', 'transactional'],\n}\n\nexport async function isSuppressed(\n collections: Collections,\n email: string,\n kind: TemplateKind,\n): Promise<SuppressionResult> {\n const normalized = email.toLowerCase()\n const allowed = SCOPES_BY_KIND[kind]\n\n const byEmail = await collections.suppressions.findOne({\n email: normalized,\n scope: { $in: allowed },\n $or: [{ expiresAt: null }, { expiresAt: { $gt: new Date() } }],\n })\n if (byEmail) return { suppressed: true, scope: byEmail.scope, reason: byEmail.reason }\n\n const hashed = await collections.suppressions.findOne({\n emailHash: sha256Hex(normalized),\n scope: { $in: allowed },\n })\n if (hashed) return { suppressed: true, scope: hashed.scope, reason: hashed.reason }\n\n return { suppressed: false }\n}\n","/**\n * Circuit breaker. Tracks rolling counters in mailer_health, computes rates\n * on each tick, trips the breaker when thresholds are exceeded.\n *\n * status: 'healthy' — normal\n * 'degraded' — non-blocking warnings (e.g. high failed-to-send rate)\n * 'tripped' — marketing sends held; transactional bypasses (INVARIANT 6)\n *\n * Recovery is manual (admin UI: POST /api/health/resume).\n */\n\nimport type { HealthDoc } from '../models/index.js'\nimport type { RunnerContext } from './index.js'\n\ntype CounterKey =\n | 'sent'\n | 'delivered'\n | 'bounced'\n | 'hardBounced'\n | 'softBounced'\n | 'complained'\n | 'failedToSend'\n\n/**\n * Bump a counter on the singleton health doc. Called from the send / webhook\n * paths. Idempotent at the document level (upsert).\n */\nexport async function recordHealthCounter(ctx: RunnerContext, counter: CounterKey, by = 1): Promise<void> {\n await ctx.collections.health.updateOne(\n { _id: 'singleton' },\n {\n $inc: { [`counters.${counter}`]: by },\n $setOnInsert: {\n _id: 'singleton',\n windowStartedAt: new Date(),\n windowDurationMs: ctx.config.circuitBreaker.windowMinutes * 60 * 1000,\n status: 'healthy',\n trippedAt: null,\n trippedReason: null,\n manuallyResumedAt: null,\n rates: { bounceRate: 0, hardBounceRate: 0, complaintRate: 0, failureRate: 0 },\n } as Partial<HealthDoc>,\n $set: { updatedAt: new Date() },\n },\n { upsert: true },\n )\n}\n\n/**\n * Recompute rates from the rolling window and trip the breaker if thresholds\n * are exceeded. Called from the tick.\n */\nexport async function evaluateHealth(ctx: RunnerContext): Promise<void> {\n const cb = ctx.config.circuitBreaker\n const windowMs = cb.windowMinutes * 60 * 1000\n\n // Reset the window if we've rolled past it. Simple \"window of length N\" —\n // when the window expires, we reset counters to 0 and start fresh. This\n // matches the conservative behavior described in the spec.\n const doc = await ctx.collections.health.findOne({ _id: 'singleton' })\n if (!doc) return\n\n const windowAge = Date.now() - new Date(doc.windowStartedAt).getTime()\n if (windowAge > windowMs && doc.status !== 'tripped') {\n // Roll the window.\n await ctx.collections.health.updateOne(\n { _id: 'singleton' },\n {\n $set: {\n windowStartedAt: new Date(),\n windowDurationMs: windowMs,\n counters: { sent: 0, delivered: 0, bounced: 0, hardBounced: 0, softBounced: 0, complained: 0, failedToSend: 0 },\n rates: { bounceRate: 0, hardBounceRate: 0, complaintRate: 0, failureRate: 0 },\n updatedAt: new Date(),\n },\n },\n )\n return\n }\n\n const c = doc.counters\n const total = c.sent || 1 // avoid div-by-zero; rates against `sent` total\n const rates = {\n bounceRate: c.bounced / total,\n hardBounceRate: c.hardBounced / total,\n complaintRate: c.complained / total,\n failureRate: c.failedToSend / total,\n }\n\n await ctx.collections.health.updateOne(\n { _id: 'singleton' },\n { $set: { rates, updatedAt: new Date() } },\n )\n\n // Don't evaluate trips on tiny sample sizes.\n if (c.sent < cb.minSendsBeforeEval) return\n if (doc.status === 'tripped') return // already tripped; wait for manual resume\n\n // Trip rules — first matching rule wins.\n let trippedReason: string | null = null\n if (rates.hardBounceRate * 100 >= cb.hardBounceRatePctTrip) {\n trippedReason = `hard bounce rate ${(rates.hardBounceRate * 100).toFixed(2)}% >= ${cb.hardBounceRatePctTrip}%`\n } else if (rates.complaintRate * 100 >= cb.complaintRatePctTrip) {\n trippedReason = `complaint rate ${(rates.complaintRate * 100).toFixed(2)}% >= ${cb.complaintRatePctTrip}%`\n } else if (rates.bounceRate * 100 >= cb.combinedBounceRatePctTrip) {\n trippedReason = `combined bounce rate ${(rates.bounceRate * 100).toFixed(2)}% >= ${cb.combinedBounceRatePctTrip}%`\n }\n\n if (trippedReason) {\n await ctx.collections.health.updateOne(\n { _id: 'singleton' },\n { $set: { status: 'tripped', trippedAt: new Date(), trippedReason, updatedAt: new Date() } },\n )\n if (ctx.config.onCircuitBreakerTrip) {\n try {\n await ctx.config.onCircuitBreakerTrip({ reason: trippedReason, rates })\n } catch {\n /* swallow — alert hook failures don't propagate */\n }\n }\n return\n }\n\n // Degraded?\n if (rates.failureRate * 100 >= cb.failedToSendRatePctDegrade) {\n if (doc.status !== 'degraded') {\n await ctx.collections.health.updateOne(\n { _id: 'singleton' },\n { $set: { status: 'degraded', updatedAt: new Date() } },\n )\n }\n } else if (doc.status === 'degraded') {\n await ctx.collections.health.updateOne(\n { _id: 'singleton' },\n { $set: { status: 'healthy', updatedAt: new Date() } },\n )\n }\n}\n","/**\n * Send pipeline. `handleSend` is called by the runner state machine; it creates\n * the Send document and enqueues a mailer:send job. `dispatchSend` is the\n * worker — re-checks suppression + circuit breaker, applies tracking, calls\n * the provider, updates the Send row.\n */\n\nimport crypto from 'node:crypto'\nimport { ObjectId } from 'mongodb'\n\nimport type { Contact, FlowStep } from '../../shared/types.js'\nimport type { FlowRunDoc, FlowDoc, SendDoc, TemplateDoc } from '../models/index.js'\nimport {\n applyTracking,\n renderTemplate,\n type RenderContext,\n} from '../templates/render.js'\nimport { signUnsubscribeToken } from '../tokens.js'\nimport { isSuppressed } from './suppression.js'\nimport { advanceStep, failFlowRun } from './step.js'\nimport { recordHealthCounter } from './health.js'\nimport type { RunnerContext } from './index.js'\n\nexport async function handleSend(\n run: FlowRunDoc,\n step: Extract<FlowStep, { type: 'send' }>,\n contact: Contact,\n flow: FlowDoc,\n ctx: RunnerContext,\n): Promise<void> {\n const template = await ctx.collections.templates.findOne({ slug: step.templateSlug })\n if (!template) {\n await failFlowRun(run, `template not found: ${step.templateSlug}`, ctx)\n return\n }\n\n const dedupeKey = `flowrun:${run._id}:step${run.currentStepIndex}`\n\n // Idempotency: has this exact step already produced a send?\n const existing = await ctx.collections.sends.findOne({ dedupeKey })\n if (existing) {\n await advanceStep(run, ctx, {\n action: 'sent',\n details: { dedupeKey, alreadySent: true, sendId: String(existing._id) },\n })\n return\n }\n\n const providerName = pickProviderName(step.providerOverride, template, ctx)\n\n // Render now (with fresh contact + vars). Tracking application happens in\n // dispatchSend once we have the persisted sendId.\n const renderCtx = buildRenderContext(contact, run, step.vars ?? {}, ctx)\n let rendered\n try {\n rendered = await renderTemplate(template, renderCtx, { helpers: ctx.handlebarsHelpers })\n } catch (err: any) {\n await ctx.collections.sends.insertOne(\n newSendDoc({\n dedupeKey,\n run,\n contact,\n template,\n flow,\n providerName,\n renderedSubject: template.subject,\n bodyHash: '',\n status: 'failed',\n errorMessage: `render error: ${err?.message ?? err}`,\n }),\n )\n await advanceStep(run, ctx, {\n action: 'send_skipped',\n details: { reason: 'render_error', message: String(err?.message ?? err) },\n })\n return\n }\n\n const sendId = new ObjectId()\n await ctx.collections.sends.insertOne(\n newSendDoc({\n _id: sendId,\n dedupeKey,\n run,\n contact,\n template,\n flow,\n providerName,\n renderedSubject: rendered.subject,\n bodyHash: sha256(rendered.html),\n status: 'queued',\n renderedFrom: rendered.fromName ? { name: rendered.fromName, email: rendered.fromEmail } : undefined,\n vars: step.vars ?? {},\n }),\n )\n\n await ctx.queues.send.add(\n 'send',\n { sendId: String(sendId) },\n { attempts: ctx.config.sendRetryAttempts, backoff: { type: 'exponential', delay: 60_000 } },\n )\n\n await advanceStep(run, ctx, { action: 'sent', details: { dedupeKey, sendId: String(sendId) } })\n}\n\n// ---------------------------------------------------------------------------\n// Send worker entry point\n// ---------------------------------------------------------------------------\n\nexport async function dispatchSend(sendId: ObjectId, ctx: RunnerContext): Promise<void> {\n const send = await ctx.collections.sends.findOne({ _id: sendId })\n if (!send) return\n if (send.status !== 'queued' && send.status !== 'failed') return // already dispatched / cancelled\n\n const template = await ctx.collections.templates.findOne({ _id: send.templateId })\n if (!template) {\n await markFailed(send._id!, 'template_missing', ctx)\n return\n }\n\n // 1. Suppression check (INVARIANT 3: always re-checked at send time).\n const supp = await isSuppressed(ctx.collections, send.emailAtSend, send.kind)\n if (supp.suppressed) {\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n { $set: { status: 'suppressed', errorMessage: `suppressed: ${supp.reason}` } },\n )\n return\n }\n\n // 2. Circuit-breaker check (only blocks marketing).\n if (send.kind === 'marketing') {\n const health = await ctx.collections.health.findOne({ _id: 'singleton' })\n if (health?.status === 'tripped') {\n // Re-enqueue with a delay; held until resume.\n await ctx.queues.send.add('send', { sendId: String(send._id) }, { delay: 60_000 })\n return\n }\n }\n\n // 3. Pull the contact + re-render (use the contact that exists now, not at flow entry).\n const contact = await ctx.adapter.getById(send.externalId)\n if (!contact) {\n await markFailed(send._id!, 'contact_missing', ctx)\n return\n }\n\n const run = send.flowRunId ? await ctx.collections.flowRuns.findOne({ _id: send.flowRunId }) : null\n const renderCtx = buildRenderContext(\n contact,\n run,\n send.vars ?? {},\n ctx,\n )\n const rendered = await renderTemplate(template, renderCtx, { helpers: ctx.handlebarsHelpers })\n\n // 4. Apply tracking using the now-known send id.\n const tracking = applyTracking(rendered.html, {\n sendId: String(send._id),\n publicUrl: ctx.config.publicUrl,\n trackOpens: template.trackOpens ?? ctx.config.trackOpens,\n trackClicks: template.trackClicks ?? ctx.config.trackClicks,\n preserveUrls: [renderCtx.unsubscribeUrl],\n })\n\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n {\n $set: {\n links: tracking.links,\n bodyHash: sha256(tracking.html),\n status: 'sending',\n fromName: rendered.fromName,\n fromEmail: rendered.fromEmail,\n subject: rendered.subject,\n },\n },\n )\n\n // 5. Provider dispatch.\n const provider = ctx.providers[send.provider] ?? ctx.providers[ctx.config.defaultProvider]\n if (!provider) {\n await markFailed(send._id!, `provider_unknown: ${send.provider}`, ctx)\n return\n }\n\n try {\n const result = await provider.send({\n to: send.emailAtSend,\n fromName: rendered.fromName,\n fromEmail: rendered.fromEmail,\n replyTo: rendered.replyTo ?? undefined,\n subject: rendered.subject,\n html: tracking.html,\n text: rendered.plainText,\n headers: {\n 'List-Unsubscribe': `<${renderCtx.unsubscribeUrl}>`,\n 'List-Unsubscribe-Post': 'List-Unsubscribe=One-Click',\n },\n messageMeta: { sendId: String(send._id) },\n })\n\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n {\n $set: {\n status: 'sent',\n sentAt: new Date(),\n providerMessageId: result.providerId,\n },\n },\n )\n await recordHealthCounter(ctx, 'sent')\n } catch (err: any) {\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n { $set: { status: 'failed', errorMessage: String(err?.message ?? err) } },\n )\n await recordHealthCounter(ctx, 'failedToSend')\n if (ctx.config.onSendFailure) {\n try {\n await ctx.config.onSendFailure({ send, error: err })\n } catch {\n /* swallow */\n }\n }\n throw err // let BullMQ retry per the attempts policy\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction pickProviderName(stepOverride: string | undefined, tpl: TemplateDoc, ctx: RunnerContext): string {\n if (stepOverride) return stepOverride\n if (tpl.providerOverride) return tpl.providerOverride\n if (tpl.kind === 'transactional' && ctx.config.defaultTransactionalProvider) {\n return ctx.config.defaultTransactionalProvider\n }\n return ctx.config.defaultProvider\n}\n\nfunction buildRenderContext(\n contact: Contact,\n run: FlowRunDoc | null,\n vars: Record<string, unknown>,\n ctx: RunnerContext,\n): RenderContext {\n const scope = 'marketing'\n const expiresAt = new Date(Date.now() + ctx.config.unsubscribeTokenLifetimeDays * 24 * 60 * 60 * 1000)\n const token = signUnsubscribeToken(\n { email: contact.email, scope, expiresAt },\n ctx.config.unsubscribeSecret,\n )\n const unsubscribeUrl = `${ctx.config.publicUrl}/m/unsub/${token}`\n\n void run\n return {\n contact,\n vars,\n unsubscribeUrl,\n senderAddress: ctx.config.senderAddress,\n }\n}\n\ninterface NewSendInput {\n _id?: ObjectId\n dedupeKey: string\n run: FlowRunDoc\n contact: Contact\n template: TemplateDoc\n flow: FlowDoc\n providerName: string\n renderedSubject: string\n bodyHash: string\n status: SendDoc['status']\n errorMessage?: string\n renderedFrom?: { name: string; email: string }\n vars?: Record<string, unknown>\n}\n\nfunction newSendDoc(input: NewSendInput): SendDoc {\n return {\n _id: input._id,\n dedupeKey: input.dedupeKey,\n externalId: input.run.externalId,\n emailAtSend: input.contact.email,\n templateId: input.template._id!,\n templateSlug: input.template.slug,\n flowRunId: input.run._id!,\n broadcastId: null,\n manualSendBy: null,\n kind: input.template.kind,\n provider: input.providerName,\n providerMessageId: null,\n fromName: input.renderedFrom?.name ?? input.template.fromName,\n fromEmail: input.renderedFrom?.email ?? input.template.fromEmail,\n subject: input.renderedSubject,\n bodyHash: input.bodyHash,\n status: input.status,\n errorMessage: input.errorMessage ?? null,\n bounceType: null,\n bounceReason: null,\n links: [],\n vars: input.vars ?? {},\n openedAt: null,\n openCount: 0,\n firstClickAt: null,\n clickCount: 0,\n clickedLinks: [],\n unsubscribedAt: null,\n complainedAt: null,\n queuedAt: new Date(),\n sentAt: null,\n deliveredAt: null,\n }\n}\n\nasync function markFailed(sendId: ObjectId, reason: string, ctx: RunnerContext): Promise<void> {\n await ctx.collections.sends.updateOne(\n { _id: sendId },\n { $set: { status: 'failed', errorMessage: reason } },\n )\n}\n\nfunction sha256(s: string): string {\n return crypto.createHash('sha256').update(s).digest('hex')\n}\n","/**\n * Flow_run state machine. One step transition per `processOneRunStep` call.\n * Idempotent — optimistic concurrency on `currentStepIndex` means two workers\n * racing on the same run advance exactly once.\n */\n\nimport type { ObjectId } from 'mongodb'\n\nimport type { FlowStep } from '../../shared/types.js'\nimport type { FlowRunDoc, FlowDoc } from '../models/index.js'\nimport { evaluatePredicate } from './predicate.js'\nimport type { RunnerContext } from './index.js'\nimport { handleSend } from './send.js'\n\nexport async function processOneRunStep(runId: ObjectId, ctx: RunnerContext): Promise<void> {\n const run = await ctx.collections.flowRuns.findOne({ _id: runId })\n if (!run || run.status !== 'active') return\n\n const flow = await ctx.collections.flows.findOne({ _id: run.flowId })\n if (!flow) {\n await failFlowRun(run, 'flow_missing', ctx)\n return\n }\n\n const steps = await loadStepsForRun(run, flow, ctx)\n const step = locateStep(steps, run.currentStepIndex, run.currentBranchPath)\n if (!step) {\n await completeFlowRun(run, 'completed', ctx)\n return\n }\n\n const contact = await ctx.adapter.getById(run.externalId)\n if (!contact) {\n await exitFlowRun(run, 'contact_missing', ctx)\n return\n }\n\n // Marketing-flow subscription gate. Transactional sends bypass this at\n // send-step level (re-checked there).\n const sub = await ctx.collections.subscriptions.findOne({ externalId: run.externalId })\n if (sub && sub.status !== 'subscribed') {\n await exitFlowRun(run, sub.status, ctx)\n return\n }\n\n switch (step.type) {\n case 'wait':\n return handleWait(run, step, ctx)\n case 'condition':\n return handleCondition(run, step, contact, ctx)\n case 'branch':\n return handleBranch(run, step, contact, ctx)\n case 'send':\n return handleSend(run, step, contact, flow, ctx)\n case 'tag':\n return handleTag(run, step, ctx)\n case 'fire_event':\n return handleFireEvent(run, step, ctx)\n case 'webhook':\n return handleWebhookStep(run, step, ctx)\n case 'exit':\n return exitFlowRun(run, step.reason ?? 'exit_step', ctx)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Step handlers\n// ---------------------------------------------------------------------------\n\nasync function handleWait(\n run: FlowRunDoc,\n step: Extract<FlowStep, { type: 'wait' }>,\n ctx: RunnerContext,\n): Promise<void> {\n const ms = unitToMs(step.value, step.unit)\n const nextAt = new Date(Date.now() + ms)\n\n const updated = await ctx.collections.flowRuns.findOneAndUpdate(\n { _id: run._id, currentStepIndex: run.currentStepIndex },\n {\n $set: { nextActionAt: nextAt, attemptsForCurrentStep: 0, updatedAt: new Date() },\n $inc: { currentStepIndex: 1 },\n $push: {\n history: {\n stepIndex: run.currentStepIndex,\n action: 'wait_started',\n at: new Date(),\n details: { until: nextAt },\n },\n },\n },\n { returnDocument: 'after' },\n )\n\n if (!updated) return // another worker advanced; their job will fire.\n\n await ctx.queues.advance.add(\n 'advance',\n { flowRunId: String(run._id) },\n { delay: ms, jobId: `advance:${run._id}:${run.currentStepIndex + 1}` },\n )\n}\n\nasync function handleCondition(\n run: FlowRunDoc,\n step: Extract<FlowStep, { type: 'condition' }>,\n contact: Awaited<ReturnType<typeof ctx.adapter.getById>>,\n ctx: RunnerContext,\n): Promise<void> {\n if (!contact) return\n const result = await evaluatePredicate(step.test, { contact, run, collections: ctx.collections })\n\n if (result) {\n await advanceStep(run, ctx, { action: 'condition_evaluated', details: { result: true } })\n return\n }\n if (step.ifFalse === 'continue') {\n await advanceStep(run, ctx, { action: 'condition_evaluated', details: { result: false, skipped: 1 } }, { stepInc: 2 })\n return\n }\n await exitFlowRun(run, 'condition_false', ctx)\n}\n\nasync function handleBranch(\n run: FlowRunDoc,\n step: Extract<FlowStep, { type: 'branch' }>,\n contact: Awaited<ReturnType<typeof ctx.adapter.getById>>,\n ctx: RunnerContext,\n): Promise<void> {\n if (!contact) return\n const result = await evaluatePredicate(step.test, { contact, run, collections: ctx.collections })\n const newPath = [...run.currentBranchPath, run.currentStepIndex, result ? 'true' : 'false', 0] as Array<number | 'true' | 'false'>\n\n const updated = await ctx.collections.flowRuns.findOneAndUpdate(\n { _id: run._id, currentStepIndex: run.currentStepIndex },\n {\n $set: {\n currentBranchPath: newPath,\n currentStepIndex: 0,\n nextActionAt: new Date(),\n attemptsForCurrentStep: 0,\n updatedAt: new Date(),\n },\n $push: {\n history: {\n stepIndex: run.currentStepIndex,\n action: 'branch_taken',\n at: new Date(),\n details: { result },\n },\n },\n },\n { returnDocument: 'after' },\n )\n\n if (!updated) return\n await ctx.queues.advance.add('advance', { flowRunId: String(run._id) })\n}\n\nasync function handleTag(\n run: FlowRunDoc,\n step: Extract<FlowStep, { type: 'tag' }>,\n ctx: RunnerContext,\n): Promise<void> {\n const adds = step.addTags ?? []\n const removes = step.removeTags ?? []\n\n if (ctx.adapter.addTags && adds.length > 0) {\n await ctx.adapter.addTags(run.externalId, adds)\n } else if (adds.length > 0) {\n await ctx.collections.contactTags.bulkWrite(\n adds.map((tag) => ({\n updateOne: {\n filter: { externalId: run.externalId, tag },\n update: { $setOnInsert: { externalId: run.externalId, tag, appliedBy: 'flow', appliedAt: new Date() } },\n upsert: true,\n },\n })),\n )\n }\n\n if (ctx.adapter.removeTags && removes.length > 0) {\n await ctx.adapter.removeTags(run.externalId, removes)\n } else if (removes.length > 0) {\n await ctx.collections.contactTags.deleteMany({ externalId: run.externalId, tag: { $in: removes } })\n }\n\n await advanceStep(run, ctx, { action: 'tagged', details: { addTags: adds, removeTags: removes } })\n}\n\nasync function handleFireEvent(\n run: FlowRunDoc,\n step: Extract<FlowStep, { type: 'fire_event' }>,\n ctx: RunnerContext,\n): Promise<void> {\n const dedupeKey = `flowrun:${run._id}:step${run.currentStepIndex}:${step.eventName}`\n try {\n await ctx.collections.events.insertOne({\n externalId: run.externalId,\n name: step.eventName,\n properties: step.properties ?? {},\n dedupeKey,\n occurredAt: new Date(),\n createdAt: new Date(),\n })\n } catch (err: any) {\n if (err?.code !== 11000) throw err\n }\n await advanceStep(run, ctx, { action: 'event_fired', details: { name: step.eventName } })\n}\n\nasync function handleWebhookStep(\n run: FlowRunDoc,\n step: Extract<FlowStep, { type: 'webhook' }>,\n ctx: RunnerContext,\n): Promise<void> {\n try {\n const res = await fetch(step.url, {\n method: step.method ?? 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(step.payload ?? { externalId: run.externalId, flowRunId: String(run._id) }),\n signal: AbortSignal.timeout(10_000),\n })\n if (!res.ok) throw new Error(`webhook step returned ${res.status}`)\n await advanceStep(run, ctx, { action: 'webhook_called', details: { url: step.url, status: res.status } })\n } catch (err: any) {\n const attempts = (run.attemptsForCurrentStep ?? 0) + 1\n if (attempts >= ctx.config.webhookRetryAttempts) {\n if (step.failureMode === 'fail_run') {\n await failFlowRun(run, `webhook failed: ${err?.message}`, ctx)\n } else {\n // Soft fail — log and advance.\n await advanceStep(run, ctx, {\n action: 'webhook_called',\n details: { url: step.url, error: err?.message, exhausted: true },\n })\n }\n } else {\n await ctx.collections.flowRuns.updateOne(\n { _id: run._id, currentStepIndex: run.currentStepIndex },\n { $inc: { attemptsForCurrentStep: 1 }, $set: { nextActionAt: new Date(Date.now() + 60_000) } },\n )\n await ctx.queues.advance.add(\n 'advance',\n { flowRunId: String(run._id) },\n { delay: 60_000, jobId: `advance:${run._id}:${run.currentStepIndex}:retry-${attempts}` },\n )\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Common helpers\n// ---------------------------------------------------------------------------\n\nexport interface AdvanceOptions {\n stepInc?: number\n}\n\nexport interface AdvanceLog {\n action: FlowRunDoc['history'][number]['action']\n details?: Record<string, unknown>\n}\n\nexport async function advanceStep(\n run: FlowRunDoc,\n ctx: RunnerContext,\n log: AdvanceLog,\n opts: AdvanceOptions = {},\n): Promise<void> {\n const stepInc = opts.stepInc ?? 1\n const updated = await ctx.collections.flowRuns.findOneAndUpdate(\n { _id: run._id, currentStepIndex: run.currentStepIndex },\n {\n $set: { nextActionAt: new Date(), attemptsForCurrentStep: 0, updatedAt: new Date() },\n $inc: { currentStepIndex: stepInc },\n $push: {\n history: { stepIndex: run.currentStepIndex, action: log.action, at: new Date(), details: log.details },\n },\n },\n { returnDocument: 'after' },\n )\n if (!updated) return\n await ctx.queues.advance.add('advance', { flowRunId: String(run._id) })\n}\n\nexport async function exitFlowRun(run: FlowRunDoc, reason: string, ctx: RunnerContext): Promise<void> {\n await ctx.collections.flowRuns.updateOne(\n { _id: run._id, status: 'active' },\n {\n $set: { status: 'exited', exitedAt: new Date(), exitReason: reason, updatedAt: new Date() },\n $push: { history: { stepIndex: run.currentStepIndex, action: 'exited', at: new Date(), details: { reason } } },\n },\n )\n}\n\nexport async function completeFlowRun(run: FlowRunDoc, reason: string, ctx: RunnerContext): Promise<void> {\n await ctx.collections.flowRuns.updateOne(\n { _id: run._id, status: 'active' },\n {\n $set: { status: 'completed', exitedAt: new Date(), exitReason: reason, updatedAt: new Date() },\n },\n )\n}\n\nexport async function failFlowRun(run: FlowRunDoc, reason: string, ctx: RunnerContext): Promise<void> {\n await ctx.collections.flowRuns.updateOne(\n { _id: run._id, status: 'active' },\n {\n $set: { status: 'failed', exitedAt: new Date(), exitReason: reason, updatedAt: new Date() },\n $push: { history: { stepIndex: run.currentStepIndex, action: 'failed', at: new Date(), details: { reason } } },\n },\n )\n}\n\nexport async function loadStepsForRun(\n run: FlowRunDoc,\n flow: FlowDoc,\n ctx: RunnerContext,\n): Promise<FlowStep[]> {\n if (run.flowVersion === flow.version) return flow.steps\n const snapshot = await ctx.collections.flowVersions.findOne({ flowId: run.flowId, version: run.flowVersion })\n return snapshot?.steps ?? flow.steps\n}\n\n/**\n * Walk a branch path through nested branch steps to find the active step.\n * Branch path layout: [parentStepIndex, 'true'|'false', childStepIndex, ...repeat]\n */\nexport function locateStep(\n steps: FlowStep[],\n currentStepIndex: number,\n branchPath: ReadonlyArray<number | 'true' | 'false'>,\n): FlowStep | null {\n let arr: FlowStep[] = steps\n\n for (let i = 0; i < branchPath.length; i += 3) {\n const parentIndex = branchPath[i] as number\n const branchKey = branchPath[i + 1] as 'true' | 'false'\n const parent = arr[parentIndex]\n if (!parent || parent.type !== 'branch') return null\n arr = branchKey === 'true' ? parent.ifTrueSteps : parent.ifFalseSteps\n }\n\n return arr[currentStepIndex] ?? null\n}\n\nfunction unitToMs(value: number, unit: 'minutes' | 'hours' | 'days' | 'weeks'): number {\n const m = 60_000\n switch (unit) {\n case 'minutes':\n return value * m\n case 'hours':\n return value * 60 * m\n case 'days':\n return value * 24 * 60 * m\n case 'weeks':\n return value * 7 * 24 * 60 * m\n }\n}\n","/**\n * Recovery sweep: finds active flow_runs whose `nextActionAt` has passed but\n * weren't woken by their delayed `mailer:advance` job (worker restart, BullMQ\n * data loss). Processes each one inline.\n */\n\nimport { processOneRunStep } from './step.js'\nimport type { RunnerContext } from './index.js'\n\nconst SWEEP_LIMIT = 500\n\nexport async function sweepStrandedFlowRuns(ctx: RunnerContext): Promise<void> {\n const runs = await ctx.collections.flowRuns\n .find({ status: 'active', nextActionAt: { $lte: new Date() } })\n .sort({ nextActionAt: 1 })\n .limit(SWEEP_LIMIT)\n .toArray()\n\n for (const run of runs) {\n try {\n await processOneRunStep(run._id!, ctx)\n } catch (err) {\n console.error('mailery: sweep advance failed', { runId: String(run._id), err })\n }\n }\n}\n","/**\n * Broadcast dispatch. Picks up scheduled broadcasts whose `scheduledAt` has\n * passed, streams the segment via the adapter cursor + mailer-side post-filter,\n * and bulk-enqueues Send docs + jobs. Per-provider rate limiting + bounded\n * enqueue (pause when waitingCount > broadcastEnqueueMaxWaiting).\n */\n\nimport { ObjectId } from 'mongodb'\n\nimport type { Contact, SegmentDefinition, SegmentFilter, AdapterFilter } from '../../shared/types.js'\nimport type { BroadcastDoc, SendDoc, TemplateDoc } from '../models/index.js'\nimport { isSuppressed } from './suppression.js'\nimport { sha256Hex } from '../tokens.js'\nimport type { RunnerContext } from './index.js'\n\n/**\n * Process scheduled broadcasts whose `scheduledAt` has passed. Called from the\n * tick. Marks each broadcast `sending` before streaming so concurrent ticks\n * don't double-dispatch.\n */\nexport async function processScheduledBroadcasts(ctx: RunnerContext): Promise<void> {\n const now = new Date()\n const due = await ctx.collections.broadcasts\n .find({ status: 'scheduled', scheduledAt: { $lte: now } })\n .toArray()\n\n for (const b of due) {\n // Optimistic claim — only one worker takes this broadcast.\n const claimed = await ctx.collections.broadcasts.findOneAndUpdate(\n { _id: b._id, status: 'scheduled' },\n { $set: { status: 'sending', startedAt: now, updatedAt: now } },\n { returnDocument: 'after' },\n )\n if (!claimed) continue\n\n try {\n await dispatchBroadcast(claimed, ctx)\n } catch (err) {\n console.error('mailery: broadcast dispatch failed', { id: String(b._id), err })\n await ctx.collections.broadcasts.updateOne(\n { _id: b._id },\n { $set: { status: 'failed', updatedAt: new Date() } },\n )\n }\n }\n}\n\nasync function dispatchBroadcast(broadcast: BroadcastDoc, ctx: RunnerContext): Promise<void> {\n const template = await ctx.collections.templates.findOne({ slug: broadcast.templateSlug })\n if (!template) {\n await ctx.collections.broadcasts.updateOne(\n { _id: broadcast._id },\n { $set: { status: 'failed', updatedAt: new Date() } },\n )\n return\n }\n\n const hostFilter = toAdapterFilter(broadcast.segmentDefinition)\n const postFilters = broadcast.segmentDefinition.filters.filter((f) => isMailerSide(f))\n\n let cursor: string | undefined = undefined\n let total = 0\n const batchSize = ctx.config.broadcastEnqueueBatchSize\n const maxWaiting = ctx.config.broadcastEnqueueMaxWaiting\n const respectTimezone = broadcast.respectRecipientTimezone === true\n const scheduledMs = broadcast.scheduledAt?.getTime() ?? Date.now()\n\n for (;;) {\n const page = await ctx.adapter.query(hostFilter, { limit: batchSize, cursor })\n if (page.contacts.length === 0) break\n\n // Stage B: mailer-side post-filter.\n const eligible = await applyPostFilters(page.contacts, postFilters, ctx)\n\n if (eligible.length > 0) {\n // Backpressure: wait until the send queue's waiting set drains below cap.\n while ((await ctx.queues.send.getWaitingCount()) > maxWaiting) {\n await sleep(2000)\n }\n\n const sendDocs = await Promise.all(\n eligible.map(async (contact) => buildSendDoc(broadcast, template, contact, ctx, scheduledMs, respectTimezone)),\n )\n\n // Filter out suppressed (mailer-side suppression check is the same one\n // dispatchSend would do; we short-circuit here to avoid enqueuing).\n const inserted: Array<{ sendId: ObjectId; delayMs: number }> = []\n for (const { doc, delayMs } of sendDocs) {\n if (!doc) continue\n try {\n await ctx.collections.sends.insertOne(doc)\n inserted.push({ sendId: doc._id!, delayMs })\n } catch (err: any) {\n if (err?.code !== 11000) throw err\n // dup dedupeKey — already dispatched somewhere\n }\n }\n\n // Bulk enqueue.\n if (inserted.length > 0) {\n await Promise.all(\n inserted.map(({ sendId, delayMs }) =>\n ctx.queues.send.add(\n 'send',\n { sendId: String(sendId) },\n {\n attempts: ctx.config.sendRetryAttempts,\n backoff: { type: 'exponential', delay: 60_000 },\n ...(delayMs > 0 ? { delay: delayMs } : {}),\n },\n ),\n ),\n )\n }\n\n total += inserted.length\n }\n\n if (!page.nextCursor) break\n cursor = page.nextCursor\n }\n\n await ctx.collections.broadcasts.updateOne(\n { _id: broadcast._id },\n {\n $set: {\n status: 'sent',\n completedAt: new Date(),\n recipientCount: total,\n updatedAt: new Date(),\n },\n },\n )\n}\n\n// ---------------------------------------------------------------------------\n// Segment translation\n// ---------------------------------------------------------------------------\n\nfunction toAdapterFilter(seg: SegmentDefinition): AdapterFilter {\n const out: AdapterFilter = {}\n for (const f of seg.filters) {\n switch (f.kind) {\n case 'hasTag':\n out.hasTag = f.tag\n break\n case 'fieldEquals':\n out.fieldEquals = { field: f.field, value: f.value }\n break\n case 'fieldIn':\n out.fieldIn = { field: f.field, values: f.values }\n break\n case 'fieldExists':\n out.fieldExists = f.field\n break\n // notHasTag isn't a single-condition adapter filter, defer to post-filter\n // subscriptionStatus / firedEvent / opened are all mailer-side\n }\n }\n return out\n}\n\nfunction isMailerSide(f: SegmentFilter): boolean {\n return (\n f.kind === 'subscriptionStatus' ||\n f.kind === 'firedEvent' ||\n f.kind === 'notFiredEvent' ||\n f.kind === 'subscribedAfter' ||\n f.kind === 'subscribedBefore' ||\n f.kind === 'opened' ||\n f.kind === 'notOpened' ||\n f.kind === 'notHasTag' ||\n f.kind === 'any' ||\n f.kind === 'not'\n )\n}\n\nasync function applyPostFilters(contacts: Contact[], filters: SegmentFilter[], ctx: RunnerContext): Promise<Contact[]> {\n if (filters.length === 0) return contacts\n const externalIds = contacts.map((c) => c.externalId)\n\n // Cache common lookups in one Mongo round-trip per filter.\n const cache: Record<string, Set<string>> = {}\n for (const f of filters) {\n if (f.kind === 'subscriptionStatus') {\n const docs = await ctx.collections.subscriptions\n .find({ externalId: { $in: externalIds }, status: f.equals })\n .project<{ externalId: string }>({ externalId: 1 })\n .toArray()\n cache[`sub:${f.equals}`] = new Set(docs.map((d) => d.externalId))\n }\n if (f.kind === 'firedEvent' || f.kind === 'notFiredEvent') {\n const query: any = { externalId: { $in: externalIds }, name: f.eventName }\n if (f.withinDays) {\n query.occurredAt = { $gt: new Date(Date.now() - f.withinDays * 86_400_000) }\n }\n const docs = await ctx.collections.events\n .find(query)\n .project<{ externalId: string }>({ externalId: 1 })\n .toArray()\n cache[`evt:${f.eventName}`] = new Set(docs.map((d) => d.externalId))\n }\n }\n\n return contacts.filter((c) => filters.every((f) => filterMatches(c, f, cache)))\n}\n\nfunction filterMatches(c: Contact, f: SegmentFilter, cache: Record<string, Set<string>>): boolean {\n switch (f.kind) {\n case 'subscriptionStatus':\n return cache[`sub:${f.equals}`]?.has(c.externalId) ?? false\n case 'firedEvent':\n return cache[`evt:${f.eventName}`]?.has(c.externalId) ?? false\n case 'notFiredEvent':\n return !cache[`evt:${f.eventName}`]?.has(c.externalId)\n case 'notHasTag':\n return !c.tags.includes(f.tag)\n case 'opened':\n case 'notOpened':\n // V1: not implemented in batch — would need a per-contact send lookup.\n // Treat as pass for now; suppress at dispatch time.\n return true\n case 'subscribedAfter':\n case 'subscribedBefore':\n return true // V2\n case 'any':\n return f.filters.some((sub) => filterMatches(c, sub, cache))\n case 'not':\n return !filterMatches(c, f.filter, cache)\n default:\n return true\n }\n}\n\n// ---------------------------------------------------------------------------\n// Send doc construction\n// ---------------------------------------------------------------------------\n\ninterface BuildResult {\n doc: SendDoc | null\n delayMs: number\n}\n\nasync function buildSendDoc(\n broadcast: BroadcastDoc,\n template: TemplateDoc,\n contact: Contact,\n ctx: RunnerContext,\n scheduledMs: number,\n respectTimezone: boolean,\n): Promise<BuildResult> {\n // Final suppression check before we insert.\n const supp = await isSuppressed(ctx.collections, contact.email, template.kind)\n if (supp.suppressed) return { doc: null, delayMs: 0 }\n\n const sendId = new ObjectId()\n const dedupeKey = `broadcast:${broadcast._id}:${contact.externalId}`\n\n // Per-recipient TZ delay calculation.\n let delayMs = Math.max(0, scheduledMs - Date.now())\n if (respectTimezone && contact.timezone) {\n delayMs = Math.max(0, perRecipientDelayMs(scheduledMs, contact.timezone))\n }\n\n const doc: SendDoc = {\n _id: sendId,\n dedupeKey,\n externalId: contact.externalId,\n emailAtSend: contact.email,\n templateId: template._id!,\n templateSlug: template.slug,\n flowRunId: null,\n broadcastId: broadcast._id!,\n manualSendBy: null,\n kind: template.kind,\n provider: template.providerOverride ?? ctx.config.defaultProvider,\n providerMessageId: null,\n fromName: template.fromName,\n fromEmail: template.fromEmail,\n subject: template.subject,\n bodyHash: '',\n status: 'queued',\n errorMessage: null,\n bounceType: null,\n bounceReason: null,\n links: [],\n vars: {},\n openedAt: null,\n openCount: 0,\n firstClickAt: null,\n clickCount: 0,\n clickedLinks: [],\n unsubscribedAt: null,\n complainedAt: null,\n queuedAt: new Date(),\n sentAt: null,\n deliveredAt: null,\n }\n void sha256Hex\n return { doc, delayMs }\n}\n\n/**\n * Compute the delay so the recipient receives the email at `scheduledMs` in\n * their LOCAL timezone (rather than the configured scheduled UTC instant).\n *\n * Example: broadcast `scheduledAt` is 10am UTC, contact is in PST (UTC-8).\n * Without respect: contact gets it at 2am local. With respect: contact gets it\n * at 10am their time = 6pm UTC. delayMs = 8 hours.\n */\nfunction perRecipientDelayMs(scheduledMs: number, timezone: string): number {\n try {\n // Get the offset between the scheduled UTC instant interpreted as a wall\n // clock and the same wall clock in the recipient's tz.\n const scheduled = new Date(scheduledMs)\n const utc = scheduled.toLocaleString('en-US', { timeZone: 'UTC', hour12: false })\n const local = scheduled.toLocaleString('en-US', { timeZone: timezone, hour12: false })\n\n // Parse both as Date objects in the runner's local tz and take the diff.\n const parse = (s: string) => {\n const m = s.match(/(\\d+)\\/(\\d+)\\/(\\d+),\\s*(\\d+):(\\d+):(\\d+)/)\n if (!m) return 0\n return Date.UTC(+m[3]!, +m[1]! - 1, +m[2]!, +m[4]!, +m[5]!, +m[6]!)\n }\n const utcMs = parse(utc)\n const localMs = parse(local)\n const offsetMs = utcMs - localMs\n\n // Target = scheduledMs (as a wall-clock in tz) + (utc - local offset) so\n // it lands at the same WALL CLOCK in tz.\n return offsetMs\n } catch {\n return 0\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","/**\n * Soft → hard bounce promotion. Configurable threshold + window:\n *\n * softBouncePromotionThreshold soft bounces for the same email within\n * softBouncePromotionWindowDays → insert a hard suppression + mark\n * the subscription bounced.\n *\n * Runs on each tick. Idempotent: if a hard suppression already exists for\n * that email, we skip.\n */\n\nimport { sha256Hex } from '../tokens.js'\nimport { recordHealthCounter } from './health.js'\nimport type { RunnerContext } from './index.js'\n\nexport async function promoteSoftBounces(ctx: RunnerContext): Promise<void> {\n const threshold = ctx.config.softBouncePromotionThreshold\n const windowDays = ctx.config.softBouncePromotionWindowDays\n if (threshold <= 0 || windowDays <= 0) return\n\n const cutoff = new Date(Date.now() - windowDays * 86_400_000)\n\n // Aggregate: count soft bounces per emailAtSend since cutoff, hitting the\n // threshold. Bounded limit to keep the tick fast.\n const offenders = await ctx.collections.sends\n .aggregate<{ _id: string; count: number }>([\n { $match: { status: 'bounced', bounceType: 'soft', queuedAt: { $gt: cutoff } } },\n { $group: { _id: '$emailAtSend', count: { $sum: 1 } } },\n { $match: { count: { $gte: threshold } } },\n { $limit: 200 },\n ])\n .toArray()\n\n for (const o of offenders) {\n const email = String(o._id ?? '').toLowerCase()\n if (!email) continue\n\n // Skip if already hard-suppressed.\n const existing = await ctx.collections.suppressions.findOne({\n email,\n scope: 'all',\n })\n if (existing) continue\n\n await ctx.collections.suppressions.updateOne(\n { email, scope: 'all' },\n {\n $setOnInsert: {\n email,\n emailHash: sha256Hex(email),\n scope: 'all',\n reason: 'hard_bounce',\n source: 'soft_promotion',\n notes: `${o.count} soft bounces in last ${windowDays} days`,\n addedAt: new Date(),\n expiresAt: null,\n },\n },\n { upsert: true },\n )\n\n await ctx.collections.subscriptions.updateOne(\n { emailAtSubscribe: email },\n { $set: { status: 'bounced', updatedAt: new Date() } },\n )\n\n await recordHealthCounter(ctx, 'hardBounced')\n }\n}\n","/**\n * The mailer:tick handler. Orchestrates all the periodic work that doesn't\n * fit a delayed-job model: event-trigger scanning, recovery sweep,\n * scheduled-broadcast dispatch, outbox draining, rollups.\n */\n\nimport { processNewlyFiredEventTriggers } from './triggers.js'\nimport { sweepStrandedFlowRuns } from './sweep.js'\nimport { processScheduledBroadcasts as dispatchScheduled } from './broadcasts.js'\nimport { evaluateHealth } from './health.js'\nimport { promoteSoftBounces } from './bounce-promotion.js'\nimport type { RunnerContext } from './index.js'\n\nexport async function runTick(ctx: RunnerContext): Promise<void> {\n await processNewlyFiredEventTriggers(ctx).catch((err) => {\n console.error('mailery: triggers scan failed', err)\n })\n await sweepStrandedFlowRuns(ctx).catch((err) => {\n console.error('mailery: sweep failed', err)\n })\n await drainOutbox(ctx).catch((err) => {\n console.error('mailery: outbox drain failed', err)\n })\n await processScheduledBroadcasts(ctx).catch((err) => {\n console.error('mailery: broadcast dispatch failed', err)\n })\n await evaluateHealth(ctx).catch((err) => {\n console.error('mailery: health evaluation failed', err)\n })\n await promoteSoftBounces(ctx).catch((err) => {\n console.error('mailery: soft-bounce promotion failed', err)\n })\n}\n\n/**\n * Pull pending outbox rows committed by host transactions and promote them\n * into the real collections (events / subscriptions / suppressions).\n */\nasync function drainOutbox(ctx: RunnerContext): Promise<void> {\n const batch = await ctx.collections.outbox\n .find({ status: 'pending' })\n .sort({ enqueuedAt: 1 })\n .limit(200)\n .toArray()\n\n for (const row of batch) {\n try {\n if (row.payload.type === 'event') {\n try {\n await ctx.collections.events.insertOne({\n externalId: row.payload.data.externalId as string,\n name: row.payload.data.name as string,\n properties: (row.payload.data.properties as Record<string, unknown>) ?? {},\n dedupeKey: row.payload.dedupeKey,\n occurredAt: (row.payload.data.occurredAt as Date | undefined) ?? new Date(),\n createdAt: new Date(),\n })\n } catch (err: any) {\n if (err?.code !== 11000) throw err\n }\n }\n await ctx.collections.outbox.updateOne(\n { _id: row._id },\n { $set: { status: 'processed', processedAt: new Date() } },\n )\n } catch (err: any) {\n await ctx.collections.outbox.updateOne(\n { _id: row._id },\n {\n $set: { lastAttemptAt: new Date(), lastError: String(err?.message ?? err) },\n $inc: { attempts: 1 },\n },\n )\n }\n }\n}\n\n/**\n * Dispatch broadcasts whose `scheduledAt` has passed. Streams the segment\n * cursor and bulk-enqueues sends, pausing when the send queue's waiting\n * count exceeds the configured cap (broadcastEnqueueMaxWaiting).\n */\nasync function processScheduledBroadcasts(ctx: RunnerContext): Promise<void> {\n await dispatchScheduled(ctx)\n}\n","/**\n * Apply a normalized provider event to the corresponding Send + cascading\n * suppression / subscription updates. Called from the webhook worker.\n */\n\nimport type { NormalizedEvent } from '../../shared/types.js'\nimport type { RunnerContext } from './index.js'\nimport { sha256Hex } from '../tokens.js'\nimport { recordHealthCounter } from './health.js'\n\nexport async function applyWebhookEvent(event: NormalizedEvent, ctx: RunnerContext): Promise<void> {\n const send = await ctx.collections.sends.findOne(\n event.providerMessageId\n ? { $or: [{ providerMessageId: event.providerMessageId }, { emailAtSend: event.email }] }\n : { emailAtSend: event.email },\n { sort: { queuedAt: -1 } },\n )\n\n switch (event.type) {\n case 'delivered':\n if (send) {\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n { $set: { status: 'delivered', deliveredAt: event.occurredAt } },\n )\n }\n await recordHealthCounter(ctx, 'delivered')\n break\n\n case 'open':\n if (send) {\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n {\n $set: {\n openedAt: send.openedAt ?? event.occurredAt,\n status: send.status === 'sent' ? 'delivered' : send.status,\n },\n $inc: { openCount: 1 },\n },\n )\n }\n break\n\n case 'click':\n if (send) {\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n {\n $set: { firstClickAt: send.firstClickAt ?? event.occurredAt },\n $inc: { clickCount: 1 },\n $push: {\n clickedLinks: {\n url: event.details.clickedUrl ?? '',\n linkId: '',\n clickedAt: event.occurredAt,\n },\n },\n },\n )\n }\n break\n\n case 'bounce': {\n const bounceType = event.details.bounceType ?? 'hard'\n if (send) {\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n {\n $set: {\n status: 'bounced',\n bounceType,\n bounceReason: event.details.bounceReason ?? null,\n },\n },\n )\n }\n if (bounceType === 'hard') {\n await suppressOnce(ctx, event.email, 'hard_bounce', 'all')\n await ctx.collections.subscriptions.updateOne(\n { emailAtSubscribe: event.email },\n { $set: { status: 'bounced', updatedAt: new Date() } },\n )\n }\n await recordHealthCounter(ctx, 'bounced')\n await recordHealthCounter(ctx, bounceType === 'hard' ? 'hardBounced' : 'softBounced')\n break\n }\n\n case 'complaint':\n case 'spam_report':\n if (send) {\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n { $set: { complainedAt: event.occurredAt, status: 'complained' } },\n )\n }\n await suppressOnce(ctx, event.email, 'complaint', 'all')\n await ctx.collections.subscriptions.updateOne(\n { emailAtSubscribe: event.email },\n { $set: { status: 'complained', updatedAt: new Date() } },\n )\n await recordHealthCounter(ctx, 'complained')\n break\n\n case 'unsubscribe':\n if (send) {\n await ctx.collections.sends.updateOne({ _id: send._id }, { $set: { unsubscribedAt: event.occurredAt } })\n }\n await suppressOnce(ctx, event.email, 'unsubscribed', 'marketing')\n await ctx.collections.subscriptions.updateOne(\n { emailAtSubscribe: event.email },\n {\n $set: {\n status: 'unsubscribed',\n unsubscribedAt: event.occurredAt,\n unsubscribeReason: 'user_request',\n updatedAt: new Date(),\n },\n },\n )\n break\n }\n}\n\nasync function suppressOnce(\n ctx: RunnerContext,\n email: string,\n reason: 'hard_bounce' | 'complaint' | 'unsubscribed',\n scope: 'all' | 'marketing' | 'transactional',\n): Promise<void> {\n const normalized = email.toLowerCase()\n await ctx.collections.suppressions.updateOne(\n { email: normalized, scope },\n {\n $setOnInsert: {\n email: normalized,\n emailHash: sha256Hex(normalized),\n scope,\n reason,\n source: 'provider_webhook',\n notes: null,\n addedAt: new Date(),\n expiresAt: null,\n },\n },\n { upsert: true },\n )\n}\n","/**\n * Mailer — public facade. Hosts call `Mailer.init(config)` and get an object\n * exposing the public API (fire, upsertSubscription, unsubscribe, ...) plus\n * mountable Express routers.\n *\n * See plans/10-public-api.md for the surface.\n */\n\nimport type { Db, ClientSession, ObjectId } from 'mongodb'\nimport { ObjectId as ObjectIdCtor } from 'mongodb'\nimport type IORedis from 'ioredis'\n\nimport type {\n ContactAdapter,\n MailProvider,\n} from '../shared/types.js'\nimport {\n fireInputSchema,\n registerEventSchema,\n sendOneOffInputSchema,\n suppressInputSchema,\n tagInputSchema,\n unsubscribeInputSchema,\n upsertSubscriptionSchema,\n type FireInput,\n type RegisterEventInput,\n type SendOneOffInput,\n type SuppressInput,\n type TagInput,\n type UnsubscribeInput,\n type UpsertSubscriptionInput,\n} from '../shared/schemas.js'\nimport { resolveConfig, type MailerConfig, type ResolvedConfig } from './config.js'\nimport {\n ensureIndexes,\n getCollections,\n} from './models/index.js'\nimport type { Collections } from './models/index.js'\nimport { EventRegistry } from './events.js'\nimport { sha256Hex, signDoiToken } from './tokens.js'\nimport {\n closeBullQueues,\n closeQueues,\n closeWorkers,\n createQueues,\n createWorkers,\n makeRedis,\n noopQueues,\n scheduleTick,\n type BullQueues,\n type Queues,\n type Workers,\n} from './queues/index.js'\nimport {\n dispatchSend,\n processOneRunStep,\n runTick,\n type RunnerContext,\n} from './runner/index.js'\nimport { applyWebhookEvent } from './runner/webhook.js'\n\nexport class Mailer {\n readonly db: Db\n readonly collections: Collections\n readonly adapter: ContactAdapter\n readonly providers: Record<string, MailProvider>\n readonly redis: IORedis | null\n readonly queues: Queues\n readonly config: ResolvedConfig\n readonly events: EventRegistry\n\n private workers: Workers | null = null\n private bullQueues: BullQueues | null\n private runnerContext: RunnerContext\n\n private constructor(args: {\n config: ResolvedConfig\n db: Db\n collections: Collections\n adapter: ContactAdapter\n providers: Record<string, MailProvider>\n redis: IORedis | null\n queues: Queues\n bullQueues: BullQueues | null\n events: EventRegistry\n }) {\n this.config = args.config\n this.db = args.db\n this.collections = args.collections\n this.adapter = args.adapter\n this.providers = args.providers\n this.redis = args.redis\n this.queues = args.queues\n this.bullQueues = args.bullQueues\n this.events = args.events\n\n this.runnerContext = {\n db: this.db,\n collections: this.collections,\n adapter: this.adapter,\n providers: this.providers,\n queues: this.queues,\n config: this.config,\n handlebarsHelpers: this.config.handlebarsHelpers,\n }\n }\n\n /**\n * Construct a Mailer from environment variables. Reads:\n *\n * MAILER_MONGODB_URI — Mongo connection string (required)\n * MAILER_MONGODB_DB — database name (optional; defaults to the URI default)\n * MAILER_REDIS_URL — Redis connection URL (required)\n * MAILER_PUBLIC_URL — base for tracking/unsub URLs (required)\n * MAILER_UNSUBSCRIBE_SECRET — HMAC key (required)\n * MAILER_SENDER_ADDRESS — postal address for CAN-SPAM (optional)\n * MAILER_FROM_NAME / MAILER_FROM_EMAIL\n * MAILER_DEFAULT_PROVIDER — defaults to 'sendgrid' if SENDGRID_API_KEY is set\n * MAILER_SENDGRID_API_KEY / MAILER_SENDGRID_WEBHOOK_KEY\n * MAILER_HOST_USERS_COLLECTION (default 'users')\n * MAILER_HOST_USERS_EMAIL_FIELD (default 'email')\n * MAILER_HOST_USERS_ID_FIELD (default '_id')\n * MAILER_HOST_USERS_TAGS_FIELD\n * MAILER_HOST_USERS_TAGS_WRITABLE — '1' or 'true' to enable\n *\n * For anything beyond this (custom toContact, custom providers, hooks),\n * use the programmatic init.\n */\n static async fromEnv(): Promise<Mailer> {\n const env = process.env\n const required = (k: string) => {\n const v = env[k]\n if (!v) throw new Error(`Mailer.fromEnv: missing env var ${k}`)\n return v\n }\n\n const { MongoClient } = await import('mongodb')\n const mongoClient = await MongoClient.connect(required('MAILER_MONGODB_URI'))\n const db = env.MAILER_MONGODB_DB ? mongoClient.db(env.MAILER_MONGODB_DB) : mongoClient.db()\n\n const { MongoContactAdapter } = await import('./adapters/mongo.js')\n const adapter = new MongoContactAdapter({\n db,\n collection: env.MAILER_HOST_USERS_COLLECTION ?? 'users',\n emailField: env.MAILER_HOST_USERS_EMAIL_FIELD ?? 'email',\n idField: env.MAILER_HOST_USERS_ID_FIELD ?? '_id',\n tagsField: env.MAILER_HOST_USERS_TAGS_FIELD,\n tagsWritable:\n env.MAILER_HOST_USERS_TAGS_WRITABLE === '1' || env.MAILER_HOST_USERS_TAGS_WRITABLE === 'true',\n })\n\n const providers: Record<string, MailProvider> = {}\n if (env.MAILER_SENDGRID_API_KEY) {\n const { SendGridProvider } = await import('./providers/sendgrid.js')\n providers.sendgrid = new SendGridProvider({\n apiKey: env.MAILER_SENDGRID_API_KEY,\n webhookVerificationKey: env.MAILER_SENDGRID_WEBHOOK_KEY,\n sandbox: env.NODE_ENV !== 'production',\n })\n }\n if (Object.keys(providers).length === 0) {\n throw new Error('Mailer.fromEnv: no provider configured (set MAILER_SENDGRID_API_KEY, ...)')\n }\n\n const defaultProvider = env.MAILER_DEFAULT_PROVIDER ?? Object.keys(providers)[0]!\n\n return Mailer.init({\n db,\n adapter,\n redis: { url: required('MAILER_REDIS_URL') },\n providers,\n defaultProvider,\n publicUrl: required('MAILER_PUBLIC_URL'),\n unsubscribeSecret: required('MAILER_UNSUBSCRIBE_SECRET'),\n senderAddress: env.MAILER_SENDER_ADDRESS,\n fromDefaults:\n env.MAILER_FROM_NAME && env.MAILER_FROM_EMAIL\n ? { name: env.MAILER_FROM_NAME, email: env.MAILER_FROM_EMAIL }\n : undefined,\n })\n }\n\n static async init(input: MailerConfig): Promise<Mailer> {\n const config = resolveConfig(input)\n if (!config.providers[config.defaultProvider]) {\n throw new Error(`defaultProvider \"${config.defaultProvider}\" not in providers map`)\n }\n\n const collections = getCollections(config.db, config.collectionPrefix)\n await ensureIndexes(config.db, config.collectionPrefix)\n\n // Allow opt-out from BullMQ entirely. Useful for tests, and for hosts that\n // want to run mailer in a queueless mode (synchronous-only). Triggered by\n // `redis: null` in the config.\n let redis: IORedis | null = null\n let queues: Queues\n let bullQueues: BullQueues | null = null\n if (config.redis === null) {\n queues = noopQueues()\n } else {\n redis = makeRedis(config.redis)\n const created = createQueues(redis)\n queues = created.queues\n bullQueues = created.bullQueues\n if (!config.workerless) {\n await scheduleTick(bullQueues, config.tickIntervalSeconds)\n }\n }\n\n return new Mailer({\n config,\n db: config.db,\n collections,\n adapter: config.adapter,\n providers: config.providers,\n redis,\n queues,\n bullQueues,\n events: new EventRegistry(),\n })\n }\n\n // -------------------------------------------------------------------------\n // Event registration + firing\n // -------------------------------------------------------------------------\n\n registerEvent(reg: RegisterEventInput): void {\n const parsed = registerEventSchema.parse(reg)\n this.events.register(parsed)\n }\n\n async fire(\n eventName: string,\n externalId: string,\n properties: Record<string, unknown> = {},\n dedupeKey?: string,\n ): Promise<void> {\n const input = fireInputSchema.parse({ eventName, externalId, properties, dedupeKey })\n const key = this.events.deriveKey(input.eventName, input.externalId, input.dedupeKey, new Date())\n if (!key) {\n throw new Error(\n `fire(\"${input.eventName}\") missing dedupeKey and no policy registered. ` +\n `Call mailer.registerEvent(\"${input.eventName}\", { dedupePolicy }) or pass a key explicitly.`,\n )\n }\n try {\n await this.collections.events.insertOne({\n externalId: input.externalId,\n name: input.eventName,\n properties: input.properties ?? {},\n dedupeKey: key,\n occurredAt: new Date(),\n createdAt: new Date(),\n })\n } catch (err: any) {\n if (err?.code !== 11000) throw err\n // Duplicate dedupeKey — no-op by design.\n }\n }\n\n async fireFromSession(\n session: ClientSession,\n eventName: string,\n externalId: string,\n properties: Record<string, unknown> = {},\n dedupeKey?: string,\n ): Promise<void> {\n const input = fireInputSchema.parse({ eventName, externalId, properties, dedupeKey })\n const key = this.events.deriveKey(input.eventName, input.externalId, input.dedupeKey, new Date())\n if (!key) {\n throw new Error(`fireFromSession(\"${input.eventName}\") missing dedupeKey and no policy registered.`)\n }\n try {\n await this.collections.outbox.insertOne(\n {\n payload: {\n type: 'event',\n data: {\n externalId: input.externalId,\n name: input.eventName,\n properties: input.properties ?? {},\n occurredAt: new Date(),\n },\n dedupeKey: key,\n },\n status: 'pending',\n attempts: 0,\n lastAttemptAt: null,\n lastError: null,\n enqueuedAt: new Date(),\n processedAt: null,\n },\n { session },\n )\n } catch (err: any) {\n if (err?.code !== 11000) throw err\n }\n }\n\n // -------------------------------------------------------------------------\n // Subscription / unsubscribe / tags / suppression\n // -------------------------------------------------------------------------\n\n async upsertSubscription(input: UpsertSubscriptionInput): Promise<void> {\n const parsed = upsertSubscriptionSchema.parse(input)\n const contact = await this.adapter.getById(parsed.externalId)\n if (!contact) throw new Error(`adapter has no contact for externalId ${parsed.externalId}`)\n\n const status = this.config.requireDoubleOptIn ? 'pending_doi' : 'subscribed'\n const now = new Date()\n\n // Generate a DOI token up front when DOI is required. We store its hash\n // (not the raw token) on the subscription doc for audit.\n let doiToken: string | null = null\n let doiTokenHash: string | null = null\n if (status === 'pending_doi') {\n const expiresAt = new Date(now.getTime() + this.config.doiTokenLifetimeDays * 86_400_000)\n doiToken = signDoiToken({ externalId: parsed.externalId, expiresAt }, this.config.unsubscribeSecret)\n doiTokenHash = sha256Hex(doiToken)\n }\n\n await this.collections.subscriptions.updateOne(\n { externalId: parsed.externalId },\n {\n $set: {\n status,\n source: parsed.source,\n emailAtSubscribe: contact.email,\n subscribedAt: status === 'subscribed' ? (parsed.consentTimestamp ?? now) : null,\n updatedAt: now,\n ...(doiTokenHash ? { doiTokenHash, doiRequestedAt: now } : {}),\n },\n $setOnInsert: {\n externalId: parsed.externalId,\n createdAt: now,\n unsubscribedAt: null,\n unsubscribeReason: null,\n doiTokenHash: null,\n doiRequestedAt: null,\n doiConfirmedAt: null,\n doiIp: parsed.consentIp ?? null,\n doiUserAgent: parsed.consentUserAgent ?? null,\n },\n },\n { upsert: true },\n )\n\n // Send the DOI confirmation email (best-effort — failures here don't\n // unwind the subscription; the host can poll pending DOI rows + re-fire).\n if (status === 'pending_doi' && doiToken) {\n const tpl = await this.collections.templates.findOne({ slug: this.config.doiTemplateSlug })\n if (!tpl) {\n console.warn(`mailery: DOI required but template \"${this.config.doiTemplateSlug}\" not found — skipping confirmation email`)\n return\n }\n const dedupeKey = `doi:${parsed.externalId}:${now.toISOString().slice(0, 10)}`\n try {\n await this.sendOneOff({\n templateSlug: tpl.slug,\n externalId: parsed.externalId,\n vars: { confirmDoiUrl: `${this.config.publicUrl}/m/confirm-doi/${doiToken}` },\n dedupeKey,\n })\n } catch (err) {\n console.error('mailery: DOI confirmation send failed', err)\n }\n }\n }\n\n async unsubscribe(email: string, opts: Omit<UnsubscribeInput, 'email'>): Promise<void> {\n const parsed = unsubscribeInputSchema.parse({ email, ...opts })\n const normalized = parsed.email\n const now = new Date()\n\n await this.collections.suppressions.updateOne(\n { email: normalized, scope: parsed.scope },\n {\n $setOnInsert: {\n email: normalized,\n emailHash: sha256Hex(normalized),\n scope: parsed.scope,\n // mailer_suppressions canonical reason — see plans/02-data-model.md.\n reason: 'unsubscribed' as const,\n source: parsed.source,\n notes: parsed.notes ?? null,\n addedAt: now,\n expiresAt: null,\n },\n },\n { upsert: true },\n )\n\n await this.collections.subscriptions.updateOne(\n { emailAtSubscribe: normalized },\n {\n $set: {\n status: 'unsubscribed' as const,\n unsubscribedAt: now,\n unsubscribeReason: parsed.reason,\n updatedAt: now,\n },\n },\n )\n }\n\n async suppress(email: string, opts: Omit<SuppressInput, 'email'>): Promise<void> {\n const parsed = suppressInputSchema.parse({ email, ...opts })\n await this.collections.suppressions.updateOne(\n { email: parsed.email, scope: parsed.scope },\n {\n $setOnInsert: {\n email: parsed.email,\n emailHash: sha256Hex(parsed.email),\n scope: parsed.scope,\n reason: parsed.reason,\n source: parsed.source,\n notes: parsed.notes ?? null,\n addedAt: new Date(),\n expiresAt: parsed.expiresAt ?? null,\n },\n },\n { upsert: true },\n )\n }\n\n async tag(externalId: string, tag: string): Promise<void> {\n const parsed = tagInputSchema.parse({ externalId, tag })\n if (this.adapter.addTags) {\n await this.adapter.addTags(parsed.externalId, [parsed.tag])\n } else {\n await this.collections.contactTags.updateOne(\n { externalId: parsed.externalId, tag: parsed.tag },\n {\n $setOnInsert: {\n externalId: parsed.externalId,\n tag: parsed.tag,\n appliedBy: 'admin',\n appliedAt: new Date(),\n },\n },\n { upsert: true },\n )\n }\n }\n\n async untag(externalId: string, tag: string): Promise<void> {\n const parsed = tagInputSchema.parse({ externalId, tag })\n if (this.adapter.removeTags) {\n await this.adapter.removeTags(parsed.externalId, [parsed.tag])\n } else {\n await this.collections.contactTags.deleteOne({ externalId: parsed.externalId, tag: parsed.tag })\n }\n }\n\n /**\n * GDPR right-to-erasure. Hard-deletes the contact's PII and leaves a hashed\n * suppression row to block re-import. INVARIANT 9.\n */\n async forget(externalId: string): Promise<void> {\n const sub = await this.collections.subscriptions.findOne({ externalId })\n const email = sub?.emailAtSubscribe?.toLowerCase()\n\n const collected = await Promise.all([\n this.collections.sends.find({ externalId }).map((s) => s.emailAtSend).toArray(),\n ])\n const emails = new Set<string>()\n if (email) emails.add(email)\n for (const e of collected[0]) if (e) emails.add(e.toLowerCase())\n\n await Promise.all([\n this.collections.events.deleteMany({ externalId }),\n this.collections.flowRuns.deleteMany({ externalId }),\n this.collections.sends.deleteMany({ externalId }),\n this.collections.subscriptions.deleteMany({ externalId }),\n this.collections.contactTags.deleteMany({ externalId }),\n ])\n if (email) {\n await this.collections.leads.deleteMany({ email })\n }\n\n for (const e of emails) {\n await this.collections.suppressions.updateOne(\n { emailHash: sha256Hex(e), scope: 'all' },\n {\n $setOnInsert: {\n email: null,\n emailHash: sha256Hex(e),\n scope: 'all',\n reason: 'gdpr_forget',\n source: 'gdpr_request',\n notes: null,\n addedAt: new Date(),\n expiresAt: null,\n },\n },\n { upsert: true },\n )\n }\n\n await this.audit({\n actor: 'system:gdpr',\n action: 'gdpr.forget',\n resource: { collection: 'mailer_subscriptions', id: sub?._id },\n diffSummary: `forget externalId=${externalId}`,\n })\n }\n\n /** GDPR data export. JSON-serializable. */\n async exportContactData(externalId: string): Promise<Record<string, unknown>> {\n const subscription = await this.collections.subscriptions.findOne({ externalId })\n const [events, flowRuns, sends, suppressions, tags] = await Promise.all([\n this.collections.events.find({ externalId }).toArray(),\n this.collections.flowRuns.find({ externalId }).toArray(),\n this.collections.sends.find({ externalId }).toArray(),\n subscription?.emailAtSubscribe\n ? this.collections.suppressions.find({ email: subscription.emailAtSubscribe }).toArray()\n : Promise.resolve([]),\n this.collections.contactTags.find({ externalId }).toArray(),\n ])\n return { subscription, events, flowRuns, sends, suppressions, tags }\n }\n\n // -------------------------------------------------------------------------\n // One-off transactional send (password reset etc.)\n // -------------------------------------------------------------------------\n\n async sendOneOff(input: SendOneOffInput): Promise<{ sendId: string }> {\n const parsed = sendOneOffInputSchema.parse(input)\n const template = await this.collections.templates.findOne({ slug: parsed.templateSlug })\n if (!template) throw new Error(`template not found: ${parsed.templateSlug}`)\n\n const contact = await this.adapter.getById(parsed.externalId)\n if (!contact) throw new Error(`contact not found: ${parsed.externalId}`)\n\n const dedupeKey = `oneoff:${parsed.dedupeKey}`\n const existing = await this.collections.sends.findOne({ dedupeKey })\n if (existing) return { sendId: String(existing._id) }\n\n const providerName =\n parsed.providerOverride\n ?? template.providerOverride\n ?? (template.kind === 'transactional' ? this.config.defaultTransactionalProvider : null)\n ?? this.config.defaultProvider\n\n const sendId = new ObjectIdCtor()\n await this.collections.sends.insertOne({\n _id: sendId,\n dedupeKey,\n externalId: parsed.externalId,\n emailAtSend: contact.email,\n templateId: template._id!,\n templateSlug: template.slug,\n flowRunId: null,\n broadcastId: null,\n manualSendBy: 'sendOneOff',\n kind: template.kind,\n provider: providerName,\n providerMessageId: null,\n fromName: template.fromName,\n fromEmail: template.fromEmail,\n subject: template.subject,\n bodyHash: '',\n status: 'queued',\n errorMessage: null,\n bounceType: null,\n bounceReason: null,\n links: [],\n vars: parsed.vars ?? {},\n openedAt: null,\n openCount: 0,\n firstClickAt: null,\n clickCount: 0,\n clickedLinks: [],\n unsubscribedAt: null,\n complainedAt: null,\n queuedAt: new Date(),\n sentAt: null,\n deliveredAt: null,\n })\n\n await this.queues.send.add(\n 'send',\n { sendId: String(sendId) },\n { attempts: this.config.sendRetryAttempts, backoff: { type: 'exponential', delay: 60_000 } },\n )\n\n return { sendId: String(sendId) }\n }\n\n // -------------------------------------------------------------------------\n // Audit log helper\n // -------------------------------------------------------------------------\n\n async audit(entry: {\n actor: string\n action: string\n resource: { collection: string; id?: string | ObjectId; slug?: string }\n before?: Record<string, unknown> | null\n after?: Record<string, unknown> | null\n diffSummary?: string\n ip?: string\n userAgent?: string\n requestId?: string\n }): Promise<void> {\n await this.collections.auditLog.insertOne({\n actor: entry.actor,\n action: entry.action,\n resource: entry.resource,\n before: entry.before ?? null,\n after: entry.after ?? null,\n diffSummary: entry.diffSummary ?? null,\n ip: entry.ip ?? null,\n userAgent: entry.userAgent ?? null,\n requestId: entry.requestId ?? null,\n occurredAt: new Date(),\n })\n }\n\n // -------------------------------------------------------------------------\n // Workers\n // -------------------------------------------------------------------------\n\n async startWorkers(): Promise<void> {\n if (this.workers) return\n if (!this.redis) throw new Error('startWorkers requires a Redis connection (redis was null in config)')\n const provider = this.providers[this.config.defaultProvider]\n const sendRate = provider?.sendRatePerSecond ?? this.config.sendRatePerSecond\n\n this.workers = createWorkers({\n redis: this.redis,\n concurrency: { send: this.config.sendConcurrency },\n sendRateLimit: { max: sendRate, durationMs: 1_000 },\n handlers: {\n tick: async () => {\n await runTick(this.runnerContext)\n },\n advance: async (data) => {\n if (!ObjectIdCtor.isValid(data.flowRunId)) return\n await processOneRunStep(new ObjectIdCtor(data.flowRunId), this.runnerContext)\n },\n send: async (data) => {\n if (!ObjectIdCtor.isValid(data.sendId)) return\n await dispatchSend(new ObjectIdCtor(data.sendId), this.runnerContext)\n },\n webhook: async () => {\n await this.processWebhookBacklog()\n },\n },\n })\n }\n\n /** Process unprocessed webhook events in mailer_webhook_events. */\n private async processWebhookBacklog(): Promise<void> {\n const batch = await this.collections.webhookEvents\n .find({ processed: false })\n .limit(500)\n .toArray()\n\n for (const evt of batch) {\n try {\n // The stored `raw` wraps the normalized event we captured at ingest;\n // pull details back out so applyWebhookEvent has the bounce reason etc.\n const normalized = (evt.raw as any)?.normalized\n const details = normalized?.details ?? {}\n await applyWebhookEvent(\n {\n type: evt.normalizedType,\n providerEventId: evt.providerEventId,\n providerMessageId: evt.providerMessageId,\n email: evt.email,\n occurredAt: evt.occurredAt,\n details,\n },\n this.runnerContext,\n )\n await this.collections.webhookEvents.updateOne({ _id: evt._id }, { $set: { processed: true } })\n } catch (err) {\n console.error('mailery: webhook apply failed', { id: String(evt._id), err })\n }\n }\n }\n\n async stop(): Promise<void> {\n if (this.workers) {\n await closeWorkers(this.workers)\n this.workers = null\n }\n if (this.bullQueues) {\n await closeBullQueues(this.bullQueues)\n this.bullQueues = null\n } else {\n await closeQueues(this.queues)\n }\n if (this.redis) {\n await this.redis.quit().catch(() => {})\n }\n }\n\n /** Used internally by the admin router and tests; not part of the public API. */\n getRunnerContext(): RunnerContext {\n return this.runnerContext\n }\n}\n","/**\n * Public exports for the `mailery` package.\n */\n\nexport const VERSION = '0.1.0'\n\n// Core\nexport { Mailer } from './mailer.js'\nexport type { MailerConfig, RedisOptions, CircuitBreakerThresholds } from './config.js'\n\n// Adapters\nexport { MongoContactAdapter } from './adapters/mongo.js'\nexport type { MongoContactAdapterOptions } from './adapters/mongo.js'\n\n// Providers\nexport { NullProvider } from './providers/null.js'\nexport { SendGridProvider } from './providers/sendgrid.js'\nexport type { SendGridProviderOptions } from './providers/sendgrid.js'\n\n// HTTP routers\nexport { createAdminRouter } from './api/admin.js'\nexport type { AdminRouterOptions } from './api/admin.js'\nexport { createPublicRouter } from './api/public.js'\nexport type { PublicRouterOptions } from './api/public.js'\n\n// Templates (host apps may want compile + render directly for previews)\nexport {\n compileTemplate,\n compileMailyTemplate,\n derivePlaintext,\n renderTemplate,\n applyTracking,\n} from './templates/render.js'\n\n// Runner internals — exported so test harnesses and advanced hosts can drive\n// the runner inline. In production let `startWorkers()` invoke these.\nexport {\n runTick,\n processOneRunStep,\n dispatchSend,\n applyWebhookEvent,\n processNewlyFiredEventTriggers,\n sweepStrandedFlowRuns,\n} from './runner/index.js'\n\n// Models (collection helpers, in case hosts need to query directly)\nexport { getCollections, ensureIndexes } from './models/index.js'\nexport type {\n Collections,\n SubscriptionDoc,\n EventDoc,\n FlowDoc,\n FlowRunDoc,\n TemplateDoc,\n SendDoc,\n SuppressionDoc,\n BroadcastDoc,\n AuditLogDoc,\n WebhookEventDoc,\n HealthDoc,\n ContactTagDoc,\n LeadDoc,\n OutboxDoc,\n FlowVersionDoc,\n TemplateVersionDoc,\n} from './models/index.js'\n\n// Token helpers (rarely needed by hosts, useful for tests)\nexport { signUnsubscribeToken, verifyUnsubscribeToken, sha256Hex } from './tokens.js'\n\n// Shared types\nexport type {\n Contact,\n ContactAdapter,\n AdapterFilter,\n MailProvider,\n SendArgs,\n SendResult,\n NormalizedEvent,\n FlowStep,\n Predicate,\n SegmentDefinition,\n SegmentFilter,\n} from '../shared/types.js'\n\nexport type {\n SubscriptionStatus,\n SendStatus,\n TemplateKind,\n SuppressionScope,\n SuppressionReason,\n FlowRunStatus,\n BroadcastStatus,\n HealthStatus,\n FlowGoal,\n} from '../shared/enums.js'\n\n// Option lists for tooling / admin UIs — flow step kinds, predicate kinds,\n// segment filter kinds, dedupe policies.\nexport {\n FLOW_STEP_KINDS,\n defaultFlowStep,\n PREDICATE_KINDS,\n defaultPredicate,\n predicateKind,\n SEGMENT_FILTER_KINDS,\n defaultSegmentFilter,\n DEDUPE_POLICIES,\n} from '../shared/options.js'\nexport type {\n FlowStepKindOption,\n PredicateKindOption,\n PredicateKind,\n SegmentFilterKindOption,\n SegmentFilterKind,\n DedupePolicyOption,\n} from '../shared/options.js'\n","/**\n * NullProvider — in-memory provider for tests and dev. Records every send\n * without dispatching anything. Inspect `.sent` to assert what would have\n * been delivered.\n */\n\nimport type { MailProvider, NormalizedEvent, SendArgs, SendResult } from '../../shared/types.js'\n\nlet counter = 0\n\nexport class NullProvider implements MailProvider {\n readonly name = 'null'\n readonly sendRatePerSecond = 1000\n public readonly sent: SendArgs[] = []\n\n async send(args: SendArgs): Promise<SendResult> {\n this.sent.push(args)\n return {\n providerId: `null-${Date.now()}-${++counter}`,\n status: 'accepted',\n }\n }\n\n async verifyWebhook(): Promise<boolean> {\n return true\n }\n\n parseWebhookEvents(): NormalizedEvent[] {\n return []\n }\n\n reset(): void {\n this.sent.length = 0\n }\n}\n","/**\n * Admin router — serves the prebuilt React SPA + REST endpoints the SPA\n * consumes. Mount inside a host Express app, gated by host auth.\n *\n * app.use('/admin/mailer', requireAdmin, createAdminRouter(mailer))\n *\n * REST routes under /api/* are documented in plans/14-admin-api.md.\n */\n\nimport express, { Router, type Request, type Response, type NextFunction } from 'express'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { ObjectId } from 'mongodb'\n\nimport type { Mailer } from '../mailer.js'\nimport {\n applyTracking,\n compileMailyTemplate,\n compileTemplate,\n renderTemplate,\n} from '../templates/render.js'\nimport { signUnsubscribeToken } from '../tokens.js'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\nfunction defaultSpaDir(): string {\n // After tsup build: dist/index.{js,cjs} + dist/admin/spa/. __dirname = dist/.\n return path.resolve(__dirname, 'admin/spa')\n}\n\nexport interface AdminRouterOptions {\n /** Override path to the built SPA. Defaults to `dist/admin/spa` shipped with the package. */\n spaDir?: string\n /** Resolve actor metadata from a Request. Defaults to `human:${req.user?.email || 'anonymous'}`. */\n getActor?: (req: Request) => string\n}\n\nexport function createAdminRouter(mailer: Mailer, opts: AdminRouterOptions = {}): Router {\n const router = Router()\n const spaDir = opts.spaDir ?? defaultSpaDir()\n const getActor =\n opts.getActor ?? ((req: Request) => `human:${(req as any).user?.email ?? 'anonymous'}`)\n\n // Static assets — long cache, hashed filenames.\n router.use(\n '/_assets',\n express.static(spaDir, {\n maxAge: '1y',\n immutable: true,\n index: false,\n }),\n )\n\n // JSON body parsing for mutating endpoints.\n router.use('/api', express.json({ limit: '1mb' }))\n\n // Inject actor on every API request (read after the host's auth middleware).\n router.use('/api', (req: Request, _res, next: NextFunction) => {\n ;(req as any).actor = getActor(req)\n next()\n })\n\n router.use('/api', apiRouter(mailer))\n\n // SPA shell — any other route returns index.html so client-side routing\n // doesn't 404 on refresh.\n router.get(/.*/, (_req: Request, res: Response) => {\n res.sendFile(path.join(spaDir, 'index.html'))\n })\n\n return router\n}\n\n// ---------------------------------------------------------------------------\n// JSON API\n// ---------------------------------------------------------------------------\n\nfunction apiRouter(mailer: Mailer): Router {\n const r = Router()\n const c = mailer.collections\n\n r.get('/me', (req, res) => {\n res.json({\n actor: (req as any).actor,\n permissions: { canPublish: true, canSendBroadcasts: true, canManageSuppressions: true },\n })\n })\n\n // ----- Dashboard ----------------------------------------------------------\n r.get(\n '/dashboard',\n asyncHandler(async (_req, res) => {\n const since24h = new Date(Date.now() - 24 * 60 * 60 * 1000)\n const [sentTotal, deliveredCount, bouncedCount, openedCount, clickedCount] = await Promise.all([\n c.sends.countDocuments({ queuedAt: { $gt: since24h } }),\n c.sends.countDocuments({ queuedAt: { $gt: since24h }, status: 'delivered' }),\n c.sends.countDocuments({ queuedAt: { $gt: since24h }, status: 'bounced' }),\n c.sends.countDocuments({ queuedAt: { $gt: since24h }, openedAt: { $ne: null } }),\n c.sends.countDocuments({ queuedAt: { $gt: since24h }, firstClickAt: { $ne: null } }),\n ])\n\n const health = await c.health.findOne({ _id: 'singleton' })\n const recentFlows = await c.flows.find({ enabled: true }).limit(5).toArray()\n const recentSends = await c.sends.find().sort({ queuedAt: -1 }).limit(6).toArray()\n const recentAudit = await c.auditLog.find().sort({ occurredAt: -1 }).limit(5).toArray()\n\n res.json({\n kpis: {\n sends: { value: sentTotal, delta: null },\n deliveredRate: {\n value: sentTotal === 0 ? 1 : deliveredCount / sentTotal,\n delta: null,\n bounced: bouncedCount,\n },\n openRate: { value: sentTotal === 0 ? 0 : openedCount / sentTotal, delta: null, exclBots: false },\n clickRate: { value: sentTotal === 0 ? 0 : clickedCount / sentTotal, delta: null },\n },\n health: health\n ? { status: health.status, rates: health.rates }\n : {\n status: 'healthy',\n rates: { hardBounceRate: 0, complaintRate: 0, combinedBounceRate: 0, failureRate: 0 },\n },\n queue: { inFlight: 0, delayed: 0, providerOk: true, providerName: mailer.config.defaultProvider },\n recentFlows,\n recentSends,\n recentAudit,\n })\n }),\n )\n\n // ----- Flows --------------------------------------------------------------\n r.get(\n '/flows',\n asyncHandler(async (_req, res) => {\n const flows = await c.flows.find().sort({ updatedAt: -1 }).toArray()\n res.json(flows)\n }),\n )\n\n r.get(\n '/flows/:slug',\n asyncHandler(async (req, res) => {\n const flow = await c.flows.findOne({ slug: req.params.slug })\n if (!flow) return res.status(404).json({ error: 'not_found' })\n return res.json(flow)\n }),\n )\n\n r.post(\n '/flows/:slug/pause',\n asyncHandler(async (req, res) => {\n const before = await c.flows.findOne({ slug: req.params.slug })\n if (!before) return res.status(404).json({ error: 'not_found' })\n await c.flows.updateOne({ _id: before._id }, { $set: { enabled: false, updatedAt: new Date() } })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'flow.pause',\n resource: { collection: 'mailer_flows', id: before._id, slug: before.slug },\n })\n return res.json({ ok: true })\n }),\n )\n\n r.post(\n '/flows/:slug/resume',\n asyncHandler(async (req, res) => {\n const before = await c.flows.findOne({ slug: req.params.slug })\n if (!before) return res.status(404).json({ error: 'not_found' })\n await c.flows.updateOne({ _id: before._id }, { $set: { enabled: true, updatedAt: new Date() } })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'flow.resume',\n resource: { collection: 'mailer_flows', id: before._id, slug: before.slug },\n })\n return res.json({ ok: true })\n }),\n )\n\n // ----- Templates ----------------------------------------------------------\n r.get(\n '/templates',\n asyncHandler(async (_req, res) => {\n const templates = await c.templates.find().sort({ updatedAt: -1 }).toArray()\n res.json(templates)\n }),\n )\n\n r.get(\n '/templates/:slug',\n asyncHandler(async (req, res) => {\n const template = await c.templates.findOne({ slug: req.params.slug })\n if (!template) return res.status(404).json({ error: 'not_found' })\n return res.json(template)\n }),\n )\n\n // ----- Broadcasts ---------------------------------------------------------\n r.get(\n '/broadcasts',\n asyncHandler(async (_req, res) => {\n const broadcasts = await c.broadcasts.find().sort({ createdAt: -1 }).toArray()\n res.json(broadcasts)\n }),\n )\n\n r.get(\n '/broadcasts/:slug',\n asyncHandler(async (req, res) => {\n const broadcast = await c.broadcasts.findOne({ slug: req.params.slug })\n if (!broadcast) return res.status(404).json({ error: 'not_found' })\n return res.json(broadcast)\n }),\n )\n\n // ----- Contacts -----------------------------------------------------------\n r.get(\n '/contacts',\n asyncHandler(async (req, res) => {\n const cursor = typeof req.query.cursor === 'string' ? req.query.cursor : undefined\n const limit = Math.min(Number(req.query.limit ?? 50), 200)\n const { contacts, nextCursor } = await mailer.adapter.query({}, { limit, cursor })\n res.json({ contacts, nextCursor })\n }),\n )\n\n r.get(\n '/contacts/:externalId',\n asyncHandler(async (req, res) => {\n const externalId = String(req.params.externalId)\n const [contact, subscription, recentEvents, recentSends, activeRuns] = await Promise.all([\n mailer.adapter.getById(externalId),\n c.subscriptions.findOne({ externalId }),\n c.events.find({ externalId }).sort({ occurredAt: -1 }).limit(50).toArray(),\n c.sends.find({ externalId }).sort({ queuedAt: -1 }).limit(50).toArray(),\n c.flowRuns.find({ externalId, status: 'active' }).toArray(),\n ])\n if (!contact) return res.status(404).json({ error: 'not_found' })\n return res.json({ contact, subscription, recentEvents, recentSends, activeRuns })\n }),\n )\n\n // ----- Sends --------------------------------------------------------------\n r.get(\n '/sends',\n asyncHandler(async (req, res) => {\n const limit = Math.min(Number(req.query.limit ?? 100), 500)\n const status = typeof req.query.status === 'string' ? req.query.status : undefined\n const filter: any = {}\n if (status) filter.status = status\n const sends = await c.sends.find(filter).sort({ queuedAt: -1 }).limit(limit).toArray()\n res.json(sends)\n }),\n )\n\n r.get(\n '/sends/:id',\n asyncHandler(async (req, res) => {\n const id = String(req.params.id)\n if (!ObjectId.isValid(id)) return res.status(400).json({ error: 'bad_id' })\n const send = await c.sends.findOne({ _id: new ObjectId(id) })\n if (!send) return res.status(404).json({ error: 'not_found' })\n const events = send.providerMessageId\n ? await c.webhookEvents.find({ providerMessageId: send.providerMessageId }).toArray()\n : []\n return res.json({ send, webhookEvents: events })\n }),\n )\n\n // ----- Suppressions -------------------------------------------------------\n r.get(\n '/suppressions',\n asyncHandler(async (_req, res) => {\n const rows = await c.suppressions.find().sort({ addedAt: -1 }).limit(500).toArray()\n res.json(rows)\n }),\n )\n\n r.post(\n '/suppressions',\n asyncHandler(async (req, res) => {\n const { email, scope, reason, source, notes } = req.body ?? {}\n await mailer.suppress(email, { scope, reason, source, notes })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'suppression.add',\n resource: { collection: 'mailer_suppressions' },\n diffSummary: `${email} → ${scope}/${reason}`,\n })\n res.json({ ok: true })\n }),\n )\n\n // ----- Audit log ----------------------------------------------------------\n r.get(\n '/audit',\n asyncHandler(async (_req, res) => {\n const rows = await c.auditLog.find().sort({ occurredAt: -1 }).limit(200).toArray()\n res.json(rows)\n }),\n )\n\n // ----- Health -------------------------------------------------------------\n r.get(\n '/health',\n asyncHandler(async (_req, res) => {\n const h = await c.health.findOne({ _id: 'singleton' })\n res.json(\n h ?? {\n _id: 'singleton',\n status: 'healthy',\n windowStartedAt: new Date(Date.now() - 60 * 60 * 1000),\n windowDurationMs: 60 * 60 * 1000,\n counters: { sent: 0, delivered: 0, bounced: 0, hardBounced: 0, softBounced: 0, complained: 0, failedToSend: 0 },\n rates: { bounceRate: 0, hardBounceRate: 0, complaintRate: 0, failureRate: 0 },\n },\n )\n }),\n )\n\n r.post(\n '/health/resume',\n asyncHandler(async (req, res) => {\n await c.health.updateOne(\n { _id: 'singleton' },\n { $set: { status: 'healthy', manuallyResumedAt: new Date(), updatedAt: new Date() } },\n )\n await mailer.audit({\n actor: (req as any).actor,\n action: 'health.resume',\n resource: { collection: 'mailer_health' },\n })\n res.json({ ok: true })\n }),\n )\n\n // ----- Flows: create / edit / publish ------------------------------------\n r.post(\n '/flows',\n asyncHandler(async (req, res) => {\n const { slug, name, description, trigger, goal, audience } = req.body ?? {}\n if (!slug || !name || !trigger?.eventName) {\n return res.status(400).json({ error: 'validation_failed', message: 'slug, name, and trigger.eventName required' })\n }\n const now = new Date()\n const doc = {\n slug,\n name,\n description: description ?? '',\n trigger: { type: 'event' as const, eventName: trigger.eventName, once: trigger.once !== false },\n enabled: false,\n steps: [],\n version: 0,\n draft: {\n steps: [],\n notes: 'Initial draft',\n lastModifiedBy: (req as any).actor ?? 'unknown',\n lastModifiedAt: now,\n },\n goal: goal ?? 'activation',\n audience: audience ?? '',\n expectedVolumePerWeek: null,\n stats: { activeRuns: 0, completedRuns: 0, sendsTotal: 0, sendsLast7Days: 0 },\n lastTriggerScanAt: null,\n publishedAt: null,\n publishedBy: null,\n createdAt: now,\n updatedAt: now,\n }\n try {\n await c.flows.insertOne(doc as any)\n } catch (err: any) {\n if (err?.code === 11000) return res.status(409).json({ error: 'slug_taken' })\n throw err\n }\n await mailer.audit({\n actor: (req as any).actor,\n action: 'flow.create',\n resource: { collection: 'mailer_flows', slug },\n })\n return res.json({ ok: true, slug })\n }),\n )\n\n r.patch(\n '/flows/:slug/draft',\n asyncHandler(async (req, res) => {\n const flow = await c.flows.findOne({ slug: req.params.slug })\n if (!flow) return res.status(404).json({ error: 'not_found' })\n const { steps, notes, trigger, name, description, goal, audience } = req.body ?? {}\n\n const set: Record<string, unknown> = {\n 'draft.lastModifiedBy': (req as any).actor,\n 'draft.lastModifiedAt': new Date(),\n updatedAt: new Date(),\n }\n if (Array.isArray(steps)) set['draft.steps'] = steps\n if (typeof notes === 'string') set['draft.notes'] = notes\n if (trigger?.eventName) set.trigger = { type: 'event' as const, eventName: trigger.eventName, once: trigger.once !== false }\n if (typeof name === 'string') set.name = name\n if (typeof description === 'string') set.description = description\n if (typeof goal === 'string') set.goal = goal\n if (typeof audience === 'string') set.audience = audience\n\n await c.flows.updateOne({ _id: flow._id }, { $set: set })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'flow.draft.update',\n resource: { collection: 'mailer_flows', id: flow._id, slug: flow.slug },\n diffSummary: `Updated draft (${steps ? `${steps.length} steps` : 'metadata only'})`,\n })\n return res.json({ ok: true })\n }),\n )\n\n r.post(\n '/flows/:slug/publish',\n asyncHandler(async (req, res) => {\n const flow = await c.flows.findOne({ slug: req.params.slug })\n if (!flow) return res.status(404).json({ error: 'not_found' })\n const draftSteps = flow.draft?.steps ?? flow.steps\n if (!Array.isArray(draftSteps) || draftSteps.length === 0) {\n return res.status(400).json({ error: 'empty_flow', message: 'flow has no steps to publish' })\n }\n const nextVersion = (flow.version ?? 0) + 1\n const now = new Date()\n await c.flowVersions.insertOne({\n flowId: flow._id!,\n version: nextVersion,\n steps: draftSteps,\n trigger: flow.trigger,\n publishedAt: now,\n publishedBy: (req as any).actor,\n })\n await c.flows.updateOne(\n { _id: flow._id },\n {\n $set: {\n steps: draftSteps,\n version: nextVersion,\n enabled: true,\n draft: null,\n publishedAt: now,\n publishedBy: (req as any).actor,\n updatedAt: now,\n },\n },\n )\n await mailer.audit({\n actor: (req as any).actor,\n action: 'flow.publish',\n resource: { collection: 'mailer_flows', id: flow._id, slug: flow.slug },\n diffSummary: `Published v${nextVersion}`,\n })\n return res.json({ ok: true, version: nextVersion })\n }),\n )\n\n r.delete(\n '/flows/:slug',\n asyncHandler(async (req, res) => {\n const flow = await c.flows.findOne({ slug: req.params.slug })\n if (!flow) return res.status(404).json({ error: 'not_found' })\n const everRan = await c.flowRuns.countDocuments({ flowId: flow._id }, { limit: 1 })\n if (everRan > 0) return res.status(409).json({ error: 'has_runs', message: 'flow has runs — pause it instead' })\n await c.flows.deleteOne({ _id: flow._id })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'flow.delete',\n resource: { collection: 'mailer_flows', id: flow._id, slug: flow.slug },\n })\n return res.json({ ok: true })\n }),\n )\n\n // ----- Templates: create / edit / publish --------------------------------\n r.post(\n '/templates',\n asyncHandler(async (req, res) => {\n const { slug, name, kind, subject, preheader, fromName, fromEmail } = req.body ?? {}\n if (!slug || !name || !kind) {\n return res.status(400).json({ error: 'validation_failed', message: 'slug, name, kind required' })\n }\n if (kind !== 'marketing' && kind !== 'transactional') {\n return res.status(400).json({ error: 'validation_failed', message: 'kind must be marketing or transactional' })\n }\n const now = new Date()\n try {\n await c.templates.insertOne({\n slug,\n name,\n description: '',\n kind,\n fromName: fromName ?? mailer.config.fromDefaults?.name ?? 'Mailery',\n fromEmail: fromEmail ?? mailer.config.fromDefaults?.email ?? 'noreply@example.com',\n replyTo: null,\n providerOverride: null,\n subject: subject ?? `Untitled — ${name}`,\n preheader: preheader ?? '',\n body: { mjml: '', editorJson: null, html: '', plainText: '', compiledAt: null },\n variablesSchema: {},\n draft: {\n subject: subject ?? `Untitled — ${name}`,\n preheader: preheader ?? '',\n mjml: '',\n editorJson: null,\n notes: 'Initial draft',\n lastModifiedBy: (req as any).actor,\n lastModifiedAt: now,\n },\n tags: [],\n trackOpens: kind === 'marketing',\n trackClicks: kind === 'marketing',\n stats: { sent: 0, delivered: 0, opened: 0, clicked: 0, bounced: 0, complained: 0, unsubscribed: 0, lastSentAt: null },\n publishedAt: null,\n publishedBy: null,\n createdAt: now,\n updatedAt: now,\n } as any)\n } catch (err: any) {\n if (err?.code === 11000) return res.status(409).json({ error: 'slug_taken' })\n throw err\n }\n await mailer.audit({\n actor: (req as any).actor,\n action: 'template.create',\n resource: { collection: 'mailer_templates', slug },\n })\n return res.json({ ok: true, slug })\n }),\n )\n\n r.patch(\n '/templates/:slug/draft',\n asyncHandler(async (req, res) => {\n const tpl = await c.templates.findOne({ slug: req.params.slug })\n if (!tpl) return res.status(404).json({ error: 'not_found' })\n\n const { subject, preheader, mjml, editorJson, notes, name, fromName, fromEmail, replyTo, kind, trackOpens, trackClicks } = req.body ?? {}\n\n const set: Record<string, unknown> = {\n 'draft.lastModifiedBy': (req as any).actor,\n 'draft.lastModifiedAt': new Date(),\n updatedAt: new Date(),\n }\n if (typeof subject === 'string') set['draft.subject'] = subject\n if (typeof preheader === 'string') set['draft.preheader'] = preheader\n if (typeof mjml === 'string') set['draft.mjml'] = mjml\n if (editorJson !== undefined) set['draft.editorJson'] = editorJson\n if (typeof notes === 'string') set['draft.notes'] = notes\n if (typeof name === 'string') set.name = name\n if (typeof fromName === 'string') set.fromName = fromName\n if (typeof fromEmail === 'string') set.fromEmail = fromEmail\n if (typeof replyTo === 'string' || replyTo === null) set.replyTo = replyTo\n if (kind === 'marketing' || kind === 'transactional') set.kind = kind\n if (typeof trackOpens === 'boolean') set.trackOpens = trackOpens\n if (typeof trackClicks === 'boolean') set.trackClicks = trackClicks\n\n await c.templates.updateOne({ _id: tpl._id }, { $set: set })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'template.draft.update',\n resource: { collection: 'mailer_templates', id: tpl._id, slug: tpl.slug },\n })\n return res.json({ ok: true })\n }),\n )\n\n r.post(\n '/templates/:slug/publish',\n asyncHandler(async (req, res) => {\n const tpl = await c.templates.findOne({ slug: req.params.slug })\n if (!tpl) return res.status(404).json({ error: 'not_found' })\n const draft = tpl.draft\n if (!draft) return res.status(400).json({ error: 'no_draft' })\n\n let compiled: { html: string; plainText: string; errors: any[] }\n if (draft.editorJson) {\n compiled = await compileMailyTemplate(draft.editorJson)\n } else if (draft.mjml) {\n compiled = await compileTemplate(draft.mjml)\n } else {\n return res.status(400).json({ error: 'empty_draft', message: 'draft has no MJML or editorJson content' })\n }\n\n const now = new Date()\n const nextVersion = await c.templateVersions.countDocuments({ templateId: tpl._id }) + 1\n await c.templateVersions.insertOne({\n templateId: tpl._id!,\n version: nextVersion,\n mjml: draft.mjml,\n html: compiled.html,\n plainText: compiled.plainText,\n subject: draft.subject,\n preheader: draft.preheader,\n publishedAt: now,\n publishedBy: (req as any).actor,\n })\n\n await c.templates.updateOne(\n { _id: tpl._id },\n {\n $set: {\n subject: draft.subject,\n preheader: draft.preheader,\n body: {\n mjml: draft.mjml,\n editorJson: draft.editorJson,\n html: compiled.html,\n plainText: compiled.plainText,\n compiledAt: now,\n },\n draft: null,\n publishedAt: now,\n publishedBy: (req as any).actor,\n updatedAt: now,\n },\n },\n )\n await mailer.audit({\n actor: (req as any).actor,\n action: 'template.publish',\n resource: { collection: 'mailer_templates', id: tpl._id, slug: tpl.slug },\n diffSummary: `Published v${nextVersion}`,\n })\n return res.json({ ok: true, version: nextVersion, warnings: compiled.errors })\n }),\n )\n\n r.post(\n '/templates/:slug/preview',\n asyncHandler(async (req, res) => {\n const tpl = await c.templates.findOne({ slug: req.params.slug })\n if (!tpl) return res.status(404).json({ error: 'not_found' })\n\n const useDraft = req.body?.useDraft !== false\n let html = ''\n let plainText = ''\n if (useDraft && tpl.draft) {\n const compiled = tpl.draft.editorJson\n ? await compileMailyTemplate(tpl.draft.editorJson)\n : await compileTemplate(tpl.draft.mjml || '<mjml><mj-body></mj-body></mjml>')\n html = compiled.html\n plainText = compiled.plainText\n } else {\n html = tpl.body.html\n plainText = tpl.body.plainText\n }\n\n const sampleContact = req.body?.sampleContact ?? {\n externalId: 'preview-contact',\n email: 'preview@example.com',\n tags: [],\n fields: { firstName: 'Alex' },\n }\n const renderCtx = {\n contact: sampleContact,\n vars: req.body?.vars ?? {},\n unsubscribeUrl: `${mailer.config.publicUrl}/m/unsub/preview`,\n senderAddress: mailer.config.senderAddress,\n }\n\n const previewTpl = { ...tpl, body: { ...tpl.body, html, plainText } }\n const rendered = await renderTemplate(previewTpl as any, renderCtx, { helpers: mailer.config.handlebarsHelpers })\n return res.json({ subject: rendered.subject, preheader: rendered.preheader, html: rendered.html, plainText: rendered.plainText })\n }),\n )\n\n r.post(\n '/templates/:slug/send-test',\n asyncHandler(async (req, res) => {\n const { to, sampleData } = req.body ?? {}\n if (!to) return res.status(400).json({ error: 'to_required' })\n const tpl = await c.templates.findOne({ slug: req.params.slug })\n if (!tpl) return res.status(404).json({ error: 'not_found' })\n\n const contact = sampleData?.contact ?? {\n externalId: 'test-recipient',\n email: to,\n tags: [],\n fields: { firstName: 'Test' },\n }\n contact.email = to\n\n const renderCtx = {\n contact,\n vars: sampleData?.vars ?? {},\n unsubscribeUrl: `${mailer.config.publicUrl}/m/unsub/test`,\n senderAddress: mailer.config.senderAddress,\n }\n const rendered = await renderTemplate(tpl as any, renderCtx, { helpers: mailer.config.handlebarsHelpers })\n const tracking = applyTracking(rendered.html, {\n sendId: `test-${Date.now()}`,\n publicUrl: mailer.config.publicUrl,\n trackOpens: false,\n trackClicks: false,\n })\n\n const provider = mailer.providers[tpl.providerOverride ?? mailer.config.defaultProvider]!\n const result = await provider.send({\n to,\n fromName: rendered.fromName,\n fromEmail: rendered.fromEmail,\n subject: `[TEST] ${rendered.subject}`,\n html: tracking.html,\n text: rendered.plainText,\n })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'template.send-test',\n resource: { collection: 'mailer_templates', slug: tpl.slug },\n diffSummary: `to=${to}`,\n })\n // Avoid unused — sign helper is exposed for future preview routes.\n void signUnsubscribeToken\n return res.json({ ok: true, providerId: result.providerId })\n }),\n )\n\n // ----- Broadcasts: create / patch / schedule / cancel --------------------\n r.post(\n '/broadcasts',\n asyncHandler(async (req, res) => {\n const { slug, name, templateSlug, segmentDefinition } = req.body ?? {}\n if (!slug || !name || !templateSlug) {\n return res.status(400).json({ error: 'validation_failed', message: 'slug, name, templateSlug required' })\n }\n const now = new Date()\n try {\n await c.broadcasts.insertOne({\n slug,\n name,\n templateSlug,\n segmentDefinition: segmentDefinition ?? { filters: [{ kind: 'subscriptionStatus', equals: 'subscribed' }] },\n status: 'draft',\n scheduledAt: null,\n startedAt: null,\n completedAt: null,\n confirmationRequired: true,\n confirmedCount: null,\n confirmedAt: null,\n confirmedBy: null,\n recipientCount: null,\n stats: { sent: 0, delivered: 0, opened: 0, clicked: 0, bounced: 0, complained: 0, unsubscribed: 0 },\n createdAt: now,\n createdBy: (req as any).actor,\n updatedAt: now,\n } as any)\n } catch (err: any) {\n if (err?.code === 11000) return res.status(409).json({ error: 'slug_taken' })\n throw err\n }\n await mailer.audit({\n actor: (req as any).actor,\n action: 'broadcast.create',\n resource: { collection: 'mailer_broadcasts', slug },\n })\n return res.json({ ok: true, slug })\n }),\n )\n\n r.patch(\n '/broadcasts/:slug',\n asyncHandler(async (req, res) => {\n const b = await c.broadcasts.findOne({ slug: req.params.slug })\n if (!b) return res.status(404).json({ error: 'not_found' })\n if (b.status !== 'draft') return res.status(409).json({ error: 'not_draft' })\n const { name, templateSlug, segmentDefinition } = req.body ?? {}\n const set: Record<string, unknown> = { updatedAt: new Date() }\n if (typeof name === 'string') set.name = name\n if (typeof templateSlug === 'string') set.templateSlug = templateSlug\n if (segmentDefinition) set.segmentDefinition = segmentDefinition\n await c.broadcasts.updateOne({ _id: b._id }, { $set: set })\n return res.json({ ok: true })\n }),\n )\n\n r.post(\n '/broadcasts/:slug/segment/count',\n asyncHandler(async (req, res) => {\n const segmentDefinition = req.body?.segmentDefinition\n if (!segmentDefinition?.filters) return res.status(400).json({ error: 'segment_required' })\n const t0 = Date.now()\n // Stage A: host-side via adapter. For V1 we just translate the first\n // host-side filter we recognize; richer segmentation lands later.\n const hostFilter: any = {}\n for (const f of segmentDefinition.filters) {\n if (f.kind === 'hasTag') hostFilter.hasTag = f.tag\n if (f.kind === 'fieldEquals') hostFilter.fieldEquals = { field: f.field, value: f.value }\n }\n const stageA = await mailer.adapter.count(hostFilter)\n // Stage B + suppression are estimated for the live counter; the real\n // numbers come at dispatch time when the cursor is streamed.\n return res.json({ stageA, stageB: stageA, afterSuppression: stageA, computedMs: Date.now() - t0 })\n }),\n )\n\n r.post(\n '/broadcasts/:slug/schedule',\n asyncHandler(async (req, res) => {\n const b = await c.broadcasts.findOne({ slug: req.params.slug })\n if (!b) return res.status(404).json({ error: 'not_found' })\n if (b.status !== 'draft') return res.status(409).json({ error: 'not_draft' })\n const { scheduledAt, confirmedCount, respectRecipientTimezone } = req.body ?? {}\n if (!scheduledAt) return res.status(400).json({ error: 'scheduledAt_required' })\n const scheduled = new Date(scheduledAt)\n if (Number.isNaN(scheduled.getTime())) return res.status(400).json({ error: 'bad_scheduledAt' })\n\n const threshold = mailer.config.broadcastConfirmationThreshold\n if (typeof confirmedCount !== 'number') {\n return res.status(400).json({ error: 'confirmedCount_required' })\n }\n\n const set: Record<string, unknown> = {\n status: 'scheduled',\n scheduledAt: scheduled,\n confirmedCount,\n confirmedAt: new Date(),\n confirmedBy: (req as any).actor,\n updatedAt: new Date(),\n }\n if (respectRecipientTimezone) set.respectRecipientTimezone = true\n\n await c.broadcasts.updateOne({ _id: b._id }, { $set: set })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'broadcast.schedule',\n resource: { collection: 'mailer_broadcasts', id: b._id, slug: b.slug },\n diffSummary: `scheduled at ${scheduled.toISOString()} · confirmedCount=${confirmedCount} · threshold=${threshold}`,\n })\n return res.json({ ok: true })\n }),\n )\n\n r.post(\n '/broadcasts/:slug/cancel',\n asyncHandler(async (req, res) => {\n const b = await c.broadcasts.findOne({ slug: req.params.slug })\n if (!b) return res.status(404).json({ error: 'not_found' })\n await c.broadcasts.updateOne({ _id: b._id }, { $set: { status: 'cancelled', updatedAt: new Date() } })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'broadcast.cancel',\n resource: { collection: 'mailer_broadcasts', id: b._id, slug: b.slug },\n })\n return res.json({ ok: true })\n }),\n )\n\n // Catch-all 404 for /api.\n r.use((_req, res) => res.status(404).json({ error: 'not_found' }))\n\n return r\n}\n\ntype AsyncHandler = (req: Request, res: Response, next: NextFunction) => Promise<unknown>\nfunction asyncHandler(fn: AsyncHandler) {\n return (req: Request, res: Response, next: NextFunction) => {\n fn(req, res, next).catch(next)\n }\n}\n","/**\n * Public router — endpoints that must be reachable by email clients and\n * provider webhooks. Mount under your tracking base path (default `/m`).\n *\n * app.use('/m', createPublicRouter(mailer))\n *\n * Routes:\n * GET /open/:sendId.png — open pixel (records open, returns 1×1 PNG)\n * GET /click/:sendId/:linkId — click redirect (records click, 302 → target)\n * GET /unsub/:token — confirmation page (one-click POST link)\n * POST /unsub/:token — RFC 8058 one-click unsubscribe\n * POST /webhooks/:provider — inbound provider event webhook\n */\n\nimport express, { Router, type Request, type Response } from 'express'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { ObjectId } from 'mongodb'\n\nimport { sha256Hex, verifyUnsubscribeToken, verifyDoiToken } from '../tokens.js'\nimport type { Mailer } from '../mailer.js'\n\nexport interface PublicRouterOptions {\n /**\n * Path on disk where unsubscribe events fall back to when Mongo is degraded.\n * Defaults to /tmp/mailery-pending-unsubs.jsonl.\n */\n pendingUnsubsPath?: string\n}\n\n// 1×1 transparent PNG (43 bytes)\nconst PIXEL = Buffer.from(\n 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=',\n 'base64',\n)\n\nexport function createPublicRouter(mailer: Mailer, opts: PublicRouterOptions = {}): Router {\n const router = Router()\n const pendingUnsubsPath = opts.pendingUnsubsPath ?? '/tmp/mailery-pending-unsubs.jsonl'\n\n // Parse JSON for webhooks — capture raw body for signature verification.\n router.use(\n '/webhooks',\n express.json({\n limit: '5mb',\n verify: (req: any, _res, buf) => {\n req.rawBody = buf\n },\n }),\n )\n\n // Pre-parsed JSON for the POST one-click unsubscribe path (RFC 8058 sends a\n // small form/JSON body; we accept either by reading the URL only).\n router.use('/unsub', express.urlencoded({ extended: false }))\n\n // -------------------------------------------------------------------------\n // GET /open/:sendId.png\n // -------------------------------------------------------------------------\n router.get('/open/:sendId.png', async (req: Request, res: Response) => {\n res.setHeader('Content-Type', 'image/png')\n res.setHeader('Content-Length', String(PIXEL.length))\n res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')\n res.status(200).end(PIXEL)\n\n // Async update — never block the response.\n const id = (req.params as any).sendId as string\n if (!ObjectId.isValid(id)) return\n const sendId = new ObjectId(id)\n try {\n const send = await mailer.collections.sends.findOne({ _id: sendId }, { projection: { openedAt: 1 } })\n if (!send) return\n await mailer.collections.sends.updateOne(\n { _id: sendId },\n {\n $set: {\n openedAt: send.openedAt ?? new Date(),\n status: 'delivered' as const,\n },\n $inc: { openCount: 1 },\n },\n )\n } catch (err) {\n console.error('mailery: open pixel update failed', err)\n }\n })\n\n // -------------------------------------------------------------------------\n // GET /click/:sendId/:linkId\n // -------------------------------------------------------------------------\n router.get('/click/:sendId/:linkId', async (req: Request, res: Response) => {\n const { sendId: sendIdStr, linkId } = req.params as { sendId: string; linkId: string }\n if (!ObjectId.isValid(sendIdStr)) return res.status(400).end()\n const sendId = new ObjectId(sendIdStr)\n\n const send = await mailer.collections.sends.findOne(\n { _id: sendId },\n { projection: { links: 1, firstClickAt: 1 } },\n )\n if (!send) return res.status(404).end()\n\n const link = (send.links ?? []).find((l) => l.linkId === linkId)\n if (!link) return res.status(404).end()\n\n res.redirect(302, link.url)\n\n try {\n await mailer.collections.sends.updateOne(\n { _id: sendId },\n {\n $set: { firstClickAt: send.firstClickAt ?? new Date() },\n $inc: { clickCount: 1 },\n $push: {\n clickedLinks: {\n url: link.url,\n linkId,\n clickedAt: new Date(),\n },\n },\n },\n )\n } catch (err) {\n console.error('mailery: click recording failed', err)\n }\n })\n\n // -------------------------------------------------------------------------\n // GET + POST /unsub/:token\n // -------------------------------------------------------------------------\n router.get('/unsub/:token', (req: Request, res: Response) => {\n const decoded = verifyUnsubscribeToken((req.params as any).token, mailer.config.unsubscribeSecret)\n if (!decoded) return sendUnsubError(res, 'Invalid or expired link.')\n\n res.status(200).type('html').send(`<!doctype html>\n<html><head>\n <meta charset=\"utf-8\" />\n <title>Unsubscribe</title>\n <style>body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;max-width:480px;margin:48px auto;padding:0 16px;color:#1c1917;line-height:1.5}h1{font-size:20px}button{padding:10px 18px;background:#dc2626;color:#fff;border:0;border-radius:6px;font-size:14px;cursor:pointer}</style>\n</head><body>\n <h1>Confirm unsubscribe</h1>\n <p>Click the button below to unsubscribe <strong>${escapeHtml(decoded.email)}</strong>${decoded.scope === 'all' ? ' from everything' : ' from marketing emails'}.</p>\n <form method=\"POST\" action=\"${escapeHtml(req.originalUrl)}\">\n <button type=\"submit\">Unsubscribe</button>\n </form>\n</body></html>`)\n })\n\n router.post('/unsub/:token', async (req: Request, res: Response) => {\n const decoded = verifyUnsubscribeToken((req.params as any).token, mailer.config.unsubscribeSecret)\n if (!decoded) {\n res.status(200).end() // never 5xx; let provider stop retrying\n return\n }\n\n // Reply 200 immediately. INVARIANT 8: bulletproof unsubscribe.\n res.status(200).type('html').send('<!doctype html><html><body><p>You are unsubscribed.</p></body></html>')\n\n try {\n await mailer.unsubscribe(decoded.email, {\n scope: decoded.scope,\n reason: 'user_request',\n source: 'one-click',\n })\n } catch (err) {\n try {\n fs.appendFileSync(\n pendingUnsubsPath,\n JSON.stringify({ email: decoded.email, scope: decoded.scope, at: Date.now() }) + '\\n',\n )\n } catch (diskErr) {\n console.error('mailery: unsub disk fallback failed', { err, diskErr })\n }\n }\n })\n\n // -------------------------------------------------------------------------\n // GET /confirm-doi/:token\n // -------------------------------------------------------------------------\n router.get('/confirm-doi/:token', async (req: Request, res: Response) => {\n const token = (req.params as any).token as string\n const decoded = verifyDoiToken(token, mailer.config.unsubscribeSecret)\n if (!decoded) {\n return res.status(400).type('html').send('<!doctype html><html><body><p>Confirmation link is invalid or expired.</p></body></html>')\n }\n const now = new Date()\n const result = await mailer.collections.subscriptions.updateOne(\n { externalId: decoded.externalId, status: 'pending_doi' },\n {\n $set: {\n status: 'subscribed',\n subscribedAt: now,\n doiConfirmedAt: now,\n doiIp: req.ip ?? null,\n doiUserAgent: (req.headers['user-agent'] as string | undefined) ?? null,\n updatedAt: now,\n },\n },\n )\n if (result.matchedCount === 0) {\n return res.status(200).type('html').send('<!doctype html><html><body><p>Already confirmed. Thanks.</p></body></html>')\n }\n try {\n await mailer.fire('subscription.confirmed', decoded.externalId, {}, `doi-confirmed:${decoded.externalId}`)\n } catch {\n /* swallow — subscription is confirmed regardless */\n }\n return res.status(200).type('html').send('<!doctype html><html><body><p>Thanks — you\\'re subscribed.</p></body></html>')\n })\n\n // -------------------------------------------------------------------------\n // POST /webhooks/:provider\n // -------------------------------------------------------------------------\n router.post('/webhooks/:provider', async (req: Request, res: Response) => {\n const providerName = (req.params as any).provider as string\n const provider = mailer.providers[providerName]\n if (!provider) return res.status(404).end()\n\n const rawBody = (req as any).rawBody as Buffer | undefined\n if (!rawBody) return res.status(400).end()\n\n const headers = lowercaseHeaders(req.headers)\n const valid = await provider.verifyWebhook(rawBody, headers)\n if (!valid) return res.status(401).end()\n\n const events = provider.parseWebhookEvents(req.body, headers)\n\n // Always 200 fast — fail-open, retry inbound is wasted bandwidth.\n res.status(200).end()\n\n // Preserve the original provider payload alongside each normalized event so the\n // audit trail isn't reduced to just our extracted fields. The raw body is the\n // full provider response array; we record it once per parsed event for clarity.\n const rawBodyRef = req.body as unknown\n for (const evt of events) {\n try {\n await mailer.collections.webhookEvents.updateOne(\n { provider: providerName, providerEventId: evt.providerEventId },\n {\n $setOnInsert: {\n provider: providerName,\n providerEventId: evt.providerEventId,\n eventType: evt.type,\n normalizedType: evt.type,\n providerMessageId: evt.providerMessageId,\n email: evt.email,\n occurredAt: evt.occurredAt,\n receivedAt: new Date(),\n processed: false,\n raw: { normalized: evt, providerBody: rawBodyRef },\n },\n },\n { upsert: true },\n )\n } catch (err) {\n console.error('mailery: webhook dedupe insert failed', err)\n }\n }\n\n if (events.length > 0) {\n try {\n await mailer.queues.webhook.add('webhook', { provider: providerName })\n } catch {\n /* will be picked up by next tick */\n }\n }\n\n // Bypass linting — `path` import retained for any future on-disk fallback.\n void path\n })\n\n return router\n}\n\nfunction sendUnsubError(res: Response, msg: string): Response {\n return res.status(400).type('html').send(`<!doctype html><html><body><p>${escapeHtml(msg)}</p></body></html>`)\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;')\n}\n\nfunction lowercaseHeaders(h: any): Record<string, string> {\n const out: Record<string, string> = {}\n for (const k of Object.keys(h)) {\n const v = h[k]\n out[k.toLowerCase()] = Array.isArray(v) ? v.join(',') : String(v ?? '')\n }\n return out\n}\n\n// silence unused\nvoid sha256Hex\n","/**\n * Enumerable option lists for the union types in `./types.ts`. Used by the\n * admin client to render dropdowns + by tooling to enumerate the surface.\n *\n * Kept in `shared/` so the client and server agree on the canonical labels +\n * default constructors. Pure data + pure functions — no React, no DOM.\n */\n\nimport type { FlowStep, Predicate, SegmentFilter } from './types.js'\n\n// ---------------------------------------------------------------------------\n// Flow step types\n// ---------------------------------------------------------------------------\n\nexport interface FlowStepKindOption {\n value: FlowStep['type']\n label: string\n /** Icon name from the client's icon set (lookup at render time). */\n icon: string\n /** Visual class on the canvas chip. */\n iconClass: string\n /** One-line description for tooltips / docs generation. */\n description: string\n}\n\nexport const FLOW_STEP_KINDS: readonly FlowStepKindOption[] = [\n { value: 'wait', label: 'Wait', icon: 'Clock', iconClass: 'wait', description: 'Pause the run for a duration before continuing.' },\n { value: 'condition', label: 'Condition', icon: 'Branch', iconClass: 'condition', description: 'Evaluate a predicate. Exit or skip on false.' },\n { value: 'branch', label: 'Branch', icon: 'Branch', iconClass: 'condition', description: 'Evaluate a predicate. Recurse into one of two sub-lists.' },\n { value: 'send', label: 'Send', icon: 'Mail', iconClass: 'send', description: 'Send a template to the contact.' },\n { value: 'tag', label: 'Tag', icon: 'Tag', iconClass: 'tag', description: 'Add or remove tags on the contact.' },\n { value: 'fire_event', label: 'Fire event', icon: 'Activity', iconClass: 'send', description: 'Insert a synthetic event (cross-flow handoff).' },\n { value: 'webhook', label: 'Webhook', icon: 'Webhook', iconClass: 'tag', description: 'POST to an external URL.' },\n { value: 'exit', label: 'Exit', icon: 'Exit', iconClass: 'exit', description: 'End the run with an optional reason.' },\n] as const\n\nexport function defaultFlowStep(type: FlowStep['type']): FlowStep {\n switch (type) {\n case 'wait': return { type: 'wait', value: 1, unit: 'days' }\n case 'condition': return { type: 'condition', test: { hasTag: 'engaged' }, ifFalse: 'exit' }\n case 'branch': return { type: 'branch', test: { hasTag: 'vip' }, ifTrueSteps: [], ifFalseSteps: [] }\n case 'send': return { type: 'send', templateSlug: '' }\n case 'tag': return { type: 'tag', addTags: [], removeTags: [] }\n case 'fire_event': return { type: 'fire_event', eventName: '' }\n case 'webhook': return { type: 'webhook', url: '', method: 'POST' }\n case 'exit': return { type: 'exit' }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Predicate kinds (the union variants of Predicate, minus composites)\n// ---------------------------------------------------------------------------\n\nexport type PredicateKind =\n | 'hasTag'\n | 'notHasTag'\n | 'fieldEquals'\n | 'fieldExists'\n | 'hasFiredEvent'\n | 'notHasFiredEvent'\n | 'subscriptionStatus'\n | 'hasOpened'\n | 'hasClicked'\n | 'hasOpenedExcludingBots'\n | 'hasClickedExcludingBots'\n | 'openedAtLeastN'\n | 'clickedAtLeastN'\n\nexport interface PredicateKindOption {\n value: PredicateKind\n label: string\n /** True when this predicate's signal is noisy (Apple MPP, bot prefetch). */\n noisy?: boolean\n}\n\nexport const PREDICATE_KINDS: readonly PredicateKindOption[] = [\n { value: 'hasTag', label: 'has tag' },\n { value: 'notHasTag', label: 'does NOT have tag' },\n { value: 'fieldEquals', label: 'field equals' },\n { value: 'fieldExists', label: 'field exists' },\n { value: 'hasFiredEvent', label: 'fired event' },\n { value: 'notHasFiredEvent', label: 'has NOT fired event' },\n { value: 'subscriptionStatus', label: 'subscription status' },\n { value: 'hasOpened', label: 'opened', noisy: true },\n { value: 'hasClicked', label: 'clicked', noisy: true },\n { value: 'hasOpenedExcludingBots', label: 'opened (excl. bots)' },\n { value: 'hasClickedExcludingBots', label: 'clicked (excl. bots)' },\n { value: 'openedAtLeastN', label: 'opened at least N' },\n { value: 'clickedAtLeastN', label: 'clicked at least N' },\n] as const\n\n/** Identify which kind of predicate this object is (or null for composites/unknown). */\nexport function predicateKind(p: Predicate | null | undefined): PredicateKind | null {\n if (!p) return null\n for (const k of PREDICATE_KINDS) {\n if (k.value in (p as object)) return k.value\n }\n return null\n}\n\nexport function defaultPredicate(kind: PredicateKind): Predicate {\n switch (kind) {\n case 'hasTag': return { hasTag: 'engaged' }\n case 'notHasTag': return { notHasTag: 'cold' }\n case 'fieldEquals': return { fieldEquals: { field: 'tier', value: 'Pro' } }\n case 'fieldExists': return { fieldExists: 'tier' }\n case 'hasFiredEvent': return { hasFiredEvent: 'Activated app' }\n case 'notHasFiredEvent': return { notHasFiredEvent: 'Cancelled' }\n case 'subscriptionStatus': return { subscriptionStatus: 'subscribed' }\n case 'hasOpened': return { hasOpened: { sinceFlowStart: true } }\n case 'hasClicked': return { hasClicked: { sinceFlowStart: true } }\n case 'hasOpenedExcludingBots': return { hasOpenedExcludingBots: { sinceFlowStart: true } }\n case 'hasClickedExcludingBots': return { hasClickedExcludingBots: { sinceFlowStart: true } }\n case 'openedAtLeastN': return { openedAtLeastN: { count: 1, withinDays: 7 } }\n case 'clickedAtLeastN': return { clickedAtLeastN: { count: 1, withinDays: 7 } }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Segment filter kinds\n// ---------------------------------------------------------------------------\n\nexport type SegmentFilterKind = SegmentFilter['kind']\n\nexport interface SegmentFilterKindOption {\n value: SegmentFilterKind\n label: string\n /** Where the filter is evaluated: host-side via adapter, or mailer-side post-filter. */\n side: 'host' | 'mailer' | 'composite'\n}\n\nexport const SEGMENT_FILTER_KINDS: readonly SegmentFilterKindOption[] = [\n { value: 'subscriptionStatus', label: 'Subscription status', side: 'mailer' },\n { value: 'hasTag', label: 'Has tag', side: 'host' },\n { value: 'notHasTag', label: 'Does NOT have tag', side: 'host' },\n { value: 'fieldEquals', label: 'Field equals', side: 'host' },\n { value: 'fieldIn', label: 'Field in list', side: 'host' },\n { value: 'fieldExists', label: 'Field exists', side: 'host' },\n { value: 'firedEvent', label: 'Fired event', side: 'mailer' },\n { value: 'notFiredEvent', label: 'Has NOT fired event', side: 'mailer' },\n { value: 'subscribedAfter', label: 'Subscribed after', side: 'mailer' },\n { value: 'subscribedBefore', label: 'Subscribed before', side: 'mailer' },\n { value: 'opened', label: 'Opened', side: 'mailer' },\n { value: 'notOpened', label: 'Did NOT open', side: 'mailer' },\n { value: 'any', label: 'Any of (OR)', side: 'composite' },\n { value: 'not', label: 'NOT', side: 'composite' },\n] as const\n\nexport function defaultSegmentFilter(kind: SegmentFilterKind): SegmentFilter {\n switch (kind) {\n case 'subscriptionStatus': return { kind: 'subscriptionStatus', equals: 'subscribed' }\n case 'hasTag': return { kind: 'hasTag', tag: '' }\n case 'notHasTag': return { kind: 'notHasTag', tag: '' }\n case 'fieldEquals': return { kind: 'fieldEquals', field: '', value: '' }\n case 'fieldIn': return { kind: 'fieldIn', field: '', values: [] }\n case 'fieldExists': return { kind: 'fieldExists', field: '' }\n case 'firedEvent': return { kind: 'firedEvent', eventName: '', withinDays: 30 }\n case 'notFiredEvent': return { kind: 'notFiredEvent', eventName: '', withinDays: 90 }\n case 'subscribedAfter': return { kind: 'subscribedAfter', date: new Date(Date.now() - 30 * 86_400_000) }\n case 'subscribedBefore': return { kind: 'subscribedBefore', date: new Date() }\n case 'opened': return { kind: 'opened', withinDays: 14 }\n case 'notOpened': return { kind: 'notOpened', withinDays: 14 }\n case 'any': return { kind: 'any', filters: [] }\n case 'not': return { kind: 'not', filter: { kind: 'hasTag', tag: '' } }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Dedupe policies for event registration\n// ---------------------------------------------------------------------------\n\nexport interface DedupePolicyOption {\n value: 'once-per-contact' | 'once-per-day' | 'every-time'\n label: string\n description: string\n derivedKeyShape: string\n}\n\nexport const DEDUPE_POLICIES: readonly DedupePolicyOption[] = [\n {\n value: 'once-per-contact',\n label: 'Once per contact',\n description: 'Lifecycle markers (Created, Activated)',\n derivedKeyShape: '${externalId}:${eventName}',\n },\n {\n value: 'once-per-day',\n label: 'Once per day',\n description: 'Daily behaviors (Viewed Storyboard)',\n derivedKeyShape: '${externalId}:${eventName}:${YYYY-MM-DD}',\n },\n {\n value: 'every-time',\n label: 'Every time',\n description: 'True every-occurrence events (Imported)',\n derivedKeyShape: '${externalId}:${eventName}:${UUIDv4}',\n },\n] as const\n"]}
1
+ {"version":3,"sources":["../src/server/adapters/mongo.ts","../src/server/providers/sendgrid.ts","../src/shared/schemas.ts","../src/server/config.ts","../src/server/models/index.ts","../src/server/events.ts","../src/server/tokens.ts","../src/server/queues/bull.ts","../src/server/queues/agenda.ts","../src/server/queues/noop.ts","../src/server/queues/index.ts","../src/server/runner/triggers.ts","../src/server/runner/predicate.ts","../src/server/templates/render.ts","../src/server/runner/suppression.ts","../src/server/runner/health.ts","../src/server/runner/send.ts","../src/server/runner/step.ts","../src/server/runner/sweep.ts","../src/server/runner/broadcasts.ts","../src/server/runner/bounce-promotion.ts","../src/server/runner/tick.ts","../src/server/runner/webhook.ts","../src/server/mailer.ts","../src/server/templates/sender-domain.ts","../src/server/index.ts","../src/server/providers/null.ts","../src/server/api/setup-status.ts","../src/server/api/admin.ts","../src/server/api/public.ts","../src/shared/options.ts"],"names":["MongoContactAdapter","ObjectId","SendGridProvider","sgMail","crypto","z","IORedis","QUEUE_NAMES","mjml2html","htmlToText","Handlebars","counter","processScheduledBroadcasts","ObjectIdCtor","__filename","fileURLToPath","__dirname","path","Router","express","fs"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * MongoContactAdapter — reads contacts directly from the host's `users`\n * collection (read-mostly; optional narrow tag writes). Mailer never\n * duplicates identity data — the host is the source of truth.\n */\n\nimport type { Collection, Db, Filter } from 'mongodb'\nimport { ObjectId } from 'mongodb'\n\nimport type {\n AdapterFilter,\n Contact,\n ContactAdapter,\n} from '../../shared/types.js'\n\nexport interface MongoContactAdapterOptions {\n db: Db\n collection: string\n emailField?: string\n idField?: string\n /** Path to the tags array on the user document. */\n tagsField?: string\n /** When true, mailer writes tags via `$addToSet` / `$pull` on the user doc. */\n tagsWritable?: boolean\n /** 'strings' = ['vip','beta'], 'objects' = [{ name: 'vip' }]. */\n tagsArrayShape?: 'strings' | 'objects'\n /** Customize the projection mailer sees. Defaults pick up email + tags + a few common fields. */\n toContact?: (userDoc: any) => Contact\n /** Customize how AdapterFilter becomes a Mongo query. */\n translateFilter?: (filter: AdapterFilter) => Filter<any>\n /** Per-call default for query() limit. */\n batchSize?: number\n}\n\nexport class MongoContactAdapter implements ContactAdapter {\n private readonly col: Collection<any>\n private readonly emailField: string\n private readonly idField: string\n private readonly tagsField: string | null\n private readonly tagsWritable: boolean\n private readonly tagsArrayShape: 'strings' | 'objects'\n private readonly toContactFn: (doc: any) => Contact\n private readonly translateFilterFn: (filter: AdapterFilter) => Filter<any>\n private readonly batchSize: number\n\n constructor(opts: MongoContactAdapterOptions) {\n this.col = opts.db.collection(opts.collection)\n this.emailField = opts.emailField ?? 'email'\n this.idField = opts.idField ?? '_id'\n this.tagsField = opts.tagsField ?? null\n this.tagsWritable = !!opts.tagsWritable\n this.tagsArrayShape = opts.tagsArrayShape ?? 'strings'\n this.toContactFn = opts.toContact ?? this.defaultToContact.bind(this)\n this.translateFilterFn = opts.translateFilter ?? this.defaultTranslateFilter.bind(this)\n this.batchSize = opts.batchSize ?? 500\n\n // Only expose tag write methods if the host opted in.\n if (this.tagsWritable && this.tagsField) {\n this.addTags = this.addTagsImpl.bind(this)\n this.removeTags = this.removeTagsImpl.bind(this)\n }\n }\n\n async getById(externalId: string): Promise<Contact | null> {\n const filter = this.idFilter(externalId)\n const doc = await this.col.findOne(filter)\n return doc ? this.toContactFn(doc) : null\n }\n\n async getByEmail(email: string): Promise<Contact | null> {\n const doc = await this.col.findOne({ [this.emailField]: email.toLowerCase() })\n return doc ? this.toContactFn(doc) : null\n }\n\n async getBatch(externalIds: string[]): Promise<Map<string, Contact>> {\n if (externalIds.length === 0) return new Map()\n const tryObjectId = externalIds.every(canBeObjectId)\n const ids: any[] = tryObjectId ? externalIds.map((s) => new ObjectId(s)) : externalIds\n const docs = await this.col.find({ [this.idField]: { $in: ids } }).toArray()\n const out = new Map<string, Contact>()\n for (const doc of docs) {\n const c = this.toContactFn(doc)\n out.set(c.externalId, c)\n }\n return out\n }\n\n async query(\n filter: AdapterFilter,\n opts: { limit: number; cursor?: string },\n ): Promise<{ contacts: Contact[]; nextCursor?: string }> {\n const query = this.translateFilterFn(filter)\n const limit = Math.min(opts.limit, this.batchSize)\n\n // Cursor is an ObjectId-or-externalId encoded as a string; we use it as a >\n // bound on the idField for stable pagination ordered by id.\n if (opts.cursor) {\n const cursorVal = canBeObjectId(opts.cursor) ? new ObjectId(opts.cursor) : opts.cursor\n ;(query as any)[this.idField] = { ...((query as any)[this.idField] ?? {}), $gt: cursorVal }\n }\n\n const docs = await this.col\n .find(query)\n .sort({ [this.idField]: 1 })\n .limit(limit + 1)\n .toArray()\n\n const hasMore = docs.length > limit\n const slice = hasMore ? docs.slice(0, limit) : docs\n const contacts = slice.map((d) => this.toContactFn(d))\n const last = slice[slice.length - 1]\n const nextCursor = hasMore && last ? String((last as any)[this.idField]) : undefined\n return { contacts, nextCursor }\n }\n\n async count(filter: AdapterFilter): Promise<number> {\n const query = this.translateFilterFn(filter)\n return await this.col.countDocuments(query)\n }\n\n addTags?: (externalId: string, tags: string[]) => Promise<void>\n removeTags?: (externalId: string, tags: string[]) => Promise<void>\n\n // -------------------------------------------------------------------------\n // Private helpers\n // -------------------------------------------------------------------------\n\n private idFilter(externalId: string): Filter<any> {\n if (this.idField === '_id' && canBeObjectId(externalId)) {\n return { _id: new ObjectId(externalId) } as Filter<any>\n }\n return { [this.idField]: externalId }\n }\n\n private defaultToContact(doc: any): Contact {\n const tagsRaw = this.tagsField ? doc[this.tagsField] ?? [] : []\n const tags: string[] =\n this.tagsArrayShape === 'objects'\n ? (Array.isArray(tagsRaw) ? tagsRaw : []).map((t: any) => String(t.name ?? t))\n : (Array.isArray(tagsRaw) ? tagsRaw : []).map((t: any) => String(t))\n\n const externalId = String(doc[this.idField] ?? '')\n const email = String(doc[this.emailField] ?? '').toLowerCase()\n\n // Default projection: everything that's not _id / email / tags becomes a field.\n const fields: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(doc)) {\n if (k === this.idField || k === this.emailField || k === this.tagsField) continue\n fields[k] = v\n }\n\n return {\n externalId,\n email,\n tags,\n fields,\n timezone: typeof doc.timezone === 'string' ? doc.timezone : undefined,\n locale: typeof doc.locale === 'string' ? doc.locale : undefined,\n }\n }\n\n private defaultTranslateFilter(filter: AdapterFilter): Filter<any> {\n const q: Record<string, unknown> = {}\n\n if (filter.emailIn && filter.emailIn.length > 0) {\n q[this.emailField] = { $in: filter.emailIn.map((e) => e.toLowerCase()) }\n }\n if (filter.externalIdIn && filter.externalIdIn.length > 0) {\n const tryObjectId = filter.externalIdIn.every(canBeObjectId)\n q[this.idField] = {\n $in: tryObjectId ? filter.externalIdIn.map((s) => new ObjectId(s)) : filter.externalIdIn,\n }\n }\n if (filter.fieldEquals) {\n q[filter.fieldEquals.field] = filter.fieldEquals.value\n }\n if (filter.fieldIn) {\n q[filter.fieldIn.field] = { $in: filter.fieldIn.values }\n }\n if (filter.fieldExists) {\n q[filter.fieldExists] = { $exists: true }\n }\n if (filter.createdAfter || filter.createdBefore) {\n const r: any = {}\n if (filter.createdAfter) r.$gte = filter.createdAfter\n if (filter.createdBefore) r.$lte = filter.createdBefore\n q.createdAt = r\n }\n if (this.tagsField) {\n if (filter.hasTag) {\n q[this.tagsField] = filter.hasTag\n }\n if (filter.hasTagIn && filter.hasTagIn.length > 0) {\n q[this.tagsField] = { $in: filter.hasTagIn }\n }\n }\n return q\n }\n\n private async addTagsImpl(externalId: string, tags: string[]): Promise<void> {\n if (!this.tagsField || tags.length === 0) return\n const value =\n this.tagsArrayShape === 'objects'\n ? tags.map((name) => ({ name }))\n : tags\n await this.col.updateOne(this.idFilter(externalId), {\n $addToSet: { [this.tagsField]: { $each: value } } as any,\n })\n }\n\n private async removeTagsImpl(externalId: string, tags: string[]): Promise<void> {\n if (!this.tagsField || tags.length === 0) return\n const value =\n this.tagsArrayShape === 'objects'\n ? { $in: tags.map((name) => ({ name })) }\n : { $in: tags }\n await this.col.updateOne(this.idFilter(externalId), {\n $pull: { [this.tagsField]: value } as any,\n })\n }\n}\n\nfunction canBeObjectId(s: string): boolean {\n return typeof s === 'string' && /^[a-f0-9]{24}$/i.test(s)\n}\n","/**\n * SendGridProvider — sends mail through @sendgrid/mail, verifies the Event\n * Webhook signature with the ECDSA public key configured in SendGrid, and\n * normalizes inbound event payloads into our shared shape.\n *\n * Setup steps required on the SendGrid side (one-time):\n * 1. Authenticate sender domain (SPF, DKIM, DMARC).\n * 2. Configure event webhook → POST to https://your.host/m/webhooks/sendgrid\n * 3. Enable: delivered, open, click, bounce, dropped, spamreport, unsubscribe\n * 4. Generate Signed Event Webhook key → store as webhookVerificationKey\n */\n\nimport crypto from 'node:crypto'\nimport sgMail from '@sendgrid/mail'\n\nimport type {\n MailProvider,\n NormalizedEvent,\n SendArgs,\n SendResult,\n} from '../../shared/types.js'\n\nexport interface SendGridProviderOptions {\n apiKey: string\n /** ECDSA public key (PEM) from SendGrid → Settings → Mail Settings → Signed Event Webhook. */\n webhookVerificationKey?: string\n /** Send-rate cap per second (BullMQ group limiter consults this). */\n sendRatePerSecond?: number\n /** Sandbox mode bypasses actual delivery — useful in dev/test. */\n sandbox?: boolean\n}\n\nconst SG_SIG_HEADER = 'x-twilio-email-event-webhook-signature'\nconst SG_TS_HEADER = 'x-twilio-email-event-webhook-timestamp'\n\nexport class SendGridProvider implements MailProvider {\n readonly name = 'sendgrid'\n readonly sendRatePerSecond: number\n\n constructor(private readonly opts: SendGridProviderOptions) {\n sgMail.setApiKey(opts.apiKey)\n this.sendRatePerSecond = opts.sendRatePerSecond ?? 10\n }\n\n async send(args: SendArgs): Promise<SendResult> {\n const msg: sgMail.MailDataRequired = {\n to: args.to,\n from: { name: args.fromName, email: args.fromEmail },\n replyTo: args.replyTo,\n subject: args.subject,\n text: args.text,\n html: args.html,\n headers: args.headers,\n customArgs: args.messageMeta,\n trackingSettings: {\n // We do our own click/open tracking — let provider stay out of it.\n clickTracking: { enable: false, enableText: false },\n openTracking: { enable: false },\n },\n mailSettings: {\n sandboxMode: { enable: this.opts.sandbox ?? false },\n },\n }\n\n const [response] = await sgMail.send(msg)\n const providerId =\n (response.headers['x-message-id'] as string | undefined) ?? `sg-${Date.now()}`\n return {\n providerId,\n status: response.statusCode < 300 ? 'accepted' : 'rejected',\n raw: response,\n }\n }\n\n async verifyWebhook(rawBody: Buffer, headers: Record<string, string>): Promise<boolean> {\n if (!this.opts.webhookVerificationKey) return false\n const sig = headers[SG_SIG_HEADER]\n const ts = headers[SG_TS_HEADER]\n if (!sig || !ts) return false\n\n const payload = Buffer.concat([Buffer.from(ts, 'utf8'), rawBody])\n try {\n const verifier = crypto.createVerify('sha256')\n verifier.update(payload)\n return verifier.verify(this.opts.webhookVerificationKey, sig, 'base64')\n } catch {\n return false\n }\n }\n\n parseWebhookEvents(payload: unknown): NormalizedEvent[] {\n if (!Array.isArray(payload)) return []\n return payload\n .map((raw) => normalizeSendGridEvent(raw))\n .filter((e): e is NormalizedEvent => e !== null)\n }\n}\n\nfunction normalizeSendGridEvent(e: any): NormalizedEvent | null {\n const type = mapEventType(e.event)\n if (!type) return null\n return {\n type,\n providerEventId: String(e.sg_event_id ?? e['smtp-id'] ?? `${e.event}-${e.timestamp}-${e.email}`),\n providerMessageId: String(e.sg_message_id ?? e['smtp-id'] ?? ''),\n email: String(e.email ?? '').toLowerCase(),\n occurredAt: new Date(Number(e.timestamp) * 1000),\n details: {\n bounceType:\n e.event === 'bounce' ? (e.type === 'bounce' ? 'hard' : 'soft') : undefined,\n bounceReason: e.reason,\n clickedUrl: e.url,\n userAgent: e.useragent,\n ipAddress: e.ip,\n },\n }\n}\n\nfunction mapEventType(sgEvent: string): NormalizedEvent['type'] | null {\n switch (sgEvent) {\n case 'delivered':\n return 'delivered'\n case 'open':\n return 'open'\n case 'click':\n return 'click'\n case 'bounce':\n case 'dropped':\n return 'bounce'\n case 'spamreport':\n return 'spam_report'\n case 'unsubscribe':\n case 'group_unsubscribe':\n return 'unsubscribe'\n default:\n return null\n }\n}\n","/**\n * Zod schemas for runtime validation at write boundaries — public API entry\n * points (fire, upsertSubscription, suppress, sendOneOff, scheduleBroadcast)\n * and REST handler bodies.\n *\n * Domain TypeScript types live in `./types.ts`; these schemas overlap with\n * those types deliberately so we get both compile-time and runtime checking\n * at the surfaces that need it.\n */\n\nimport { z } from 'zod'\n\n// ---------------------------------------------------------------------------\n// Primitive helpers\n// ---------------------------------------------------------------------------\n\nexport const externalIdSchema = z.string().min(1).max(256)\nexport const emailSchema = z.string().email().toLowerCase().trim()\nexport const slugSchema = z\n .string()\n .min(1)\n .max(128)\n .regex(/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/, 'must be kebab-case slug')\n\n// ---------------------------------------------------------------------------\n// Public API inputs\n// ---------------------------------------------------------------------------\n\nexport const fireInputSchema = z.object({\n eventName: z.string().min(1).max(128),\n externalId: externalIdSchema,\n properties: z.record(z.string(), z.unknown()).optional(),\n dedupeKey: z.string().min(1).max(512).optional(),\n})\nexport type FireInput = z.infer<typeof fireInputSchema>\n\nexport const registerEventSchema = z.object({\n name: z.string().min(1).max(128),\n dedupePolicy: z.enum(['once-per-contact', 'once-per-day', 'every-time']),\n})\nexport type RegisterEventInput = z.infer<typeof registerEventSchema>\n\nexport const upsertSubscriptionSchema = z.object({\n externalId: externalIdSchema,\n source: z.string().min(1).max(256),\n consentTimestamp: z.date().optional(),\n consentIp: z.string().optional(),\n consentUserAgent: z.string().optional(),\n})\nexport type UpsertSubscriptionInput = z.infer<typeof upsertSubscriptionSchema>\n\nexport const unsubscribeScopeSchema = z.enum(['all', 'marketing', 'transactional'])\nexport const unsubscribeReasonSchema = z.enum([\n 'user_request',\n 'hard_bounce',\n 'complaint',\n 'manual',\n 'gdpr_forget',\n 'list_cleaning',\n])\n\nexport const unsubscribeInputSchema = z.object({\n email: emailSchema,\n scope: unsubscribeScopeSchema,\n reason: unsubscribeReasonSchema.default('user_request'),\n source: z.string().max(256).default('manual'),\n notes: z.string().max(1024).optional(),\n})\nexport type UnsubscribeInput = z.infer<typeof unsubscribeInputSchema>\n\nexport const suppressInputSchema = z.object({\n email: emailSchema,\n scope: unsubscribeScopeSchema,\n reason: z.enum(['unsubscribed', 'hard_bounce', 'complaint', 'manual', 'list_cleaning', 'gdpr_forget']),\n source: z.string().max(256).default('manual'),\n notes: z.string().max(1024).optional(),\n expiresAt: z.date().optional(),\n})\nexport type SuppressInput = z.infer<typeof suppressInputSchema>\n\nexport const tagInputSchema = z.object({\n externalId: externalIdSchema,\n tag: z.string().min(1).max(128),\n})\nexport type TagInput = z.infer<typeof tagInputSchema>\n\nexport const sendOneOffInputSchema = z.object({\n templateSlug: slugSchema,\n externalId: externalIdSchema,\n vars: z.record(z.string(), z.unknown()).optional(),\n providerOverride: z.string().optional(),\n dedupeKey: z.string().min(1).max(512),\n})\nexport type SendOneOffInput = z.infer<typeof sendOneOffInputSchema>\n\n// ---------------------------------------------------------------------------\n// Flow step + predicate schemas (mirror types.ts)\n// ---------------------------------------------------------------------------\n\nexport const flowStepSchema: z.ZodType<unknown> = z.lazy(() =>\n z.discriminatedUnion('type', [\n z.object({\n type: z.literal('wait'),\n value: z.number().int().positive(),\n unit: z.enum(['minutes', 'hours', 'days', 'weeks']),\n }),\n z.object({\n type: z.literal('condition'),\n test: predicateSchema,\n ifFalse: z.enum(['continue', 'exit']),\n }),\n z.object({\n type: z.literal('branch'),\n test: predicateSchema,\n ifTrueSteps: z.array(flowStepSchema),\n ifFalseSteps: z.array(flowStepSchema),\n }),\n z.object({\n type: z.literal('send'),\n templateSlug: slugSchema,\n providerOverride: z.string().optional(),\n vars: z.record(z.string(), z.unknown()).optional(),\n }),\n z.object({\n type: z.literal('tag'),\n addTags: z.array(z.string()).optional(),\n removeTags: z.array(z.string()).optional(),\n }),\n z.object({\n type: z.literal('fire_event'),\n eventName: z.string().min(1).max(128),\n properties: z.record(z.string(), z.unknown()).optional(),\n }),\n z.object({\n type: z.literal('webhook'),\n url: z.string().url(),\n method: z.enum(['POST', 'PUT']).optional(),\n payload: z.record(z.string(), z.unknown()).optional(),\n failureMode: z.enum(['soft', 'fail_run']).optional(),\n }),\n z.object({\n type: z.literal('exit'),\n reason: z.string().optional(),\n }),\n ]),\n)\n\nexport const predicateSchema: z.ZodType<unknown> = z.lazy(() =>\n z.union([\n z.object({ hasTag: z.string() }),\n z.object({ notHasTag: z.string() }),\n z.object({ fieldEquals: z.object({ field: z.string(), value: z.unknown() }) }),\n z.object({ fieldExists: z.string() }),\n z.object({\n hasFiredEvent: z.string(),\n sinceFlowStart: z.boolean().optional(),\n withinDays: z.number().int().positive().optional(),\n }),\n z.object({\n notHasFiredEvent: z.string(),\n withinDays: z.number().int().positive().optional(),\n }),\n z.object({\n subscriptionStatus: z.enum(['subscribed', 'unsubscribed', 'pending_doi', 'bounced', 'complained']),\n }),\n z.object({\n hasOpened: z.object({\n templateSlug: slugSchema.optional(),\n sinceFlowStart: z.boolean().optional(),\n withinDays: z.number().int().positive().optional(),\n }),\n }),\n z.object({\n hasClicked: z.object({\n templateSlug: slugSchema.optional(),\n sinceFlowStart: z.boolean().optional(),\n withinDays: z.number().int().positive().optional(),\n }),\n }),\n z.object({\n hasOpenedExcludingBots: z.object({\n templateSlug: slugSchema.optional(),\n sinceFlowStart: z.boolean().optional(),\n withinDays: z.number().int().positive().optional(),\n }),\n }),\n z.object({\n hasClickedExcludingBots: z.object({\n templateSlug: slugSchema.optional(),\n sinceFlowStart: z.boolean().optional(),\n withinDays: z.number().int().positive().optional(),\n }),\n }),\n z.object({\n openedAtLeastN: z.object({ count: z.number().int().positive(), withinDays: z.number().int().positive() }),\n }),\n z.object({\n clickedAtLeastN: z.object({ count: z.number().int().positive(), withinDays: z.number().int().positive() }),\n }),\n z.object({ all: z.array(predicateSchema) }),\n z.object({ any: z.array(predicateSchema) }),\n z.object({ not: predicateSchema }),\n ]),\n)\n","/**\n * Mailer configuration shape. Required + optional surfaces with sane defaults.\n */\n\nimport type { Db } from 'mongodb'\nimport type Handlebars from 'handlebars'\nimport type {\n ContactAdapter,\n MailProvider,\n} from '../shared/types.js'\nimport type { QueueDriverConfig } from './queues/types.js'\nimport type { SenderDomainRegistry } from './templates/sender-domain.js'\n\nexport type { SenderDomainConfig, SenderDomainRegistry } from './templates/sender-domain.js'\n\nexport interface RedisOptions {\n host?: string\n port?: number\n password?: string\n url?: string\n db?: number\n username?: string\n tls?: boolean\n}\n\nexport interface CircuitBreakerThresholds {\n /** Trip when last-hour hard-bounce rate >= this percent (e.g. 2 = 2%). */\n hardBounceRatePctTrip: number\n complaintRatePctTrip: number\n combinedBounceRatePctTrip: number\n failedToSendRatePctDegrade: number\n windowMinutes: number\n minSendsBeforeEval: number\n}\n\nexport interface MailerConfig {\n // ---- Storage --------------------------------------------------------------\n db: Db\n collectionPrefix?: string\n adapter: ContactAdapter\n\n // ---- Queue ----------------------------------------------------------------\n /**\n * Queue driver selection. One of:\n * - `{ driver: 'bull', redis: ... }` — BullMQ (default for prod; requires Redis)\n * - `{ driver: 'agenda' }` — @hokify/agenda using this Mongo (no Redis required, single-process)\n * - `{ driver: 'noop' }` — no background workers (tests, synchronous-only hosts)\n */\n queue: QueueDriverConfig\n\n // ---- Providers ------------------------------------------------------------\n providers: Record<string, MailProvider>\n defaultProvider: string\n defaultTransactionalProvider?: string\n\n // ---- Identity / URLs ------------------------------------------------------\n publicUrl: string\n unsubscribeSecret: string\n senderAddress?: string\n fromDefaults?: { name: string; email: string }\n transactionalFromDefaults?: { name: string; email: string }\n /**\n * Optional registry of sender domains by kind. When set, mailery enforces at\n * template publish time that a template's `fromEmail` domain is declared and\n * matches the template's `kind`. Used to keep marketing reputation isolated\n * from transactional reputation by sending from separate verified domains.\n *\n * Domains are case-insensitive. If unset, no enforcement happens.\n */\n senderDomains?: SenderDomainRegistry\n\n // ---- Compliance -----------------------------------------------------------\n requireDoubleOptIn?: boolean\n unsubscribeTokenLifetimeDays?: number\n transactionalRespectUnsubscribe?: boolean\n /** Slug of the transactional template sent for DOI confirmation. Defaults to 'doi-confirmation'. */\n doiTemplateSlug?: string\n /** How long the DOI token stays valid. Default 7 days. */\n doiTokenLifetimeDays?: number\n\n // ---- Circuit breaker ------------------------------------------------------\n circuitBreaker?: Partial<CircuitBreakerThresholds>\n\n // ---- Broadcast safety + throughput ---------------------------------------\n broadcastConfirmationThreshold?: number\n broadcastEnqueueBatchSize?: number\n broadcastEnqueueMaxWaiting?: number\n\n // ---- Worker behavior ------------------------------------------------------\n workerless?: boolean\n tickIntervalSeconds?: number\n sendConcurrency?: number\n sendRatePerSecond?: number\n softBouncePromotionThreshold?: number\n softBouncePromotionWindowDays?: number\n webhookRetryAttempts?: number\n sendRetryAttempts?: number\n\n // ---- Tracking -------------------------------------------------------------\n trackOpens?: boolean\n trackClicks?: boolean\n storeTrackingIp?: boolean\n storeRenderedBody?: boolean\n\n // ---- Hooks ----------------------------------------------------------------\n getAdminActor?: (req: any) => string\n onCircuitBreakerTrip?: (info: { reason: string; rates: Record<string, number> }) => Promise<void> | void\n onSendFailure?: (info: { send: any; error: Error }) => Promise<void> | void\n handlebarsHelpers?: Record<string, Handlebars.HelperDelegate>\n}\n\nexport type ResolvedConfig = Required<\n Pick<\n MailerConfig,\n | 'collectionPrefix'\n | 'requireDoubleOptIn'\n | 'unsubscribeTokenLifetimeDays'\n | 'transactionalRespectUnsubscribe'\n | 'doiTemplateSlug'\n | 'doiTokenLifetimeDays'\n | 'broadcastConfirmationThreshold'\n | 'broadcastEnqueueBatchSize'\n | 'broadcastEnqueueMaxWaiting'\n | 'workerless'\n | 'tickIntervalSeconds'\n | 'sendConcurrency'\n | 'sendRatePerSecond'\n | 'softBouncePromotionThreshold'\n | 'softBouncePromotionWindowDays'\n | 'webhookRetryAttempts'\n | 'sendRetryAttempts'\n | 'trackOpens'\n | 'trackClicks'\n | 'storeTrackingIp'\n | 'storeRenderedBody'\n >\n> & {\n circuitBreaker: CircuitBreakerThresholds\n} & MailerConfig\n\nexport const DEFAULTS = {\n collectionPrefix: 'mailer_',\n requireDoubleOptIn: false,\n unsubscribeTokenLifetimeDays: 90,\n transactionalRespectUnsubscribe: false,\n doiTemplateSlug: 'doi-confirmation',\n doiTokenLifetimeDays: 7,\n broadcastConfirmationThreshold: 1000,\n broadcastEnqueueBatchSize: 1000,\n broadcastEnqueueMaxWaiting: 5000,\n workerless: false,\n tickIntervalSeconds: 60,\n sendConcurrency: 5,\n sendRatePerSecond: 10,\n softBouncePromotionThreshold: 3,\n softBouncePromotionWindowDays: 30,\n webhookRetryAttempts: 3,\n sendRetryAttempts: 4,\n trackOpens: true,\n trackClicks: true,\n storeTrackingIp: false,\n storeRenderedBody: false,\n} as const\n\nexport const CIRCUIT_BREAKER_DEFAULTS: CircuitBreakerThresholds = {\n hardBounceRatePctTrip: 2,\n complaintRatePctTrip: 0.3,\n combinedBounceRatePctTrip: 5,\n failedToSendRatePctDegrade: 10,\n windowMinutes: 60,\n minSendsBeforeEval: 100,\n}\n\nexport function resolveConfig(c: MailerConfig): ResolvedConfig {\n return {\n ...c,\n collectionPrefix: c.collectionPrefix ?? DEFAULTS.collectionPrefix,\n requireDoubleOptIn: c.requireDoubleOptIn ?? DEFAULTS.requireDoubleOptIn,\n unsubscribeTokenLifetimeDays: c.unsubscribeTokenLifetimeDays ?? DEFAULTS.unsubscribeTokenLifetimeDays,\n transactionalRespectUnsubscribe: c.transactionalRespectUnsubscribe ?? DEFAULTS.transactionalRespectUnsubscribe,\n doiTemplateSlug: c.doiTemplateSlug ?? DEFAULTS.doiTemplateSlug,\n doiTokenLifetimeDays: c.doiTokenLifetimeDays ?? DEFAULTS.doiTokenLifetimeDays,\n broadcastConfirmationThreshold: c.broadcastConfirmationThreshold ?? DEFAULTS.broadcastConfirmationThreshold,\n broadcastEnqueueBatchSize: c.broadcastEnqueueBatchSize ?? DEFAULTS.broadcastEnqueueBatchSize,\n broadcastEnqueueMaxWaiting: c.broadcastEnqueueMaxWaiting ?? DEFAULTS.broadcastEnqueueMaxWaiting,\n workerless: c.workerless ?? DEFAULTS.workerless,\n tickIntervalSeconds: c.tickIntervalSeconds ?? DEFAULTS.tickIntervalSeconds,\n sendConcurrency: c.sendConcurrency ?? DEFAULTS.sendConcurrency,\n sendRatePerSecond: c.sendRatePerSecond ?? DEFAULTS.sendRatePerSecond,\n softBouncePromotionThreshold: c.softBouncePromotionThreshold ?? DEFAULTS.softBouncePromotionThreshold,\n softBouncePromotionWindowDays: c.softBouncePromotionWindowDays ?? DEFAULTS.softBouncePromotionWindowDays,\n webhookRetryAttempts: c.webhookRetryAttempts ?? DEFAULTS.webhookRetryAttempts,\n sendRetryAttempts: c.sendRetryAttempts ?? DEFAULTS.sendRetryAttempts,\n trackOpens: c.trackOpens ?? DEFAULTS.trackOpens,\n trackClicks: c.trackClicks ?? DEFAULTS.trackClicks,\n storeTrackingIp: c.storeTrackingIp ?? DEFAULTS.storeTrackingIp,\n storeRenderedBody: c.storeRenderedBody ?? DEFAULTS.storeRenderedBody,\n circuitBreaker: { ...CIRCUIT_BREAKER_DEFAULTS, ...(c.circuitBreaker ?? {}) },\n }\n}\n","/**\n * Mongo collection helpers + indexes for every mailer-owned collection.\n *\n * The single source of truth for `mailer_*` schemas lives in\n * `plans/02-data-model.md`. The TS interfaces here track that doc.\n *\n * const collections = getCollections(db)\n * await ensureIndexes(db)\n * await collections.events.insertOne({ ... })\n */\n\nimport type { Db, Collection, ObjectId } from 'mongodb'\n\nimport type {\n SubscriptionStatus,\n SendStatus,\n TemplateKind,\n SuppressionScope,\n SuppressionReason,\n FlowRunStatus,\n BroadcastStatus,\n HealthStatus,\n FlowGoal,\n} from '../../shared/enums.js'\nimport type { FlowStep, SegmentDefinition } from '../../shared/types.js'\n\n// ---------------------------------------------------------------------------\n// Document interfaces (per collection)\n// ---------------------------------------------------------------------------\n\nexport interface SubscriptionDoc {\n _id?: ObjectId\n externalId: string\n status: SubscriptionStatus\n subscribedAt: Date | null\n unsubscribedAt: Date | null\n unsubscribeReason: string | null\n doiTokenHash: string | null\n doiRequestedAt: Date | null\n doiConfirmedAt: Date | null\n doiIp: string | null\n doiUserAgent: string | null\n source: string\n emailAtSubscribe: string\n createdAt: Date\n updatedAt: Date\n}\n\nexport interface LeadDoc {\n _id?: ObjectId\n email: string\n source: string\n capturedFields: Record<string, unknown>\n status: 'lead' | 'promoted' | 'rejected'\n promotedToExternalId: string | null\n promotedAt: Date | null\n consentedAt: Date | null\n consentIp: string | null\n unsubscribedAt: Date | null\n createdAt: Date\n updatedAt: Date\n}\n\nexport interface EventDoc {\n _id?: ObjectId\n externalId: string\n name: string\n properties: Record<string, unknown>\n dedupeKey: string\n occurredAt: Date\n createdAt: Date\n}\n\nexport interface FlowTrigger {\n type: 'event' | 'segment_enter' | 'cron'\n eventName?: string\n segmentDefinition?: SegmentDefinition\n cronExpression?: string\n once: boolean\n}\n\nexport interface FlowDraft {\n steps: FlowStep[]\n notes: string\n lastModifiedBy: string\n lastModifiedAt: Date\n}\n\nexport interface FlowDoc {\n _id?: ObjectId\n slug: string\n name: string\n description: string\n trigger: FlowTrigger\n enabled: boolean\n steps: FlowStep[]\n version: number\n draft: FlowDraft | null\n goal: FlowGoal\n audience: string\n expectedVolumePerWeek: number | null\n stats: {\n activeRuns: number\n completedRuns: number\n sendsTotal: number\n sendsLast7Days: number\n }\n lastTriggerScanAt: Date | null\n publishedAt: Date | null\n publishedBy: string | null\n createdAt: Date\n updatedAt: Date\n}\n\nexport interface FlowVersionDoc {\n _id?: ObjectId\n flowId: ObjectId\n version: number\n steps: FlowStep[]\n trigger: FlowTrigger\n publishedAt: Date\n publishedBy: string\n}\n\nexport interface FlowRunHistoryEntry {\n stepIndex: number\n action:\n | 'entered'\n | 'wait_started'\n | 'wait_completed'\n | 'condition_evaluated'\n | 'branch_taken'\n | 'sent'\n | 'send_skipped'\n | 'tagged'\n | 'event_fired'\n | 'webhook_called'\n | 'exited'\n | 'failed'\n at: Date\n details?: Record<string, unknown>\n}\n\nexport interface FlowRunDoc {\n _id?: ObjectId\n externalId: string\n flowId: ObjectId\n flowSlug: string\n flowVersion: number\n emailAtEntry: string\n enteredAt: Date\n status: FlowRunStatus\n currentStepIndex: number\n currentBranchPath: Array<number | 'true' | 'false'>\n nextActionAt: Date\n attemptsForCurrentStep: number\n history: FlowRunHistoryEntry[]\n exitedAt: Date | null\n exitReason: string | null\n createdAt: Date\n updatedAt: Date\n}\n\nexport interface TemplateDraft {\n subject: string\n preheader: string\n /** MJML source (when template is authored as MJML). Empty string if Maily-authored. */\n mjml: string\n /** Maily editor JSON (when template is authored via the WYSIWYG editor). null otherwise. */\n editorJson: Record<string, unknown> | null\n notes: string\n lastModifiedBy: string\n lastModifiedAt: Date\n}\n\nexport interface TemplateDoc {\n _id?: ObjectId\n slug: string\n name: string\n description: string\n kind: TemplateKind\n fromName: string\n fromEmail: string\n replyTo: string | null\n providerOverride: string | null\n subject: string\n preheader: string\n body: {\n /** MJML source (set when published from MJML). */\n mjml: string\n /** Maily editor JSON (set when published from the WYSIWYG editor). null otherwise. */\n editorJson: Record<string, unknown> | null\n html: string\n plainText: string\n compiledAt: Date | null\n }\n variablesSchema: Record<\n string,\n {\n type: 'string' | 'number' | 'boolean' | 'date' | 'url'\n required: boolean\n description?: string\n defaultValue?: unknown\n }\n >\n draft: TemplateDraft | null\n tags: string[]\n trackOpens: boolean\n trackClicks: boolean\n stats: {\n sent: number\n delivered: number\n opened: number\n clicked: number\n bounced: number\n complained: number\n unsubscribed: number\n lastSentAt: Date | null\n }\n publishedAt: Date | null\n publishedBy: string | null\n createdAt: Date\n updatedAt: Date\n}\n\nexport interface TemplateVersionDoc {\n _id?: ObjectId\n templateId: ObjectId\n version: number\n mjml: string\n html: string\n plainText: string\n subject: string\n preheader: string\n publishedAt: Date\n publishedBy: string\n}\n\nexport interface SendDoc {\n _id?: ObjectId\n dedupeKey: string\n externalId: string\n emailAtSend: string\n templateId: ObjectId\n templateSlug: string\n flowRunId: ObjectId | null\n broadcastId: ObjectId | null\n manualSendBy: string | null\n kind: TemplateKind\n provider: string\n providerMessageId: string | null\n fromName: string\n fromEmail: string\n subject: string\n bodyHash: string\n status: SendStatus\n errorMessage: string | null\n bounceType: 'hard' | 'soft' | null\n bounceReason: string | null\n /** Pre-send map: every rewritten link's linkId → original URL. Lookup target on click. */\n links: Array<{ linkId: string; url: string }>\n /** Render-time vars from the flow step or one-off send. Re-applied at dispatch. */\n vars: Record<string, unknown>\n openedAt: Date | null\n openCount: number\n firstClickAt: Date | null\n clickCount: number\n /** History of actual clicks (a linkId may appear multiple times). */\n clickedLinks: Array<{ url: string; linkId: string; clickedAt: Date }>\n unsubscribedAt: Date | null\n complainedAt: Date | null\n queuedAt: Date\n /** Last time the row was mutated; used by the stranded-send sweep. */\n updatedAt: Date\n sentAt: Date | null\n deliveredAt: Date | null\n}\n\nexport interface SuppressionDoc {\n _id?: ObjectId\n email: string | null\n emailHash: string\n scope: SuppressionScope\n reason: SuppressionReason\n source: string\n notes: string | null\n addedAt: Date\n expiresAt: Date | null\n}\n\nexport interface BroadcastDoc {\n _id?: ObjectId\n slug: string\n name: string\n templateSlug: string\n segmentDefinition: SegmentDefinition\n status: BroadcastStatus\n scheduledAt: Date | null\n startedAt: Date | null\n completedAt: Date | null\n confirmationRequired: boolean\n confirmedCount: number | null\n confirmedAt: Date | null\n confirmedBy: string | null\n recipientCount: number | null\n /** When true, dispatch fires each recipient at their local-timezone equivalent of `scheduledAt`. */\n respectRecipientTimezone?: boolean\n stats: {\n sent: number\n delivered: number\n opened: number\n clicked: number\n bounced: number\n complained: number\n unsubscribed: number\n }\n createdAt: Date\n createdBy: string\n updatedAt: Date\n}\n\nexport interface OutboxDoc {\n _id?: ObjectId\n payload: {\n type: 'event' | 'upsert_subscription' | 'unsubscribe'\n data: Record<string, unknown>\n dedupeKey: string\n }\n status: 'pending' | 'processed' | 'failed' | 'duplicate'\n attempts: number\n lastAttemptAt: Date | null\n lastError: string | null\n enqueuedAt: Date\n processedAt: Date | null\n}\n\nexport interface AuditLogDoc {\n _id?: ObjectId\n actor: string\n action: string\n resource: { collection: string; id?: ObjectId | string; slug?: string }\n before: Record<string, unknown> | null\n after: Record<string, unknown> | null\n diffSummary: string | null\n ip: string | null\n userAgent: string | null\n requestId: string | null\n occurredAt: Date\n}\n\nexport interface WebhookEventDoc {\n _id?: ObjectId\n provider: string\n providerEventId: string\n eventType: string\n normalizedType: 'delivered' | 'open' | 'click' | 'bounce' | 'complaint' | 'unsubscribe' | 'spam_report'\n providerMessageId: string\n email: string\n occurredAt: Date\n receivedAt: Date\n processed: boolean\n raw: unknown\n}\n\nexport interface HealthDoc {\n _id: 'singleton'\n windowStartedAt: Date\n windowDurationMs: number\n counters: {\n sent: number\n delivered: number\n bounced: number\n hardBounced: number\n softBounced: number\n complained: number\n failedToSend: number\n }\n rates: {\n bounceRate: number\n hardBounceRate: number\n complaintRate: number\n failureRate: number\n }\n status: HealthStatus\n trippedAt: Date | null\n trippedReason: string | null\n manuallyResumedAt: Date | null\n updatedAt: Date\n}\n\nexport interface ContactTagDoc {\n _id?: ObjectId\n externalId: string\n tag: string\n appliedBy: 'flow' | 'admin' | 'script' | 'import'\n appliedAt: Date\n}\n\n// ---------------------------------------------------------------------------\n// Collection factory\n// ---------------------------------------------------------------------------\n\nexport interface Collections {\n subscriptions: Collection<SubscriptionDoc>\n leads: Collection<LeadDoc>\n events: Collection<EventDoc>\n flows: Collection<FlowDoc>\n flowVersions: Collection<FlowVersionDoc>\n flowRuns: Collection<FlowRunDoc>\n templates: Collection<TemplateDoc>\n templateVersions: Collection<TemplateVersionDoc>\n sends: Collection<SendDoc>\n suppressions: Collection<SuppressionDoc>\n broadcasts: Collection<BroadcastDoc>\n outbox: Collection<OutboxDoc>\n auditLog: Collection<AuditLogDoc>\n webhookEvents: Collection<WebhookEventDoc>\n health: Collection<HealthDoc>\n contactTags: Collection<ContactTagDoc>\n}\n\nexport function getCollections(db: Db, prefix = 'mailer_'): Collections {\n return {\n subscriptions: db.collection<SubscriptionDoc>(`${prefix}subscriptions`),\n leads: db.collection<LeadDoc>(`${prefix}leads`),\n events: db.collection<EventDoc>(`${prefix}events`),\n flows: db.collection<FlowDoc>(`${prefix}flows`),\n flowVersions: db.collection<FlowVersionDoc>(`${prefix}flow_versions`),\n flowRuns: db.collection<FlowRunDoc>(`${prefix}flow_runs`),\n templates: db.collection<TemplateDoc>(`${prefix}templates`),\n templateVersions: db.collection<TemplateVersionDoc>(`${prefix}template_versions`),\n sends: db.collection<SendDoc>(`${prefix}sends`),\n suppressions: db.collection<SuppressionDoc>(`${prefix}suppressions`),\n broadcasts: db.collection<BroadcastDoc>(`${prefix}broadcasts`),\n outbox: db.collection<OutboxDoc>(`${prefix}outbox`),\n auditLog: db.collection<AuditLogDoc>(`${prefix}audit_log`),\n webhookEvents: db.collection<WebhookEventDoc>(`${prefix}webhook_events`),\n health: db.collection<HealthDoc>(`${prefix}health`),\n contactTags: db.collection<ContactTagDoc>(`${prefix}contact_tags`),\n }\n}\n\n// ---------------------------------------------------------------------------\n// Index ensurer\n// ---------------------------------------------------------------------------\n\nexport async function ensureIndexes(db: Db, prefix = 'mailer_'): Promise<void> {\n const c = getCollections(db, prefix)\n\n await Promise.all([\n c.subscriptions.createIndexes([\n { key: { externalId: 1 }, unique: true },\n { key: { status: 1, unsubscribedAt: -1 } },\n ]),\n c.leads.createIndexes([\n { key: { email: 1 }, unique: true },\n { key: { status: 1, createdAt: -1 } },\n ]),\n c.events.createIndexes([\n { key: { dedupeKey: 1 }, unique: true },\n { key: { externalId: 1, occurredAt: -1 } },\n { key: { name: 1, occurredAt: -1 } },\n { key: { externalId: 1, name: 1 } },\n ]),\n c.flows.createIndexes([\n { key: { slug: 1 }, unique: true },\n { key: { enabled: 1, 'trigger.type': 1, 'trigger.eventName': 1 } },\n ]),\n c.flowVersions.createIndexes([{ key: { flowId: 1, version: 1 }, unique: true }]),\n c.flowRuns.createIndexes([\n { key: { status: 1, nextActionAt: 1 } },\n { key: { externalId: 1, flowId: 1 } },\n { key: { flowId: 1, status: 1 } },\n ]),\n c.templates.createIndexes([\n { key: { slug: 1 }, unique: true },\n { key: { tags: 1 } },\n { key: { kind: 1 } },\n ]),\n c.templateVersions.createIndexes([{ key: { templateId: 1, version: 1 }, unique: true }]),\n c.sends.createIndexes([\n { key: { dedupeKey: 1 }, unique: true },\n { key: { externalId: 1, sentAt: -1 } },\n { key: { templateId: 1, sentAt: -1 } },\n { key: { flowRunId: 1 }, sparse: true },\n { key: { broadcastId: 1 }, sparse: true },\n { key: { providerMessageId: 1 }, sparse: true },\n { key: { status: 1, queuedAt: 1 } },\n { key: { status: 1, updatedAt: 1 } },\n ]),\n c.suppressions.createIndexes([\n { key: { email: 1, scope: 1 }, unique: true, partialFilterExpression: { email: { $type: 'string' } } },\n { key: { emailHash: 1 } },\n { key: { addedAt: -1 } },\n ]),\n c.broadcasts.createIndexes([\n { key: { slug: 1 }, unique: true },\n { key: { status: 1, scheduledAt: 1 } },\n ]),\n c.outbox.createIndexes([\n { key: { status: 1, enqueuedAt: 1 } },\n { key: { 'payload.dedupeKey': 1 }, unique: true },\n ]),\n c.auditLog.createIndexes([\n { key: { occurredAt: -1 } },\n { key: { 'resource.collection': 1, 'resource.id': 1, occurredAt: -1 } },\n { key: { actor: 1, occurredAt: -1 } },\n ]),\n c.webhookEvents.createIndexes([\n { key: { provider: 1, providerEventId: 1 }, unique: true },\n { key: { providerMessageId: 1 } },\n { key: { processed: 1, receivedAt: 1 } },\n ]),\n c.contactTags.createIndexes([\n { key: { externalId: 1, tag: 1 }, unique: true },\n { key: { tag: 1 } },\n ]),\n ])\n}\n","/**\n * Event registry + dedupe-key policy. INVARIANT 1: every `mailer_events` row\n * has a unique dedupeKey. Callers either pass one or `mailer.registerEvent`\n * declares a policy and we derive it.\n */\n\nimport crypto from 'node:crypto'\n\nexport type DedupePolicy = 'once-per-contact' | 'once-per-day' | 'every-time'\n\nexport interface EventRegistration {\n name: string\n dedupePolicy: DedupePolicy\n}\n\nexport class EventRegistry {\n private readonly policies = new Map<string, DedupePolicy>()\n\n register(reg: EventRegistration): void {\n this.policies.set(reg.name, reg.dedupePolicy)\n }\n\n has(name: string): boolean {\n return this.policies.has(name)\n }\n\n policy(name: string): DedupePolicy | undefined {\n return this.policies.get(name)\n }\n\n /**\n * Derive a dedupeKey for an event call. Returns null when no policy is\n * registered AND no key was passed — caller should throw.\n */\n deriveKey(\n name: string,\n externalId: string,\n passedKey: string | undefined,\n now: Date,\n ): string | null {\n if (passedKey) return passedKey\n const policy = this.policies.get(name)\n if (!policy) return null\n\n switch (policy) {\n case 'once-per-contact':\n return `${externalId}:${name}`\n case 'once-per-day':\n return `${externalId}:${name}:${isoDay(now)}`\n case 'every-time':\n return `${externalId}:${name}:${randomId()}`\n }\n }\n}\n\nfunction isoDay(d: Date): string {\n return d.toISOString().slice(0, 10)\n}\n\nfunction randomId(): string {\n return crypto.randomBytes(8).toString('hex')\n}\n","/**\n * HMAC-signed tokens for unsubscribe + preference-center URLs.\n *\n * Format: base64url(payload) '.' base64url(hmac)\n * payload = JSON.stringify({ e: email, s: scope, x: expiresAtMs })\n * hmac = HMAC-SHA256(secret, payload)\n *\n * Tokens expire because long-lived signed URLs are a liability.\n */\n\nimport crypto from 'node:crypto'\nimport type { SuppressionScope } from '../shared/enums.js'\n\nexport interface UnsubscribeTokenPayload {\n email: string\n scope: SuppressionScope\n expiresAt: Date\n}\n\nexport function signUnsubscribeToken(\n payload: UnsubscribeTokenPayload,\n secret: string,\n): string {\n const body = JSON.stringify({\n e: payload.email.toLowerCase(),\n s: payload.scope,\n x: payload.expiresAt.getTime(),\n })\n const bodyB64 = b64url(Buffer.from(body, 'utf8'))\n const hmac = crypto.createHmac('sha256', secret).update(bodyB64).digest()\n return `${bodyB64}.${b64url(hmac)}`\n}\n\nexport function verifyUnsubscribeToken(\n token: string,\n secret: string,\n now: Date = new Date(),\n): UnsubscribeTokenPayload | null {\n const parts = token.split('.')\n if (parts.length !== 2) return null\n const [bodyB64, sigB64] = parts as [string, string]\n\n const expected = crypto.createHmac('sha256', secret).update(bodyB64).digest()\n let actual: Buffer\n try {\n actual = b64urlDecode(sigB64)\n } catch {\n return null\n }\n if (expected.length !== actual.length) return null\n if (!crypto.timingSafeEqual(expected, actual)) return null\n\n let body: { e?: string; s?: string; x?: number }\n try {\n body = JSON.parse(b64urlDecode(bodyB64).toString('utf8'))\n } catch {\n return null\n }\n if (!body.e || !body.s || typeof body.x !== 'number') return null\n if (body.x < now.getTime()) return null\n if (body.s !== 'all' && body.s !== 'marketing' && body.s !== 'transactional') return null\n\n return {\n email: body.e,\n scope: body.s,\n expiresAt: new Date(body.x),\n }\n}\n\nfunction b64url(buf: Buffer): string {\n return buf.toString('base64').replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\nfunction b64urlDecode(s: string): Buffer {\n const padded = s.replace(/-/g, '+').replace(/_/g, '/') + '==='.slice((s.length + 3) % 4)\n return Buffer.from(padded, 'base64')\n}\n\n/**\n * sha256 hex digest, used for storing email hashes (GDPR forget) and dedup helpers.\n */\nexport function sha256Hex(input: string): string {\n return crypto.createHash('sha256').update(input).digest('hex')\n}\n\n// ---------------------------------------------------------------------------\n// Double opt-in tokens\n// ---------------------------------------------------------------------------\n\nexport interface DoiTokenPayload {\n externalId: string\n expiresAt: Date\n}\n\n/**\n * Sign a DOI confirmation token. Same shape as the unsubscribe token, but\n * scoped to \"this externalId confirmed their subscription.\"\n */\nexport function signDoiToken(payload: DoiTokenPayload, secret: string): string {\n const body = JSON.stringify({\n i: payload.externalId,\n x: payload.expiresAt.getTime(),\n k: 'doi',\n })\n const bodyB64 = b64url(Buffer.from(body, 'utf8'))\n const hmac = crypto.createHmac('sha256', secret).update(bodyB64).digest()\n return `${bodyB64}.${b64url(hmac)}`\n}\n\nexport function verifyDoiToken(token: string, secret: string, now: Date = new Date()): DoiTokenPayload | null {\n const parts = token.split('.')\n if (parts.length !== 2) return null\n const [bodyB64, sigB64] = parts as [string, string]\n\n const expected = crypto.createHmac('sha256', secret).update(bodyB64).digest()\n let actual: Buffer\n try {\n actual = b64urlDecode(sigB64)\n } catch {\n return null\n }\n if (expected.length !== actual.length) return null\n if (!crypto.timingSafeEqual(expected, actual)) return null\n\n let body: { i?: string; x?: number; k?: string }\n try {\n body = JSON.parse(b64urlDecode(bodyB64).toString('utf8'))\n } catch {\n return null\n }\n if (!body.i || typeof body.x !== 'number' || body.k !== 'doi') return null\n if (body.x < now.getTime()) return null\n\n return { externalId: body.i, expiresAt: new Date(body.x) }\n}\n","/**\n * BullMQ driver. Four named queues backed by Redis. Job-level `attempts`,\n * `backoff`, `delay`, and `jobId` pass through to BullMQ's native semantics.\n * Send rate limit is enforced via BullMQ's `limiter` option (Redis Lua script).\n */\n\nimport type { Queue, Worker } from 'bullmq'\nimport IORedis, { type RedisOptions as IORedisOptions } from 'ioredis'\n\nimport type { RedisOptions } from '../config.js'\nimport type {\n AddOptions,\n QueueAPI,\n QueueDriver,\n Queues,\n WorkerStartOptions,\n} from './types.js'\n\ninterface BullQueues {\n tick: Queue\n advance: Queue\n send: Queue\n webhook: Queue\n}\n\ninterface BullModule {\n Queue: typeof Queue\n Worker: typeof Worker\n}\n\nconst QUEUE_NAMES = {\n tick: 'mailer-tick',\n advance: 'mailer-advance',\n send: 'mailer-send',\n webhook: 'mailer-webhook',\n} as const\n\nexport class BullDriver implements QueueDriver {\n readonly queues: Queues\n private redis: IORedis\n private bullQueues: BullQueues\n private workers: { tick: Worker; advance: Worker; send: Worker; webhook: Worker } | null = null\n private bull: BullModule\n\n static async create(redisConfig: RedisOptions | IORedis): Promise<BullDriver> {\n let bull: BullModule\n try {\n bull = (await import('bullmq')) as unknown as BullModule\n } catch {\n throw new Error(\n \"mailery: queue driver 'bull' requires the 'bullmq' peer dependency. Run `npm install bullmq ioredis`.\",\n )\n }\n const redis = isRedisLike(redisConfig) ? (redisConfig as IORedis) : connect(redisConfig as RedisOptions)\n return new BullDriver(bull, redis)\n }\n\n private constructor(bull: BullModule, redis: IORedis) {\n this.bull = bull\n this.redis = redis\n const opts = { connection: redis }\n this.bullQueues = {\n tick: new bull.Queue(QUEUE_NAMES.tick, opts),\n advance: new bull.Queue(QUEUE_NAMES.advance, opts),\n send: new bull.Queue(QUEUE_NAMES.send, opts),\n webhook: new bull.Queue(QUEUE_NAMES.webhook, opts),\n }\n this.queues = {\n tick: adaptBullQueue(this.bullQueues.tick),\n advance: adaptBullQueue(this.bullQueues.advance),\n send: adaptBullQueue(this.bullQueues.send),\n webhook: adaptBullQueue(this.bullQueues.webhook),\n }\n }\n\n async scheduleRepeatingTick(intervalSeconds: number): Promise<void> {\n await (this.bullQueues.tick as any).upsertJobScheduler(\n 'mailer-tick-repeat',\n { every: intervalSeconds * 1000 },\n { name: 'tick', data: {} },\n )\n }\n\n async startWorkers(opts: WorkerStartOptions): Promise<void> {\n if (this.workers) return\n const base = { connection: this.redis }\n const { Worker } = this.bull\n\n const tick = new Worker(\n QUEUE_NAMES.tick,\n async (job: any) => opts.handlers.tick(job.data),\n { ...base, concurrency: 1 },\n )\n const advance = new Worker(\n QUEUE_NAMES.advance,\n async (job: any) => opts.handlers.advance(job.data),\n { ...base, concurrency: 10 },\n )\n const send = new Worker(\n QUEUE_NAMES.send,\n async (job: any) => opts.handlers.send(job.data),\n {\n ...base,\n concurrency: opts.concurrency.send,\n limiter: opts.sendRateLimit\n ? { max: opts.sendRateLimit.max, duration: opts.sendRateLimit.durationMs }\n : undefined,\n },\n )\n const webhook = new Worker(\n QUEUE_NAMES.webhook,\n async (job: any) => opts.handlers.webhook(job.data),\n { ...base, concurrency: 4 },\n )\n\n this.workers = { tick, advance, send, webhook }\n }\n\n async stopWorkers(): Promise<void> {\n if (!this.workers) return\n await Promise.all([\n this.workers.tick.close(),\n this.workers.advance.close(),\n this.workers.send.close(),\n this.workers.webhook.close(),\n ])\n this.workers = null\n }\n\n async close(): Promise<void> {\n await this.stopWorkers()\n await Promise.all([\n this.bullQueues.tick.close(),\n this.bullQueues.advance.close(),\n this.bullQueues.send.close(),\n this.bullQueues.webhook.close(),\n ])\n }\n}\n\nfunction adaptBullQueue(q: Queue): QueueAPI {\n return {\n add: (name, data, opts) => q.add(name, data as any, opts as any),\n getWaitingCount: () => q.getWaitingCount(),\n close: () => q.close(),\n }\n}\n\nfunction isRedisLike(x: unknown): boolean {\n return !!x && typeof x === 'object' && typeof (x as any).get === 'function' && typeof (x as any).set === 'function'\n}\n\nfunction connect(opts: RedisOptions): IORedis {\n const config: IORedisOptions = {\n maxRetriesPerRequest: null, // BullMQ requirement\n enableReadyCheck: false,\n }\n if (opts.url) return new IORedis(opts.url, config)\n return new IORedis({\n ...config,\n host: opts.host ?? '127.0.0.1',\n port: opts.port ?? 6379,\n password: opts.password,\n db: opts.db,\n username: opts.username,\n tls: opts.tls ? {} : undefined,\n })\n}\n\n// Re-exports needed by the broader queue surface\nexport type { AddOptions }\n","/**\n * Agenda driver. Backed by the same MongoDB instance the rest of mailery uses,\n * so no Redis is required. Uses `agenda` + `@agendajs/mongo-backend`.\n *\n * Single-process only: send rate limit is enforced via an in-memory Bottleneck\n * wrapped around the send handler. Multi-process Agenda deployments would\n * fan-out beyond the rate cap — out of scope.\n *\n * Retry/backoff: applied per-definition via Agenda's built-in\n * `backoffStrategies.exponential`. Per-call `attempts` from add() is ignored;\n * the driver uses the shared config-level `sendRetryAttempts`.\n *\n * Idempotency: per-call `jobId` is stored as `data.__jobId`. Before scheduling\n * we look for a pending (not-yet-run, not-finished) job with the same key.\n */\n\nimport type { Db } from 'mongodb'\nimport type { Agenda, Job } from 'agenda'\nimport type Bottleneck from 'bottleneck'\n\nimport type {\n AddOptions,\n QueueAPI,\n QueueDriver,\n Queues,\n WorkerStartOptions,\n} from './types.js'\n\ninterface AgendaModule {\n Agenda: typeof Agenda\n backoffStrategies: { exponential: (opts: { delay: number; maxRetries: number; factor?: number }) => any }\n}\n\ninterface MongoBackendModule {\n MongoBackend: new (cfg: { mongo: Db; collection?: string; ensureIndex?: boolean }) => any\n}\n\ninterface BottleneckCtor {\n new (opts: { minTime?: number; maxConcurrent?: number }): Bottleneck\n}\n\nconst QUEUE_NAMES = {\n tick: 'mailer-tick',\n advance: 'mailer-advance',\n send: 'mailer-send',\n webhook: 'mailer-webhook',\n} as const\n\nexport interface AgendaDriverOptions {\n db: Db\n processEverySeconds?: number\n lockLifetimeSeconds?: number\n collectionName?: string\n}\n\nexport class AgendaDriver implements QueueDriver {\n readonly queues: Queues\n private agenda: Agenda\n private agendaMod: AgendaModule\n private sendLimiter: Bottleneck | null = null\n private started = false\n\n static async create(opts: AgendaDriverOptions): Promise<AgendaDriver> {\n let agendaMod: AgendaModule\n let backendMod: MongoBackendModule\n try {\n agendaMod = (await import('agenda')) as unknown as AgendaModule\n backendMod = (await import('@agendajs/mongo-backend')) as unknown as MongoBackendModule\n } catch {\n throw new Error(\n \"mailery: queue driver 'agenda' requires the 'agenda' and '@agendajs/mongo-backend' peer dependencies. Run `npm install agenda @agendajs/mongo-backend bottleneck`.\",\n )\n }\n\n const backend = new backendMod.MongoBackend({\n mongo: opts.db,\n collection: opts.collectionName ?? '_mailerJobs',\n })\n\n const agenda = new agendaMod.Agenda({\n backend,\n processEvery: `${opts.processEverySeconds ?? 5} seconds`,\n defaultLockLifetime: (opts.lockLifetimeSeconds ?? 10 * 60) * 1000,\n maxConcurrency: 50,\n defaultConcurrency: 5,\n } as any)\n\n return new AgendaDriver(agenda, agendaMod, opts.db)\n }\n\n private db: Db\n\n private constructor(agenda: Agenda, agendaMod: AgendaModule, db: Db) {\n this.agenda = agenda\n this.agendaMod = agendaMod\n this.db = db\n this.queues = {\n tick: this.makeQueueAPI(QUEUE_NAMES.tick),\n advance: this.makeQueueAPI(QUEUE_NAMES.advance),\n send: this.makeQueueAPI(QUEUE_NAMES.send),\n webhook: this.makeQueueAPI(QUEUE_NAMES.webhook),\n }\n }\n\n private makeQueueAPI(name: string): QueueAPI {\n return {\n add: async (_jobName: string, data: unknown, opts?: AddOptions) => {\n const payload: Record<string, unknown> = { ...(data as object) }\n if (opts?.jobId) {\n payload.__jobId = opts.jobId\n if (await this.findPending(name, opts.jobId)) return\n }\n const job = this.agenda.create(name, payload as any)\n if (opts?.delay) job.schedule(new Date(Date.now() + opts.delay))\n await job.save()\n },\n getWaitingCount: async () => {\n return this.jobsCollection().countDocuments({\n name,\n $or: [{ lockedAt: null }, { lockedAt: { $exists: false } }],\n nextRunAt: { $lte: new Date() },\n })\n },\n close: async () => {},\n }\n }\n\n /** Direct access to the Mongo collection Agenda persists jobs into. */\n private jobsCollection() {\n return this.db.collection(this.collectionName())\n }\n\n private collectionName(): string {\n // We set this on the backend; the field isn't exposed publicly so we keep it in sync.\n return '_mailerJobs'\n }\n\n private async findPending(name: string, jobId: string): Promise<unknown> {\n return this.jobsCollection().findOne({\n name,\n 'data.__jobId': jobId,\n $or: [{ lastFinishedAt: null }, { lastFinishedAt: { $exists: false } }],\n })\n }\n\n async scheduleRepeatingTick(intervalSeconds: number): Promise<void> {\n if (!this.started) {\n // Define tick first so Agenda knows about it before start.\n // We'll re-define it during startWorkers() with the real handler; until\n // then this is a no-op handler that the tick should never actually run.\n this.agenda.define(QUEUE_NAMES.tick, async () => {}, { concurrency: 1 })\n await this.agenda.start()\n this.started = true\n }\n await this.agenda.every(`${intervalSeconds} seconds`, QUEUE_NAMES.tick)\n }\n\n async startWorkers(opts: WorkerStartOptions): Promise<void> {\n const exp = this.agendaMod.backoffStrategies.exponential\n\n if (opts.sendRateLimit) {\n try {\n const Bottleneck = (await import('bottleneck')).default as unknown as BottleneckCtor\n this.sendLimiter = new Bottleneck({\n minTime: Math.ceil(opts.sendRateLimit.durationMs / opts.sendRateLimit.max),\n maxConcurrent: opts.concurrency.send,\n })\n } catch {\n throw new Error(\n \"mailery: queue driver 'agenda' with sendRateLimit requires the 'bottleneck' peer dependency. Run `npm install bottleneck`.\",\n )\n }\n }\n\n const retryBackoff = exp({ delay: 60_000, maxRetries: Math.max(0, opts.retryAttempts - 1), factor: 2 })\n\n this.agenda.define(QUEUE_NAMES.tick, async (job: Job) => {\n await opts.handlers.tick(job.attrs.data)\n }, { concurrency: 1 })\n\n this.agenda.define(QUEUE_NAMES.advance, async (job: Job) => {\n await opts.handlers.advance(job.attrs.data as any)\n }, { concurrency: 10, backoff: retryBackoff })\n\n this.agenda.define(QUEUE_NAMES.send, async (job: Job) => {\n const data = job.attrs.data as any\n if (this.sendLimiter) {\n await this.sendLimiter.schedule(() => opts.handlers.send(data))\n } else {\n await opts.handlers.send(data)\n }\n }, { concurrency: opts.concurrency.send, backoff: retryBackoff })\n\n this.agenda.define(QUEUE_NAMES.webhook, async (job: Job) => {\n await opts.handlers.webhook(job.attrs.data as any)\n }, { concurrency: 4, backoff: retryBackoff })\n\n if (!this.started) {\n await this.agenda.start()\n this.started = true\n }\n }\n\n async stopWorkers(): Promise<void> {\n if (!this.started) return\n await this.agenda.stop()\n this.started = false\n if (this.sendLimiter) {\n await this.sendLimiter.stop({ dropWaitingJobs: true }).catch(() => {})\n this.sendLimiter = null\n }\n }\n\n async close(): Promise<void> {\n await this.stopWorkers()\n }\n}\n","/**\n * No-op queue driver. Used by tests and by hosts that drive the runner\n * synchronously (no background workers, no Redis, no Agenda). `add()` is a\n * no-op; the caller is expected to invoke runner functions directly.\n */\n\nimport type {\n QueueAPI,\n QueueDriver,\n Queues,\n WorkerStartOptions,\n} from './types.js'\n\nfunction noopQueueAPI(): QueueAPI {\n return {\n add: async () => undefined,\n getWaitingCount: async () => 0,\n close: async () => undefined,\n }\n}\n\nexport class NoopDriver implements QueueDriver {\n readonly queues: Queues = {\n tick: noopQueueAPI(),\n advance: noopQueueAPI(),\n send: noopQueueAPI(),\n webhook: noopQueueAPI(),\n }\n\n async scheduleRepeatingTick(_intervalSeconds: number): Promise<void> {\n /* noop */\n }\n\n async startWorkers(_opts: WorkerStartOptions): Promise<void> {\n /* noop */\n }\n\n async stopWorkers(): Promise<void> {\n /* noop */\n }\n\n async close(): Promise<void> {\n /* noop */\n }\n}\n","/**\n * Queue subsystem entry point. Exports the driver interface, the three\n * built-in drivers (Bull, Agenda, Noop), and a factory that resolves a\n * `QueueDriverConfig` to a concrete driver.\n */\n\nimport type { Db } from 'mongodb'\n\nimport { BullDriver } from './bull.js'\nimport { AgendaDriver } from './agenda.js'\nimport { NoopDriver } from './noop.js'\nimport type { QueueDriver, QueueDriverConfig } from './types.js'\n\nexport { BullDriver } from './bull.js'\nexport { AgendaDriver } from './agenda.js'\nexport { NoopDriver } from './noop.js'\nexport type {\n AddOptions,\n QueueAPI,\n QueueDriver,\n QueueDriverConfig,\n QueueHandlers,\n Queues,\n WorkerStartOptions,\n} from './types.js'\n\nexport async function createQueueDriver(\n config: QueueDriverConfig,\n fallbackDb: Db,\n): Promise<QueueDriver> {\n switch (config.driver) {\n case 'bull':\n return BullDriver.create(config.redis)\n case 'agenda':\n return AgendaDriver.create({\n db: config.db ?? fallbackDb,\n processEverySeconds: config.processEverySeconds,\n lockLifetimeSeconds: config.lockLifetimeSeconds,\n collectionName: config.collectionName,\n })\n case 'noop':\n return new NoopDriver()\n default: {\n const _exhaustive: never = config\n void _exhaustive\n throw new Error(`mailery: unknown queue driver`)\n }\n }\n}\n","/**\n * Event-trigger scan. Finds new event firings since each flow's\n * lastTriggerScanAt watermark, creates flow_runs for matching contacts,\n * enqueues immediate-advance jobs.\n */\n\nimport type { RunnerContext } from './index.js'\nimport type { FlowDoc, EventDoc } from '../models/index.js'\n\nconst BATCH_SIZE = 1000\n\nexport async function processNewlyFiredEventTriggers(ctx: RunnerContext): Promise<void> {\n const flows = await ctx.collections.flows.find({ enabled: true, 'trigger.type': 'event' }).toArray()\n for (const flow of flows) {\n await processFlowTriggers(flow, ctx)\n }\n}\n\nasync function processFlowTriggers(flow: FlowDoc, ctx: RunnerContext): Promise<void> {\n const eventName = flow.trigger.eventName\n if (!eventName) return\n const since = flow.lastTriggerScanAt ?? flow.createdAt\n\n const events = await ctx.collections.events\n .find({ name: eventName, occurredAt: { $gt: since } })\n .sort({ occurredAt: 1 })\n .limit(BATCH_SIZE)\n .toArray()\n\n if (events.length === 0) return\n\n for (const event of events) {\n await tryEnterFlow(flow, event, ctx)\n }\n\n const newestOccurredAt = events[events.length - 1]!.occurredAt\n await ctx.collections.flows.updateOne(\n { _id: flow._id },\n { $set: { lastTriggerScanAt: newestOccurredAt, updatedAt: new Date() } },\n )\n}\n\nasync function tryEnterFlow(flow: FlowDoc, event: EventDoc, ctx: RunnerContext): Promise<void> {\n if (flow.trigger.once) {\n const existing = await ctx.collections.flowRuns.findOne(\n { externalId: event.externalId, flowId: flow._id },\n { projection: { _id: 1 } },\n )\n if (existing) return\n }\n\n const sub = await ctx.collections.subscriptions.findOne({ externalId: event.externalId })\n if (!sub || sub.status !== 'subscribed') return\n\n const result = await ctx.collections.flowRuns.insertOne({\n externalId: event.externalId,\n flowId: flow._id!,\n flowSlug: flow.slug,\n flowVersion: flow.version,\n emailAtEntry: sub.emailAtSubscribe,\n enteredAt: new Date(),\n status: 'active',\n currentStepIndex: 0,\n currentBranchPath: [],\n nextActionAt: new Date(),\n attemptsForCurrentStep: 0,\n history: [{ stepIndex: -1, action: 'entered', at: new Date(), details: { eventDedupeKey: event.dedupeKey } }],\n exitedAt: null,\n exitReason: null,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n\n await ctx.queues.advance.add('advance', { flowRunId: String(result.insertedId) })\n}\n","/**\n * Predicate evaluator. Resolves all Predicate variants from `shared/types.ts`\n * against a Contact (host-side fields/tags) + mailer state (events, sends,\n * subscription).\n *\n * Network calls hit Mongo. Cache the Contact at the call site if you evaluate\n * many predicates in a row.\n */\n\nimport type { Contact, Predicate } from '../../shared/types.js'\nimport type { Collections, FlowRunDoc, SendDoc } from '../models/index.js'\n\nexport interface PredicateContext {\n contact: Contact\n run: FlowRunDoc\n collections: Collections\n now?: Date\n}\n\nconst BOT_UA_RE = /Mimecast|SafeLinks|proofpoint|HeadlessChrome|Googlebot|bingbot/i\n\nexport async function evaluatePredicate(\n predicate: Predicate,\n ctx: PredicateContext,\n): Promise<boolean> {\n const p = predicate as any\n\n if ('hasTag' in p) return ctx.contact.tags.includes(p.hasTag)\n if ('notHasTag' in p) return !ctx.contact.tags.includes(p.notHasTag)\n\n if ('fieldEquals' in p) {\n return ctx.contact.fields[p.fieldEquals.field] === p.fieldEquals.value\n }\n if ('fieldExists' in p) {\n return ctx.contact.fields[p.fieldExists] !== undefined\n }\n\n if ('subscriptionStatus' in p) {\n const sub = await ctx.collections.subscriptions.findOne({ externalId: ctx.contact.externalId })\n return sub?.status === p.subscriptionStatus\n }\n\n if ('hasFiredEvent' in p) {\n return hasEvent(ctx, p.hasFiredEvent, { sinceFlowStart: p.sinceFlowStart, withinDays: p.withinDays })\n }\n if ('notHasFiredEvent' in p) {\n return !(await hasEvent(ctx, p.notHasFiredEvent, { withinDays: p.withinDays }))\n }\n\n if ('hasOpened' in p) return await openOrClickCount(ctx, 'opened', p.hasOpened, false) > 0\n if ('hasClicked' in p) return await openOrClickCount(ctx, 'clicked', p.hasClicked, false) > 0\n if ('hasOpenedExcludingBots' in p) return await openOrClickCount(ctx, 'opened', p.hasOpenedExcludingBots, true) > 0\n if ('hasClickedExcludingBots' in p) return await openOrClickCount(ctx, 'clicked', p.hasClickedExcludingBots, true) > 0\n if ('openedAtLeastN' in p) return await openOrClickCount(ctx, 'opened', p.openedAtLeastN, true) >= p.openedAtLeastN.count\n if ('clickedAtLeastN' in p) return await openOrClickCount(ctx, 'clicked', p.clickedAtLeastN, true) >= p.clickedAtLeastN.count\n\n if ('all' in p) {\n for (const sub of p.all) {\n if (!(await evaluatePredicate(sub, ctx))) return false\n }\n return true\n }\n if ('any' in p) {\n for (const sub of p.any) {\n if (await evaluatePredicate(sub, ctx)) return true\n }\n return false\n }\n if ('not' in p) {\n return !(await evaluatePredicate(p.not, ctx))\n }\n\n return false\n}\n\nasync function hasEvent(\n ctx: PredicateContext,\n name: string,\n opts: { sinceFlowStart?: boolean; withinDays?: number },\n): Promise<boolean> {\n const filter: any = { externalId: ctx.contact.externalId, name }\n const lower = effectiveLowerBound(ctx, opts)\n if (lower) filter.occurredAt = { $gt: lower }\n const found = await ctx.collections.events.findOne(filter, { projection: { _id: 1 } })\n return !!found\n}\n\nasync function openOrClickCount(\n ctx: PredicateContext,\n kind: 'opened' | 'clicked',\n opts: { templateSlug?: string; sinceFlowStart?: boolean; withinDays?: number },\n excludeBots: boolean,\n): Promise<number> {\n const filter: any = { externalId: ctx.contact.externalId }\n if (opts.templateSlug) filter.templateSlug = opts.templateSlug\n if (kind === 'opened') filter.openedAt = { $ne: null }\n if (kind === 'clicked') filter.firstClickAt = { $ne: null }\n const lower = effectiveLowerBound(ctx, opts)\n if (lower) filter[kind === 'opened' ? 'openedAt' : 'firstClickAt'] = { $gt: lower }\n\n if (!excludeBots) {\n return await ctx.collections.sends.countDocuments(filter)\n }\n\n // Bot filter is best-effort: we only know UA for clicks (open pixel hits don't reliably carry one)\n const docs = await ctx.collections.sends.find(filter).limit(1000).toArray()\n let n = 0\n for (const s of docs) {\n if (kind === 'opened') {\n n++\n continue\n }\n const hasHumanClick = (s as SendDoc).clickedLinks?.some((c: any) => !c.userAgent || !BOT_UA_RE.test(c.userAgent))\n if (hasHumanClick) n++\n }\n return n\n}\n\nfunction effectiveLowerBound(ctx: PredicateContext, opts: { sinceFlowStart?: boolean; withinDays?: number }): Date | null {\n const now = ctx.now ?? new Date()\n if (opts.sinceFlowStart) return ctx.run.enteredAt\n if (opts.withinDays && opts.withinDays > 0) {\n return new Date(now.getTime() - opts.withinDays * 24 * 60 * 60 * 1000)\n }\n return null\n}\n","/**\n * Template render pipeline.\n *\n * authorMjml + handlebarsContext\n * ↓ Handlebars render → MJML with substituted vars\n * ↓ mjml-core compile → HTML\n * ↓ html-to-text derive → plain text alternative\n * ↓ applyTracking(sendId) → tracked HTML with rewritten links + open pixel\n *\n * Subject and preheader run through Handlebars too. Plain text is auto-derived\n * unless the template explicitly overrides it.\n */\n\nimport crypto from 'node:crypto'\nimport Handlebars from 'handlebars'\nimport { convert as htmlToText } from 'html-to-text'\nimport mjml2html from 'mjml'\n\nimport type { Contact } from '../../shared/types.js'\nimport type { TemplateDoc } from '../models/index.js'\n\n// ---------------------------------------------------------------------------\n// Compile (publish-time)\n// ---------------------------------------------------------------------------\n\nexport interface CompileResult {\n html: string\n plainText: string\n errors: Array<{ line?: number; message: string; tagName?: string; formattedMessage?: string }>\n}\n\n/** Compile MJML → HTML, then derive plain text. Called at template publish time. */\nexport async function compileTemplate(mjml: string): Promise<CompileResult> {\n const out = await mjml2html(mjml, { validationLevel: 'soft', minify: false })\n const plainText = derivePlaintext(out.html)\n return { html: out.html, plainText, errors: out.errors ?? [] }\n}\n\n/**\n * Compile Maily editor JSON (Tiptap-shape) → HTML via `@maily-to/render`, then\n * derive plain text. Called at template publish time when the template was\n * authored via the WYSIWYG editor.\n */\nexport async function compileMailyTemplate(content: unknown): Promise<CompileResult> {\n const { render } = await import('@maily-to/render')\n const html = await render(content as any)\n const plainText = derivePlaintext(html)\n return { html, plainText, errors: [] }\n}\n\n/** Auto-derive plain text from compiled HTML. */\nexport function derivePlaintext(html: string): string {\n return htmlToText(html, {\n wordwrap: 80,\n selectors: [\n { selector: 'img', format: 'skip' },\n { selector: 'a', options: { hideLinkHrefIfSameAsText: true } },\n ],\n }).trim()\n}\n\n// ---------------------------------------------------------------------------\n// Render (send-time)\n// ---------------------------------------------------------------------------\n\nexport interface RenderContext {\n contact: Contact\n vars: Record<string, unknown>\n /** URL the recipient hits to one-click unsubscribe. */\n unsubscribeUrl: string\n /** URL to view this email in a browser (when implemented). */\n viewInBrowserUrl?: string\n /** URL for the preference center (when implemented). */\n preferenceCenterUrl?: string\n /** Configured sender postal address (CAN-SPAM). */\n senderAddress?: string\n}\n\nexport interface RenderedTemplate {\n subject: string\n preheader: string\n html: string\n plainText: string\n fromName: string\n fromEmail: string\n replyTo: string | null\n}\n\nexport interface RenderOptions {\n /** Extra Handlebars helpers contributed by the host. */\n helpers?: Record<string, Handlebars.HelperDelegate>\n}\n\n/**\n * Render a published template against a contact + vars context. Returns the\n * substituted subject/preheader/html/plainText. Tracking is NOT applied here —\n * that step needs the send id and runs separately via `applyTracking`.\n */\nexport async function renderTemplate(\n template: TemplateDoc,\n ctx: RenderContext,\n opts: RenderOptions = {},\n): Promise<RenderedTemplate> {\n const hb = makeHandlebars(opts.helpers)\n\n const subject = hb.compile(template.subject)(ctx)\n const preheader = hb.compile(template.preheader)(ctx)\n\n // Prefer the compiled HTML if present; fall back to compiling MJML on the fly.\n let html: string\n if (template.body.html) {\n html = hb.compile(template.body.html)(ctx)\n } else {\n const compiled = await compileTemplate(template.body.mjml)\n html = hb.compile(compiled.html)(ctx)\n }\n\n const plainText = template.body.plainText\n ? hb.compile(template.body.plainText)(ctx)\n : derivePlaintext(html)\n\n return {\n subject,\n preheader,\n html,\n plainText,\n fromName: template.fromName,\n fromEmail: template.fromEmail,\n replyTo: template.replyTo,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Tracking application\n// ---------------------------------------------------------------------------\n\nexport interface TrackingOptions {\n sendId: string\n publicUrl: string\n trackOpens: boolean\n trackClicks: boolean\n /** URL that must NOT be rewritten (e.g. the resolved unsubscribe URL). */\n preserveUrls?: string[]\n}\n\nexport interface TrackingResult {\n html: string\n /** linkId → original URL map; persist on `mailer_sends.links` for click resolution. */\n links: Array<{ linkId: string; url: string }>\n}\n\n/**\n * Rewrite `<a href>` in `html` to /m/click/<sendId>/<linkId>?... and append an\n * open pixel. Returns the modified HTML plus the link map to persist on the\n * send document.\n */\nexport function applyTracking(html: string, opts: TrackingOptions): TrackingResult {\n const preserve = new Set((opts.preserveUrls ?? []).map((u) => u.trim()))\n const links: Array<{ linkId: string; url: string }> = []\n const seen = new Map<string, string>() // url → linkId\n\n let out = html\n\n if (opts.trackClicks) {\n out = out.replace(/<a\\b([^>]*?)\\bhref=([\"'])([^\"']+)\\2([^>]*)>/gi, (full, pre, _q, url, post) => {\n if (shouldSkipClickRewrite(url, preserve, full)) return full\n let linkId = seen.get(url)\n if (!linkId) {\n linkId = shortHash(`${opts.sendId}:${url}:${links.length}`)\n seen.set(url, linkId)\n links.push({ linkId, url })\n }\n const newHref = `${opts.publicUrl}/m/click/${opts.sendId}/${linkId}`\n return `<a${pre}href=\"${newHref}\"${post}>`\n })\n }\n\n if (opts.trackOpens) {\n const pixel = `<img src=\"${opts.publicUrl}/m/open/${opts.sendId}.png\" width=\"1\" height=\"1\" alt=\"\" style=\"display:block;border:0\" />`\n if (/<\\/body>/i.test(out)) {\n out = out.replace(/<\\/body>/i, `${pixel}</body>`)\n } else {\n out = out + pixel\n }\n }\n\n return { html: out, links }\n}\n\nfunction shouldSkipClickRewrite(url: string, preserve: Set<string>, fullTag: string): boolean {\n if (!url) return true\n if (url.startsWith('mailto:')) return true\n if (url.startsWith('tel:')) return true\n if (url.startsWith('#')) return true\n if (url.startsWith('{{') || url.startsWith('{')) return true // unrendered handlebars\n if (preserve.has(url.trim())) return true\n if (/data-mailer-notrack=[\"']true[\"']/.test(fullTag)) return true\n return false\n}\n\nfunction shortHash(input: string): string {\n return crypto.createHash('sha256').update(input).digest('hex').slice(0, 12)\n}\n\n// ---------------------------------------------------------------------------\n// Handlebars instance + helpers\n// ---------------------------------------------------------------------------\n\nfunction makeHandlebars(extra?: Record<string, Handlebars.HelperDelegate>): typeof Handlebars {\n const hb = Handlebars.create()\n\n hb.registerHelper('eq', (a: unknown, b: unknown) => a === b)\n hb.registerHelper('ne', (a: unknown, b: unknown) => a !== b)\n hb.registerHelper('gt', (a: any, b: any) => a > b)\n hb.registerHelper('lt', (a: any, b: any) => a < b)\n hb.registerHelper('gte', (a: any, b: any) => a >= b)\n hb.registerHelper('lte', (a: any, b: any) => a <= b)\n hb.registerHelper('and', (...args: any[]) => args.slice(0, -1).every(Boolean))\n hb.registerHelper('or', (...args: any[]) => args.slice(0, -1).some(Boolean))\n hb.registerHelper('not', (a: unknown) => !a)\n\n hb.registerHelper('formatDate', (value: unknown, fmt?: string) => {\n if (!value) return ''\n const d = value instanceof Date ? value : new Date(String(value))\n if (Number.isNaN(d.getTime())) return ''\n if (fmt === 'long') return d.toLocaleDateString('en-US', { dateStyle: 'long' })\n if (fmt === 'short') return d.toLocaleDateString('en-US', { dateStyle: 'short' })\n return d.toISOString().slice(0, 10)\n })\n\n hb.registerHelper('formatNumber', (n: unknown) => {\n const v = Number(n)\n return Number.isFinite(v) ? v.toLocaleString('en-US') : ''\n })\n\n hb.registerHelper('formatCurrency', (cents: unknown, currency: string = 'usd') => {\n const v = Number(cents)\n if (!Number.isFinite(v)) return ''\n return new Intl.NumberFormat('en-US', { style: 'currency', currency }).format(v / 100)\n })\n\n hb.registerHelper('pluralize', (n: unknown, one: string, many: string) =>\n Number(n) === 1 ? one : many,\n )\n\n if (extra) {\n for (const [name, fn] of Object.entries(extra)) {\n hb.registerHelper(name, fn)\n }\n }\n\n return hb\n}\n\nexport { makeHandlebars }\n","/**\n * Suppression checks. INVARIANT 3: re-checked at send time, never trusted\n * from enqueue time. INVARIANT 9: hashed-suppression records (GDPR forget)\n * block sends without retaining the plaintext email.\n */\n\nimport type { Collections } from '../models/index.js'\nimport type { SuppressionScope, TemplateKind } from '../../shared/enums.js'\nimport { sha256Hex } from '../tokens.js'\n\nexport interface SuppressionResult {\n suppressed: boolean\n scope?: string\n reason?: string\n}\n\nconst SCOPES_BY_KIND: Record<TemplateKind, SuppressionScope[]> = {\n marketing: ['all', 'marketing'],\n transactional: ['all', 'transactional'],\n}\n\nexport async function isSuppressed(\n collections: Collections,\n email: string,\n kind: TemplateKind,\n): Promise<SuppressionResult> {\n const normalized = email.toLowerCase()\n const allowed = SCOPES_BY_KIND[kind]\n\n const byEmail = await collections.suppressions.findOne({\n email: normalized,\n scope: { $in: allowed },\n $or: [{ expiresAt: null }, { expiresAt: { $gt: new Date() } }],\n })\n if (byEmail) return { suppressed: true, scope: byEmail.scope, reason: byEmail.reason }\n\n const hashed = await collections.suppressions.findOne({\n emailHash: sha256Hex(normalized),\n scope: { $in: allowed },\n })\n if (hashed) return { suppressed: true, scope: hashed.scope, reason: hashed.reason }\n\n return { suppressed: false }\n}\n","/**\n * Circuit breaker. Tracks rolling counters in mailer_health, computes rates\n * on each tick, trips the breaker when thresholds are exceeded.\n *\n * status: 'healthy' — normal\n * 'degraded' — non-blocking warnings (e.g. high failed-to-send rate)\n * 'tripped' — marketing sends held; transactional bypasses (INVARIANT 6)\n *\n * Recovery is manual (admin UI: POST /api/health/resume).\n */\n\nimport type { HealthDoc } from '../models/index.js'\nimport type { RunnerContext } from './index.js'\n\ntype CounterKey =\n | 'sent'\n | 'delivered'\n | 'bounced'\n | 'hardBounced'\n | 'softBounced'\n | 'complained'\n | 'failedToSend'\n\n/**\n * Bump a counter on the singleton health doc. Called from the send / webhook\n * paths. Idempotent at the document level (upsert).\n */\nexport async function recordHealthCounter(ctx: RunnerContext, counter: CounterKey, by = 1): Promise<void> {\n await ctx.collections.health.updateOne(\n { _id: 'singleton' },\n {\n $inc: { [`counters.${counter}`]: by },\n $setOnInsert: {\n _id: 'singleton',\n windowStartedAt: new Date(),\n windowDurationMs: ctx.config.circuitBreaker.windowMinutes * 60 * 1000,\n status: 'healthy',\n trippedAt: null,\n trippedReason: null,\n manuallyResumedAt: null,\n rates: { bounceRate: 0, hardBounceRate: 0, complaintRate: 0, failureRate: 0 },\n } as Partial<HealthDoc>,\n $set: { updatedAt: new Date() },\n },\n { upsert: true },\n )\n}\n\n/**\n * Recompute rates from the rolling window and trip the breaker if thresholds\n * are exceeded. Called from the tick.\n */\nexport async function evaluateHealth(ctx: RunnerContext): Promise<void> {\n const cb = ctx.config.circuitBreaker\n const windowMs = cb.windowMinutes * 60 * 1000\n\n // Reset the window if we've rolled past it. Simple \"window of length N\" —\n // when the window expires, we reset counters to 0 and start fresh. This\n // matches the conservative behavior described in the spec.\n const doc = await ctx.collections.health.findOne({ _id: 'singleton' })\n if (!doc) return\n\n const windowAge = Date.now() - new Date(doc.windowStartedAt).getTime()\n if (windowAge > windowMs && doc.status !== 'tripped') {\n // Roll the window.\n await ctx.collections.health.updateOne(\n { _id: 'singleton' },\n {\n $set: {\n windowStartedAt: new Date(),\n windowDurationMs: windowMs,\n counters: { sent: 0, delivered: 0, bounced: 0, hardBounced: 0, softBounced: 0, complained: 0, failedToSend: 0 },\n rates: { bounceRate: 0, hardBounceRate: 0, complaintRate: 0, failureRate: 0 },\n updatedAt: new Date(),\n },\n },\n )\n return\n }\n\n const c = doc.counters\n const total = c.sent || 1 // avoid div-by-zero; rates against `sent` total\n const rates = {\n bounceRate: c.bounced / total,\n hardBounceRate: c.hardBounced / total,\n complaintRate: c.complained / total,\n failureRate: c.failedToSend / total,\n }\n\n await ctx.collections.health.updateOne(\n { _id: 'singleton' },\n { $set: { rates, updatedAt: new Date() } },\n )\n\n // Don't evaluate trips on tiny sample sizes.\n if (c.sent < cb.minSendsBeforeEval) return\n if (doc.status === 'tripped') return // already tripped; wait for manual resume\n\n // Trip rules — first matching rule wins.\n let trippedReason: string | null = null\n if (rates.hardBounceRate * 100 >= cb.hardBounceRatePctTrip) {\n trippedReason = `hard bounce rate ${(rates.hardBounceRate * 100).toFixed(2)}% >= ${cb.hardBounceRatePctTrip}%`\n } else if (rates.complaintRate * 100 >= cb.complaintRatePctTrip) {\n trippedReason = `complaint rate ${(rates.complaintRate * 100).toFixed(2)}% >= ${cb.complaintRatePctTrip}%`\n } else if (rates.bounceRate * 100 >= cb.combinedBounceRatePctTrip) {\n trippedReason = `combined bounce rate ${(rates.bounceRate * 100).toFixed(2)}% >= ${cb.combinedBounceRatePctTrip}%`\n }\n\n if (trippedReason) {\n await ctx.collections.health.updateOne(\n { _id: 'singleton' },\n { $set: { status: 'tripped', trippedAt: new Date(), trippedReason, updatedAt: new Date() } },\n )\n if (ctx.config.onCircuitBreakerTrip) {\n try {\n await ctx.config.onCircuitBreakerTrip({ reason: trippedReason, rates })\n } catch {\n /* swallow — alert hook failures don't propagate */\n }\n }\n return\n }\n\n // Degraded?\n if (rates.failureRate * 100 >= cb.failedToSendRatePctDegrade) {\n if (doc.status !== 'degraded') {\n await ctx.collections.health.updateOne(\n { _id: 'singleton' },\n { $set: { status: 'degraded', updatedAt: new Date() } },\n )\n }\n } else if (doc.status === 'degraded') {\n await ctx.collections.health.updateOne(\n { _id: 'singleton' },\n { $set: { status: 'healthy', updatedAt: new Date() } },\n )\n }\n}\n","/**\n * Send pipeline. `handleSend` is called by the runner state machine; it creates\n * the Send document and enqueues a mailer:send job. `dispatchSend` is the\n * worker — re-checks suppression + circuit breaker, applies tracking, calls\n * the provider, updates the Send row.\n */\n\nimport crypto from 'node:crypto'\nimport { ObjectId } from 'mongodb'\n\nimport type { Contact, FlowStep } from '../../shared/types.js'\nimport type { FlowRunDoc, FlowDoc, SendDoc, TemplateDoc } from '../models/index.js'\nimport {\n applyTracking,\n renderTemplate,\n type RenderContext,\n} from '../templates/render.js'\nimport { signUnsubscribeToken } from '../tokens.js'\nimport { isSuppressed } from './suppression.js'\nimport { advanceStep, failFlowRun } from './step.js'\nimport { recordHealthCounter } from './health.js'\nimport type { RunnerContext } from './index.js'\n\nexport async function handleSend(\n run: FlowRunDoc,\n step: Extract<FlowStep, { type: 'send' }>,\n contact: Contact,\n flow: FlowDoc,\n ctx: RunnerContext,\n): Promise<void> {\n const template = await ctx.collections.templates.findOne({ slug: step.templateSlug })\n if (!template) {\n await failFlowRun(run, `template not found: ${step.templateSlug}`, ctx)\n return\n }\n\n const dedupeKey = `flowrun:${run._id}:step${run.currentStepIndex}`\n\n // Idempotency: has this exact step already produced a send?\n const existing = await ctx.collections.sends.findOne({ dedupeKey })\n if (existing) {\n await advanceStep(run, ctx, {\n action: 'sent',\n details: { dedupeKey, alreadySent: true, sendId: String(existing._id) },\n })\n return\n }\n\n const providerName = pickProviderName(step.providerOverride, template, ctx)\n\n // Render now (with fresh contact + vars). Tracking application happens in\n // dispatchSend once we have the persisted sendId.\n const renderCtx = buildRenderContext(contact, run, step.vars ?? {}, ctx)\n let rendered\n try {\n rendered = await renderTemplate(template, renderCtx, { helpers: ctx.handlebarsHelpers })\n } catch (err: any) {\n await ctx.collections.sends.insertOne(\n newSendDoc({\n dedupeKey,\n run,\n contact,\n template,\n flow,\n providerName,\n renderedSubject: template.subject,\n bodyHash: '',\n status: 'failed',\n errorMessage: `render error: ${err?.message ?? err}`,\n }),\n )\n await advanceStep(run, ctx, {\n action: 'send_skipped',\n details: { reason: 'render_error', message: String(err?.message ?? err) },\n })\n return\n }\n\n const sendId = new ObjectId()\n await ctx.collections.sends.insertOne(\n newSendDoc({\n _id: sendId,\n dedupeKey,\n run,\n contact,\n template,\n flow,\n providerName,\n renderedSubject: rendered.subject,\n bodyHash: sha256(rendered.html),\n status: 'queued',\n renderedFrom: rendered.fromName ? { name: rendered.fromName, email: rendered.fromEmail } : undefined,\n vars: step.vars ?? {},\n }),\n )\n\n await ctx.queues.send.add(\n 'send',\n { sendId: String(sendId) },\n { attempts: ctx.config.sendRetryAttempts, backoff: { type: 'exponential', delay: 60_000 } },\n )\n\n await advanceStep(run, ctx, { action: 'sent', details: { dedupeKey, sendId: String(sendId) } })\n}\n\n// ---------------------------------------------------------------------------\n// Send worker entry point\n// ---------------------------------------------------------------------------\n\nexport async function dispatchSend(sendId: ObjectId, ctx: RunnerContext): Promise<void> {\n const send = await ctx.collections.sends.findOne({ _id: sendId })\n if (!send) return\n if (send.status !== 'queued' && send.status !== 'failed') return // already dispatched / cancelled\n\n const template = await ctx.collections.templates.findOne({ _id: send.templateId })\n if (!template) {\n await markFailed(send._id!, 'template_missing', ctx)\n return\n }\n\n // 1. Suppression check (INVARIANT 3: always re-checked at send time).\n const supp = await isSuppressed(ctx.collections, send.emailAtSend, send.kind)\n if (supp.suppressed) {\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n { $set: { status: 'suppressed', errorMessage: `suppressed: ${supp.reason}` } },\n )\n return\n }\n\n // 2. Circuit-breaker check (only blocks marketing).\n if (send.kind === 'marketing') {\n const health = await ctx.collections.health.findOne({ _id: 'singleton' })\n if (health?.status === 'tripped') {\n // Re-enqueue with a delay; held until resume.\n await ctx.queues.send.add('send', { sendId: String(send._id) }, { delay: 60_000 })\n return\n }\n }\n\n // 3. Pull the contact + re-render (use the contact that exists now, not at flow entry).\n const contact = await ctx.adapter.getById(send.externalId)\n if (!contact) {\n await markFailed(send._id!, 'contact_missing', ctx)\n return\n }\n\n const run = send.flowRunId ? await ctx.collections.flowRuns.findOne({ _id: send.flowRunId }) : null\n const renderCtx = buildRenderContext(\n contact,\n run,\n send.vars ?? {},\n ctx,\n )\n const rendered = await renderTemplate(template, renderCtx, { helpers: ctx.handlebarsHelpers })\n\n // 4. Apply tracking using the now-known send id.\n const tracking = applyTracking(rendered.html, {\n sendId: String(send._id),\n publicUrl: ctx.config.publicUrl,\n trackOpens: template.trackOpens ?? ctx.config.trackOpens,\n trackClicks: template.trackClicks ?? ctx.config.trackClicks,\n preserveUrls: [renderCtx.unsubscribeUrl],\n })\n\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n {\n $set: {\n links: tracking.links,\n bodyHash: sha256(tracking.html),\n status: 'sending',\n fromName: rendered.fromName,\n fromEmail: rendered.fromEmail,\n subject: rendered.subject,\n updatedAt: new Date(),\n },\n },\n )\n\n // 5. Provider dispatch.\n const provider = ctx.providers[send.provider] ?? ctx.providers[ctx.config.defaultProvider]\n if (!provider) {\n await markFailed(send._id!, `provider_unknown: ${send.provider}`, ctx)\n return\n }\n\n try {\n const result = await provider.send({\n to: send.emailAtSend,\n fromName: rendered.fromName,\n fromEmail: rendered.fromEmail,\n replyTo: rendered.replyTo ?? undefined,\n subject: rendered.subject,\n html: tracking.html,\n text: rendered.plainText,\n headers: {\n 'List-Unsubscribe': `<${renderCtx.unsubscribeUrl}>`,\n 'List-Unsubscribe-Post': 'List-Unsubscribe=One-Click',\n },\n messageMeta: { sendId: String(send._id) },\n })\n\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n {\n $set: {\n status: 'sent',\n sentAt: new Date(),\n providerMessageId: result.providerId,\n },\n },\n )\n await recordHealthCounter(ctx, 'sent')\n } catch (err: any) {\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n { $set: { status: 'failed', errorMessage: String(err?.message ?? err) } },\n )\n await recordHealthCounter(ctx, 'failedToSend')\n if (ctx.config.onSendFailure) {\n try {\n await ctx.config.onSendFailure({ send, error: err })\n } catch {\n /* swallow */\n }\n }\n throw err // let BullMQ retry per the attempts policy\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction pickProviderName(stepOverride: string | undefined, tpl: TemplateDoc, ctx: RunnerContext): string {\n if (stepOverride) return stepOverride\n if (tpl.providerOverride) return tpl.providerOverride\n if (tpl.kind === 'transactional' && ctx.config.defaultTransactionalProvider) {\n return ctx.config.defaultTransactionalProvider\n }\n return ctx.config.defaultProvider\n}\n\nfunction buildRenderContext(\n contact: Contact,\n run: FlowRunDoc | null,\n vars: Record<string, unknown>,\n ctx: RunnerContext,\n): RenderContext {\n const scope = 'marketing'\n const expiresAt = new Date(Date.now() + ctx.config.unsubscribeTokenLifetimeDays * 24 * 60 * 60 * 1000)\n const token = signUnsubscribeToken(\n { email: contact.email, scope, expiresAt },\n ctx.config.unsubscribeSecret,\n )\n const unsubscribeUrl = `${ctx.config.publicUrl}/m/unsub/${token}`\n\n void run\n return {\n contact,\n vars,\n unsubscribeUrl,\n senderAddress: ctx.config.senderAddress,\n }\n}\n\ninterface NewSendInput {\n _id?: ObjectId\n dedupeKey: string\n run: FlowRunDoc\n contact: Contact\n template: TemplateDoc\n flow: FlowDoc\n providerName: string\n renderedSubject: string\n bodyHash: string\n status: SendDoc['status']\n errorMessage?: string\n renderedFrom?: { name: string; email: string }\n vars?: Record<string, unknown>\n}\n\nfunction newSendDoc(input: NewSendInput): SendDoc {\n const now = new Date()\n return {\n _id: input._id,\n dedupeKey: input.dedupeKey,\n externalId: input.run.externalId,\n emailAtSend: input.contact.email,\n templateId: input.template._id!,\n templateSlug: input.template.slug,\n flowRunId: input.run._id!,\n broadcastId: null,\n manualSendBy: null,\n kind: input.template.kind,\n provider: input.providerName,\n providerMessageId: null,\n fromName: input.renderedFrom?.name ?? input.template.fromName,\n fromEmail: input.renderedFrom?.email ?? input.template.fromEmail,\n subject: input.renderedSubject,\n bodyHash: input.bodyHash,\n status: input.status,\n errorMessage: input.errorMessage ?? null,\n bounceType: null,\n bounceReason: null,\n links: [],\n vars: input.vars ?? {},\n openedAt: null,\n openCount: 0,\n firstClickAt: null,\n clickCount: 0,\n clickedLinks: [],\n unsubscribedAt: null,\n complainedAt: null,\n queuedAt: now,\n updatedAt: now,\n sentAt: null,\n deliveredAt: null,\n }\n}\n\nasync function markFailed(sendId: ObjectId, reason: string, ctx: RunnerContext): Promise<void> {\n await ctx.collections.sends.updateOne(\n { _id: sendId },\n { $set: { status: 'failed', errorMessage: reason } },\n )\n}\n\nfunction sha256(s: string): string {\n return crypto.createHash('sha256').update(s).digest('hex')\n}\n","/**\n * Flow_run state machine. One step transition per `processOneRunStep` call.\n * Idempotent — optimistic concurrency on `currentStepIndex` means two workers\n * racing on the same run advance exactly once.\n */\n\nimport type { ObjectId } from 'mongodb'\n\nimport type { FlowStep } from '../../shared/types.js'\nimport type { FlowRunDoc, FlowDoc } from '../models/index.js'\nimport { evaluatePredicate } from './predicate.js'\nimport type { RunnerContext } from './index.js'\nimport { handleSend } from './send.js'\n\nexport async function processOneRunStep(runId: ObjectId, ctx: RunnerContext): Promise<void> {\n const run = await ctx.collections.flowRuns.findOne({ _id: runId })\n if (!run || run.status !== 'active') return\n\n const flow = await ctx.collections.flows.findOne({ _id: run.flowId })\n if (!flow) {\n await failFlowRun(run, 'flow_missing', ctx)\n return\n }\n\n const steps = await loadStepsForRun(run, flow, ctx)\n const step = locateStep(steps, run.currentStepIndex, run.currentBranchPath)\n if (!step) {\n await completeFlowRun(run, 'completed', ctx)\n return\n }\n\n const contact = await ctx.adapter.getById(run.externalId)\n if (!contact) {\n await exitFlowRun(run, 'contact_missing', ctx)\n return\n }\n\n // Marketing-flow subscription gate. Transactional sends bypass this at\n // send-step level (re-checked there).\n const sub = await ctx.collections.subscriptions.findOne({ externalId: run.externalId })\n if (sub && sub.status !== 'subscribed') {\n await exitFlowRun(run, sub.status, ctx)\n return\n }\n\n switch (step.type) {\n case 'wait':\n return handleWait(run, step, ctx)\n case 'condition':\n return handleCondition(run, step, contact, ctx)\n case 'branch':\n return handleBranch(run, step, contact, ctx)\n case 'send':\n return handleSend(run, step, contact, flow, ctx)\n case 'tag':\n return handleTag(run, step, ctx)\n case 'fire_event':\n return handleFireEvent(run, step, ctx)\n case 'webhook':\n return handleWebhookStep(run, step, ctx)\n case 'exit':\n return exitFlowRun(run, step.reason ?? 'exit_step', ctx)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Step handlers\n// ---------------------------------------------------------------------------\n\nasync function handleWait(\n run: FlowRunDoc,\n step: Extract<FlowStep, { type: 'wait' }>,\n ctx: RunnerContext,\n): Promise<void> {\n const ms = unitToMs(step.value, step.unit)\n const nextAt = new Date(Date.now() + ms)\n\n const updated = await ctx.collections.flowRuns.findOneAndUpdate(\n { _id: run._id, currentStepIndex: run.currentStepIndex },\n {\n $set: { nextActionAt: nextAt, attemptsForCurrentStep: 0, updatedAt: new Date() },\n $inc: { currentStepIndex: 1 },\n $push: {\n history: {\n stepIndex: run.currentStepIndex,\n action: 'wait_started',\n at: new Date(),\n details: { until: nextAt },\n },\n },\n },\n { returnDocument: 'after' },\n )\n\n if (!updated) return // another worker advanced; their job will fire.\n\n await ctx.queues.advance.add(\n 'advance',\n { flowRunId: String(run._id) },\n { delay: ms, jobId: `advance:${run._id}:${run.currentStepIndex + 1}` },\n )\n}\n\nasync function handleCondition(\n run: FlowRunDoc,\n step: Extract<FlowStep, { type: 'condition' }>,\n contact: Awaited<ReturnType<typeof ctx.adapter.getById>>,\n ctx: RunnerContext,\n): Promise<void> {\n if (!contact) return\n const result = await evaluatePredicate(step.test, { contact, run, collections: ctx.collections })\n\n if (result) {\n await advanceStep(run, ctx, { action: 'condition_evaluated', details: { result: true } })\n return\n }\n if (step.ifFalse === 'continue') {\n await advanceStep(run, ctx, { action: 'condition_evaluated', details: { result: false, skipped: 1 } }, { stepInc: 2 })\n return\n }\n await exitFlowRun(run, 'condition_false', ctx)\n}\n\nasync function handleBranch(\n run: FlowRunDoc,\n step: Extract<FlowStep, { type: 'branch' }>,\n contact: Awaited<ReturnType<typeof ctx.adapter.getById>>,\n ctx: RunnerContext,\n): Promise<void> {\n if (!contact) return\n const result = await evaluatePredicate(step.test, { contact, run, collections: ctx.collections })\n const newPath = [...run.currentBranchPath, run.currentStepIndex, result ? 'true' : 'false', 0] as Array<number | 'true' | 'false'>\n\n const updated = await ctx.collections.flowRuns.findOneAndUpdate(\n { _id: run._id, currentStepIndex: run.currentStepIndex },\n {\n $set: {\n currentBranchPath: newPath,\n currentStepIndex: 0,\n nextActionAt: new Date(),\n attemptsForCurrentStep: 0,\n updatedAt: new Date(),\n },\n $push: {\n history: {\n stepIndex: run.currentStepIndex,\n action: 'branch_taken',\n at: new Date(),\n details: { result },\n },\n },\n },\n { returnDocument: 'after' },\n )\n\n if (!updated) return\n await ctx.queues.advance.add('advance', { flowRunId: String(run._id) })\n}\n\nasync function handleTag(\n run: FlowRunDoc,\n step: Extract<FlowStep, { type: 'tag' }>,\n ctx: RunnerContext,\n): Promise<void> {\n const adds = step.addTags ?? []\n const removes = step.removeTags ?? []\n\n if (ctx.adapter.addTags && adds.length > 0) {\n await ctx.adapter.addTags(run.externalId, adds)\n } else if (adds.length > 0) {\n await ctx.collections.contactTags.bulkWrite(\n adds.map((tag) => ({\n updateOne: {\n filter: { externalId: run.externalId, tag },\n update: { $setOnInsert: { externalId: run.externalId, tag, appliedBy: 'flow', appliedAt: new Date() } },\n upsert: true,\n },\n })),\n )\n }\n\n if (ctx.adapter.removeTags && removes.length > 0) {\n await ctx.adapter.removeTags(run.externalId, removes)\n } else if (removes.length > 0) {\n await ctx.collections.contactTags.deleteMany({ externalId: run.externalId, tag: { $in: removes } })\n }\n\n await advanceStep(run, ctx, { action: 'tagged', details: { addTags: adds, removeTags: removes } })\n}\n\nasync function handleFireEvent(\n run: FlowRunDoc,\n step: Extract<FlowStep, { type: 'fire_event' }>,\n ctx: RunnerContext,\n): Promise<void> {\n const dedupeKey = `flowrun:${run._id}:step${run.currentStepIndex}:${step.eventName}`\n try {\n await ctx.collections.events.insertOne({\n externalId: run.externalId,\n name: step.eventName,\n properties: step.properties ?? {},\n dedupeKey,\n occurredAt: new Date(),\n createdAt: new Date(),\n })\n } catch (err: any) {\n if (err?.code !== 11000) throw err\n }\n await advanceStep(run, ctx, { action: 'event_fired', details: { name: step.eventName } })\n}\n\nasync function handleWebhookStep(\n run: FlowRunDoc,\n step: Extract<FlowStep, { type: 'webhook' }>,\n ctx: RunnerContext,\n): Promise<void> {\n try {\n const res = await fetch(step.url, {\n method: step.method ?? 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(step.payload ?? { externalId: run.externalId, flowRunId: String(run._id) }),\n signal: AbortSignal.timeout(10_000),\n })\n if (!res.ok) throw new Error(`webhook step returned ${res.status}`)\n await advanceStep(run, ctx, { action: 'webhook_called', details: { url: step.url, status: res.status } })\n } catch (err: any) {\n const attempts = (run.attemptsForCurrentStep ?? 0) + 1\n if (attempts >= ctx.config.webhookRetryAttempts) {\n if (step.failureMode === 'fail_run') {\n await failFlowRun(run, `webhook failed: ${err?.message}`, ctx)\n } else {\n // Soft fail — log and advance.\n await advanceStep(run, ctx, {\n action: 'webhook_called',\n details: { url: step.url, error: err?.message, exhausted: true },\n })\n }\n } else {\n await ctx.collections.flowRuns.updateOne(\n { _id: run._id, currentStepIndex: run.currentStepIndex },\n { $inc: { attemptsForCurrentStep: 1 }, $set: { nextActionAt: new Date(Date.now() + 60_000) } },\n )\n await ctx.queues.advance.add(\n 'advance',\n { flowRunId: String(run._id) },\n { delay: 60_000, jobId: `advance:${run._id}:${run.currentStepIndex}:retry-${attempts}` },\n )\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Common helpers\n// ---------------------------------------------------------------------------\n\nexport interface AdvanceOptions {\n stepInc?: number\n}\n\nexport interface AdvanceLog {\n action: FlowRunDoc['history'][number]['action']\n details?: Record<string, unknown>\n}\n\nexport async function advanceStep(\n run: FlowRunDoc,\n ctx: RunnerContext,\n log: AdvanceLog,\n opts: AdvanceOptions = {},\n): Promise<void> {\n const stepInc = opts.stepInc ?? 1\n const updated = await ctx.collections.flowRuns.findOneAndUpdate(\n { _id: run._id, currentStepIndex: run.currentStepIndex },\n {\n $set: { nextActionAt: new Date(), attemptsForCurrentStep: 0, updatedAt: new Date() },\n $inc: { currentStepIndex: stepInc },\n $push: {\n history: { stepIndex: run.currentStepIndex, action: log.action, at: new Date(), details: log.details },\n },\n },\n { returnDocument: 'after' },\n )\n if (!updated) return\n await ctx.queues.advance.add('advance', { flowRunId: String(run._id) })\n}\n\nexport async function exitFlowRun(run: FlowRunDoc, reason: string, ctx: RunnerContext): Promise<void> {\n await ctx.collections.flowRuns.updateOne(\n { _id: run._id, status: 'active' },\n {\n $set: { status: 'exited', exitedAt: new Date(), exitReason: reason, updatedAt: new Date() },\n $push: { history: { stepIndex: run.currentStepIndex, action: 'exited', at: new Date(), details: { reason } } },\n },\n )\n}\n\nexport async function completeFlowRun(run: FlowRunDoc, reason: string, ctx: RunnerContext): Promise<void> {\n await ctx.collections.flowRuns.updateOne(\n { _id: run._id, status: 'active' },\n {\n $set: { status: 'completed', exitedAt: new Date(), exitReason: reason, updatedAt: new Date() },\n },\n )\n}\n\nexport async function failFlowRun(run: FlowRunDoc, reason: string, ctx: RunnerContext): Promise<void> {\n await ctx.collections.flowRuns.updateOne(\n { _id: run._id, status: 'active' },\n {\n $set: { status: 'failed', exitedAt: new Date(), exitReason: reason, updatedAt: new Date() },\n $push: { history: { stepIndex: run.currentStepIndex, action: 'failed', at: new Date(), details: { reason } } },\n },\n )\n}\n\nexport async function loadStepsForRun(\n run: FlowRunDoc,\n flow: FlowDoc,\n ctx: RunnerContext,\n): Promise<FlowStep[]> {\n if (run.flowVersion === flow.version) return flow.steps\n const snapshot = await ctx.collections.flowVersions.findOne({ flowId: run.flowId, version: run.flowVersion })\n return snapshot?.steps ?? flow.steps\n}\n\n/**\n * Walk a branch path through nested branch steps to find the active step.\n * Branch path layout: [parentStepIndex, 'true'|'false', childStepIndex, ...repeat]\n */\nexport function locateStep(\n steps: FlowStep[],\n currentStepIndex: number,\n branchPath: ReadonlyArray<number | 'true' | 'false'>,\n): FlowStep | null {\n let arr: FlowStep[] = steps\n\n for (let i = 0; i < branchPath.length; i += 3) {\n const parentIndex = branchPath[i] as number\n const branchKey = branchPath[i + 1] as 'true' | 'false'\n const parent = arr[parentIndex]\n if (!parent || parent.type !== 'branch') return null\n arr = branchKey === 'true' ? parent.ifTrueSteps : parent.ifFalseSteps\n }\n\n return arr[currentStepIndex] ?? null\n}\n\nfunction unitToMs(value: number, unit: 'minutes' | 'hours' | 'days' | 'weeks'): number {\n const m = 60_000\n switch (unit) {\n case 'minutes':\n return value * m\n case 'hours':\n return value * 60 * m\n case 'days':\n return value * 24 * 60 * m\n case 'weeks':\n return value * 7 * 24 * 60 * m\n }\n}\n","/**\n * Recovery sweep: finds active flow_runs whose `nextActionAt` has passed but\n * weren't woken by their delayed `mailer:advance` job (worker restart, BullMQ\n * data loss). Processes each one inline.\n */\n\nimport { processOneRunStep } from './step.js'\nimport type { RunnerContext } from './index.js'\n\nconst SWEEP_LIMIT = 500\n\nexport async function sweepStrandedFlowRuns(ctx: RunnerContext): Promise<void> {\n const runs = await ctx.collections.flowRuns\n .find({ status: 'active', nextActionAt: { $lte: new Date() } })\n .sort({ nextActionAt: 1 })\n .limit(SWEEP_LIMIT)\n .toArray()\n\n for (const run of runs) {\n try {\n await processOneRunStep(run._id!, ctx)\n } catch (err) {\n console.error('mailery: sweep advance failed', { runId: String(run._id), err })\n }\n }\n}\n","/**\n * Broadcast dispatch. Picks up scheduled broadcasts whose `scheduledAt` has\n * passed, streams the segment via the adapter cursor + mailer-side post-filter,\n * and bulk-enqueues Send docs + jobs. Per-provider rate limiting + bounded\n * enqueue (pause when waitingCount > broadcastEnqueueMaxWaiting).\n */\n\nimport { ObjectId } from 'mongodb'\n\nimport type { Contact, SegmentDefinition, SegmentFilter, AdapterFilter } from '../../shared/types.js'\nimport type { BroadcastDoc, SendDoc, TemplateDoc } from '../models/index.js'\nimport { isSuppressed } from './suppression.js'\nimport { sha256Hex } from '../tokens.js'\nimport type { RunnerContext } from './index.js'\n\n/**\n * Process scheduled broadcasts whose `scheduledAt` has passed. Called from the\n * tick. Marks each broadcast `sending` before streaming so concurrent ticks\n * don't double-dispatch.\n */\nexport async function processScheduledBroadcasts(ctx: RunnerContext): Promise<void> {\n const now = new Date()\n const due = await ctx.collections.broadcasts\n .find({ status: 'scheduled', scheduledAt: { $lte: now } })\n .toArray()\n\n for (const b of due) {\n // Optimistic claim — only one worker takes this broadcast.\n const claimed = await ctx.collections.broadcasts.findOneAndUpdate(\n { _id: b._id, status: 'scheduled' },\n { $set: { status: 'sending', startedAt: now, updatedAt: now } },\n { returnDocument: 'after' },\n )\n if (!claimed) continue\n\n try {\n await dispatchBroadcast(claimed, ctx)\n } catch (err) {\n console.error('mailery: broadcast dispatch failed', { id: String(b._id), err })\n await ctx.collections.broadcasts.updateOne(\n { _id: b._id },\n { $set: { status: 'failed', updatedAt: new Date() } },\n )\n }\n }\n}\n\nasync function dispatchBroadcast(broadcast: BroadcastDoc, ctx: RunnerContext): Promise<void> {\n const template = await ctx.collections.templates.findOne({ slug: broadcast.templateSlug })\n if (!template) {\n await ctx.collections.broadcasts.updateOne(\n { _id: broadcast._id },\n { $set: { status: 'failed', updatedAt: new Date() } },\n )\n return\n }\n\n const hostFilter = toAdapterFilter(broadcast.segmentDefinition)\n const postFilters = broadcast.segmentDefinition.filters.filter((f) => isMailerSide(f))\n\n let cursor: string | undefined = undefined\n let total = 0\n const batchSize = ctx.config.broadcastEnqueueBatchSize\n const maxWaiting = ctx.config.broadcastEnqueueMaxWaiting\n const respectTimezone = broadcast.respectRecipientTimezone === true\n const scheduledMs = broadcast.scheduledAt?.getTime() ?? Date.now()\n\n for (;;) {\n const page = await ctx.adapter.query(hostFilter, { limit: batchSize, cursor })\n if (page.contacts.length === 0) break\n\n // Stage B: mailer-side post-filter.\n const eligible = await applyPostFilters(page.contacts, postFilters, ctx)\n\n if (eligible.length > 0) {\n // Backpressure: wait until the send queue's waiting set drains below cap.\n while ((await ctx.queues.send.getWaitingCount()) > maxWaiting) {\n await sleep(2000)\n }\n\n const sendDocs = await Promise.all(\n eligible.map(async (contact) => buildSendDoc(broadcast, template, contact, ctx, scheduledMs, respectTimezone)),\n )\n\n // Filter out suppressed (mailer-side suppression check is the same one\n // dispatchSend would do; we short-circuit here to avoid enqueuing).\n const inserted: Array<{ sendId: ObjectId; delayMs: number }> = []\n for (const { doc, delayMs } of sendDocs) {\n if (!doc) continue\n try {\n await ctx.collections.sends.insertOne(doc)\n inserted.push({ sendId: doc._id!, delayMs })\n } catch (err: any) {\n if (err?.code !== 11000) throw err\n // dup dedupeKey — already dispatched somewhere\n }\n }\n\n // Bulk enqueue.\n if (inserted.length > 0) {\n await Promise.all(\n inserted.map(({ sendId, delayMs }) =>\n ctx.queues.send.add(\n 'send',\n { sendId: String(sendId) },\n {\n attempts: ctx.config.sendRetryAttempts,\n backoff: { type: 'exponential', delay: 60_000 },\n ...(delayMs > 0 ? { delay: delayMs } : {}),\n },\n ),\n ),\n )\n }\n\n total += inserted.length\n }\n\n if (!page.nextCursor) break\n cursor = page.nextCursor\n }\n\n await ctx.collections.broadcasts.updateOne(\n { _id: broadcast._id },\n {\n $set: {\n status: 'sent',\n completedAt: new Date(),\n recipientCount: total,\n updatedAt: new Date(),\n },\n },\n )\n}\n\n// ---------------------------------------------------------------------------\n// Segment translation\n// ---------------------------------------------------------------------------\n\nfunction toAdapterFilter(seg: SegmentDefinition): AdapterFilter {\n const out: AdapterFilter = {}\n for (const f of seg.filters) {\n switch (f.kind) {\n case 'hasTag':\n out.hasTag = f.tag\n break\n case 'fieldEquals':\n out.fieldEquals = { field: f.field, value: f.value }\n break\n case 'fieldIn':\n out.fieldIn = { field: f.field, values: f.values }\n break\n case 'fieldExists':\n out.fieldExists = f.field\n break\n // notHasTag isn't a single-condition adapter filter, defer to post-filter\n // subscriptionStatus / firedEvent / opened are all mailer-side\n }\n }\n return out\n}\n\nfunction isMailerSide(f: SegmentFilter): boolean {\n return (\n f.kind === 'subscriptionStatus' ||\n f.kind === 'firedEvent' ||\n f.kind === 'notFiredEvent' ||\n f.kind === 'subscribedAfter' ||\n f.kind === 'subscribedBefore' ||\n f.kind === 'opened' ||\n f.kind === 'notOpened' ||\n f.kind === 'notHasTag' ||\n f.kind === 'any' ||\n f.kind === 'not'\n )\n}\n\nasync function applyPostFilters(contacts: Contact[], filters: SegmentFilter[], ctx: RunnerContext): Promise<Contact[]> {\n if (filters.length === 0) return contacts\n const externalIds = contacts.map((c) => c.externalId)\n\n // Cache common lookups in one Mongo round-trip per filter.\n const cache: Record<string, Set<string>> = {}\n for (const f of filters) {\n if (f.kind === 'subscriptionStatus') {\n const docs = await ctx.collections.subscriptions\n .find({ externalId: { $in: externalIds }, status: f.equals })\n .project<{ externalId: string }>({ externalId: 1 })\n .toArray()\n cache[`sub:${f.equals}`] = new Set(docs.map((d) => d.externalId))\n }\n if (f.kind === 'firedEvent' || f.kind === 'notFiredEvent') {\n const query: any = { externalId: { $in: externalIds }, name: f.eventName }\n if (f.withinDays) {\n query.occurredAt = { $gt: new Date(Date.now() - f.withinDays * 86_400_000) }\n }\n const docs = await ctx.collections.events\n .find(query)\n .project<{ externalId: string }>({ externalId: 1 })\n .toArray()\n cache[`evt:${f.eventName}`] = new Set(docs.map((d) => d.externalId))\n }\n }\n\n return contacts.filter((c) => filters.every((f) => filterMatches(c, f, cache)))\n}\n\nfunction filterMatches(c: Contact, f: SegmentFilter, cache: Record<string, Set<string>>): boolean {\n switch (f.kind) {\n case 'subscriptionStatus':\n return cache[`sub:${f.equals}`]?.has(c.externalId) ?? false\n case 'firedEvent':\n return cache[`evt:${f.eventName}`]?.has(c.externalId) ?? false\n case 'notFiredEvent':\n return !cache[`evt:${f.eventName}`]?.has(c.externalId)\n case 'notHasTag':\n return !c.tags.includes(f.tag)\n case 'opened':\n case 'notOpened':\n // V1: not implemented in batch — would need a per-contact send lookup.\n // Treat as pass for now; suppress at dispatch time.\n return true\n case 'subscribedAfter':\n case 'subscribedBefore':\n return true // V2\n case 'any':\n return f.filters.some((sub) => filterMatches(c, sub, cache))\n case 'not':\n return !filterMatches(c, f.filter, cache)\n default:\n return true\n }\n}\n\n// ---------------------------------------------------------------------------\n// Send doc construction\n// ---------------------------------------------------------------------------\n\ninterface BuildResult {\n doc: SendDoc | null\n delayMs: number\n}\n\nasync function buildSendDoc(\n broadcast: BroadcastDoc,\n template: TemplateDoc,\n contact: Contact,\n ctx: RunnerContext,\n scheduledMs: number,\n respectTimezone: boolean,\n): Promise<BuildResult> {\n // Final suppression check before we insert.\n const supp = await isSuppressed(ctx.collections, contact.email, template.kind)\n if (supp.suppressed) return { doc: null, delayMs: 0 }\n\n const sendId = new ObjectId()\n const dedupeKey = `broadcast:${broadcast._id}:${contact.externalId}`\n\n // Per-recipient TZ delay calculation.\n let delayMs = Math.max(0, scheduledMs - Date.now())\n if (respectTimezone && contact.timezone) {\n delayMs = Math.max(0, perRecipientDelayMs(scheduledMs, contact.timezone))\n }\n\n const doc: SendDoc = {\n _id: sendId,\n dedupeKey,\n externalId: contact.externalId,\n emailAtSend: contact.email,\n templateId: template._id!,\n templateSlug: template.slug,\n flowRunId: null,\n broadcastId: broadcast._id!,\n manualSendBy: null,\n kind: template.kind,\n provider: template.providerOverride ?? ctx.config.defaultProvider,\n providerMessageId: null,\n fromName: template.fromName,\n fromEmail: template.fromEmail,\n subject: template.subject,\n bodyHash: '',\n status: 'queued',\n errorMessage: null,\n bounceType: null,\n bounceReason: null,\n links: [],\n vars: {},\n openedAt: null,\n openCount: 0,\n firstClickAt: null,\n clickCount: 0,\n clickedLinks: [],\n unsubscribedAt: null,\n complainedAt: null,\n queuedAt: new Date(),\n updatedAt: new Date(),\n sentAt: null,\n deliveredAt: null,\n }\n void sha256Hex\n return { doc, delayMs }\n}\n\n/**\n * Compute the delay so the recipient receives the email at `scheduledMs` in\n * their LOCAL timezone (rather than the configured scheduled UTC instant).\n *\n * Example: broadcast `scheduledAt` is 10am UTC, contact is in PST (UTC-8).\n * Without respect: contact gets it at 2am local. With respect: contact gets it\n * at 10am their time = 6pm UTC. delayMs = 8 hours.\n */\nfunction perRecipientDelayMs(scheduledMs: number, timezone: string): number {\n try {\n // Get the offset between the scheduled UTC instant interpreted as a wall\n // clock and the same wall clock in the recipient's tz.\n const scheduled = new Date(scheduledMs)\n const utc = scheduled.toLocaleString('en-US', { timeZone: 'UTC', hour12: false })\n const local = scheduled.toLocaleString('en-US', { timeZone: timezone, hour12: false })\n\n // Parse both as Date objects in the runner's local tz and take the diff.\n const parse = (s: string) => {\n const m = s.match(/(\\d+)\\/(\\d+)\\/(\\d+),\\s*(\\d+):(\\d+):(\\d+)/)\n if (!m) return 0\n return Date.UTC(+m[3]!, +m[1]! - 1, +m[2]!, +m[4]!, +m[5]!, +m[6]!)\n }\n const utcMs = parse(utc)\n const localMs = parse(local)\n const offsetMs = utcMs - localMs\n\n // Target = scheduledMs (as a wall-clock in tz) + (utc - local offset) so\n // it lands at the same WALL CLOCK in tz.\n return offsetMs\n } catch {\n return 0\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","/**\n * Soft → hard bounce promotion. Configurable threshold + window:\n *\n * softBouncePromotionThreshold soft bounces for the same email within\n * softBouncePromotionWindowDays → insert a hard suppression + mark\n * the subscription bounced.\n *\n * Runs on each tick. Idempotent: if a hard suppression already exists for\n * that email, we skip.\n */\n\nimport { sha256Hex } from '../tokens.js'\nimport { recordHealthCounter } from './health.js'\nimport type { RunnerContext } from './index.js'\n\nexport async function promoteSoftBounces(ctx: RunnerContext): Promise<void> {\n const threshold = ctx.config.softBouncePromotionThreshold\n const windowDays = ctx.config.softBouncePromotionWindowDays\n if (threshold <= 0 || windowDays <= 0) return\n\n const cutoff = new Date(Date.now() - windowDays * 86_400_000)\n\n // Aggregate: count soft bounces per emailAtSend since cutoff, hitting the\n // threshold. Bounded limit to keep the tick fast.\n const offenders = await ctx.collections.sends\n .aggregate<{ _id: string; count: number }>([\n { $match: { status: 'bounced', bounceType: 'soft', queuedAt: { $gt: cutoff } } },\n { $group: { _id: '$emailAtSend', count: { $sum: 1 } } },\n { $match: { count: { $gte: threshold } } },\n { $limit: 200 },\n ])\n .toArray()\n\n for (const o of offenders) {\n const email = String(o._id ?? '').toLowerCase()\n if (!email) continue\n\n // Skip if already hard-suppressed.\n const existing = await ctx.collections.suppressions.findOne({\n email,\n scope: 'all',\n })\n if (existing) continue\n\n await ctx.collections.suppressions.updateOne(\n { email, scope: 'all' },\n {\n $setOnInsert: {\n email,\n emailHash: sha256Hex(email),\n scope: 'all',\n reason: 'hard_bounce',\n source: 'soft_promotion',\n notes: `${o.count} soft bounces in last ${windowDays} days`,\n addedAt: new Date(),\n expiresAt: null,\n },\n },\n { upsert: true },\n )\n\n await ctx.collections.subscriptions.updateOne(\n { emailAtSubscribe: email },\n { $set: { status: 'bounced', updatedAt: new Date() } },\n )\n\n await recordHealthCounter(ctx, 'hardBounced')\n }\n}\n","/**\n * The mailer:tick handler. Orchestrates all the periodic work that doesn't\n * fit a delayed-job model: event-trigger scanning, recovery sweep,\n * scheduled-broadcast dispatch, outbox draining, rollups.\n */\n\nimport { processNewlyFiredEventTriggers } from './triggers.js'\nimport { sweepStrandedFlowRuns } from './sweep.js'\nimport { processScheduledBroadcasts as dispatchScheduled } from './broadcasts.js'\nimport { evaluateHealth } from './health.js'\nimport { promoteSoftBounces } from './bounce-promotion.js'\nimport type { RunnerContext } from './index.js'\n\n/**\n * Sends that entered the 'sending' state more than this long ago are assumed\n * to have been abandoned mid-dispatch (worker crash, OOM kill, ...). The tick\n * resets them to 'queued' and re-enqueues. Providers should treat the sendId\n * (passed in messageMeta) as an idempotency key to avoid duplicate delivery on\n * the rare case where the original call did reach the provider.\n */\nconst STRANDED_SEND_THRESHOLD_MS = 5 * 60 * 1000\n\nexport async function runTick(ctx: RunnerContext): Promise<void> {\n // Heartbeat: ensure the singleton health doc exists with an up-to-date\n // `updatedAt` so the setup-status check can detect \"workers are running.\"\n await ctx.collections.health.updateOne(\n { _id: 'singleton' },\n {\n $set: { updatedAt: new Date() },\n $setOnInsert: {\n _id: 'singleton',\n windowStartedAt: new Date(),\n windowDurationMs: ctx.config.circuitBreaker.windowMinutes * 60 * 1000,\n status: 'healthy',\n trippedAt: null,\n trippedReason: null,\n manuallyResumedAt: null,\n counters: { sent: 0, delivered: 0, bounced: 0, hardBounced: 0, softBounced: 0, complained: 0, failedToSend: 0 },\n rates: { bounceRate: 0, hardBounceRate: 0, complaintRate: 0, failureRate: 0 },\n },\n },\n { upsert: true },\n ).catch(() => {})\n\n await processNewlyFiredEventTriggers(ctx).catch((err) => {\n console.error('mailery: triggers scan failed', err)\n })\n await sweepStrandedFlowRuns(ctx).catch((err) => {\n console.error('mailery: sweep failed', err)\n })\n await sweepStrandedSends(ctx).catch((err) => {\n console.error('mailery: stranded-send sweep failed', err)\n })\n await drainOutbox(ctx).catch((err) => {\n console.error('mailery: outbox drain failed', err)\n })\n await processScheduledBroadcasts(ctx).catch((err) => {\n console.error('mailery: broadcast dispatch failed', err)\n })\n await evaluateHealth(ctx).catch((err) => {\n console.error('mailery: health evaluation failed', err)\n })\n await promoteSoftBounces(ctx).catch((err) => {\n console.error('mailery: soft-bounce promotion failed', err)\n })\n}\n\n/**\n * Find sends stuck in 'sending' past the threshold (crashed mid-dispatch) and\n * re-enqueue them. Returning to 'queued' lets `dispatchSend` pick them back up.\n */\nasync function sweepStrandedSends(ctx: RunnerContext): Promise<void> {\n const cutoff = new Date(Date.now() - STRANDED_SEND_THRESHOLD_MS)\n const cursor = ctx.collections.sends.find(\n { status: 'sending', updatedAt: { $lt: cutoff } },\n { projection: { _id: 1 } },\n ).limit(500)\n for await (const row of cursor) {\n const reset = await ctx.collections.sends.updateOne(\n { _id: row._id, status: 'sending', updatedAt: { $lt: cutoff } },\n { $set: { status: 'queued', updatedAt: new Date() } },\n )\n if (reset.modifiedCount === 0) continue\n await ctx.queues.send.add('send', { sendId: String(row._id) }, {\n attempts: ctx.config.sendRetryAttempts,\n backoff: { type: 'exponential', delay: 60_000 },\n })\n }\n}\n\n/**\n * Pull pending outbox rows committed by host transactions and promote them\n * into the real collections (events / subscriptions / suppressions).\n */\nasync function drainOutbox(ctx: RunnerContext): Promise<void> {\n const batch = await ctx.collections.outbox\n .find({ status: 'pending' })\n .sort({ enqueuedAt: 1 })\n .limit(200)\n .toArray()\n\n for (const row of batch) {\n try {\n if (row.payload.type === 'event') {\n try {\n await ctx.collections.events.insertOne({\n externalId: row.payload.data.externalId as string,\n name: row.payload.data.name as string,\n properties: (row.payload.data.properties as Record<string, unknown>) ?? {},\n dedupeKey: row.payload.dedupeKey,\n occurredAt: (row.payload.data.occurredAt as Date | undefined) ?? new Date(),\n createdAt: new Date(),\n })\n } catch (err: any) {\n if (err?.code !== 11000) throw err\n }\n }\n await ctx.collections.outbox.updateOne(\n { _id: row._id },\n { $set: { status: 'processed', processedAt: new Date() } },\n )\n } catch (err: any) {\n await ctx.collections.outbox.updateOne(\n { _id: row._id },\n {\n $set: { lastAttemptAt: new Date(), lastError: String(err?.message ?? err) },\n $inc: { attempts: 1 },\n },\n )\n }\n }\n}\n\n/**\n * Dispatch broadcasts whose `scheduledAt` has passed. Streams the segment\n * cursor and bulk-enqueues sends, pausing when the send queue's waiting\n * count exceeds the configured cap (broadcastEnqueueMaxWaiting).\n */\nasync function processScheduledBroadcasts(ctx: RunnerContext): Promise<void> {\n await dispatchScheduled(ctx)\n}\n","/**\n * Apply a normalized provider event to the corresponding Send + cascading\n * suppression / subscription updates. Called from the webhook worker.\n */\n\nimport type { NormalizedEvent } from '../../shared/types.js'\nimport type { RunnerContext } from './index.js'\nimport { sha256Hex } from '../tokens.js'\nimport { recordHealthCounter } from './health.js'\n\nexport async function applyWebhookEvent(event: NormalizedEvent, ctx: RunnerContext): Promise<void> {\n const send = await ctx.collections.sends.findOne(\n event.providerMessageId\n ? { $or: [{ providerMessageId: event.providerMessageId }, { emailAtSend: event.email }] }\n : { emailAtSend: event.email },\n { sort: { queuedAt: -1 } },\n )\n\n switch (event.type) {\n case 'delivered':\n if (send) {\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n { $set: { status: 'delivered', deliveredAt: event.occurredAt } },\n )\n }\n await recordHealthCounter(ctx, 'delivered')\n break\n\n case 'open':\n if (send) {\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n {\n $set: {\n openedAt: send.openedAt ?? event.occurredAt,\n status: send.status === 'sent' ? 'delivered' : send.status,\n },\n $inc: { openCount: 1 },\n },\n )\n }\n break\n\n case 'click':\n if (send) {\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n {\n $set: { firstClickAt: send.firstClickAt ?? event.occurredAt },\n $inc: { clickCount: 1 },\n $push: {\n clickedLinks: {\n url: event.details.clickedUrl ?? '',\n linkId: '',\n clickedAt: event.occurredAt,\n },\n },\n },\n )\n }\n break\n\n case 'bounce': {\n const bounceType = event.details.bounceType ?? 'hard'\n if (send) {\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n {\n $set: {\n status: 'bounced',\n bounceType,\n bounceReason: event.details.bounceReason ?? null,\n },\n },\n )\n }\n if (bounceType === 'hard') {\n await suppressOnce(ctx, event.email, 'hard_bounce', 'all')\n await ctx.collections.subscriptions.updateOne(\n { emailAtSubscribe: event.email },\n { $set: { status: 'bounced', updatedAt: new Date() } },\n )\n }\n await recordHealthCounter(ctx, 'bounced')\n await recordHealthCounter(ctx, bounceType === 'hard' ? 'hardBounced' : 'softBounced')\n break\n }\n\n case 'complaint':\n case 'spam_report':\n if (send) {\n await ctx.collections.sends.updateOne(\n { _id: send._id },\n { $set: { complainedAt: event.occurredAt, status: 'complained' } },\n )\n }\n await suppressOnce(ctx, event.email, 'complaint', 'all')\n await ctx.collections.subscriptions.updateOne(\n { emailAtSubscribe: event.email },\n { $set: { status: 'complained', updatedAt: new Date() } },\n )\n await recordHealthCounter(ctx, 'complained')\n break\n\n case 'unsubscribe':\n if (send) {\n await ctx.collections.sends.updateOne({ _id: send._id }, { $set: { unsubscribedAt: event.occurredAt } })\n }\n await suppressOnce(ctx, event.email, 'unsubscribed', 'marketing')\n await ctx.collections.subscriptions.updateOne(\n { emailAtSubscribe: event.email },\n {\n $set: {\n status: 'unsubscribed',\n unsubscribedAt: event.occurredAt,\n unsubscribeReason: 'user_request',\n updatedAt: new Date(),\n },\n },\n )\n break\n }\n}\n\nasync function suppressOnce(\n ctx: RunnerContext,\n email: string,\n reason: 'hard_bounce' | 'complaint' | 'unsubscribed',\n scope: 'all' | 'marketing' | 'transactional',\n): Promise<void> {\n const normalized = email.toLowerCase()\n await ctx.collections.suppressions.updateOne(\n { email: normalized, scope },\n {\n $setOnInsert: {\n email: normalized,\n emailHash: sha256Hex(normalized),\n scope,\n reason,\n source: 'provider_webhook',\n notes: null,\n addedAt: new Date(),\n expiresAt: null,\n },\n },\n { upsert: true },\n )\n}\n","/**\n * Mailer — public facade. Hosts call `Mailer.init(config)` and get an object\n * exposing the public API (fire, upsertSubscription, unsubscribe, ...) plus\n * mountable Express routers.\n *\n * See plans/10-public-api.md for the surface.\n */\n\nimport type { Db, ClientSession, ObjectId } from 'mongodb'\nimport { ObjectId as ObjectIdCtor } from 'mongodb'\n\nimport type {\n ContactAdapter,\n MailProvider,\n} from '../shared/types.js'\nimport {\n fireInputSchema,\n registerEventSchema,\n sendOneOffInputSchema,\n suppressInputSchema,\n tagInputSchema,\n unsubscribeInputSchema,\n upsertSubscriptionSchema,\n type FireInput,\n type RegisterEventInput,\n type SendOneOffInput,\n type SuppressInput,\n type TagInput,\n type UnsubscribeInput,\n type UpsertSubscriptionInput,\n} from '../shared/schemas.js'\nimport { resolveConfig, type MailerConfig, type ResolvedConfig } from './config.js'\nimport {\n ensureIndexes,\n getCollections,\n} from './models/index.js'\nimport type { Collections } from './models/index.js'\nimport { EventRegistry } from './events.js'\nimport { sha256Hex, signDoiToken } from './tokens.js'\nimport {\n createQueueDriver,\n type QueueDriver,\n type Queues,\n} from './queues/index.js'\nimport {\n dispatchSend,\n processOneRunStep,\n runTick,\n type RunnerContext,\n} from './runner/index.js'\nimport { applyWebhookEvent } from './runner/webhook.js'\n\nexport class Mailer {\n readonly db: Db\n readonly collections: Collections\n readonly adapter: ContactAdapter\n readonly providers: Record<string, MailProvider>\n readonly queues: Queues\n readonly config: ResolvedConfig\n readonly events: EventRegistry\n\n private queueDriver: QueueDriver\n private workersStarted = false\n private runnerContext: RunnerContext\n\n private constructor(args: {\n config: ResolvedConfig\n db: Db\n collections: Collections\n adapter: ContactAdapter\n providers: Record<string, MailProvider>\n queueDriver: QueueDriver\n events: EventRegistry\n }) {\n this.config = args.config\n this.db = args.db\n this.collections = args.collections\n this.adapter = args.adapter\n this.providers = args.providers\n this.queueDriver = args.queueDriver\n this.queues = args.queueDriver.queues\n this.events = args.events\n\n this.runnerContext = {\n db: this.db,\n collections: this.collections,\n adapter: this.adapter,\n providers: this.providers,\n queues: this.queues,\n config: this.config,\n handlebarsHelpers: this.config.handlebarsHelpers,\n }\n }\n\n /**\n * Construct a Mailer from environment variables. Reads:\n *\n * MAILER_MONGODB_URI — Mongo connection string (required)\n * MAILER_MONGODB_DB — database name (optional; defaults to the URI default)\n * MAILER_REDIS_URL — Redis connection URL (required)\n * MAILER_PUBLIC_URL — base for tracking/unsub URLs (required)\n * MAILER_UNSUBSCRIBE_SECRET — HMAC key (required)\n * MAILER_SENDER_ADDRESS — postal address for CAN-SPAM (optional)\n * MAILER_FROM_NAME / MAILER_FROM_EMAIL\n * MAILER_DEFAULT_PROVIDER — defaults to 'sendgrid' if SENDGRID_API_KEY is set\n * MAILER_SENDGRID_API_KEY / MAILER_SENDGRID_WEBHOOK_KEY\n * MAILER_HOST_USERS_COLLECTION (default 'users')\n * MAILER_HOST_USERS_EMAIL_FIELD (default 'email')\n * MAILER_HOST_USERS_ID_FIELD (default '_id')\n * MAILER_HOST_USERS_TAGS_FIELD\n * MAILER_HOST_USERS_TAGS_WRITABLE — '1' or 'true' to enable\n *\n * For anything beyond this (custom toContact, custom providers, hooks),\n * use the programmatic init.\n */\n static async fromEnv(): Promise<Mailer> {\n const env = process.env\n const required = (k: string) => {\n const v = env[k]\n if (!v) throw new Error(`Mailer.fromEnv: missing env var ${k}`)\n return v\n }\n\n const { MongoClient } = await import('mongodb')\n const mongoClient = await MongoClient.connect(required('MAILER_MONGODB_URI'))\n const db = env.MAILER_MONGODB_DB ? mongoClient.db(env.MAILER_MONGODB_DB) : mongoClient.db()\n\n const { MongoContactAdapter } = await import('./adapters/mongo.js')\n const adapter = new MongoContactAdapter({\n db,\n collection: env.MAILER_HOST_USERS_COLLECTION ?? 'users',\n emailField: env.MAILER_HOST_USERS_EMAIL_FIELD ?? 'email',\n idField: env.MAILER_HOST_USERS_ID_FIELD ?? '_id',\n tagsField: env.MAILER_HOST_USERS_TAGS_FIELD,\n tagsWritable:\n env.MAILER_HOST_USERS_TAGS_WRITABLE === '1' || env.MAILER_HOST_USERS_TAGS_WRITABLE === 'true',\n })\n\n const providers: Record<string, MailProvider> = {}\n if (env.MAILER_SENDGRID_API_KEY) {\n const { SendGridProvider } = await import('./providers/sendgrid.js')\n providers.sendgrid = new SendGridProvider({\n apiKey: env.MAILER_SENDGRID_API_KEY,\n webhookVerificationKey: env.MAILER_SENDGRID_WEBHOOK_KEY,\n sandbox: env.NODE_ENV !== 'production',\n })\n }\n if (Object.keys(providers).length === 0) {\n throw new Error('Mailer.fromEnv: no provider configured (set MAILER_SENDGRID_API_KEY, ...)')\n }\n\n const defaultProvider = env.MAILER_DEFAULT_PROVIDER ?? Object.keys(providers)[0]!\n\n const driverEnv = env.MAILER_QUEUE_DRIVER ?? 'bull'\n const queue =\n driverEnv === 'agenda'\n ? ({ driver: 'agenda' as const })\n : driverEnv === 'noop'\n ? ({ driver: 'noop' as const })\n : ({ driver: 'bull' as const, redis: { url: required('MAILER_REDIS_URL') } })\n\n return Mailer.init({\n db,\n adapter,\n queue,\n providers,\n defaultProvider,\n publicUrl: required('MAILER_PUBLIC_URL'),\n unsubscribeSecret: required('MAILER_UNSUBSCRIBE_SECRET'),\n senderAddress: env.MAILER_SENDER_ADDRESS,\n fromDefaults:\n env.MAILER_FROM_NAME && env.MAILER_FROM_EMAIL\n ? { name: env.MAILER_FROM_NAME, email: env.MAILER_FROM_EMAIL }\n : undefined,\n })\n }\n\n static async init(input: MailerConfig): Promise<Mailer> {\n const config = resolveConfig(input)\n if (!config.providers[config.defaultProvider]) {\n throw new Error(`defaultProvider \"${config.defaultProvider}\" not in providers map`)\n }\n\n const collections = getCollections(config.db, config.collectionPrefix)\n await ensureIndexes(config.db, config.collectionPrefix)\n\n const queueDriver = await createQueueDriver(config.queue, config.db)\n if (!config.workerless && config.queue.driver !== 'noop') {\n await queueDriver.scheduleRepeatingTick(config.tickIntervalSeconds)\n }\n\n return new Mailer({\n config,\n db: config.db,\n collections,\n adapter: config.adapter,\n providers: config.providers,\n queueDriver,\n events: new EventRegistry(),\n })\n }\n\n // -------------------------------------------------------------------------\n // Event registration + firing\n // -------------------------------------------------------------------------\n\n registerEvent(reg: RegisterEventInput): void {\n const parsed = registerEventSchema.parse(reg)\n this.events.register(parsed)\n }\n\n async fire(\n eventName: string,\n externalId: string,\n properties: Record<string, unknown> = {},\n dedupeKey?: string,\n ): Promise<void> {\n const input = fireInputSchema.parse({ eventName, externalId, properties, dedupeKey })\n const key = this.events.deriveKey(input.eventName, input.externalId, input.dedupeKey, new Date())\n if (!key) {\n throw new Error(\n `fire(\"${input.eventName}\") missing dedupeKey and no policy registered. ` +\n `Call mailer.registerEvent(\"${input.eventName}\", { dedupePolicy }) or pass a key explicitly.`,\n )\n }\n try {\n await this.collections.events.insertOne({\n externalId: input.externalId,\n name: input.eventName,\n properties: input.properties ?? {},\n dedupeKey: key,\n occurredAt: new Date(),\n createdAt: new Date(),\n })\n } catch (err: any) {\n if (err?.code !== 11000) throw err\n // Duplicate dedupeKey — no-op by design.\n }\n }\n\n async fireFromSession(\n session: ClientSession,\n eventName: string,\n externalId: string,\n properties: Record<string, unknown> = {},\n dedupeKey?: string,\n ): Promise<void> {\n const input = fireInputSchema.parse({ eventName, externalId, properties, dedupeKey })\n const key = this.events.deriveKey(input.eventName, input.externalId, input.dedupeKey, new Date())\n if (!key) {\n throw new Error(`fireFromSession(\"${input.eventName}\") missing dedupeKey and no policy registered.`)\n }\n try {\n await this.collections.outbox.insertOne(\n {\n payload: {\n type: 'event',\n data: {\n externalId: input.externalId,\n name: input.eventName,\n properties: input.properties ?? {},\n occurredAt: new Date(),\n },\n dedupeKey: key,\n },\n status: 'pending',\n attempts: 0,\n lastAttemptAt: null,\n lastError: null,\n enqueuedAt: new Date(),\n processedAt: null,\n },\n { session },\n )\n } catch (err: any) {\n if (err?.code !== 11000) throw err\n }\n }\n\n // -------------------------------------------------------------------------\n // Subscription / unsubscribe / tags / suppression\n // -------------------------------------------------------------------------\n\n async upsertSubscription(input: UpsertSubscriptionInput): Promise<void> {\n const parsed = upsertSubscriptionSchema.parse(input)\n const contact = await this.adapter.getById(parsed.externalId)\n if (!contact) throw new Error(`adapter has no contact for externalId ${parsed.externalId}`)\n\n const status = this.config.requireDoubleOptIn ? 'pending_doi' : 'subscribed'\n const now = new Date()\n\n // Generate a DOI token up front when DOI is required. We store its hash\n // (not the raw token) on the subscription doc for audit.\n let doiToken: string | null = null\n let doiTokenHash: string | null = null\n if (status === 'pending_doi') {\n const expiresAt = new Date(now.getTime() + this.config.doiTokenLifetimeDays * 86_400_000)\n doiToken = signDoiToken({ externalId: parsed.externalId, expiresAt }, this.config.unsubscribeSecret)\n doiTokenHash = sha256Hex(doiToken)\n }\n\n await this.collections.subscriptions.updateOne(\n { externalId: parsed.externalId },\n {\n $set: {\n status,\n source: parsed.source,\n emailAtSubscribe: contact.email,\n subscribedAt: status === 'subscribed' ? (parsed.consentTimestamp ?? now) : null,\n updatedAt: now,\n ...(doiTokenHash ? { doiTokenHash, doiRequestedAt: now } : {}),\n },\n $setOnInsert: {\n externalId: parsed.externalId,\n createdAt: now,\n unsubscribedAt: null,\n unsubscribeReason: null,\n doiTokenHash: null,\n doiRequestedAt: null,\n doiConfirmedAt: null,\n doiIp: parsed.consentIp ?? null,\n doiUserAgent: parsed.consentUserAgent ?? null,\n },\n },\n { upsert: true },\n )\n\n // Send the DOI confirmation email (best-effort — failures here don't\n // unwind the subscription; the host can poll pending DOI rows + re-fire).\n if (status === 'pending_doi' && doiToken) {\n const tpl = await this.collections.templates.findOne({ slug: this.config.doiTemplateSlug })\n if (!tpl) {\n console.warn(`mailery: DOI required but template \"${this.config.doiTemplateSlug}\" not found — skipping confirmation email`)\n return\n }\n const dedupeKey = `doi:${parsed.externalId}:${now.toISOString().slice(0, 10)}`\n try {\n await this.sendOneOff({\n templateSlug: tpl.slug,\n externalId: parsed.externalId,\n vars: { confirmDoiUrl: `${this.config.publicUrl}/m/confirm-doi/${doiToken}` },\n dedupeKey,\n })\n } catch (err) {\n console.error('mailery: DOI confirmation send failed', err)\n }\n }\n }\n\n async unsubscribe(email: string, opts: Omit<UnsubscribeInput, 'email'>): Promise<void> {\n const parsed = unsubscribeInputSchema.parse({ email, ...opts })\n const normalized = parsed.email\n const now = new Date()\n\n await this.collections.suppressions.updateOne(\n { email: normalized, scope: parsed.scope },\n {\n $setOnInsert: {\n email: normalized,\n emailHash: sha256Hex(normalized),\n scope: parsed.scope,\n // mailer_suppressions canonical reason — see plans/02-data-model.md.\n reason: 'unsubscribed' as const,\n source: parsed.source,\n notes: parsed.notes ?? null,\n addedAt: now,\n expiresAt: null,\n },\n },\n { upsert: true },\n )\n\n await this.collections.subscriptions.updateOne(\n { emailAtSubscribe: normalized },\n {\n $set: {\n status: 'unsubscribed' as const,\n unsubscribedAt: now,\n unsubscribeReason: parsed.reason,\n updatedAt: now,\n },\n },\n )\n }\n\n async suppress(email: string, opts: Omit<SuppressInput, 'email'>): Promise<void> {\n const parsed = suppressInputSchema.parse({ email, ...opts })\n await this.collections.suppressions.updateOne(\n { email: parsed.email, scope: parsed.scope },\n {\n $setOnInsert: {\n email: parsed.email,\n emailHash: sha256Hex(parsed.email),\n scope: parsed.scope,\n reason: parsed.reason,\n source: parsed.source,\n notes: parsed.notes ?? null,\n addedAt: new Date(),\n expiresAt: parsed.expiresAt ?? null,\n },\n },\n { upsert: true },\n )\n }\n\n async tag(externalId: string, tag: string): Promise<void> {\n const parsed = tagInputSchema.parse({ externalId, tag })\n if (this.adapter.addTags) {\n await this.adapter.addTags(parsed.externalId, [parsed.tag])\n } else {\n await this.collections.contactTags.updateOne(\n { externalId: parsed.externalId, tag: parsed.tag },\n {\n $setOnInsert: {\n externalId: parsed.externalId,\n tag: parsed.tag,\n appliedBy: 'admin',\n appliedAt: new Date(),\n },\n },\n { upsert: true },\n )\n }\n }\n\n async untag(externalId: string, tag: string): Promise<void> {\n const parsed = tagInputSchema.parse({ externalId, tag })\n if (this.adapter.removeTags) {\n await this.adapter.removeTags(parsed.externalId, [parsed.tag])\n } else {\n await this.collections.contactTags.deleteOne({ externalId: parsed.externalId, tag: parsed.tag })\n }\n }\n\n /**\n * GDPR right-to-erasure. Hard-deletes the contact's PII and leaves a hashed\n * suppression row to block re-import. INVARIANT 9.\n */\n async forget(externalId: string): Promise<void> {\n const sub = await this.collections.subscriptions.findOne({ externalId })\n const email = sub?.emailAtSubscribe?.toLowerCase()\n\n const collected = await Promise.all([\n this.collections.sends.find({ externalId }).map((s) => s.emailAtSend).toArray(),\n ])\n const emails = new Set<string>()\n if (email) emails.add(email)\n for (const e of collected[0]) if (e) emails.add(e.toLowerCase())\n\n await Promise.all([\n this.collections.events.deleteMany({ externalId }),\n this.collections.flowRuns.deleteMany({ externalId }),\n this.collections.sends.deleteMany({ externalId }),\n this.collections.subscriptions.deleteMany({ externalId }),\n this.collections.contactTags.deleteMany({ externalId }),\n ])\n if (email) {\n await this.collections.leads.deleteMany({ email })\n }\n\n for (const e of emails) {\n await this.collections.suppressions.updateOne(\n { emailHash: sha256Hex(e), scope: 'all' },\n {\n $setOnInsert: {\n email: null,\n emailHash: sha256Hex(e),\n scope: 'all',\n reason: 'gdpr_forget',\n source: 'gdpr_request',\n notes: null,\n addedAt: new Date(),\n expiresAt: null,\n },\n },\n { upsert: true },\n )\n }\n\n await this.audit({\n actor: 'system:gdpr',\n action: 'gdpr.forget',\n resource: { collection: 'mailer_subscriptions', id: sub?._id },\n diffSummary: `forget externalId=${externalId}`,\n })\n }\n\n /** GDPR data export. JSON-serializable. */\n async exportContactData(externalId: string): Promise<Record<string, unknown>> {\n const subscription = await this.collections.subscriptions.findOne({ externalId })\n const [events, flowRuns, sends, suppressions, tags] = await Promise.all([\n this.collections.events.find({ externalId }).toArray(),\n this.collections.flowRuns.find({ externalId }).toArray(),\n this.collections.sends.find({ externalId }).toArray(),\n subscription?.emailAtSubscribe\n ? this.collections.suppressions.find({ email: subscription.emailAtSubscribe }).toArray()\n : Promise.resolve([]),\n this.collections.contactTags.find({ externalId }).toArray(),\n ])\n return { subscription, events, flowRuns, sends, suppressions, tags }\n }\n\n // -------------------------------------------------------------------------\n // One-off transactional send (password reset etc.)\n // -------------------------------------------------------------------------\n\n async sendOneOff(input: SendOneOffInput): Promise<{ sendId: string }> {\n const parsed = sendOneOffInputSchema.parse(input)\n const template = await this.collections.templates.findOne({ slug: parsed.templateSlug })\n if (!template) throw new Error(`template not found: ${parsed.templateSlug}`)\n\n const contact = await this.adapter.getById(parsed.externalId)\n if (!contact) throw new Error(`contact not found: ${parsed.externalId}`)\n\n const dedupeKey = `oneoff:${parsed.dedupeKey}`\n const existing = await this.collections.sends.findOne({ dedupeKey })\n if (existing) return { sendId: String(existing._id) }\n\n const providerName =\n parsed.providerOverride\n ?? template.providerOverride\n ?? (template.kind === 'transactional' ? this.config.defaultTransactionalProvider : null)\n ?? this.config.defaultProvider\n\n const sendId = new ObjectIdCtor()\n await this.collections.sends.insertOne({\n _id: sendId,\n dedupeKey,\n externalId: parsed.externalId,\n emailAtSend: contact.email,\n templateId: template._id!,\n templateSlug: template.slug,\n flowRunId: null,\n broadcastId: null,\n manualSendBy: 'sendOneOff',\n kind: template.kind,\n provider: providerName,\n providerMessageId: null,\n fromName: template.fromName,\n fromEmail: template.fromEmail,\n subject: template.subject,\n bodyHash: '',\n status: 'queued',\n errorMessage: null,\n bounceType: null,\n bounceReason: null,\n links: [],\n vars: parsed.vars ?? {},\n openedAt: null,\n openCount: 0,\n firstClickAt: null,\n clickCount: 0,\n clickedLinks: [],\n unsubscribedAt: null,\n complainedAt: null,\n queuedAt: new Date(),\n updatedAt: new Date(),\n sentAt: null,\n deliveredAt: null,\n })\n\n await this.queues.send.add(\n 'send',\n { sendId: String(sendId) },\n { attempts: this.config.sendRetryAttempts, backoff: { type: 'exponential', delay: 60_000 } },\n )\n\n return { sendId: String(sendId) }\n }\n\n // -------------------------------------------------------------------------\n // Audit log helper\n // -------------------------------------------------------------------------\n\n async audit(entry: {\n actor: string\n action: string\n resource: { collection: string; id?: string | ObjectId; slug?: string }\n before?: Record<string, unknown> | null\n after?: Record<string, unknown> | null\n diffSummary?: string\n ip?: string\n userAgent?: string\n requestId?: string\n }): Promise<void> {\n await this.collections.auditLog.insertOne({\n actor: entry.actor,\n action: entry.action,\n resource: entry.resource,\n before: entry.before ?? null,\n after: entry.after ?? null,\n diffSummary: entry.diffSummary ?? null,\n ip: entry.ip ?? null,\n userAgent: entry.userAgent ?? null,\n requestId: entry.requestId ?? null,\n occurredAt: new Date(),\n })\n }\n\n // -------------------------------------------------------------------------\n // Workers\n // -------------------------------------------------------------------------\n\n async startWorkers(): Promise<void> {\n if (this.workersStarted) return\n if (this.config.queue.driver === 'noop') {\n throw new Error('startWorkers requires a non-noop queue driver')\n }\n const provider = this.providers[this.config.defaultProvider]\n const sendRate = provider?.sendRatePerSecond ?? this.config.sendRatePerSecond\n\n await this.queueDriver.startWorkers({\n concurrency: { send: this.config.sendConcurrency },\n sendRateLimit: { max: sendRate, durationMs: 1_000 },\n retryAttempts: this.config.sendRetryAttempts,\n handlers: {\n tick: async () => {\n await runTick(this.runnerContext)\n },\n advance: async (data) => {\n if (!ObjectIdCtor.isValid(data.flowRunId)) return\n await processOneRunStep(new ObjectIdCtor(data.flowRunId), this.runnerContext)\n },\n send: async (data) => {\n if (!ObjectIdCtor.isValid(data.sendId)) return\n await dispatchSend(new ObjectIdCtor(data.sendId), this.runnerContext)\n },\n webhook: async () => {\n await this.processWebhookBacklog()\n },\n },\n })\n this.workersStarted = true\n }\n\n /** Process unprocessed webhook events in mailer_webhook_events. */\n private async processWebhookBacklog(): Promise<void> {\n const batch = await this.collections.webhookEvents\n .find({ processed: false })\n .limit(500)\n .toArray()\n\n for (const evt of batch) {\n try {\n // The stored `raw` wraps the normalized event we captured at ingest;\n // pull details back out so applyWebhookEvent has the bounce reason etc.\n const normalized = (evt.raw as any)?.normalized\n const details = normalized?.details ?? {}\n await applyWebhookEvent(\n {\n type: evt.normalizedType,\n providerEventId: evt.providerEventId,\n providerMessageId: evt.providerMessageId,\n email: evt.email,\n occurredAt: evt.occurredAt,\n details,\n },\n this.runnerContext,\n )\n await this.collections.webhookEvents.updateOne({ _id: evt._id }, { $set: { processed: true } })\n } catch (err) {\n console.error('mailery: webhook apply failed', { id: String(evt._id), err })\n }\n }\n }\n\n async stop(): Promise<void> {\n await this.queueDriver.close()\n this.workersStarted = false\n }\n\n /** Used internally by the admin router and tests; not part of the public API. */\n getRunnerContext(): RunnerContext {\n return this.runnerContext\n }\n}\n","/**\n * Sender-domain validator.\n *\n * Hosts may declare a `senderDomains` registry mapping a domain to which kind\n * of email is allowed to send from it. Used to isolate marketing reputation\n * from transactional reputation:\n *\n * senderDomains: {\n * 'news.example.com': { kind: 'marketing' },\n * 'mail.example.com': { kind: 'transactional' },\n * 'tools.example.com': { kind: 'both' }, // OK for either kind\n * }\n *\n * The check runs at template publish time. If a template's `fromEmail` domain\n * isn't declared, or is declared for the wrong kind, publish fails with a\n * descriptive 400. Hosts who don't set `senderDomains` get no enforcement —\n * back-compat default.\n */\n\nimport type { TemplateKind } from '../../shared/enums.js'\n\nexport interface SenderDomainConfig {\n /** Which template `kind` may use this domain as a From address. */\n kind: 'marketing' | 'transactional' | 'both'\n}\n\nexport type SenderDomainRegistry = Record<string, SenderDomainConfig>\n\nexport type SenderDomainValidation =\n | { ok: true }\n | { ok: false; code: 'invalid_email' | 'unregistered_domain' | 'wrong_kind'; reason: string }\n\nexport function validateSenderDomain(\n fromEmail: string,\n templateKind: TemplateKind,\n registry: SenderDomainRegistry | undefined,\n): SenderDomainValidation {\n if (!registry || Object.keys(registry).length === 0) return { ok: true }\n\n const domain = extractDomain(fromEmail)\n if (!domain) {\n return {\n ok: false,\n code: 'invalid_email',\n reason: `invalid fromEmail \"${fromEmail}\" — expected \"name@domain\"`,\n }\n }\n\n const entry = registry[domain]\n if (!entry) {\n const known = Object.keys(registry).join(', ')\n return {\n ok: false,\n code: 'unregistered_domain',\n reason: `sender domain \"${domain}\" is not declared in senderDomains (allowed: ${known})`,\n }\n }\n\n if (entry.kind === 'both') return { ok: true }\n if (entry.kind !== templateKind) {\n return {\n ok: false,\n code: 'wrong_kind',\n reason: `sender domain \"${domain}\" is configured for ${entry.kind} email, but this template's kind is ${templateKind}`,\n }\n }\n\n return { ok: true }\n}\n\nfunction extractDomain(email: string): string | null {\n if (typeof email !== 'string') return null\n const at = email.lastIndexOf('@')\n if (at <= 0 || at === email.length - 1) return null\n return email.slice(at + 1).toLowerCase().trim()\n}\n","/**\n * Public exports for the `mailery` package.\n */\n\nexport const VERSION = '0.1.0'\n\n// Core\nexport { Mailer } from './mailer.js'\nexport type { MailerConfig, RedisOptions, CircuitBreakerThresholds, SenderDomainConfig, SenderDomainRegistry } from './config.js'\nexport { validateSenderDomain } from './templates/sender-domain.js'\nexport type { SenderDomainValidation } from './templates/sender-domain.js'\n\n// Adapters\nexport { MongoContactAdapter } from './adapters/mongo.js'\nexport type { MongoContactAdapterOptions } from './adapters/mongo.js'\n\n// Providers\nexport { NullProvider } from './providers/null.js'\nexport { SendGridProvider } from './providers/sendgrid.js'\nexport type { SendGridProviderOptions } from './providers/sendgrid.js'\n\n// HTTP routers\nexport { createAdminRouter } from './api/admin.js'\nexport type { AdminRouterOptions } from './api/admin.js'\nexport { createPublicRouter } from './api/public.js'\nexport type { PublicRouterOptions } from './api/public.js'\n\n// Templates (host apps may want compile + render directly for previews)\nexport {\n compileTemplate,\n compileMailyTemplate,\n derivePlaintext,\n renderTemplate,\n applyTracking,\n} from './templates/render.js'\n\n// Runner internals — exported so test harnesses and advanced hosts can drive\n// the runner inline. In production let `startWorkers()` invoke these.\nexport {\n runTick,\n processOneRunStep,\n dispatchSend,\n applyWebhookEvent,\n processNewlyFiredEventTriggers,\n sweepStrandedFlowRuns,\n} from './runner/index.js'\n\n// Models (collection helpers, in case hosts need to query directly)\nexport { getCollections, ensureIndexes } from './models/index.js'\nexport type {\n Collections,\n SubscriptionDoc,\n EventDoc,\n FlowDoc,\n FlowRunDoc,\n TemplateDoc,\n SendDoc,\n SuppressionDoc,\n BroadcastDoc,\n AuditLogDoc,\n WebhookEventDoc,\n HealthDoc,\n ContactTagDoc,\n LeadDoc,\n OutboxDoc,\n FlowVersionDoc,\n TemplateVersionDoc,\n} from './models/index.js'\n\n// Token helpers (rarely needed by hosts, useful for tests)\nexport { signUnsubscribeToken, verifyUnsubscribeToken, sha256Hex } from './tokens.js'\n\n// Shared types\nexport type {\n Contact,\n ContactAdapter,\n AdapterFilter,\n MailProvider,\n SendArgs,\n SendResult,\n NormalizedEvent,\n FlowStep,\n Predicate,\n SegmentDefinition,\n SegmentFilter,\n} from '../shared/types.js'\n\nexport type {\n SubscriptionStatus,\n SendStatus,\n TemplateKind,\n SuppressionScope,\n SuppressionReason,\n FlowRunStatus,\n BroadcastStatus,\n HealthStatus,\n FlowGoal,\n} from '../shared/enums.js'\n\n// Option lists for tooling / admin UIs — flow step kinds, predicate kinds,\n// segment filter kinds, dedupe policies.\nexport {\n FLOW_STEP_KINDS,\n defaultFlowStep,\n PREDICATE_KINDS,\n defaultPredicate,\n predicateKind,\n SEGMENT_FILTER_KINDS,\n defaultSegmentFilter,\n DEDUPE_POLICIES,\n} from '../shared/options.js'\nexport type {\n FlowStepKindOption,\n PredicateKindOption,\n PredicateKind,\n SegmentFilterKindOption,\n SegmentFilterKind,\n DedupePolicyOption,\n} from '../shared/options.js'\n","/**\n * NullProvider — in-memory provider for tests and dev. Records every send\n * without dispatching anything. Inspect `.sent` to assert what would have\n * been delivered.\n */\n\nimport type { MailProvider, NormalizedEvent, SendArgs, SendResult } from '../../shared/types.js'\n\nlet counter = 0\n\nexport class NullProvider implements MailProvider {\n readonly name = 'null'\n readonly sendRatePerSecond = 1000\n public readonly sent: SendArgs[] = []\n\n async send(args: SendArgs): Promise<SendResult> {\n this.sent.push(args)\n return {\n providerId: `null-${Date.now()}-${++counter}`,\n status: 'accepted',\n }\n }\n\n async verifyWebhook(): Promise<boolean> {\n return true\n }\n\n parseWebhookEvents(): NormalizedEvent[] {\n return []\n }\n\n reset(): void {\n this.sent.length = 0\n }\n}\n","/**\n * Setup-status: a small suite of synchronous checks the admin dashboard\n * surfaces as a banner. Each check returns an `ok | warn | error` verdict\n * with a short message and optional hint. The endpoint exists to catch the\n * \"silent misconfiguration that breaks sends\" class of bug — missing DOI\n * template, workers not running, fromDefaults on a domain that doesn't pass\n * the senderDomains registry, etc.\n */\n\nimport type { Mailer } from '../mailer.js'\nimport { validateSenderDomain } from '../templates/sender-domain.js'\n\nexport type CheckSeverity = 'ok' | 'warn' | 'error'\n\nexport interface SetupCheck {\n /** Stable identifier, e.g. 'mongo', 'workers_heartbeat'. */\n name: string\n /** Human-readable label, e.g. \"MongoDB connection\". */\n label: string\n severity: CheckSeverity\n message: string\n /** Optional remediation hint shown when the user expands the row. */\n hint?: string\n}\n\nexport interface SetupStatus {\n overall: CheckSeverity\n generatedAt: string\n checks: SetupCheck[]\n}\n\nexport async function runSetupChecks(mailer: Mailer): Promise<SetupStatus> {\n const checks: SetupCheck[] = []\n\n checks.push(await checkMongo(mailer))\n checks.push(await checkQueue(mailer))\n if (mailer.config.queue.driver !== 'noop' && !mailer.config.workerless) {\n checks.push(await checkWorkersHeartbeat(mailer))\n }\n checks.push(await checkCircuitBreaker(mailer))\n checks.push(...checkFromDefaultsAgainstRegistry(mailer))\n checks.push(...(await checkPublishedTemplates(mailer)))\n checks.push(await checkPostalAddress(mailer))\n checks.push(await checkDoiTemplate(mailer))\n\n const overall: CheckSeverity = checks.some((c) => c.severity === 'error')\n ? 'error'\n : checks.some((c) => c.severity === 'warn')\n ? 'warn'\n : 'ok'\n\n return {\n overall,\n generatedAt: new Date().toISOString(),\n checks,\n }\n}\n\nasync function checkMongo(mailer: Mailer): Promise<SetupCheck> {\n try {\n await mailer.db.admin().ping()\n return { name: 'mongo', label: 'MongoDB connection', severity: 'ok', message: 'reachable' }\n } catch (err) {\n return {\n name: 'mongo',\n label: 'MongoDB connection',\n severity: 'error',\n message: `MongoDB ping failed: ${(err as Error)?.message ?? err}`,\n hint: 'Mailery is configured against an unreachable Mongo. Sends, flow advancement, and admin reads will all fail.',\n }\n }\n}\n\nasync function checkQueue(mailer: Mailer): Promise<SetupCheck> {\n const driver = mailer.config.queue.driver\n if (driver === 'noop') {\n return {\n name: 'queue',\n label: 'Queue driver',\n severity: 'ok',\n message: 'driver: noop (synchronous-only mode)',\n }\n }\n try {\n await mailer.queues.send.getWaitingCount()\n return { name: 'queue', label: 'Queue driver', severity: 'ok', message: `driver: ${driver}` }\n } catch (err) {\n return {\n name: 'queue',\n label: 'Queue driver',\n severity: 'error',\n message: `${driver} queue is not responding: ${(err as Error)?.message ?? err}`,\n hint:\n driver === 'bull'\n ? 'Check Redis connectivity (queue.redis.url).'\n : 'Check the @hokify/agenda + Mongo connection.',\n }\n }\n}\n\nasync function checkWorkersHeartbeat(mailer: Mailer): Promise<SetupCheck> {\n const h = await mailer.collections.health.findOne({ _id: 'singleton' })\n const tickIntervalMs = mailer.config.tickIntervalSeconds * 1000\n const staleAfterMs = Math.max(tickIntervalMs * 3, 30_000) // tolerate a couple missed ticks\n\n if (!h) {\n return {\n name: 'workers_heartbeat',\n label: 'Background workers',\n severity: 'warn',\n message: 'no tick has run yet',\n hint: 'If your separate worker process is started, the heartbeat will appear within one tick interval. If you forgot to run `mailer.startWorkers()`, sends will sit queued indefinitely.',\n }\n }\n\n const ageMs = Date.now() - new Date(h.updatedAt).getTime()\n if (ageMs > staleAfterMs) {\n return {\n name: 'workers_heartbeat',\n label: 'Background workers',\n severity: 'error',\n message: `last tick ${humanDuration(ageMs)} ago (expected within ${humanDuration(tickIntervalMs)})`,\n hint: 'Workers appear to be down. Sends and flow advancement are halted. Restart your worker process (`mailer.startWorkers()`).',\n }\n }\n return {\n name: 'workers_heartbeat',\n label: 'Background workers',\n severity: 'ok',\n message: `last tick ${humanDuration(ageMs)} ago`,\n }\n}\n\nasync function checkCircuitBreaker(mailer: Mailer): Promise<SetupCheck> {\n const h = await mailer.collections.health.findOne({ _id: 'singleton' })\n if (!h || h.status === 'healthy') {\n return { name: 'circuit_breaker', label: 'Circuit breaker', severity: 'ok', message: 'healthy' }\n }\n if (h.status === 'degraded') {\n return {\n name: 'circuit_breaker',\n label: 'Circuit breaker',\n severity: 'warn',\n message: 'degraded (high failure rate)',\n hint: 'Marketing sends still flow but failure rate is above the degraded threshold. Investigate provider errors before they escalate to tripped.',\n }\n }\n return {\n name: 'circuit_breaker',\n label: 'Circuit breaker',\n severity: 'error',\n message: `tripped: ${h.trippedReason ?? 'unknown reason'}`,\n hint: 'Marketing sends are held. Investigate the underlying bounce / complaint cause, then POST /api/health/resume.',\n }\n}\n\nfunction checkFromDefaultsAgainstRegistry(mailer: Mailer): SetupCheck[] {\n const registry = mailer.config.senderDomains\n if (!registry || Object.keys(registry).length === 0) return []\n\n const out: SetupCheck[] = []\n const from = mailer.config.fromDefaults?.email\n const tx = mailer.config.transactionalFromDefaults?.email\n\n if (from) {\n const r = validateSenderDomain(from, 'marketing', registry)\n if (!r.ok) {\n out.push({\n name: 'from_defaults_marketing',\n label: 'fromDefaults vs senderDomains',\n severity: 'error',\n message: r.reason,\n hint: 'New marketing templates that fall back to fromDefaults will fail to publish.',\n })\n }\n }\n\n if (tx) {\n const r = validateSenderDomain(tx, 'transactional', registry)\n if (!r.ok) {\n out.push({\n name: 'transactional_from_defaults',\n label: 'transactionalFromDefaults vs senderDomains',\n severity: 'error',\n message: r.reason,\n hint: 'New transactional templates that fall back to transactionalFromDefaults will fail to publish.',\n })\n }\n } else if (from) {\n // No transactional defaults set; transactional creates will fall back to\n // fromDefaults. Check whether that fallback is valid for transactional.\n const r = validateSenderDomain(from, 'transactional', registry)\n if (!r.ok) {\n out.push({\n name: 'transactional_fallback',\n label: 'Transactional fallback',\n severity: 'warn',\n message: `transactionalFromDefaults is unset and fromDefaults (${from}) is invalid for transactional templates`,\n hint: 'Set transactionalFromDefaults to a transactional-kind domain, or set senderDomains entry for the existing one to \"both\".',\n })\n }\n }\n\n return out\n}\n\nasync function checkPublishedTemplates(mailer: Mailer): Promise<SetupCheck[]> {\n const registry = mailer.config.senderDomains\n if (!registry || Object.keys(registry).length === 0) return []\n\n const published = await mailer.collections.templates\n .find({ publishedAt: { $ne: null } }, { projection: { slug: 1, kind: 1, fromEmail: 1 } })\n .toArray()\n\n const broken: Array<{ slug: string; reason: string }> = []\n for (const tpl of published) {\n const r = validateSenderDomain(tpl.fromEmail, tpl.kind, registry)\n if (!r.ok) broken.push({ slug: tpl.slug, reason: r.reason })\n }\n\n if (broken.length === 0) return []\n const list = broken.slice(0, 5).map((b) => `${b.slug} (${b.reason})`).join('; ')\n const more = broken.length > 5 ? ` …and ${broken.length - 5} more` : ''\n return [\n {\n name: 'published_template_domains',\n label: 'Published templates',\n severity: 'error',\n message: `${broken.length} published template${broken.length === 1 ? '' : 's'} use a fromEmail that no longer matches senderDomains: ${list}${more}`,\n hint: 'These templates will still send with their stored fromEmail until re-published. Edit each template and republish to surface the validation, or update senderDomains.',\n },\n ]\n}\n\nasync function checkPostalAddress(mailer: Mailer): Promise<SetupCheck> {\n if (mailer.config.senderAddress) {\n return { name: 'postal_address', label: 'CAN-SPAM postal address', severity: 'ok', message: 'set' }\n }\n const marketingCount = await mailer.collections.templates.countDocuments({\n kind: 'marketing',\n publishedAt: { $ne: null },\n })\n if (marketingCount === 0) {\n return { name: 'postal_address', label: 'CAN-SPAM postal address', severity: 'ok', message: 'no published marketing templates yet' }\n }\n return {\n name: 'postal_address',\n label: 'CAN-SPAM postal address',\n severity: 'warn',\n message: `${marketingCount} published marketing template${marketingCount === 1 ? '' : 's'} but senderAddress is unset`,\n hint: 'CAN-SPAM requires a postal address in marketing emails. Set `senderAddress` in your Mailer config and reference it via `{{senderAddress}}` in your templates.',\n }\n}\n\nasync function checkDoiTemplate(mailer: Mailer): Promise<SetupCheck> {\n if (!mailer.config.requireDoubleOptIn) {\n return { name: 'doi_template', label: 'DOI template', severity: 'ok', message: 'DOI not required' }\n }\n const tpl = await mailer.collections.templates.findOne({\n slug: mailer.config.doiTemplateSlug,\n publishedAt: { $ne: null },\n })\n if (tpl) {\n return { name: 'doi_template', label: 'DOI template', severity: 'ok', message: `template \"${tpl.slug}\" published` }\n }\n return {\n name: 'doi_template',\n label: 'DOI template',\n severity: 'error',\n message: `requireDoubleOptIn is true but no published template with slug \"${mailer.config.doiTemplateSlug}\"`,\n hint: 'New subscriptions will silently fail to send confirmation emails. Create and publish a template with this slug, or unset requireDoubleOptIn.',\n }\n}\n\nfunction humanDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`\n if (ms < 60_000) return `${Math.round(ms / 1000)}s`\n if (ms < 3_600_000) return `${Math.round(ms / 60_000)}m`\n return `${Math.round(ms / 3_600_000)}h`\n}\n","/**\n * Admin router — serves the prebuilt React SPA + REST endpoints the SPA\n * consumes. Mount inside a host Express app, gated by host auth.\n *\n * app.use('/admin/mailer', requireAdmin, createAdminRouter(mailer))\n *\n * REST routes under /api/* are documented in plans/14-admin-api.md.\n */\n\nimport express, { Router, type Request, type Response, type NextFunction } from 'express'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { ObjectId } from 'mongodb'\n\nimport type { Mailer } from '../mailer.js'\nimport {\n applyTracking,\n compileMailyTemplate,\n compileTemplate,\n renderTemplate,\n} from '../templates/render.js'\nimport { validateSenderDomain } from '../templates/sender-domain.js'\nimport { runSetupChecks } from './setup-status.js'\nimport { signUnsubscribeToken } from '../tokens.js'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\nfunction defaultSpaDir(): string {\n // After tsup build: dist/index.{js,cjs} + dist/admin/spa/. __dirname = dist/.\n return path.resolve(__dirname, 'admin/spa')\n}\n\nexport interface AdminRouterOptions {\n /** Override path to the built SPA. Defaults to `dist/admin/spa` shipped with the package. */\n spaDir?: string\n /** Resolve actor metadata from a Request. Defaults to `human:${req.user?.email || 'anonymous'}`. */\n getActor?: (req: Request) => string\n}\n\nexport function createAdminRouter(mailer: Mailer, opts: AdminRouterOptions = {}): Router {\n const router = Router()\n const spaDir = opts.spaDir ?? defaultSpaDir()\n const getActor =\n opts.getActor ?? ((req: Request) => `human:${(req as any).user?.email ?? 'anonymous'}`)\n\n // Static assets — long cache, hashed filenames.\n router.use(\n '/_assets',\n express.static(spaDir, {\n maxAge: '1y',\n immutable: true,\n index: false,\n }),\n )\n\n // JSON body parsing for mutating endpoints.\n router.use('/api', express.json({ limit: '1mb' }))\n\n // Inject actor on every API request (read after the host's auth middleware).\n router.use('/api', (req: Request, _res, next: NextFunction) => {\n ;(req as any).actor = getActor(req)\n next()\n })\n\n router.use('/api', apiRouter(mailer))\n\n // SPA shell — any other route returns index.html so client-side routing\n // doesn't 404 on refresh.\n router.get(/.*/, (_req: Request, res: Response) => {\n res.sendFile(path.join(spaDir, 'index.html'))\n })\n\n return router\n}\n\n// ---------------------------------------------------------------------------\n// JSON API\n// ---------------------------------------------------------------------------\n\nfunction apiRouter(mailer: Mailer): Router {\n const r = Router()\n const c = mailer.collections\n\n r.get('/me', (req, res) => {\n res.json({\n actor: (req as any).actor,\n permissions: { canPublish: true, canSendBroadcasts: true, canManageSuppressions: true },\n })\n })\n\n // ----- Dashboard ----------------------------------------------------------\n r.get(\n '/dashboard',\n asyncHandler(async (_req, res) => {\n const since24h = new Date(Date.now() - 24 * 60 * 60 * 1000)\n const [sentTotal, deliveredCount, bouncedCount, openedCount, clickedCount] = await Promise.all([\n c.sends.countDocuments({ queuedAt: { $gt: since24h } }),\n c.sends.countDocuments({ queuedAt: { $gt: since24h }, status: 'delivered' }),\n c.sends.countDocuments({ queuedAt: { $gt: since24h }, status: 'bounced' }),\n c.sends.countDocuments({ queuedAt: { $gt: since24h }, openedAt: { $ne: null } }),\n c.sends.countDocuments({ queuedAt: { $gt: since24h }, firstClickAt: { $ne: null } }),\n ])\n\n const health = await c.health.findOne({ _id: 'singleton' })\n const recentFlows = await c.flows.find({ enabled: true }).limit(5).toArray()\n const recentSends = await c.sends.find().sort({ queuedAt: -1 }).limit(6).toArray()\n const recentAudit = await c.auditLog.find().sort({ occurredAt: -1 }).limit(5).toArray()\n\n res.json({\n kpis: {\n sends: { value: sentTotal, delta: null },\n deliveredRate: {\n value: sentTotal === 0 ? 1 : deliveredCount / sentTotal,\n delta: null,\n bounced: bouncedCount,\n },\n openRate: { value: sentTotal === 0 ? 0 : openedCount / sentTotal, delta: null, exclBots: false },\n clickRate: { value: sentTotal === 0 ? 0 : clickedCount / sentTotal, delta: null },\n },\n health: health\n ? { status: health.status, rates: health.rates }\n : {\n status: 'healthy',\n rates: { hardBounceRate: 0, complaintRate: 0, combinedBounceRate: 0, failureRate: 0 },\n },\n queue: { inFlight: 0, delayed: 0, providerOk: true, providerName: mailer.config.defaultProvider },\n recentFlows,\n recentSends,\n recentAudit,\n })\n }),\n )\n\n // ----- Flows --------------------------------------------------------------\n r.get(\n '/flows',\n asyncHandler(async (_req, res) => {\n const flows = await c.flows.find().sort({ updatedAt: -1 }).toArray()\n res.json(flows)\n }),\n )\n\n r.get(\n '/flows/:slug',\n asyncHandler(async (req, res) => {\n const flow = await c.flows.findOne({ slug: req.params.slug })\n if (!flow) return res.status(404).json({ error: 'not_found' })\n return res.json(flow)\n }),\n )\n\n r.post(\n '/flows/:slug/pause',\n asyncHandler(async (req, res) => {\n const before = await c.flows.findOne({ slug: req.params.slug })\n if (!before) return res.status(404).json({ error: 'not_found' })\n await c.flows.updateOne({ _id: before._id }, { $set: { enabled: false, updatedAt: new Date() } })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'flow.pause',\n resource: { collection: 'mailer_flows', id: before._id, slug: before.slug },\n })\n return res.json({ ok: true })\n }),\n )\n\n r.post(\n '/flows/:slug/resume',\n asyncHandler(async (req, res) => {\n const before = await c.flows.findOne({ slug: req.params.slug })\n if (!before) return res.status(404).json({ error: 'not_found' })\n await c.flows.updateOne({ _id: before._id }, { $set: { enabled: true, updatedAt: new Date() } })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'flow.resume',\n resource: { collection: 'mailer_flows', id: before._id, slug: before.slug },\n })\n return res.json({ ok: true })\n }),\n )\n\n // ----- Templates ----------------------------------------------------------\n r.get(\n '/templates',\n asyncHandler(async (_req, res) => {\n const templates = await c.templates.find().sort({ updatedAt: -1 }).toArray()\n res.json(templates)\n }),\n )\n\n r.get(\n '/templates/:slug',\n asyncHandler(async (req, res) => {\n const template = await c.templates.findOne({ slug: req.params.slug })\n if (!template) return res.status(404).json({ error: 'not_found' })\n return res.json(template)\n }),\n )\n\n // ----- Broadcasts ---------------------------------------------------------\n r.get(\n '/broadcasts',\n asyncHandler(async (_req, res) => {\n const broadcasts = await c.broadcasts.find().sort({ createdAt: -1 }).toArray()\n res.json(broadcasts)\n }),\n )\n\n r.get(\n '/broadcasts/:slug',\n asyncHandler(async (req, res) => {\n const broadcast = await c.broadcasts.findOne({ slug: req.params.slug })\n if (!broadcast) return res.status(404).json({ error: 'not_found' })\n return res.json(broadcast)\n }),\n )\n\n // ----- Contacts -----------------------------------------------------------\n r.get(\n '/contacts',\n asyncHandler(async (req, res) => {\n const cursor = typeof req.query.cursor === 'string' ? req.query.cursor : undefined\n const limit = Math.min(Number(req.query.limit ?? 50), 200)\n const { contacts, nextCursor } = await mailer.adapter.query({}, { limit, cursor })\n res.json({ contacts, nextCursor })\n }),\n )\n\n r.get(\n '/contacts/:externalId',\n asyncHandler(async (req, res) => {\n const externalId = String(req.params.externalId)\n const [contact, subscription, recentEvents, recentSends, activeRuns] = await Promise.all([\n mailer.adapter.getById(externalId),\n c.subscriptions.findOne({ externalId }),\n c.events.find({ externalId }).sort({ occurredAt: -1 }).limit(50).toArray(),\n c.sends.find({ externalId }).sort({ queuedAt: -1 }).limit(50).toArray(),\n c.flowRuns.find({ externalId, status: 'active' }).toArray(),\n ])\n if (!contact) return res.status(404).json({ error: 'not_found' })\n return res.json({ contact, subscription, recentEvents, recentSends, activeRuns })\n }),\n )\n\n // ----- Sends --------------------------------------------------------------\n r.get(\n '/sends',\n asyncHandler(async (req, res) => {\n const limit = Math.min(Number(req.query.limit ?? 100), 500)\n const status = typeof req.query.status === 'string' ? req.query.status : undefined\n const filter: any = {}\n if (status) filter.status = status\n const sends = await c.sends.find(filter).sort({ queuedAt: -1 }).limit(limit).toArray()\n res.json(sends)\n }),\n )\n\n r.get(\n '/sends/:id',\n asyncHandler(async (req, res) => {\n const id = String(req.params.id)\n if (!ObjectId.isValid(id)) return res.status(400).json({ error: 'bad_id' })\n const send = await c.sends.findOne({ _id: new ObjectId(id) })\n if (!send) return res.status(404).json({ error: 'not_found' })\n const events = send.providerMessageId\n ? await c.webhookEvents.find({ providerMessageId: send.providerMessageId }).toArray()\n : []\n return res.json({ send, webhookEvents: events })\n }),\n )\n\n // ----- Suppressions -------------------------------------------------------\n r.get(\n '/suppressions',\n asyncHandler(async (_req, res) => {\n const rows = await c.suppressions.find().sort({ addedAt: -1 }).limit(500).toArray()\n res.json(rows)\n }),\n )\n\n r.post(\n '/suppressions',\n asyncHandler(async (req, res) => {\n const { email, scope, reason, source, notes } = req.body ?? {}\n await mailer.suppress(email, { scope, reason, source, notes })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'suppression.add',\n resource: { collection: 'mailer_suppressions' },\n diffSummary: `${email} → ${scope}/${reason}`,\n })\n res.json({ ok: true })\n }),\n )\n\n // ----- Audit log ----------------------------------------------------------\n r.get(\n '/audit',\n asyncHandler(async (_req, res) => {\n const rows = await c.auditLog.find().sort({ occurredAt: -1 }).limit(200).toArray()\n res.json(rows)\n }),\n )\n\n // ----- Setup status -------------------------------------------------------\n r.get(\n '/setup-status',\n asyncHandler(async (_req, res) => {\n const status = await runSetupChecks(mailer)\n res.json(status)\n }),\n )\n\n // ----- Health -------------------------------------------------------------\n r.get(\n '/health',\n asyncHandler(async (_req, res) => {\n const h = await c.health.findOne({ _id: 'singleton' })\n res.json(\n h ?? {\n _id: 'singleton',\n status: 'healthy',\n windowStartedAt: new Date(Date.now() - 60 * 60 * 1000),\n windowDurationMs: 60 * 60 * 1000,\n counters: { sent: 0, delivered: 0, bounced: 0, hardBounced: 0, softBounced: 0, complained: 0, failedToSend: 0 },\n rates: { bounceRate: 0, hardBounceRate: 0, complaintRate: 0, failureRate: 0 },\n },\n )\n }),\n )\n\n r.post(\n '/health/resume',\n asyncHandler(async (req, res) => {\n await c.health.updateOne(\n { _id: 'singleton' },\n { $set: { status: 'healthy', manuallyResumedAt: new Date(), updatedAt: new Date() } },\n )\n await mailer.audit({\n actor: (req as any).actor,\n action: 'health.resume',\n resource: { collection: 'mailer_health' },\n })\n res.json({ ok: true })\n }),\n )\n\n // ----- Flows: create / edit / publish ------------------------------------\n r.post(\n '/flows',\n asyncHandler(async (req, res) => {\n const { slug, name, description, trigger, goal, audience } = req.body ?? {}\n if (!slug || !name || !trigger?.eventName) {\n return res.status(400).json({ error: 'validation_failed', message: 'slug, name, and trigger.eventName required' })\n }\n const now = new Date()\n const doc = {\n slug,\n name,\n description: description ?? '',\n trigger: { type: 'event' as const, eventName: trigger.eventName, once: trigger.once !== false },\n enabled: false,\n steps: [],\n version: 0,\n draft: {\n steps: [],\n notes: 'Initial draft',\n lastModifiedBy: (req as any).actor ?? 'unknown',\n lastModifiedAt: now,\n },\n goal: goal ?? 'activation',\n audience: audience ?? '',\n expectedVolumePerWeek: null,\n stats: { activeRuns: 0, completedRuns: 0, sendsTotal: 0, sendsLast7Days: 0 },\n lastTriggerScanAt: null,\n publishedAt: null,\n publishedBy: null,\n createdAt: now,\n updatedAt: now,\n }\n try {\n await c.flows.insertOne(doc as any)\n } catch (err: any) {\n if (err?.code === 11000) return res.status(409).json({ error: 'slug_taken' })\n throw err\n }\n await mailer.audit({\n actor: (req as any).actor,\n action: 'flow.create',\n resource: { collection: 'mailer_flows', slug },\n })\n return res.json({ ok: true, slug })\n }),\n )\n\n r.patch(\n '/flows/:slug/draft',\n asyncHandler(async (req, res) => {\n const flow = await c.flows.findOne({ slug: req.params.slug })\n if (!flow) return res.status(404).json({ error: 'not_found' })\n const { steps, notes, trigger, name, description, goal, audience } = req.body ?? {}\n\n const set: Record<string, unknown> = {\n 'draft.lastModifiedBy': (req as any).actor,\n 'draft.lastModifiedAt': new Date(),\n updatedAt: new Date(),\n }\n if (Array.isArray(steps)) set['draft.steps'] = steps\n if (typeof notes === 'string') set['draft.notes'] = notes\n if (trigger?.eventName) set.trigger = { type: 'event' as const, eventName: trigger.eventName, once: trigger.once !== false }\n if (typeof name === 'string') set.name = name\n if (typeof description === 'string') set.description = description\n if (typeof goal === 'string') set.goal = goal\n if (typeof audience === 'string') set.audience = audience\n\n await c.flows.updateOne({ _id: flow._id }, { $set: set })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'flow.draft.update',\n resource: { collection: 'mailer_flows', id: flow._id, slug: flow.slug },\n diffSummary: `Updated draft (${steps ? `${steps.length} steps` : 'metadata only'})`,\n })\n return res.json({ ok: true })\n }),\n )\n\n r.post(\n '/flows/:slug/publish',\n asyncHandler(async (req, res) => {\n const flow = await c.flows.findOne({ slug: req.params.slug })\n if (!flow) return res.status(404).json({ error: 'not_found' })\n const draftSteps = flow.draft?.steps ?? flow.steps\n if (!Array.isArray(draftSteps) || draftSteps.length === 0) {\n return res.status(400).json({ error: 'empty_flow', message: 'flow has no steps to publish' })\n }\n const nextVersion = (flow.version ?? 0) + 1\n const now = new Date()\n await c.flowVersions.insertOne({\n flowId: flow._id!,\n version: nextVersion,\n steps: draftSteps,\n trigger: flow.trigger,\n publishedAt: now,\n publishedBy: (req as any).actor,\n })\n await c.flows.updateOne(\n { _id: flow._id },\n {\n $set: {\n steps: draftSteps,\n version: nextVersion,\n enabled: true,\n draft: null,\n publishedAt: now,\n publishedBy: (req as any).actor,\n updatedAt: now,\n },\n },\n )\n await mailer.audit({\n actor: (req as any).actor,\n action: 'flow.publish',\n resource: { collection: 'mailer_flows', id: flow._id, slug: flow.slug },\n diffSummary: `Published v${nextVersion}`,\n })\n return res.json({ ok: true, version: nextVersion })\n }),\n )\n\n r.delete(\n '/flows/:slug',\n asyncHandler(async (req, res) => {\n const flow = await c.flows.findOne({ slug: req.params.slug })\n if (!flow) return res.status(404).json({ error: 'not_found' })\n const everRan = await c.flowRuns.countDocuments({ flowId: flow._id }, { limit: 1 })\n if (everRan > 0) return res.status(409).json({ error: 'has_runs', message: 'flow has runs — pause it instead' })\n await c.flows.deleteOne({ _id: flow._id })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'flow.delete',\n resource: { collection: 'mailer_flows', id: flow._id, slug: flow.slug },\n })\n return res.json({ ok: true })\n }),\n )\n\n // ----- Templates: create / edit / publish --------------------------------\n r.post(\n '/templates',\n asyncHandler(async (req, res) => {\n const { slug, name, kind, subject, preheader, fromName, fromEmail } = req.body ?? {}\n if (!slug || !name || !kind) {\n return res.status(400).json({ error: 'validation_failed', message: 'slug, name, kind required' })\n }\n if (kind !== 'marketing' && kind !== 'transactional') {\n return res.status(400).json({ error: 'validation_failed', message: 'kind must be marketing or transactional' })\n }\n const resolvedFromEmail =\n fromEmail ??\n (kind === 'transactional' ? mailer.config.transactionalFromDefaults?.email : undefined) ??\n mailer.config.fromDefaults?.email ??\n 'noreply@example.com'\n const senderCheck = validateSenderDomain(resolvedFromEmail, kind, mailer.config.senderDomains)\n if (!senderCheck.ok) {\n return res.status(400).json({\n error: 'sender_domain_invalid',\n code: senderCheck.code,\n message: senderCheck.reason,\n })\n }\n const now = new Date()\n try {\n await c.templates.insertOne({\n slug,\n name,\n description: '',\n kind,\n fromName:\n fromName ??\n (kind === 'transactional' ? mailer.config.transactionalFromDefaults?.name : undefined) ??\n mailer.config.fromDefaults?.name ??\n 'Mailery',\n fromEmail: resolvedFromEmail,\n replyTo: null,\n providerOverride: null,\n subject: subject ?? `Untitled — ${name}`,\n preheader: preheader ?? '',\n body: { mjml: '', editorJson: null, html: '', plainText: '', compiledAt: null },\n variablesSchema: {},\n draft: {\n subject: subject ?? `Untitled — ${name}`,\n preheader: preheader ?? '',\n mjml: '',\n editorJson: null,\n notes: 'Initial draft',\n lastModifiedBy: (req as any).actor,\n lastModifiedAt: now,\n },\n tags: [],\n trackOpens: kind === 'marketing',\n trackClicks: kind === 'marketing',\n stats: { sent: 0, delivered: 0, opened: 0, clicked: 0, bounced: 0, complained: 0, unsubscribed: 0, lastSentAt: null },\n publishedAt: null,\n publishedBy: null,\n createdAt: now,\n updatedAt: now,\n } as any)\n } catch (err: any) {\n if (err?.code === 11000) return res.status(409).json({ error: 'slug_taken' })\n throw err\n }\n await mailer.audit({\n actor: (req as any).actor,\n action: 'template.create',\n resource: { collection: 'mailer_templates', slug },\n })\n return res.json({ ok: true, slug })\n }),\n )\n\n r.patch(\n '/templates/:slug/draft',\n asyncHandler(async (req, res) => {\n const tpl = await c.templates.findOne({ slug: req.params.slug })\n if (!tpl) return res.status(404).json({ error: 'not_found' })\n\n const { subject, preheader, mjml, editorJson, notes, name, fromName, fromEmail, replyTo, kind, trackOpens, trackClicks } = req.body ?? {}\n\n const set: Record<string, unknown> = {\n 'draft.lastModifiedBy': (req as any).actor,\n 'draft.lastModifiedAt': new Date(),\n updatedAt: new Date(),\n }\n if (typeof subject === 'string') set['draft.subject'] = subject\n if (typeof preheader === 'string') set['draft.preheader'] = preheader\n if (typeof mjml === 'string') set['draft.mjml'] = mjml\n if (editorJson !== undefined) set['draft.editorJson'] = editorJson\n if (typeof notes === 'string') set['draft.notes'] = notes\n if (typeof name === 'string') set.name = name\n if (typeof fromName === 'string') set.fromName = fromName\n if (typeof fromEmail === 'string') set.fromEmail = fromEmail\n if (typeof replyTo === 'string' || replyTo === null) set.replyTo = replyTo\n if (kind === 'marketing' || kind === 'transactional') set.kind = kind\n\n // Validate resulting (kind, fromEmail) against the senderDomains registry\n // whenever either field is being touched.\n if (typeof fromEmail === 'string' || kind === 'marketing' || kind === 'transactional') {\n const resultingKind = (set.kind as typeof tpl.kind) ?? tpl.kind\n const resultingFromEmail = (set.fromEmail as string) ?? tpl.fromEmail\n const senderCheck = validateSenderDomain(resultingFromEmail, resultingKind, mailer.config.senderDomains)\n if (!senderCheck.ok) {\n return res.status(400).json({\n error: 'sender_domain_invalid',\n code: senderCheck.code,\n message: senderCheck.reason,\n })\n }\n }\n if (typeof trackOpens === 'boolean') set.trackOpens = trackOpens\n if (typeof trackClicks === 'boolean') set.trackClicks = trackClicks\n\n await c.templates.updateOne({ _id: tpl._id }, { $set: set })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'template.draft.update',\n resource: { collection: 'mailer_templates', id: tpl._id, slug: tpl.slug },\n })\n return res.json({ ok: true })\n }),\n )\n\n r.post(\n '/templates/:slug/publish',\n asyncHandler(async (req, res) => {\n const tpl = await c.templates.findOne({ slug: req.params.slug })\n if (!tpl) return res.status(404).json({ error: 'not_found' })\n const draft = tpl.draft\n if (!draft) return res.status(400).json({ error: 'no_draft' })\n\n const senderCheck = validateSenderDomain(tpl.fromEmail, tpl.kind, mailer.config.senderDomains)\n if (!senderCheck.ok) {\n return res.status(400).json({\n error: 'sender_domain_invalid',\n code: senderCheck.code,\n message: senderCheck.reason,\n })\n }\n\n let compiled: { html: string; plainText: string; errors: any[] }\n if (draft.editorJson) {\n compiled = await compileMailyTemplate(draft.editorJson)\n } else if (draft.mjml) {\n compiled = await compileTemplate(draft.mjml)\n } else {\n return res.status(400).json({ error: 'empty_draft', message: 'draft has no MJML or editorJson content' })\n }\n\n const now = new Date()\n const nextVersion = await c.templateVersions.countDocuments({ templateId: tpl._id }) + 1\n await c.templateVersions.insertOne({\n templateId: tpl._id!,\n version: nextVersion,\n mjml: draft.mjml,\n html: compiled.html,\n plainText: compiled.plainText,\n subject: draft.subject,\n preheader: draft.preheader,\n publishedAt: now,\n publishedBy: (req as any).actor,\n })\n\n await c.templates.updateOne(\n { _id: tpl._id },\n {\n $set: {\n subject: draft.subject,\n preheader: draft.preheader,\n body: {\n mjml: draft.mjml,\n editorJson: draft.editorJson,\n html: compiled.html,\n plainText: compiled.plainText,\n compiledAt: now,\n },\n draft: null,\n publishedAt: now,\n publishedBy: (req as any).actor,\n updatedAt: now,\n },\n },\n )\n await mailer.audit({\n actor: (req as any).actor,\n action: 'template.publish',\n resource: { collection: 'mailer_templates', id: tpl._id, slug: tpl.slug },\n diffSummary: `Published v${nextVersion}`,\n })\n return res.json({ ok: true, version: nextVersion, warnings: compiled.errors })\n }),\n )\n\n r.post(\n '/templates/:slug/preview',\n asyncHandler(async (req, res) => {\n const tpl = await c.templates.findOne({ slug: req.params.slug })\n if (!tpl) return res.status(404).json({ error: 'not_found' })\n\n const useDraft = req.body?.useDraft !== false\n let html = ''\n let plainText = ''\n if (useDraft && tpl.draft) {\n const compiled = tpl.draft.editorJson\n ? await compileMailyTemplate(tpl.draft.editorJson)\n : await compileTemplate(tpl.draft.mjml || '<mjml><mj-body></mj-body></mjml>')\n html = compiled.html\n plainText = compiled.plainText\n } else {\n html = tpl.body.html\n plainText = tpl.body.plainText\n }\n\n const sampleContact = req.body?.sampleContact ?? {\n externalId: 'preview-contact',\n email: 'preview@example.com',\n tags: [],\n fields: { firstName: 'Alex' },\n }\n const renderCtx = {\n contact: sampleContact,\n vars: req.body?.vars ?? {},\n unsubscribeUrl: `${mailer.config.publicUrl}/m/unsub/preview`,\n senderAddress: mailer.config.senderAddress,\n }\n\n const previewTpl = { ...tpl, body: { ...tpl.body, html, plainText } }\n const rendered = await renderTemplate(previewTpl as any, renderCtx, { helpers: mailer.config.handlebarsHelpers })\n return res.json({ subject: rendered.subject, preheader: rendered.preheader, html: rendered.html, plainText: rendered.plainText })\n }),\n )\n\n r.post(\n '/templates/:slug/send-test',\n asyncHandler(async (req, res) => {\n const { to, sampleData } = req.body ?? {}\n if (!to) return res.status(400).json({ error: 'to_required' })\n const tpl = await c.templates.findOne({ slug: req.params.slug })\n if (!tpl) return res.status(404).json({ error: 'not_found' })\n\n const contact = sampleData?.contact ?? {\n externalId: 'test-recipient',\n email: to,\n tags: [],\n fields: { firstName: 'Test' },\n }\n contact.email = to\n\n const renderCtx = {\n contact,\n vars: sampleData?.vars ?? {},\n unsubscribeUrl: `${mailer.config.publicUrl}/m/unsub/test`,\n senderAddress: mailer.config.senderAddress,\n }\n const rendered = await renderTemplate(tpl as any, renderCtx, { helpers: mailer.config.handlebarsHelpers })\n const tracking = applyTracking(rendered.html, {\n sendId: `test-${Date.now()}`,\n publicUrl: mailer.config.publicUrl,\n trackOpens: false,\n trackClicks: false,\n })\n\n const provider = mailer.providers[tpl.providerOverride ?? mailer.config.defaultProvider]!\n const result = await provider.send({\n to,\n fromName: rendered.fromName,\n fromEmail: rendered.fromEmail,\n subject: `[TEST] ${rendered.subject}`,\n html: tracking.html,\n text: rendered.plainText,\n })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'template.send-test',\n resource: { collection: 'mailer_templates', slug: tpl.slug },\n diffSummary: `to=${to}`,\n })\n // Avoid unused — sign helper is exposed for future preview routes.\n void signUnsubscribeToken\n return res.json({ ok: true, providerId: result.providerId })\n }),\n )\n\n // ----- Broadcasts: create / patch / schedule / cancel --------------------\n r.post(\n '/broadcasts',\n asyncHandler(async (req, res) => {\n const { slug, name, templateSlug, segmentDefinition } = req.body ?? {}\n if (!slug || !name || !templateSlug) {\n return res.status(400).json({ error: 'validation_failed', message: 'slug, name, templateSlug required' })\n }\n const now = new Date()\n try {\n await c.broadcasts.insertOne({\n slug,\n name,\n templateSlug,\n segmentDefinition: segmentDefinition ?? { filters: [{ kind: 'subscriptionStatus', equals: 'subscribed' }] },\n status: 'draft',\n scheduledAt: null,\n startedAt: null,\n completedAt: null,\n confirmationRequired: true,\n confirmedCount: null,\n confirmedAt: null,\n confirmedBy: null,\n recipientCount: null,\n stats: { sent: 0, delivered: 0, opened: 0, clicked: 0, bounced: 0, complained: 0, unsubscribed: 0 },\n createdAt: now,\n createdBy: (req as any).actor,\n updatedAt: now,\n } as any)\n } catch (err: any) {\n if (err?.code === 11000) return res.status(409).json({ error: 'slug_taken' })\n throw err\n }\n await mailer.audit({\n actor: (req as any).actor,\n action: 'broadcast.create',\n resource: { collection: 'mailer_broadcasts', slug },\n })\n return res.json({ ok: true, slug })\n }),\n )\n\n r.patch(\n '/broadcasts/:slug',\n asyncHandler(async (req, res) => {\n const b = await c.broadcasts.findOne({ slug: req.params.slug })\n if (!b) return res.status(404).json({ error: 'not_found' })\n if (b.status !== 'draft') return res.status(409).json({ error: 'not_draft' })\n const { name, templateSlug, segmentDefinition } = req.body ?? {}\n const set: Record<string, unknown> = { updatedAt: new Date() }\n if (typeof name === 'string') set.name = name\n if (typeof templateSlug === 'string') set.templateSlug = templateSlug\n if (segmentDefinition) set.segmentDefinition = segmentDefinition\n await c.broadcasts.updateOne({ _id: b._id }, { $set: set })\n return res.json({ ok: true })\n }),\n )\n\n r.post(\n '/broadcasts/:slug/segment/count',\n asyncHandler(async (req, res) => {\n const segmentDefinition = req.body?.segmentDefinition\n if (!segmentDefinition?.filters) return res.status(400).json({ error: 'segment_required' })\n const t0 = Date.now()\n // Stage A: host-side via adapter. For V1 we just translate the first\n // host-side filter we recognize; richer segmentation lands later.\n const hostFilter: any = {}\n for (const f of segmentDefinition.filters) {\n if (f.kind === 'hasTag') hostFilter.hasTag = f.tag\n if (f.kind === 'fieldEquals') hostFilter.fieldEquals = { field: f.field, value: f.value }\n }\n const stageA = await mailer.adapter.count(hostFilter)\n // Stage B + suppression are estimated for the live counter; the real\n // numbers come at dispatch time when the cursor is streamed.\n return res.json({ stageA, stageB: stageA, afterSuppression: stageA, computedMs: Date.now() - t0 })\n }),\n )\n\n r.post(\n '/broadcasts/:slug/schedule',\n asyncHandler(async (req, res) => {\n const b = await c.broadcasts.findOne({ slug: req.params.slug })\n if (!b) return res.status(404).json({ error: 'not_found' })\n if (b.status !== 'draft') return res.status(409).json({ error: 'not_draft' })\n const { scheduledAt, confirmedCount, respectRecipientTimezone } = req.body ?? {}\n if (!scheduledAt) return res.status(400).json({ error: 'scheduledAt_required' })\n const scheduled = new Date(scheduledAt)\n if (Number.isNaN(scheduled.getTime())) return res.status(400).json({ error: 'bad_scheduledAt' })\n\n const threshold = mailer.config.broadcastConfirmationThreshold\n if (typeof confirmedCount !== 'number') {\n return res.status(400).json({ error: 'confirmedCount_required' })\n }\n\n const set: Record<string, unknown> = {\n status: 'scheduled',\n scheduledAt: scheduled,\n confirmedCount,\n confirmedAt: new Date(),\n confirmedBy: (req as any).actor,\n updatedAt: new Date(),\n }\n if (respectRecipientTimezone) set.respectRecipientTimezone = true\n\n await c.broadcasts.updateOne({ _id: b._id }, { $set: set })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'broadcast.schedule',\n resource: { collection: 'mailer_broadcasts', id: b._id, slug: b.slug },\n diffSummary: `scheduled at ${scheduled.toISOString()} · confirmedCount=${confirmedCount} · threshold=${threshold}`,\n })\n return res.json({ ok: true })\n }),\n )\n\n r.post(\n '/broadcasts/:slug/cancel',\n asyncHandler(async (req, res) => {\n const b = await c.broadcasts.findOne({ slug: req.params.slug })\n if (!b) return res.status(404).json({ error: 'not_found' })\n await c.broadcasts.updateOne({ _id: b._id }, { $set: { status: 'cancelled', updatedAt: new Date() } })\n await mailer.audit({\n actor: (req as any).actor,\n action: 'broadcast.cancel',\n resource: { collection: 'mailer_broadcasts', id: b._id, slug: b.slug },\n })\n return res.json({ ok: true })\n }),\n )\n\n // Catch-all 404 for /api.\n r.use((_req, res) => res.status(404).json({ error: 'not_found' }))\n\n return r\n}\n\ntype AsyncHandler = (req: Request, res: Response, next: NextFunction) => Promise<unknown>\nfunction asyncHandler(fn: AsyncHandler) {\n return (req: Request, res: Response, next: NextFunction) => {\n fn(req, res, next).catch(next)\n }\n}\n","/**\n * Public router — endpoints that must be reachable by email clients and\n * provider webhooks. Mount under your tracking base path (default `/m`).\n *\n * app.use('/m', createPublicRouter(mailer))\n *\n * Routes:\n * GET /open/:sendId.png — open pixel (records open, returns 1×1 PNG)\n * GET /click/:sendId/:linkId — click redirect (records click, 302 → target)\n * GET /unsub/:token — confirmation page (one-click POST link)\n * POST /unsub/:token — RFC 8058 one-click unsubscribe\n * POST /webhooks/:provider — inbound provider event webhook\n */\n\nimport express, { Router, type Request, type Response } from 'express'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { ObjectId } from 'mongodb'\n\nimport { sha256Hex, verifyUnsubscribeToken, verifyDoiToken } from '../tokens.js'\nimport type { Mailer } from '../mailer.js'\n\nexport interface PublicRouterOptions {\n /**\n * Path on disk where unsubscribe events fall back to when Mongo is degraded.\n * Defaults to /tmp/mailery-pending-unsubs.jsonl.\n */\n pendingUnsubsPath?: string\n}\n\n// 1×1 transparent PNG (43 bytes)\nconst PIXEL = Buffer.from(\n 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=',\n 'base64',\n)\n\nexport function createPublicRouter(mailer: Mailer, opts: PublicRouterOptions = {}): Router {\n const router = Router()\n const pendingUnsubsPath = opts.pendingUnsubsPath ?? '/tmp/mailery-pending-unsubs.jsonl'\n\n // Parse JSON for webhooks — capture raw body for signature verification.\n router.use(\n '/webhooks',\n express.json({\n limit: '5mb',\n verify: (req: any, _res, buf) => {\n req.rawBody = buf\n },\n }),\n )\n\n // Pre-parsed JSON for the POST one-click unsubscribe path (RFC 8058 sends a\n // small form/JSON body; we accept either by reading the URL only).\n router.use('/unsub', express.urlencoded({ extended: false }))\n\n // -------------------------------------------------------------------------\n // GET /open/:sendId.png\n // -------------------------------------------------------------------------\n router.get('/open/:sendId.png', async (req: Request, res: Response) => {\n res.setHeader('Content-Type', 'image/png')\n res.setHeader('Content-Length', String(PIXEL.length))\n res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')\n res.status(200).end(PIXEL)\n\n // Async update — never block the response.\n const id = (req.params as any).sendId as string\n if (!ObjectId.isValid(id)) return\n const sendId = new ObjectId(id)\n try {\n const send = await mailer.collections.sends.findOne({ _id: sendId }, { projection: { openedAt: 1 } })\n if (!send) return\n await mailer.collections.sends.updateOne(\n { _id: sendId },\n {\n $set: {\n openedAt: send.openedAt ?? new Date(),\n status: 'delivered' as const,\n },\n $inc: { openCount: 1 },\n },\n )\n } catch (err) {\n console.error('mailery: open pixel update failed', err)\n }\n })\n\n // -------------------------------------------------------------------------\n // GET /click/:sendId/:linkId\n // -------------------------------------------------------------------------\n router.get('/click/:sendId/:linkId', async (req: Request, res: Response) => {\n const { sendId: sendIdStr, linkId } = req.params as { sendId: string; linkId: string }\n if (!ObjectId.isValid(sendIdStr)) return res.status(400).end()\n const sendId = new ObjectId(sendIdStr)\n\n const send = await mailer.collections.sends.findOne(\n { _id: sendId },\n { projection: { links: 1, firstClickAt: 1 } },\n )\n if (!send) return res.status(404).end()\n\n const link = (send.links ?? []).find((l) => l.linkId === linkId)\n if (!link) return res.status(404).end()\n\n res.redirect(302, link.url)\n\n try {\n await mailer.collections.sends.updateOne(\n { _id: sendId },\n {\n $set: { firstClickAt: send.firstClickAt ?? new Date() },\n $inc: { clickCount: 1 },\n $push: {\n clickedLinks: {\n url: link.url,\n linkId,\n clickedAt: new Date(),\n },\n },\n },\n )\n } catch (err) {\n console.error('mailery: click recording failed', err)\n }\n })\n\n // -------------------------------------------------------------------------\n // GET + POST /unsub/:token\n // -------------------------------------------------------------------------\n router.get('/unsub/:token', (req: Request, res: Response) => {\n const decoded = verifyUnsubscribeToken((req.params as any).token, mailer.config.unsubscribeSecret)\n if (!decoded) return sendUnsubError(res, 'Invalid or expired link.')\n\n res.status(200).type('html').send(`<!doctype html>\n<html><head>\n <meta charset=\"utf-8\" />\n <title>Unsubscribe</title>\n <style>body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;max-width:480px;margin:48px auto;padding:0 16px;color:#1c1917;line-height:1.5}h1{font-size:20px}button{padding:10px 18px;background:#dc2626;color:#fff;border:0;border-radius:6px;font-size:14px;cursor:pointer}</style>\n</head><body>\n <h1>Confirm unsubscribe</h1>\n <p>Click the button below to unsubscribe <strong>${escapeHtml(decoded.email)}</strong>${decoded.scope === 'all' ? ' from everything' : ' from marketing emails'}.</p>\n <form method=\"POST\" action=\"${escapeHtml(req.originalUrl)}\">\n <button type=\"submit\">Unsubscribe</button>\n </form>\n</body></html>`)\n })\n\n router.post('/unsub/:token', async (req: Request, res: Response) => {\n const decoded = verifyUnsubscribeToken((req.params as any).token, mailer.config.unsubscribeSecret)\n if (!decoded) {\n res.status(200).end() // never 5xx; let provider stop retrying\n return\n }\n\n // Reply 200 immediately. INVARIANT 8: bulletproof unsubscribe.\n res.status(200).type('html').send('<!doctype html><html><body><p>You are unsubscribed.</p></body></html>')\n\n try {\n await mailer.unsubscribe(decoded.email, {\n scope: decoded.scope,\n reason: 'user_request',\n source: 'one-click',\n })\n } catch (err) {\n try {\n fs.appendFileSync(\n pendingUnsubsPath,\n JSON.stringify({ email: decoded.email, scope: decoded.scope, at: Date.now() }) + '\\n',\n )\n } catch (diskErr) {\n console.error('mailery: unsub disk fallback failed', { err, diskErr })\n }\n }\n })\n\n // -------------------------------------------------------------------------\n // GET /confirm-doi/:token\n // -------------------------------------------------------------------------\n router.get('/confirm-doi/:token', async (req: Request, res: Response) => {\n const token = (req.params as any).token as string\n const decoded = verifyDoiToken(token, mailer.config.unsubscribeSecret)\n if (!decoded) {\n return res.status(400).type('html').send('<!doctype html><html><body><p>Confirmation link is invalid or expired.</p></body></html>')\n }\n const now = new Date()\n const result = await mailer.collections.subscriptions.updateOne(\n { externalId: decoded.externalId, status: 'pending_doi' },\n {\n $set: {\n status: 'subscribed',\n subscribedAt: now,\n doiConfirmedAt: now,\n doiIp: req.ip ?? null,\n doiUserAgent: (req.headers['user-agent'] as string | undefined) ?? null,\n updatedAt: now,\n },\n },\n )\n if (result.matchedCount === 0) {\n return res.status(200).type('html').send('<!doctype html><html><body><p>Already confirmed. Thanks.</p></body></html>')\n }\n try {\n await mailer.fire('subscription.confirmed', decoded.externalId, {}, `doi-confirmed:${decoded.externalId}`)\n } catch {\n /* swallow — subscription is confirmed regardless */\n }\n return res.status(200).type('html').send('<!doctype html><html><body><p>Thanks — you\\'re subscribed.</p></body></html>')\n })\n\n // -------------------------------------------------------------------------\n // POST /webhooks/:provider\n // -------------------------------------------------------------------------\n router.post('/webhooks/:provider', async (req: Request, res: Response) => {\n const providerName = (req.params as any).provider as string\n const provider = mailer.providers[providerName]\n if (!provider) return res.status(404).end()\n\n const rawBody = (req as any).rawBody as Buffer | undefined\n if (!rawBody) return res.status(400).end()\n\n const headers = lowercaseHeaders(req.headers)\n const valid = await provider.verifyWebhook(rawBody, headers)\n if (!valid) return res.status(401).end()\n\n const events = provider.parseWebhookEvents(req.body, headers)\n\n // Always 200 fast — fail-open, retry inbound is wasted bandwidth.\n res.status(200).end()\n\n // Preserve the original provider payload alongside each normalized event so the\n // audit trail isn't reduced to just our extracted fields. The raw body is the\n // full provider response array; we record it once per parsed event for clarity.\n const rawBodyRef = req.body as unknown\n for (const evt of events) {\n try {\n await mailer.collections.webhookEvents.updateOne(\n { provider: providerName, providerEventId: evt.providerEventId },\n {\n $setOnInsert: {\n provider: providerName,\n providerEventId: evt.providerEventId,\n eventType: evt.type,\n normalizedType: evt.type,\n providerMessageId: evt.providerMessageId,\n email: evt.email,\n occurredAt: evt.occurredAt,\n receivedAt: new Date(),\n processed: false,\n raw: { normalized: evt, providerBody: rawBodyRef },\n },\n },\n { upsert: true },\n )\n } catch (err) {\n console.error('mailery: webhook dedupe insert failed', err)\n }\n }\n\n if (events.length > 0) {\n try {\n await mailer.queues.webhook.add('webhook', { provider: providerName })\n } catch {\n /* will be picked up by next tick */\n }\n }\n\n // Bypass linting — `path` import retained for any future on-disk fallback.\n void path\n })\n\n return router\n}\n\nfunction sendUnsubError(res: Response, msg: string): Response {\n return res.status(400).type('html').send(`<!doctype html><html><body><p>${escapeHtml(msg)}</p></body></html>`)\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;')\n}\n\nfunction lowercaseHeaders(h: any): Record<string, string> {\n const out: Record<string, string> = {}\n for (const k of Object.keys(h)) {\n const v = h[k]\n out[k.toLowerCase()] = Array.isArray(v) ? v.join(',') : String(v ?? '')\n }\n return out\n}\n\n// silence unused\nvoid sha256Hex\n","/**\n * Enumerable option lists for the union types in `./types.ts`. Used by the\n * admin client to render dropdowns + by tooling to enumerate the surface.\n *\n * Kept in `shared/` so the client and server agree on the canonical labels +\n * default constructors. Pure data + pure functions — no React, no DOM.\n */\n\nimport type { FlowStep, Predicate, SegmentFilter } from './types.js'\n\n// ---------------------------------------------------------------------------\n// Flow step types\n// ---------------------------------------------------------------------------\n\nexport interface FlowStepKindOption {\n value: FlowStep['type']\n label: string\n /** Icon name from the client's icon set (lookup at render time). */\n icon: string\n /** Visual class on the canvas chip. */\n iconClass: string\n /** One-line description for tooltips / docs generation. */\n description: string\n}\n\nexport const FLOW_STEP_KINDS: readonly FlowStepKindOption[] = [\n { value: 'wait', label: 'Wait', icon: 'Clock', iconClass: 'wait', description: 'Pause the run for a duration before continuing.' },\n { value: 'condition', label: 'Condition', icon: 'Branch', iconClass: 'condition', description: 'Evaluate a predicate. Exit or skip on false.' },\n { value: 'branch', label: 'Branch', icon: 'Branch', iconClass: 'condition', description: 'Evaluate a predicate. Recurse into one of two sub-lists.' },\n { value: 'send', label: 'Send', icon: 'Mail', iconClass: 'send', description: 'Send a template to the contact.' },\n { value: 'tag', label: 'Tag', icon: 'Tag', iconClass: 'tag', description: 'Add or remove tags on the contact.' },\n { value: 'fire_event', label: 'Fire event', icon: 'Activity', iconClass: 'send', description: 'Insert a synthetic event (cross-flow handoff).' },\n { value: 'webhook', label: 'Webhook', icon: 'Webhook', iconClass: 'tag', description: 'POST to an external URL.' },\n { value: 'exit', label: 'Exit', icon: 'Exit', iconClass: 'exit', description: 'End the run with an optional reason.' },\n] as const\n\nexport function defaultFlowStep(type: FlowStep['type']): FlowStep {\n switch (type) {\n case 'wait': return { type: 'wait', value: 1, unit: 'days' }\n case 'condition': return { type: 'condition', test: { hasTag: 'engaged' }, ifFalse: 'exit' }\n case 'branch': return { type: 'branch', test: { hasTag: 'vip' }, ifTrueSteps: [], ifFalseSteps: [] }\n case 'send': return { type: 'send', templateSlug: '' }\n case 'tag': return { type: 'tag', addTags: [], removeTags: [] }\n case 'fire_event': return { type: 'fire_event', eventName: '' }\n case 'webhook': return { type: 'webhook', url: '', method: 'POST' }\n case 'exit': return { type: 'exit' }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Predicate kinds (the union variants of Predicate, minus composites)\n// ---------------------------------------------------------------------------\n\nexport type PredicateKind =\n | 'hasTag'\n | 'notHasTag'\n | 'fieldEquals'\n | 'fieldExists'\n | 'hasFiredEvent'\n | 'notHasFiredEvent'\n | 'subscriptionStatus'\n | 'hasOpened'\n | 'hasClicked'\n | 'hasOpenedExcludingBots'\n | 'hasClickedExcludingBots'\n | 'openedAtLeastN'\n | 'clickedAtLeastN'\n\nexport interface PredicateKindOption {\n value: PredicateKind\n label: string\n /** True when this predicate's signal is noisy (Apple MPP, bot prefetch). */\n noisy?: boolean\n}\n\nexport const PREDICATE_KINDS: readonly PredicateKindOption[] = [\n { value: 'hasTag', label: 'has tag' },\n { value: 'notHasTag', label: 'does NOT have tag' },\n { value: 'fieldEquals', label: 'field equals' },\n { value: 'fieldExists', label: 'field exists' },\n { value: 'hasFiredEvent', label: 'fired event' },\n { value: 'notHasFiredEvent', label: 'has NOT fired event' },\n { value: 'subscriptionStatus', label: 'subscription status' },\n { value: 'hasOpened', label: 'opened', noisy: true },\n { value: 'hasClicked', label: 'clicked', noisy: true },\n { value: 'hasOpenedExcludingBots', label: 'opened (excl. bots)' },\n { value: 'hasClickedExcludingBots', label: 'clicked (excl. bots)' },\n { value: 'openedAtLeastN', label: 'opened at least N' },\n { value: 'clickedAtLeastN', label: 'clicked at least N' },\n] as const\n\n/** Identify which kind of predicate this object is (or null for composites/unknown). */\nexport function predicateKind(p: Predicate | null | undefined): PredicateKind | null {\n if (!p) return null\n for (const k of PREDICATE_KINDS) {\n if (k.value in (p as object)) return k.value\n }\n return null\n}\n\nexport function defaultPredicate(kind: PredicateKind): Predicate {\n switch (kind) {\n case 'hasTag': return { hasTag: 'engaged' }\n case 'notHasTag': return { notHasTag: 'cold' }\n case 'fieldEquals': return { fieldEquals: { field: 'tier', value: 'Pro' } }\n case 'fieldExists': return { fieldExists: 'tier' }\n case 'hasFiredEvent': return { hasFiredEvent: 'Activated app' }\n case 'notHasFiredEvent': return { notHasFiredEvent: 'Cancelled' }\n case 'subscriptionStatus': return { subscriptionStatus: 'subscribed' }\n case 'hasOpened': return { hasOpened: { sinceFlowStart: true } }\n case 'hasClicked': return { hasClicked: { sinceFlowStart: true } }\n case 'hasOpenedExcludingBots': return { hasOpenedExcludingBots: { sinceFlowStart: true } }\n case 'hasClickedExcludingBots': return { hasClickedExcludingBots: { sinceFlowStart: true } }\n case 'openedAtLeastN': return { openedAtLeastN: { count: 1, withinDays: 7 } }\n case 'clickedAtLeastN': return { clickedAtLeastN: { count: 1, withinDays: 7 } }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Segment filter kinds\n// ---------------------------------------------------------------------------\n\nexport type SegmentFilterKind = SegmentFilter['kind']\n\nexport interface SegmentFilterKindOption {\n value: SegmentFilterKind\n label: string\n /** Where the filter is evaluated: host-side via adapter, or mailer-side post-filter. */\n side: 'host' | 'mailer' | 'composite'\n}\n\nexport const SEGMENT_FILTER_KINDS: readonly SegmentFilterKindOption[] = [\n { value: 'subscriptionStatus', label: 'Subscription status', side: 'mailer' },\n { value: 'hasTag', label: 'Has tag', side: 'host' },\n { value: 'notHasTag', label: 'Does NOT have tag', side: 'host' },\n { value: 'fieldEquals', label: 'Field equals', side: 'host' },\n { value: 'fieldIn', label: 'Field in list', side: 'host' },\n { value: 'fieldExists', label: 'Field exists', side: 'host' },\n { value: 'firedEvent', label: 'Fired event', side: 'mailer' },\n { value: 'notFiredEvent', label: 'Has NOT fired event', side: 'mailer' },\n { value: 'subscribedAfter', label: 'Subscribed after', side: 'mailer' },\n { value: 'subscribedBefore', label: 'Subscribed before', side: 'mailer' },\n { value: 'opened', label: 'Opened', side: 'mailer' },\n { value: 'notOpened', label: 'Did NOT open', side: 'mailer' },\n { value: 'any', label: 'Any of (OR)', side: 'composite' },\n { value: 'not', label: 'NOT', side: 'composite' },\n] as const\n\nexport function defaultSegmentFilter(kind: SegmentFilterKind): SegmentFilter {\n switch (kind) {\n case 'subscriptionStatus': return { kind: 'subscriptionStatus', equals: 'subscribed' }\n case 'hasTag': return { kind: 'hasTag', tag: '' }\n case 'notHasTag': return { kind: 'notHasTag', tag: '' }\n case 'fieldEquals': return { kind: 'fieldEquals', field: '', value: '' }\n case 'fieldIn': return { kind: 'fieldIn', field: '', values: [] }\n case 'fieldExists': return { kind: 'fieldExists', field: '' }\n case 'firedEvent': return { kind: 'firedEvent', eventName: '', withinDays: 30 }\n case 'notFiredEvent': return { kind: 'notFiredEvent', eventName: '', withinDays: 90 }\n case 'subscribedAfter': return { kind: 'subscribedAfter', date: new Date(Date.now() - 30 * 86_400_000) }\n case 'subscribedBefore': return { kind: 'subscribedBefore', date: new Date() }\n case 'opened': return { kind: 'opened', withinDays: 14 }\n case 'notOpened': return { kind: 'notOpened', withinDays: 14 }\n case 'any': return { kind: 'any', filters: [] }\n case 'not': return { kind: 'not', filter: { kind: 'hasTag', tag: '' } }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Dedupe policies for event registration\n// ---------------------------------------------------------------------------\n\nexport interface DedupePolicyOption {\n value: 'once-per-contact' | 'once-per-day' | 'every-time'\n label: string\n description: string\n derivedKeyShape: string\n}\n\nexport const DEDUPE_POLICIES: readonly DedupePolicyOption[] = [\n {\n value: 'once-per-contact',\n label: 'Once per contact',\n description: 'Lifecycle markers (Created, Activated)',\n derivedKeyShape: '${externalId}:${eventName}',\n },\n {\n value: 'once-per-day',\n label: 'Once per day',\n description: 'Daily behaviors (Viewed Storyboard)',\n derivedKeyShape: '${externalId}:${eventName}:${YYYY-MM-DD}',\n },\n {\n value: 'every-time',\n label: 'Every time',\n description: 'True every-occurrence events (Imported)',\n derivedKeyShape: '${externalId}:${eventName}:${UUIDv4}',\n },\n] as const\n"]}