Skip to content
salvatore-ardisi edited this page Mar 26, 2026 · 132 revisions

NotifyEngine


NotifyEngine Logo

NotifyEngine

ML-Powered Notification Delivery Service with Adaptive Channel Routing

Website


Project Description

NotifyEngine is an intelligent notification routing service that learns from user behavior to automatically choose the best delivery channel (email, SMS, push, or in‑app) for every message. Designed for developers and product teams sending high‑volume notifications, it replaces static routing rules with an XGBoost ML model that adapts per‑user in real time.

Unlike developer tools like Courier, Knock, or Novu that rely on fixed priority rules, and enterprise platforms like Braze or MoEngage that cost $50K+/year and aren't developer-first, NotifyEngine offers a simple API with per‑user ML routing that continuously improves with every notification sent.

Key outcomes: Higher engagement rates, lower SMS spending, circuit breaker during provider outages, and no manual routing logic to maintain.

Project Description as PDF | Download Project Description as DOCX


Team Members


Zeeya Ramani
Data Analyst / Developer

Salvatore Ardisi
AI Engineer / Developer

Rhythm Patel
AI Engineer / Developer

Dhawalshree Mengane
Data Analyst / Developer

Mohammed Nazir Yusif
Security Engineer / Project Manager

Krish Dhorajiya
AI Engineer / Tester

Architecture at a Glance

                                         ┌───────────────────┐
                                         │   React Dashboard │
                                         │  (Vite + Tailwind)│
                                         └────────┬──────────┘
                                                  │ HTTP + WebSocket
                                                  ▼
┌──────────┐    POST notifications       ┌──────────────────┐     ┌──────────────┐
│ Developer│ ──────────────────────────► │  API Server      │────►│ PostgreSQL   │
│  Client  │ ◄── 202 Accepted            │  Express + TS    │     │ (Multi-tenant│
└──────────┘                             └────────┬─────────┘     │  + RLS)      │
                                                  │ Enqueue       └──────────────┘
                                                  ▼                      ▲
                                         ┌─────────────────┐             │
                                         │  Redis + BullMQ │             │
                                         │  (Job Queue)    │             │
                                         └────────┬────────┘             │
                                                  │ Dequeue              │
                                                  ▼                      │
                                         ┌────────────────┐              │
                                         │   Worker       │──────────────┘
                                         │  (Delivery +   │
                                         │ Feature Ext.)  │
                                         └───┬────────┬───┘
                                             │        │
                              ┌──────────────┘        └──────────────────┐
                              ▼                                          ▼
                     ┌───────────────────┐                    ┌─────────────────────┐
                     │  ML Service       │                    │  Delivery Channels  │
                     │  FastAPI + XGBoost│                    │  Email              │
                     │  Epsilon-Greedy   │                    │  Push               │
                     └───────────────────┘                    │  SMS                │
                                                              │  In-App             │
                                                              └─────────────────────┘
Component Technology Purpose
API Server Node.js, Express, TypeScript Request handling, auth, validation, enqueuing
Worker Node.js, BullMQ, TypeScript Feature extraction, ML routing, delivery execution
ML Service Python, FastAPI, XGBoost Engagement prediction, epsilon-greedy exploration
Database PostgreSQL 16 Multi-tenant storage with row-level security
Cache/Queue Redis + BullMQ Async job processing, rate limiting, caching
Dashboard React, Vite, Tailwind, shadcn/ui Real-time analytics, routing intelligence, notification explorer
Real-time Socket.IO In-app delivery channel + live dashboard updates
Observability Prometheus, Grafana, Pino Metrics, dashboards, structured JSON logging
CI/CD Docker, GitHub Actions Containerized deployment, automated testing, secret scanning

Core Algorithms

Algorithm Role How It Works
XGBoost Channel Prediction Decision trees trained on delivery outcomes. Each tree corrects the previous tree's errors. Outputs per-channel engagement probability-highest wins.
Epsilon-Greedy Exploration Strategy 90% exploit (use model's best prediction), 10% explore (try alternative channels). Prevents the model from getting stuck on old data.
Circuit Breaker Reliability Monitors provider failure rates in real-time. Opens on threshold -> reroutes to next-best channel -> auto-recovers utilizing a half-open test after cooldown.

Diagrams

Architecture Diagram

graph TB
    subgraph Clients["CLIENTS / TENANTS"]
        APP1["App 1<br/>REST API Client"]
        APP2["App 2<br/>REST API Client"]
        APP3["App N<br/>REST API Client"]
    end

    subgraph API["API SERVER (Express + TypeScript)"]
        AUTH["API Key Auth<br/>SHA-256 Lookup"]
        VALID["Zod Validation<br/>Middleware"]
        RATE["Rate Limiter<br/>Token Bucket"]
        ROUTES["REST Endpoints<br/>/v1/notifications<br/>/v1/tenants<br/>/v1/channels"]
        SOCKETIO["Socket.IO Server<br/>Dashboard Events"]
    end

    subgraph Queue["MESSAGE QUEUE (Redis + BullMQ)"]
        CRIT["notifications:critical<br/>concurrency: 20"]
        HIGH["notifications:high<br/>concurrency: 10"]
        STD["notifications:standard<br/>concurrency: 5"]
        BULK["notifications:bulk<br/>concurrency: 2"]
        DLQ["notifications:dlq<br/>manual review"]
        RETRAIN["ml:retrain<br/>periodic"]
        ROLLUP["stats:rollup<br/>periodic"]
    end

    subgraph Worker["DELIVERY WORKER (Node.js + TypeScript)"]
        JOBPICK["Job Processor<br/>BullMQ Worker"]
        FEAT["Feature Extractor<br/>15-Feature Vector"]
        ROUTER["Channel Router<br/>Static / Adaptive / Forced"]
        CB["Circuit Breaker<br/>Per-Channel State"]
        EMAIL["Email Delivery<br/>Nodemailer / Mailtrap"]
        SMS["SMS Webhook<br/>Mock Provider"]
        WS["WebSocket Delivery<br/>Socket.IO"]
        WEBHOOK["Generic Webhook<br/>HMAC Signed"]
    end

    subgraph ML["ML SERVICE (Python + FastAPI)"]
        PREDICT["POST /predict<br/>XGBoost Inference"]
        TRAIN["POST /train<br/>Model Retraining"]
        SYNTH["Synthetic Data<br/>Generator"]
        MODEL["XGBoost Model<br/>.joblib Artifact"]
    end

    subgraph DB["POSTGRESQL 16"]
        TENANTS["tenants"]
        APIKEYS["api_keys<br/>SHA-256 Hashed"]
        CHANNELS["channels<br/>Circuit Breaker State"]
        NOTIF["notifications<br/>routing_decision JSONB"]
        DELIVERY["delivery_attempts<br/>feature_vector JSONB"]
        STATS["recipient_channel_stats<br/>Aggregated Metrics"]
        MODELMETA["model_metadata<br/>Accuracy + Importance"]
        USAGE["usage_records<br/>Per-Tenant Metering"]
        RLS["Row-Level Security<br/>app.current_tenant_id"]
    end

    subgraph Dashboard["DASHBOARD (React + Vite + TypeScript)"]
        DASH_UI["Admin Dashboard<br/>TanStack Query"]
        REALTIME["Real-Time Feed<br/>Socket.IO Client"]
        ROUTING_INT["Routing Intelligence<br/>Feature Importance"]
    end

    subgraph Observability["OBSERVABILITY"]
        PROM["Prometheus<br/>Metrics Collection"]
        GRAF["Grafana<br/>Dashboards"]
        PINO["Pino<br/>Structured JSON Logs"]
    end

    APP1 -->|"HTTPS + API Key"| AUTH
    APP2 -->|"HTTPS + API Key"| AUTH
    APP3 -->|"HTTPS + API Key"| AUTH

    AUTH --> VALID
    VALID --> RATE
    RATE --> ROUTES
    ROUTES -->|"Enqueue Job<br/>Return 202"| Queue
    ROUTES -->|"Read/Write"| DB

    API -->|"Pub/Sub Subscribe<br/>dashboard:events"| Queue
    SOCKETIO -->|"Broadcast Events"| Dashboard

    CRIT --> JOBPICK
    HIGH --> JOBPICK
    STD --> JOBPICK
    BULK --> JOBPICK

    JOBPICK --> FEAT
    FEAT -->|"Query Stats"| DB
    FEAT --> ROUTER
    ROUTER -->|"POST /predict"| PREDICT
    PREDICT --> MODEL
    ROUTER --> CB

    CB --> EMAIL
    CB --> SMS
    CB --> WS
    CB --> WEBHOOK

    EMAIL -->|"Record Attempt"| DB
    SMS -->|"Record Attempt"| DB
    WS -->|"Record Attempt"| DB
    WEBHOOK -->|"Record Attempt"| DB

    Worker -->|"Publish Events"| Queue

    TRAIN -->|"Read Training Data"| DB
    TRAIN --> MODEL
    TRAIN -->|"Store Metadata"| DB
    RETRAIN -->|"Trigger"| TRAIN
    ROLLUP -->|"Aggregate Stats"| DB

    DASH_UI -->|"REST API Only"| ROUTES
    REALTIME -->|"Socket.IO"| SOCKETIO

    Worker --> PINO
    API --> PINO
    ML --> PINO
    PROM -->|"Scrape Metrics"| API
    PROM -->|"Scrape Metrics"| Worker
    PROM -->|"Scrape Metrics"| ML
    PROM --> GRAF

    classDef apiStyle fill:#2563eb,stroke:#1d4ed8,color:#fff
    classDef workerStyle fill:#7c3aed,stroke:#6d28d9,color:#fff
    classDef mlStyle fill:#059669,stroke:#047857,color:#fff
    classDef dbStyle fill:#dc2626,stroke:#b91c1c,color:#fff
    classDef queueStyle fill:#d97706,stroke:#b45309,color:#fff
    classDef dashStyle fill:#0891b2,stroke:#0e7490,color:#fff
    classDef obsStyle fill:#4b5563,stroke:#374151,color:#fff

    class AUTH,VALID,RATE,ROUTES,SOCKETIO apiStyle
    class JOBPICK,FEAT,ROUTER,CB,EMAIL,SMS,WS,WEBHOOK workerStyle
    class PREDICT,TRAIN,SYNTH,MODEL mlStyle
    class TENANTS,APIKEYS,CHANNELS,NOTIF,DELIVERY,STATS,MODELMETA,USAGE,RLS dbStyle
    class CRIT,HIGH,STD,BULK,DLQ,RETRAIN,ROLLUP queueStyle
    class DASH_UI,REALTIME,ROUTING_INT dashStyle
    class PROM,GRAF,PINO obsStyle
Loading

Service Boundaries

Service Technology Responsibility Does NOT
API Server Express + TypeScript Auth, validation, rate limiting, enqueue, REST endpoints, Socket.IO dashboard events Deliver notifications, call ML service, process BullMQ jobs
Worker Node.js + BullMQ Job processing, feature extraction, ML routing calls, delivery execution, outcome recording Serve HTTP endpoints, train ML models
ML Service Python + FastAPI XGBoost prediction, model training, synthetic data generation Serve notifications, connect to queue
Dashboard React + Vite Admin UI, real-time feed, routing intelligence visualization Connect to DB directly, call ML service
PostgreSQL PostgreSQL 16 All persistent data with Row-Level Security per tenant -
Redis Redis 7 + BullMQ Job queuing, rate limiting, usage counters, pub/sub events -

ER Diagram

Context Diagram

Sequence Diagram


Languages and Tools

Languages & Frameworks

TypeScript Node.js Express React Vite Python FastAPI

ML & Data Science

XGBoost scikit--learn pandas

Databases & Infrastructure

PostgreSQL Redis Socket.IO BullMQ

UI

Tailwind CSS shadcn/ui

Validation

Zod Pydantic

Observability

Prometheus Grafana Pino

Testing

Jest pytest

DevOps & CI/CD

Docker GitHub Actions

Tools

GitHub Jira Slack VS Code Claude ChatGPT


CS691 - Spring 2026 Deliverables


Presentations (Sprint Reviews)

Sprint 0

  1. Watch Sprint 0 Presentation Video | Click here to download mp4 File
    0a. View Sprint 0 Presentation Slides as PDF
    0b. Download Sprint 0 Presentation Slides as PowerPoint

Sprint 1

  1. Watch Sprint 1 Presentation Video | Click here to download mp4 File
    1a. View Sprint 1 Presentation Slides as PDF
    1b. Download Sprint 1 Presentation Slides as PowerPoint
    1c. Prototype
    1d. Watch Sprint 1 Demo Video | Click here to download mp4 File
    1e. Sprint 1 Source Code

Sprint Burndown Charts and Completed Tasks

  1. Sprint 0 Completed Tasks
  2. Sprint 1 Burndown Chart and Completed Tasks

Sprint Planning

  1. Watch Sprint 1 Planning Recording
  2. Watch Sprint 2 Planning Recording

Retrospectives

  1. Watch Sprint 0 Retrospective Video | Click here to download mp4 File
  2. Watch Sprint 1 Retrospective Video | Click here to download mp4 File

Team Working Agreement

Team Working Agreement as PDF | Download Team Working Agreement as DOCX


Architecture Diagrams


Additional Project Artifacts


Product Personas

Sarah Kim Daniel Ross Amanda Lopez
Backend Developer Persona PDF Product Manager Persona PDF Growth Lead Persona PDF

User Stories w/ Acceptance Criteria


Acceptance Criteria


Application Test Cases


Monorepo Structure

notifyengine/
├── apps/
│   ├── api/              # Node.js Express API server (TypeScript)
│   ├── worker/           # BullMQ queue workers (TypeScript)
│   ├── ml-service/       # Python FastAPI ML prediction + training
│   └── dashboard/        # React admin dashboard (Vite + Tailwind)
├── packages/
│   └── shared/           # Shared TypeScript types + constants
├── infra/
│   ├── migrations/       # PostgreSQL migrations (numbered, sequential)
│   ├── seed/             # Database seed scripts
│   └── migrate.ts        # Migration runner
├── scripts/              # Dev setup and utility scripts
├── .github/workflows/    # CI/CD + TruffleHog secret scanning
├── docker-compose.yml    # Dev infrastructure (Postgres, Redis, Mailpit, ML)
├── turbo.json            # Turborepo pipeline config
├── .env.example          # Environment variable template
├── package.json          # Root workspace config
├── README.md
└── CLAUDE.md             # Project config with coding standards + security rules

Clone this wiki locally