NotificationCore is a reusable notification foundation for backend systems.
It supports email and in-app delivery, keeps templates owned by the
consuming app, and isolates provider-specific logic behind adapters.
This repository is meant to be a real backend infrastructure project, not a single-provider wrapper around email delivery.
For repo routing, boundary guidance, release checks, and machine-readable
catalog surfaces across the Saazip SaaS repos, use
saasctl.
- keep notification delivery logic reusable across products
- separate templates from provider implementation
- support both sync and async delivery modes
- track attempts, delivery state, and in-app records explicitly
- model user and tenant notification preferences early
- keep the provider layer swappable from day one
Typical use cases:
- welcome and verification emails
- password reset and invite flows
- operational alerts
- in-app activity notifications
- product events that fan out to users
- not a campaign marketing product
- not a hard dependency on Resend
- not a place for product-specific template content
cp .env.example .env
docker compose up -d postgres
pnpm install
pnpm dev:api
pnpm dev:dispatcherLocal services:
- API:
http://localhost:3050 - Dispatcher:
http://localhost:3051 - Postgres:
localhost:5435
Operational defaults:
/healthand/readystay open for probes/v1/*must be protected withAPI_KEYSin production unless you explicitly opt out- basic request rate limiting is enabled by default for
/v1/* - requests may send
x-request-id, which is echoed back or generated emailuses the official Resend adapter when configuredin-appnotifications are persisted inside the core state
This is the default path.
- your app owns templates and payload shape
- NotificationCore owns delivery orchestration, preferences, and tracking
- useful when you want notifications close to product logic
Use the API and dispatcher as an operational sidecar.
- your app creates notifications over HTTP
- NotificationCore owns delivery state and async execution
- useful when multiple apps should share one notification subsystem
- your app implements template rendering
- your app decides which events produce notifications
- NotificationCore stays generic and reusable
apps/
api/ Reference API and admin surface
dispatcher/ Async runtime for queued notification dispatch
packages/
core/ Domain model, preferences, attempts, in-app records
contracts/ Public Zod contracts and API schemas
db/ State repository and DB-oriented helpers
sdk/ Official client kept private in this phase
adapters/resend/ Email provider adapter
adapters/queueflow/ Async scheduler adapter
observability/ JSON logs, metrics and tracing helpers
testing/ Fixtures and builders
docs/ Architecture, concepts, guides and operations
examples/ Reference app-level usage
docker/ Local runtime images- Read this README for boundaries.
- Read docs/README.md.
- Read CONTRIBUTING.md before changing delivery semantics or provider boundaries.
Useful commands:
pnpm run ci
pnpm dev:api
pnpm dev:dispatcher
pnpm example:basic-app- Contributing guide
- Security policy
- Architecture and concepts
- API reference
- Compose with the Saazip infra suite
- Basic app example
NotificationCore is library-first in v1.
- the core packages and reference API are both part of the repo
- public npm publishing is intentionally deferred until the package surface stabilizes
- Node
24.x - pnpm
10.33.x - PostgreSQL
16+ - QueueFlow integration optional
auth-corecan emit user and organization notificationsqueueflowcan schedule async deliveryeventflowcan feed event-driven notificationswebhook-corecan propagate delivery events outwardcache-corecan cache preferences and template metadata
Apache-2.0