# Notification & Alert Microservice - Unified Specification

## Document Overview
This document unifies the original high-level specification with implementation plans from Claude and Grok. It serves as the single source of truth for building the real-time alert and notification microservice.

---

## 1. Project Overview

### 1.1 Purpose
Provide a **multi-tenant B2B microservice** that allows multiple applications (projects) to integrate and send events. The microservice evaluates incoming events and business state, then pushes real-time notifications to mobile apps which play sounds/alerts when conditions are matched. Each project has its own isolated configuration: rules, users, roles, and notifications. Admins configure rules/thresholds/roles via an Admin Panel per project. Notifications are role-aware and only delivered to authorized users within each project.

### 1.2 Goals
- **Multi-tenant B2B architecture**: Support multiple applications (projects) with complete data isolation
- Real-time audible alerts on mobile clients when admin-configurable conditions are met
- Pending transaction alerts
- Low transfer bucket alerts
- Role-filtered notifications
- Secure, reliable, auditable, and easy to extend
- Mobile users can tap notifications to open editable webview
- **Project-level API key authentication** for external applications to send events
- **Project management** for creating and managing multiple client applications

---

## 2. Architecture

### 2.1 High-Level Components
- **Alert Microservice**: REST API + Real-time notification service + Rule Engine + Worker pool + DB for rules & audit
- **Multi-Tenant Architecture**: Project-based isolation with API key authentication for external applications
- **Message Broker**: Redis Streams for event ingestion and reliable delivery (project-scoped)
- **Admin Panel**: UI for rule creation, role management, thresholds, user approvals per project (separate frontend)
- **Mobile App**: Real-time notification client, sound engine, webview launcher, push fallback (separate mobile app, project-scoped)
- **Authentication & Role Service**: 
  - JWT-based authentication for admin/user access
  - API key authentication for external applications (projects)
- **Project Management**: Create, manage, and configure multiple client applications

### 2.2 Technology Stack

#### Backend Core
- **Framework**: NestJS (TypeScript)
- **Database**: MySQL with TypeORM
- **Cache/Message Broker**: Redis (Streams for events, cache for sessions)
- **Queue System**: BullMQ (for background jobs and retries)
- **Real-time**: Pusher (for server-side notification triggering)
- **Authentication**: JWT with Passport.js
- **Validation**: class-validator, class-transformer
- **Logging**: Winston
- **API Documentation**: Swagger/OpenAPI

#### External Services
- **Push Notifications**: FCM (Android), APNs (iOS) - fallback mechanism
- **File Storage**: S3/CDN for sound assets
- **Security**: Helmet, CORS, Rate limiting

---

## 3. Core Concepts & Terminology

- **Project**: A client application that integrates with the microservice. Each project has isolated data (users, rules, notifications, etc.)
- **API Key**: Secret key used by external applications to authenticate and send events to the microservice
- **Event**: An incoming activity (pending transaction, balance update, etc.) emitted by an external application (project)
- **Rule**: Admin-configurable condition (e.g., `event.type=='pending_tx' && event.amount > 10000`) - scoped to a project
- **Notification**: A message derived from an Event that is sent to users (via Pusher + optional push) - scoped to a project
- **Role**: User role (MD, Finance, Ops, Admin, Support, etc.). Rules target roles - scoped to a project
- **Transfer Bucket**: Account/ledger that funds transfers; rules reference its balance - scoped to a project
- **Webview Action**: Notification action that opens a URL within the app; address bar is editable

---

## 4. Data Models

### 4.1 Project Entity
```typescript
{
  id: UUID (VARCHAR(36))
  name: VARCHAR(255) (unique)
  slug: VARCHAR(100) (unique, URL-friendly identifier)
  description: TEXT
  apiKey: VARCHAR(255) (hashed, unique)
  apiKeyHash: VARCHAR(255) (for authentication)
  webhookUrl: VARCHAR(500) (optional, for callbacks)
  status: ENUM ('active', 'suspended', 'inactive')
  settings: JSON {
    pusherAppId: string,
    pusherKey: string,
    pusherSecret: string,
    pusherCluster: string,
    defaultSound: string,
    rateLimitPerMinute: number
  }
  createdAt: DATETIME
  updatedAt: DATETIME
  INDEX on slug, apiKeyHash, status
}
```

### 4.2 Rule Entity
```typescript
{
  id: UUID (VARCHAR(36))
  projectId: UUID (foreign key to Project)
  name: VARCHAR(255)
  description: TEXT
  condition: TEXT (DSL expression)
  targetRoles: JSON (array of strings)
  sound: VARCHAR(255) (filename)
  priority: INT
  active: TINYINT(1) (boolean)
  createdBy: UUID (foreign key to User)
  createdAt: DATETIME
  updatedAt: DATETIME
  INDEX on projectId, active, priority
}
```

### 4.3 User Entity
```typescript
{
  id: UUID (VARCHAR(36))
  projectId: UUID (foreign key to Project)
  email: VARCHAR(255) (unique within project)
  phone: VARCHAR(20) (unique within project)
  password: VARCHAR(255) (hashed with bcrypt)
  roles: JSON (array of strings)
  status: ENUM ('pending', 'active', 'disabled', 'unverified')
  pushTokens: JSON { fcm: string, apns: string }
  pusherChannels: JSON (array of subscribed channels - cached in Redis)
  createdAt: DATETIME
  updatedAt: DATETIME
  INDEX on projectId, email, phone, status
  UNIQUE constraint on (projectId, email)
  UNIQUE constraint on (projectId, phone)
}
```

### 4.5 Event Entity
```typescript
{
  id: UUID (VARCHAR(36))
  projectId: UUID (foreign key to Project)
  type: VARCHAR(100) (indexed)
  payload: JSON
  source: VARCHAR(100)
  receivedAt: DATETIME
  processedAt: DATETIME (nullable)
  INDEX on projectId, type, receivedAt
}
```

Example pending_transaction payload:
```json
{
  "txId": "TX_123",
  "userId": "U_44",
  "userName": "Sarah Chinny",
  "amount": 5000,
  "currency": "NGN",
  "status": "pending",
  "meta": { "billType": "electricity" }
}
```

### 4.5 Event Entity
```typescript
{
  id: UUID (VARCHAR(36))
  projectId: UUID (foreign key to Project)
  type: VARCHAR(100) (indexed)
  payload: JSON
  source: VARCHAR(100)
  receivedAt: DATETIME
  processedAt: DATETIME (nullable)
  INDEX on projectId, type, receivedAt
}
```

### 4.6 Notification Entity
```typescript
{
  id: UUID (VARCHAR(36))
  projectId: UUID (foreign key to Project)
  ruleId: UUID (foreign key)
  eventId: UUID (foreign key)
  recipients: JSON (array of UUIDs)
  title: VARCHAR(255)
  message: TEXT
  sound: VARCHAR(255)
  action: JSON {
    type: "open_webview",
    url: "string",
    editableAddressBar: true
  }
  delivered: TINYINT(1) (boolean)
  pusherEventSent: TINYINT(1) (boolean)
  acknowledgedBy: JSON (array of UUIDs)
  createdAt: DATETIME
  deliveredAt: DATETIME (nullable)
  INDEX on projectId, ruleId, eventId, delivered, createdAt
}
```

### 4.7 AuditLog Entity
```typescript
{
  id: UUID (VARCHAR(36))
  projectId: UUID (foreign key to Project, nullable for system-level logs)
  action: VARCHAR(100)
  userId: UUID (nullable)
  resourceType: VARCHAR(50)
  resourceId: UUID
  metadata: JSON
  timestamp: DATETIME
  INDEX on projectId, userId, resourceType, timestamp
}
```

### 4.8 TransferBucket Entity
```typescript
{
  id: UUID (VARCHAR(36))
  projectId: UUID (foreign key to Project)
  name: VARCHAR(255)
  currentBalance: DECIMAL(19,4)
  threshold: DECIMAL(19,4)
  currency: VARCHAR(3)
  updatedAt: DATETIME
  INDEX on projectId, name
}
```

### 4.9 Role Entity
```typescript
{
  id: UUID (VARCHAR(36))
  projectId: UUID (foreign key to Project)
  name: VARCHAR(100) (unique within project)
  permissions: JSON (array of strings)
  description: TEXT
  createdAt: DATETIME
  INDEX on projectId, name
  UNIQUE constraint on (projectId, name)
}
```

---

## 5. REST API Endpoints

### 5.1 Project Management Endpoints (Super Admin)
- `POST /api/v1/projects` - Create new project (Super Admin only)
- `GET /api/v1/projects` - List all projects (Super Admin only)
- `GET /api/v1/projects/:id` - Get project details
- `PUT /api/v1/projects/:id` - Update project
- `DELETE /api/v1/projects/:id` - Delete project (soft delete)
- `POST /api/v1/projects/:id/regenerate-api-key` - Regenerate API key
- `GET /api/v1/projects/:id/stats` - Get project statistics

### 5.2 Project-Scoped Authentication Endpoints
- `POST /api/v1/auth/register` - User registration (sets status to 'pending', requires project context)
- `POST /api/v1/auth/login` - Login with JWT token generation (project-scoped)
- `POST /api/v1/auth/refresh` - Refresh token endpoint
- `POST /api/v1/auth/logout` - Logout

### 5.3 API Key Authentication (For External Applications)
- `POST /api/v1/events` - Ingest events (authenticated via API key in header: `X-API-Key`)
- All event endpoints require valid API key and are automatically scoped to the project
- `POST /api/v1/auth/register` - User registration (sets status to 'pending')
- `POST /api/v1/auth/login` - Login with JWT token generation
- `POST /api/v1/auth/refresh` - Refresh token endpoint
- `POST /api/v1/auth/logout` - Logout

### 5.4 Rules Endpoints (Project-Scoped)
- `POST /api/v1/rules` - Create rule (Admin/RuleManager only, scoped to user's project)
- `GET /api/v1/rules` - List rules with pagination and filters (project-scoped)
- `GET /api/v1/rules/:id` - Get single rule (project-scoped)
- `PUT /api/v1/rules/:id` - Update rule (project-scoped)
- `DELETE /api/v1/rules/:id` - Delete rule (project-scoped)

### 5.5 Notifications Endpoints (Project-Scoped)
- `GET /api/v1/notifications` - Get user's notifications with pagination
- `GET /api/v1/notifications/:id` - Get notification details
- `PUT /api/v1/notifications/:id/acknowledge` - Mark notification as acknowledged
- `POST /api/v1/notifications/:id/webview-action` - Log webview open action
- `GET /api/v1/notifications/unread-count` - Get unread notification count
- `DELETE /api/v1/notifications/:id` - Soft delete notification

### 5.6 Users Endpoints (Project-Scoped)
- `GET /api/v1/users/pending` - List pending users (Admin only)
- `POST /api/v1/users/:id/approve` - Approve user and assign roles
- `GET /api/v1/users/me` - Get current user profile
- `PUT /api/v1/users/me` - Update profile
- `PUT /api/v1/users/me/push-tokens` - Update push tokens
- `GET /api/v1/users/me/pusher-auth` - Generate Pusher auth signature for private channels

### 5.7 Roles Endpoints (Project-Scoped)
- `GET /api/v1/roles` - List all roles (project-scoped)
- `POST /api/v1/roles` - Create role (Admin only, project-scoped)
- `PUT /api/v1/roles/:id` - Update role (project-scoped)
- `DELETE /api/v1/roles/:id` - Delete role (project-scoped)

### 5.8 Audit Endpoints (Project-Scoped)
- `GET /api/v1/audit` - Query audit logs with filters (date, user, action, resourceType, project-scoped)
- `GET /api/v1/audit/export` - Export as CSV (project-scoped)

### 5.9 Transfer Buckets Endpoints (Project-Scoped)
- `GET /api/v1/transfer-buckets` - List buckets (project-scoped)
- `GET /api/v1/transfer-buckets/:id` - Get bucket details (project-scoped)
- `PUT /api/v1/transfer-buckets/:id/threshold` - Update threshold (project-scoped)

### 5.10 Sound Management Endpoints (Project-Scoped)
- `POST /api/v1/sounds` - Upload sound (project-scoped)
- `GET /api/v1/sounds` - List sounds (project-scoped)
- `DELETE /api/v1/sounds/:id` - Delete sound (project-scoped)

### 5.10 Health & Status Endpoints
- `GET /health` - Basic health check
- `GET /api/v1/status` - Detailed system status (Pusher connection, Redis, MySQL, queue health)

---

## 6. Real-time Notification Flow

### 6.1 Pusher Integration
- Use Pusher for server-side notification triggering only
- Private channels: `private-user-{userId}` for user-specific notifications
- Mobile/Frontend teams handle client-side Pusher subscription
- Backend triggers: `pusher.trigger('private-user-123', 'notification', payload)`
- Pusher auth endpoint: `POST /api/v1/users/me/pusher-auth` validates JWT and returns auth signature

### 6.2 Event Flow Sequence (Multi-Tenant)
1. **External Application** authenticates using API key (`X-API-Key` header)
2. **External Application** sends event to `POST /api/v1/events` (automatically scoped to project)
3. **Alert Microservice** validates API key, identifies project, stores event with projectId
4. **Alert Microservice** consumes events (from API or Redis Streams), evaluates active rules for that project
5. For matched rules, compute recipients by role (fetch active users with role within the project)
6. Create Notification records with projectId, log audit
7. Publish notification to users via project's Pusher configuration:
   - If Pusher channel subscribed: trigger Pusher event using project's Pusher credentials
   - Else: persist and queue for push (FCM/APNs) and mark `delivered=false`
8. Mobile client receives notification: plays sound, shows in-app banner
9. On tap, open webview with editable address bar
10. Mobile sends ack with read/play status
11. Admin UI shows delivery and audit logs (project-scoped)

---

## 7. Module Structure

### 7.1 Core Modules
1. **ProjectsModule** - Project CRUD, API key management, project settings
2. **AuthModule** - JWT authentication, API key authentication, guards, decorators
3. **RulesModule** - Rule CRUD, RuleEngineService (project-scoped)
4. **EventsModule** - Event ingestion, Redis Streams consumer, EventProcessorService (project-scoped)
5. **NotificationsModule** - Notification creation, PusherService, PushNotificationService, delivery logic (project-scoped)
6. **UsersModule** - User management, approval, profile, push tokens (project-scoped)
7. **RolesModule** - Role CRUD, permissions (project-scoped)
8. **AuditModule** - Audit logging, query, export (project-scoped)
9. **TransferBucketsModule** - Bucket management, threshold monitoring (project-scoped)
10. **SoundsModule** - Sound upload, management, CDN integration (project-scoped)

### 7.2 Common/Shared
- **Guards**: JwtAuthGuard, RolesGuard, ApiKeyGuard, ProjectGuard
- **Decorators**: @Roles(), @CurrentUser(), @CurrentProject(), @ProjectScoped()
- **Filters**: Global exception filter
- **Interceptors**: Logging, transformation, project context injection
- **Pipes**: Validation pipes
- **DTOs**: Request/response DTOs with validation
- **Services**: ProjectContextService (manages current project context)

---

## 8. Background Jobs (BullMQ Queues)

1. **event-processing-queue** - Process incoming events against rules
2. **notification-delivery-queue** - Deliver notifications with retry
3. **push-notification-queue** - Send push notifications (FCM/APNs)
4. **bucket-monitoring-queue** - Periodic check of transfer bucket balances
5. **alert-suppression-queue** - Handle alert storm suppression

---

## 9. Services

### 9.1 RuleEngineService
- Parse and evaluate condition expressions safely
- Use `expr-eval` or similar library
- Support operators: `==`, `!=`, `>`, `<`, `>=`, `<=`, `&&`, `||`
- Access event properties: `event.type`, `event.amount`, `event.payload.status`

### 9.2 NotificationDeliveryService
- Check user Pusher channel subscription status (query Redis, project-scoped)
- If subscribed: trigger via Pusher using project's Pusher credentials
- If offline: queue for push notification (BullMQ queue)
- Update notification.delivered status
- Use project-specific Pusher app configuration

### 9.3 PushNotificationService
- Integration with Firebase Cloud Messaging (FCM) for Android
- Integration with Apple Push Notification Service (APNs) for iOS
- Fallback when Pusher unavailable

### 9.4 SoundManagementService
- Upload sound files to S3/CDN
- Generate signed URLs with TTL
- Validate audio formats (mp3, ogg, wav)

---

## 10. Security Implementation

1. **Helmet** for HTTP headers security
2. **CORS** configuration for allowed origins
3. **Rate limiting** using `@nestjs/throttler` (per-project rate limits)
4. **Password hashing** with bcrypt (cost factor 12)
5. **API Key Authentication** for external applications:
   - API keys stored as hashed values
   - Validate API key on event ingestion endpoints
   - Automatically scope requests to project
6. **Input validation** using class-validator on all DTOs
7. **SQL injection prevention** via TypeORM parameterized queries
8. **XSS protection** by sanitizing inputs
9. **Role-based guards** on all sensitive endpoints
10. **JWT tokens** with short-lived access tokens and refresh tokens
11. **Project isolation** - ensure all queries are scoped to project
12. **TLS** for all traffic (HTTPS and WSS)

---

## 11. Reliability & Edge Cases

### 11.1 Delivery Guarantees
- Use durable message broker + worker retries (exponential backoff)
- Notification status: pending -> sent -> acked -> failed

### 11.2 Offline Users
- Queue notifications; deliver via Push (FCM/APNs) for backgrounded users
- On next connection, provide API to fetch missed notifications

### 11.3 Throttling & Deduplication
- Deduplicate events by eventId
- If multiple rules fire for same event for same user: merge into single notification (preferred)

### 11.4 Alert Storms
- Implement "alert suppression window" (configurable): if rule triggers > N times in M seconds for same scope, suppress or batch

### 11.5 Bad Sound URLs / Missing Assets
- Fallback to default sound in Notification record; log missing asset

---

## 12. Performance Optimizations

- MySQL indexing on frequently queried fields (userId, ruleId, eventType, createdAt, status)
- Use composite indexes for common query patterns
- Redis caching for active users, Pusher channel subscriptions, and frequently accessed rules
- Connection pooling for MySQL database
- Batch processing for high-volume events using Pusher batch API
- Alert deduplication and aggregation
- Optimize JSON column queries in MySQL

---

## 13. Logging & Monitoring

- Use Winston for structured logging
- Log levels: error, warn, info, debug
- Include correlation IDs for request tracing
- Audit all authentication attempts, rule changes, notification deliveries
- Retention policy: logs for 90 days in hot store, archived beyond

---

## 14. Testing Strategy

- Unit tests for services (RuleEngineService, NotificationService)
- Integration tests for controllers
- E2E tests for critical flows (auth, rule evaluation, notification delivery)
- Mock external services (FCM, APNs, Redis, Pusher)

---

## 15. Configuration

Use `@nestjs/config` for:
- Database connection (MySQL)
- Redis connection (cache and streams)
- JWT secrets and expiration
- Pusher configuration (app_id, key, secret, cluster)
- FCM/APNs credentials
- Rate limiting thresholds
- Alert suppression windows
- Audit log retention policy
- CDN/S3 configuration for sound files

---

## 16. Deployment Considerations

- Docker containerization with multi-stage build
- Health check endpoint: `GET /health`
- Graceful shutdown handling
- Environment-based configuration
- Separate worker processes for queue consumers

---

## 17. File Structure

```
src/
├── modules/
│   ├── projects/
│   ├── auth/
│   ├── rules/
│   ├── events/
│   ├── notifications/
│   ├── users/
│   ├── roles/
│   ├── audit/
│   ├── transfer-buckets/
│   └── sounds/
├── common/
│   ├── guards/
│   │   ├── api-key.guard.ts
│   │   ├── project.guard.ts
│   │   └── ...
│   ├── decorators/
│   │   ├── current-project.decorator.ts
│   │   └── ...
│   ├── filters/
│   ├── interceptors/
│   │   ├── project-context.interceptor.ts
│   │   └── ...
│   ├── pipes/
│   └── services/
│       └── project-context.service.ts
├── config/
├── database/
│   ├── entities/
│   └── migrations/
└── main.ts
```

---

## 18. UI/UX Requirements (Reference for Frontend Teams)

### 18.1 Mobile App Requirements
- Onboarding flow (registration, login, pending approval)
- Main dashboard with live status indicator
- Notification center with unread badges
- Sound toggle button
- Notification details screen
- Webview with editable address bar
- Settings screen

### 18.2 Admin Panel Requirements
- Admin login
- Dashboard with widgets (users, approvals, roles, system health)
- User management (list, approve, assign roles)
- Role management (create, edit, permissions)
- Notification/rule management (create, edit, assign roles)
- Sound library management
- System logs with filters

---

## 19. Implementation Priority

Build in this sequence:
1. Project setup and configuration
2. Database models and migrations with TypeORM (including Project entity)
3. **ProjectsModule** - Project CRUD and API key management
4. **API Key Authentication** - Guard and middleware for external applications
5. **Project Context Service** - Manage current project context across requests
6. AuthModule with JWT guards (project-scoped)
7. RolesModule and UsersModule (project-scoped)
8. RulesModule with basic CRUD (project-scoped)
9. EventsModule with API key authentication and Redis Streams consumer (project-scoped)
10. RuleEngineService for condition evaluation (project-scoped)
11. NotificationsModule with REST endpoints (project-scoped)
12. PusherService integration with project-specific credentials
13. NotificationDeliveryService with Pusher triggering (project-scoped)
14. Background jobs and BullMQ queues (project-scoped)
15. TransferBucketsModule and monitoring (project-scoped)
16. AuditModule and logging (project-scoped)
17. PushNotificationService integration (FCM/APNs fallback)
18. SoundManagementService with S3/CDN (project-scoped)
19. Testing and Swagger documentation

**Key Multi-Tenant Considerations:**
- All entities must include `projectId` foreign key
- All queries must be scoped to project
- API key authentication automatically sets project context
- JWT tokens include project context
- Pusher credentials are project-specific
- Rate limiting is per-project
- All endpoints (except project management) are project-scoped

Start with a minimal viable REST API focusing on project creation, API key authentication, and core notification flow, then add advanced features like alert suppression, push fallback, and bucket monitoring.

