Skip to content

youneedgreg/notification-system

Repository files navigation

🔔 Notification System

A production-ready, scalable notification system built with microservices architecture using Docker. Handles email and push notifications with high reliability, fault tolerance, and comprehensive monitoring.

Architecture

🚀 Features

  • Multi-Channel Notifications: Email and Push notifications with unified API
  • Broadcast Delivery: Send notifications across multiple channels simultaneously
  • Message Queuing: Reliable async delivery with RabbitMQ and dead letter queues
  • Template Management: Dynamic templates with variable substitution (Handlebars)
  • Circuit Breaker: Fault tolerance with automatic service recovery
  • Idempotency: Duplicate prevention using request IDs
  • Service Discovery: Redis-based service registry
  • Real-time Monitoring: Prometheus metrics + Grafana dashboards
  • Health Checks: Comprehensive monitoring for all services
  • Retry Mechanism: Exponential backoff for failed deliveries
  • Docker Deployment: Single Dockerfile with multi-stage builds
  • Production Ready: Nginx reverse proxy, SSL/TLS, environment configs

📊 Architecture

Microservices

  • API Gateway (Port 3000): Main entry point, authentication, notification routing
  • User Service (Port 3001): User management, authentication, JWT tokens
  • Email Service (Port 3002): SMTP-based email delivery via Mailtrap/SendGrid
  • Push Service (Port 3003): Firebase Cloud Messaging (FCM) integration
  • Template Service (Port 3004): Template CRUD and rendering engine

Infrastructure

  • PostgreSQL: Primary datastore (users, notifications, templates)
  • RabbitMQ: Message broker with dead letter exchange
  • Redis: Caching, service discovery, session management
  • Prometheus: Metrics collection and time-series data
  • Grafana: Monitoring dashboards and alerts
  • Docker: Containerized deployment with docker-compose

Message Flow

🛠️ Tech Stack

  • Framework: NestJS (TypeScript/Node.js 20+)
  • Message Queue: RabbitMQ 3.12
  • Database: PostgreSQL 15 with TypeORM
  • Cache: Redis 7
  • Push: Firebase Cloud Messaging (FCM)
  • Email: SMTP (Mailtrap, SendGrid, AWS SES)
  • Monitoring: Prometheus + Grafana
  • Documentation: Swagger/OpenAPI
  • Deployment: Docker + Docker Compose
  • Container: Docker + Docker Compose
  • Fault Tolerance: Opossum Circuit Breaker

📋 Prerequisites

  • Docker: v24+ (recommended for deployment)
  • Docker Compose: v2.20+
  • Node.js: v20+ (for local development only)
  • Git: v2.30+
  • kubectl / Helm v3+ (only for Kubernetes deployment, see Deployment)

🚀 Quick Start (Docker - Recommended)

1. Clone the Repository

git clone https://github.com/youneedgreg/notification-system.git
cd notification-system

2. Configure Environment (Optional for Local Testing)

⚠️ SECURITY WARNING: The .env files contain test credentials. DO NOT use in production! Change all passwords, secrets, and API keys before deploying to a server.

For local testing: The existing .env files work as-is.

For production: Change these critical values:

  • DB_PASSWORD / POSTGRES_PASSWORD - Strong password (20+ chars)
  • REDIS_PASSWORD - Strong password
  • RABBITMQ_PASSWORD - Strong password
  • JWT_SECRET - Generate: openssl rand -base64 32
  • JWT_REFRESH_SECRET - Generate: openssl rand -base64 32
  • SMTP_* - Production email provider credentials
  • FIREBASE_SERVICE_ACCOUNT_PATH - Production Firebase credentials

3. Start All Services with Docker

# Build and start all services (infrastructure + microservices)
docker-compose up -d --build

This single command starts:

  • ✅ PostgreSQL database
  • ✅ Redis cache
  • ✅ RabbitMQ message broker
  • ✅ Prometheus metrics
  • ✅ Grafana dashboards
  • ✅ All 5 microservices (API Gateway, User, Email, Push, Template)

Wait ~30 seconds for services to initialize.

4. Verify Services

# Check all containers are running
docker-compose ps

# View logs
docker-compose logs -f api-gateway

Access Points:

5. Run Tests

# Automated test suite (tests all endpoints)
bash test-notifications.sh

6. Stop Services

# Stop all services
docker-compose down

# Stop and remove all data
docker-compose down -v

🔧 Local Development (Without Docker)

If you prefer to run services locally without Docker:

# Install dependencies
npm install

# Start infrastructure only
docker-compose up -d postgres redis rabbitmq prometheus grafana

# Start all microservices
npm run start:all

📖 API Documentation

Swagger UI

Access interactive API documentation:

Key Endpoints

Authentication

# Register User
POST /api/v1/auth/register
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "SecurePass123!",
  "name": "John Doe"
}

# Login
POST /api/v1/auth/login
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "SecurePass123!"
}

Notifications

# Send Email Notification
POST /api/v1/notifications/send
Authorization: Bearer <token>
Content-Type: application/json

{
  "type": "email",
  "recipient": "user@example.com",
  "template_code": "WELCOME_EMAIL",
  "variables": {
    "username": "John Doe",
    "app_name": "Notification System"
  },
  "request_id": "unique-id-12345"
}

# Send Push Notification
POST /api/v1/notifications/send
Authorization: Bearer <token>
Content-Type: application/json

{
  "type": "push",
  "recipient": "fcm_device_token",
  "template_code": "ORDER_UPDATE",
  "variables": {
    "order_id": "ORD-12345",
    "status": "shipped"
  }
}

# Broadcast (Email + Push)
POST /api/v1/notifications/broadcast
Authorization: Bearer <token>
Content-Type: application/json

{
  "user_id": "uuid",
  "email": "user@example.com",
  "push_token": "fcm_token",
  "email_template_code": "WELCOME_EMAIL",
  "push_template_code": "WELCOME_PUSH",
  "variables": {
    "username": "John Doe"
  },
  "request_id": "broadcast-12345",
  "priority": "high"
}

# Get Notification History
GET /api/v1/notifications/history
Authorization: Bearer <token>

Templates

# Create Template
POST /api/v1/templates
Content-Type: application/json

{
  "name": "Welcome Email",
  "code": "WELCOME_EMAIL",
  "type": "email",
  "subject": "Welcome to {{app_name}}!",
  "html_content": "<h1>Welcome {{username}}!</h1>",
  "variables": ["username", "app_name"]
}

# Get All Templates
GET /api/v1/templates

# Get Template by Code
GET /api/v1/templates/code/WELCOME_EMAIL

🔍 Monitoring

Grafana Dashboard

URL: http://localhost:3100
Credentials: admin / admin123

Monitors:

  • Request rates and latency
  • Queue depths and processing rates
  • Success/failure rates
  • Service health status
  • Database connection pools
  • Memory and CPU usage

Dashboard

Prometheus Metrics

URL: http://localhost:9090

Available metrics:

  • notification_sent_total - Total notifications sent
  • notification_failed_total - Failed notification count
  • http_request_duration_seconds - API latency
  • queue_depth - RabbitMQ queue size

RabbitMQ Management

URL: http://localhost:15672
Credentials: rabbitmq_user / rabbitmq_pass_2024

Monitor:

  • email.queue - Email notifications
  • push.queue - Push notifications
  • failed.queue - Dead letter queue

🧪 Testing

Automated Testing

# Full test suite (11 scenarios)
bash test-notifications.sh

Tests include:

  • ✅ Health checks for all services
  • ✅ Template creation
  • ✅ User registration and login
  • ✅ Email notification delivery
  • ✅ Push notification delivery
  • ✅ Broadcast notifications
  • ✅ Notification history retrieval
  • ✅ Error handling and retries

Manual Testing

See Testing Guide for detailed manual testing procedures.

Database Inspection

# Connect to database
docker exec -it notification-postgres psql -U notif_user -d notification_system

# View recent notifications
SELECT notification_id, status, notification_type, retry_count, created_at 
FROM notification_status 
ORDER BY created_at DESC 
LIMIT 10;

# Statistics
SELECT status, notification_type, COUNT(*) 
FROM notification_status 
GROUP BY status, notification_type;

🏗️ Development

Project Structure

notification-system/
├── apps/
│   ├── api-gateway/       # Main API entry point
│   ├── user-service/      # User management
│   ├── email-service/     # Email delivery
│   ├── push-service/      # Push notifications
│   └── template-service/  # Template management
├── docker/
│   ├── grafana/           # Grafana provisioning
│   ├── postgres/          # Database initialization
│   └── prometheus/        # Metrics configuration
├── docs/
│   └── diagrams/          # Architecture diagrams
├── k8s/                   # Plain Kubernetes manifests (kind/minikube)
├── charts/notification-system/  # Helm chart (staging/production)
├── docker-compose.yml     # Infrastructure orchestration
└── test-notifications.sh  # Automated test suite

Development Commands

# Install dependencies
npm install

# Start infrastructure only
npm run docker:up

# Start all microservices
npm run start:all

# Start individual service
npm run start:gateway    # API Gateway
npm run start:user       # User Service
npm run start:email      # Email Service
npm run start:push       # Push Service
npm run start:template   # Template Service

# Code quality
npm run format           # Format code with Prettier
npm run lint             # Lint code with ESLint
npm run lint:fix         # Auto-fix linting issues

# Stop infrastructure
npm run docker:down

# Clean all data
npm run docker:clean

Adding a New Service

  1. Create service directory in apps/
  2. Set up NestJS application
  3. Configure RabbitMQ consumer/producer
  4. Add health endpoint
  5. Register with service discovery (Redis)
  6. Update docker-compose.yml if needed
  7. Add to start:all script

🔒 Security

  • Authentication: JWT-based with refresh tokens
  • Authorization: Role-based access control
  • Rate Limiting: Configured per endpoint
  • Input Validation: class-validator decorators
  • Password Hashing: bcrypt with salt rounds
  • CORS: Configurable origins
  • Environment Variables: Secrets management
  • SQL Injection: TypeORM parameterized queries

🚢 Deployment

Docker (local / single-host)

See above for docker-compose up -d --build.

Kubernetes

Two ways to run this system on Kubernetes — see k8s/README.md for full details:

# Quick local cluster (kind/minikube) — plain manifests
kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/infra.yaml
kubectl apply -f k8s/services.yaml
kubectl apply -f k8s/ingress.yaml

# Staging/production — Helm chart with Bitnami Postgres/Redis/RabbitMQ subcharts
helm dependency update charts/notification-system
helm install notification-system charts/notification-system \
  --namespace notification-system --create-namespace \
  --set secrets.dbPassword=$(openssl rand -base64 24) \
  --set secrets.jwtSecret=$(openssl rand -base64 32)

All 5 microservices ship with readiness/liveness probes and HPAs where relevant. See charts/notification-system/values.yaml for every configurable knob (replicas, resources, image tags, ingress host, ServiceMonitor toggle).

See Deployment Guide for additional production deployment instructions covering:

  • Docker production builds
  • Environment configuration
  • SSL/TLS setup
  • Load balancing
  • Database migrations
  • Backup strategies

🐛 Troubleshooting

Service Won't Start

# Check Docker services
docker-compose ps

# View logs
docker-compose logs -f [service-name]

# Restart infrastructure
npm run docker:clean
docker-compose up -d

Database Connection Error

# Ensure database exists
docker exec notification-postgres psql -U notif_user -d postgres -c "CREATE DATABASE notification_system;"

# Check connection
docker exec -it notification-postgres psql -U notif_user -d notification_system

RabbitMQ Connection Refused

# Wait for RabbitMQ to fully initialize (~30 seconds)
docker logs notification-rabbitmq

# Check if port is accessible
curl http://localhost:15672

Push Notifications Not Working

  1. Verify Firebase credentials file path
  2. Check FIREBASE_SERVICE_ACCOUNT_PATH in push-service .env
  3. Ensure FCM token is valid
  4. Check push-service logs: docker-compose logs push-service

Email Not Sending

  1. Verify SMTP configuration in email-service .env
  2. Test SMTP credentials
  3. Check email-service logs
  4. Verify Mailtrap/SendGrid API keys

📊 Performance

  • Throughput: 10,000+ notifications/minute
  • Latency: <100ms API response time
  • Availability: 99.9% uptime
  • Queue Processing: 1000 messages/second
  • Database: Connection pooling (max 20)
  • Cache Hit Rate: >90% on service discovery

🤝 Contributing

  1. Fork the repository
  2. Create feature branch: git checkout -b feature/amazing-feature
  3. Commit changes: git commit -m 'feat: add amazing feature'
  4. Push to branch: git push origin feature/amazing-feature
  5. Open Pull Request

Commit Convention

Follow Conventional Commits:

  • feat: - New features
  • fix: - Bug fixes
  • docs: - Documentation changes
  • refactor: - Code refactoring
  • test: - Test additions/changes
  • chore: - Maintenance tasks

📄 License

This project is licensed under the ISC License.

👥 Authors

🙏 Acknowledgments

  • NestJS Framework
  • RabbitMQ Team
  • Firebase Cloud Messaging
  • Prometheus & Grafana
  • PostgreSQL & Redis Communities

📞 Support

🗺️ Roadmap

  • SMS notifications support
  • Slack/Discord integrations
  • WhatsApp Business API
  • Notification scheduling
  • A/B testing for templates
  • Advanced analytics dashboard
  • Multi-tenant support
  • GraphQL API
  • Webhook support
  • Mobile SDKs (iOS/Android)

Built with ❤️ using NestJS and TypeScript

About

Production-ready notification microservice — email & push via unified REST API. NestJS + RabbitMQ + Docker. Drop-in for any app. Self-hosted alternative to Courier, Novu, and Knock.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors