Skip to content

CamiloMaria/notifyhub

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

163 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NotifyHub — Multi-Channel Notification Platform

NotifyHub is a SaaS platform for sending notifications across email, webhooks, and push — through a single, unified API.

The Problem

Developers waste time integrating multiple notification providers. Each channel has different APIs, retry logic, and monitoring needs. When something fails, there's no visibility into what went wrong or where the message got stuck.

The Solution

A unified API with one endpoint to send notifications across any channel, with built-in queuing, retry, rate limiting, and real-time delivery tracking. An interactive sandbox lets you fire a notification and watch it flow through the entire pipeline — queues, processors, retries, delivery — in real time via WebSockets.

Key Features

  • Multi-channel: email (Resend), webhooks, push (FCM)
  • Async processing with BullMQ + Redis
  • Exponential backoff retry with dead letter queues (10s / 30s / 90s)
  • Rate limiting per API key (Redis sliding window, 100 req/min)
  • Real-time delivery tracking via WebSockets (Socket.io)
  • Template engine with {{variable}} substitution
  • Idempotency support for safe retries
  • Interactive API documentation (Swagger/OpenAPI)
  • Chaos engineering sandbox — inject failures and watch the system recover
  • Multi-tenancy — JWT auth + API key per project

Architecture

  Client (React SPA)
        |
        | REST + WebSocket
        v
  ┌─────────────────────────┐
  │       NestJS API         │
  │                          │
  │  Controller → Service    │
  │       │           │      │
  │       v           v      │
  │  PostgreSQL     BullMQ   │
  │  (TypeORM)     (Redis)   │
  │                   │      │
  │            ┌──────┴───┐  │
  │            │ Processor │  │
  │            │ (email /  │  │
  │            │  webhook) │  │
  │            └──────┬────┘  │
  │                   │      │
  │         EventEmitter2    │
  │                   │      │
  │          ┌────────v───┐  │
  │          │  Gateway    │  │
  │          │ (Socket.io) │  │
  │          └──────┬──────┘  │
  └─────────────────│─────────┘
                    v
            WebSocket push
            to client feed

Notification Lifecycle

  1. SendPOST /api/v1/notifications/send with X-API-Key header
  2. Queue — Notification saved to PostgreSQL, job added to BullMQ
  3. Process — Worker picks up job, calls provider (mock or real)
  4. Retry — Failed jobs retry with exponential backoff: 10s → 30s → 90s
  5. Deliver — Success updates status to SENT, then DELIVERED
  6. Broadcast — Every status change is pushed to the client via WebSocket

Tech Stack

Layer Technologies
Backend NestJS 11, TypeORM 0.3, PostgreSQL 16, BullMQ 5, Redis 7, Socket.io 4, Passport/JWT
Frontend React 19, Vite 8, TailwindCSS 4, Framer Motion 12, TanStack React Query 5, Zustand 5
Monorepo pnpm workspaces (no Turborepo)
Deployment Oracle Cloud Always Free (backend, Docker Compose, Nginx), Vercel (frontend), GitHub Actions (CI/CD)
Testing Jest 30 (backend, 125 tests), Vitest 4 (frontend, 65 tests)

Live Demo

Running Locally

Prerequisites

  • Node.js >= 22
  • pnpm >= 10
  • Docker (for PostgreSQL and Redis)

Setup

git clone https://github.com/CamiloMaria/notifyhub.git
cd notifyhub

pnpm install

# Start PostgreSQL and Redis
docker compose up -d

# Copy environment variables
cp .env.example .env

# Start API + frontend
pnpm dev

The API runs at http://localhost:3000 and the frontend at http://localhost:5173.

Swagger docs at http://localhost:3000/docs.

API Quick Start

# Send a notification
curl -X POST http://localhost:3000/api/v1/notifications/send \
  -H "Content-Type: application/json" \
  -H "X-API-Key: nhk_demo_sandbox_key_for_development_only" \
  -d '{
    "channel": "email",
    "recipient": "user@example.com",
    "subject": "Hello from NotifyHub",
    "body": "Your order #1234 has shipped."
  }'

Full API reference available at /docs (Swagger UI).

What I Learned

Event-driven architecture pays off. Decoupling notification dispatch from delivery via BullMQ meant adding chaos engineering, retry logic, and real-time tracking required zero changes to the send endpoint. Events flow through the system and each component reacts independently.

The sandbox is the documentation. Instead of writing architecture docs nobody reads, building an interactive demo that shows the pipeline in action communicates more in 30 seconds than diagrams ever could. The chaos mode — where you inject failures and watch the system retry and recover — is the strongest proof of fault tolerance.

Multi-tenancy is an early decision. Bolting on project isolation and API key scoping after the fact would have meant rewriting most queries. Designing for it from phase one (JWT + project ownership validation on every endpoint) kept the codebase clean.

License

MIT

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages