I’m working on Staccats, a headless notification platform aimed at multi-tenant saas apps.
Tech stack:
Runtime: bun for both the HTTP API and a background worker
DB: Postgres for tenants, api_keys, users, events, templates, providers, notifications, notification_attempts
Queue: MVP is DB as queue, worker polls notifications WHERE status = ‘pending’ LIMIT 50 and processes
Flow:
App calls POST /notify with { event, userId, data } 1.
API:
Auth via Authorization: Bearer <API_KEY> → resolve tenant_id
Look up event, template, user, provider
Create notifications row with status = ‘pending’ 1.
Worker:
Polls pending notifications
Renders template with data
Sends via provider adapter (e.g. SendGrid/SES/Resend etc)
Writes notification_attempts r…
I’m working on Staccats, a headless notification platform aimed at multi-tenant saas apps.
Tech stack:
Runtime: bun for both the HTTP API and a background worker
DB: Postgres for tenants, api_keys, users, events, templates, providers, notifications, notification_attempts
Queue: MVP is DB as queue, worker polls notifications WHERE status = ‘pending’ LIMIT 50 and processes
Flow:
App calls POST /notify with { event, userId, data } 1.
API:
Auth via Authorization: Bearer <API_KEY> → resolve tenant_id
Look up event, template, user, provider
Create notifications row with status = ‘pending’ 1.
Worker:
Polls pending notifications
Renders template with data
Sends via provider adapter (e.g. SendGrid/SES/Resend etc)
Writes notification_attempts row and updates notification status
Questions for other backend folks:
Is “DB-as-queue” good enough for early stage, or would you push straight to a real queue (Redis/Sidekiq/BullMQ/etc.)?
How would you structure provider adapters? Thinking sendEmail(notification, providerConfig) with an internal contract per channel.
Any obvious “you’re going to regret this” bits in the multi-tenant / API key approach?
Would you use something like this instead of rolling your own notification service inside a Node/Bun app?