# Multi-Tenant Notification Microservice - B2B Specification

## Document Overview
This document specifies a B2B multi-tenant notification platform where multiple client applications can integrate, manage their own users, rules, and notifications independently with complete isolation.

---

## 1. Project Overview

### 1.1 Purpose
Provide a SaaS notification platform that allows multiple client applications (projects) to:
- Register and manage their own notification infrastructure
- Send events from their applications via API
- Configure custom rules and alerts for their users
- Deliver real-time notifications to their mobile users
- Manage their own user base with role-based access

### 1.2 Goals
- Multi-tenant architecture with complete data isolation
- Self-service project registration and API key management
- Per-project billing and usage tracking
- Scalable to handle multiple high-volume clients
- White-label capability for client branding
- Secure API authentication per project
- Real-time audible alerts with project-specific sounds
- Mobile SDK for easy client integration

---

## 2. Architecture

### 2.1 High-Level Components
- **Platform API**: Multi-tenant REST API with project isolation
- **Project Management Service**: Project registration, API keys, billing
- **Event Ingestion Layer**: Per-project event validation and routing
- **Rule Engine**: Project-scoped rule evaluation
- **Notification Delivery Service**: Pusher + Push notification delivery
- **Platform Admin Panel**: Super admin dashboard for platform management
- **Client Admin Panel**: Per-project admin dashboard (white-labeled)
- **Mobile SDK**: Drop-in SDK for iOS/Android integration
- **Message Broker**: Redis Streams with project-based channels
- **Metrics & Analytics**: Per-project usage, delivery rates, performance

### 2.2 Technology Stack
(Same as original + additions)

#### Additional Components
- **API Gateway**: Rate limiting, routing per project
- **Tenant Management**: Project isolation middleware
- **Usage Tracking**: Metrics collection per project
- **Billing Integration**: Stripe/payment gateway hooks
- **SDK Generator**: Auto-generate client libraries

---

## 3. Multi-Tenant Core Concepts

### 3.1 Projects (Tenants)
- **Project**: A registered client application with isolated resources
- **API Key**: Per-project authentication credentials (API key + secret)
- **Namespace**: Logical isolation boundary for all resources
- **Quota**: Per-project limits (events/month, notifications/month, users)
- **Webhook**: Optional callback URL for delivery confirmations

### 3.2 Isolation Model
- **Database**: Tenant ID column on all entities (project_id)
- **Redis**: Namespaced keys (`project:{projectId}:*`)
- **Pusher**: Per-project app instances or namespaced channels
- **Storage**: Project-scoped folders for sound assets

### 3.3 Authentication Levels
1. **Platform Level**: Super admin access (manages all projects)
2. **Project Level**: Project admin access (manages their project)
3. **End User Level**: Mobile app users (receive notifications)
4. **API Level**: Server-to-server (project's backend → platform API)

---

## 4. Enhanced Data Models

### 4.1 Project Entity (NEW)
```typescript
{
  id: UUID (VARCHAR(36))
  name: VARCHAR(255)
  slug: VARCHAR(100) (unique, URL-safe)
  apiKey: VARCHAR(64) (unique, indexed)
  apiSecret: VARCHAR(128) (hashed)
  status: ENUM ('active', 'suspended', 'trial', 'cancelled')
  plan: ENUM ('free', 'starter', 'professional', 'enterprise')
  
  // Branding
  logoUrl: VARCHAR(500)
  brandColor: VARCHAR(7) (#HEX)
  customDomain: VARCHAR(255) (nullable)
  
  // Configuration
  webhookUrl: VARCHAR(500) (nullable)
  webhookSecret: VARCHAR(128) (nullable)
  pusherConfig: JSON {
    appId: string,
    key: string,
    secret: string,
    cluster: string
  }
  
  // Quotas & Usage
  quotaEventsPerMonth: INT
  quotaNotificationsPerMonth: INT
  quotaUsers: INT
  currentUsage: JSON {
    eventsThisMonth: number,
    notificationsThisMonth: number,
    activeUsers: number
  }
  
  // Billing
  billingEmail: VARCHAR(255)
  stripeCustomerId: VARCHAR(100)
  subscriptionId: VARCHAR(100)
  
  // Metadata
  ownerId: UUID (foreign key to PlatformAdmin)
  createdAt: DATETIME
  updatedAt: DATETIME
  lastEventAt: DATETIME
}
```

### 4.2 Modified User Entity
```typescript
{
  id: UUID (VARCHAR(36))
  projectId: UUID (foreign key to Project) // NEW - tenant isolation
  email: VARCHAR(255)
  phone: VARCHAR(20)
  password: VARCHAR(255) (hashed)
  roles: JSON (project-scoped roles)
  status: ENUM ('pending', 'active', 'disabled', 'unverified')
  
  externalUserId: VARCHAR(255) (nullable) // NEW - client's user ID
  metadata: JSON (custom fields from client)
  
  pushTokens: JSON { fcm: string, apns: string }
  pusherChannels: JSON
  
  createdAt: DATETIME
  updatedAt: DATETIME
  
  UNIQUE INDEX on (projectId, email)
  UNIQUE INDEX on (projectId, externalUserId)
}
```

### 4.3 Modified Rule Entity
```typescript
{
  id: UUID (VARCHAR(36))
  projectId: UUID (foreign key to Project) // NEW
  name: VARCHAR(255)
  description: TEXT
  condition: TEXT
  targetRoles: JSON
  sound: VARCHAR(255)
  priority: INT
  active: TINYINT(1)
  createdBy: UUID (foreign key to User)
  createdAt: DATETIME
  updatedAt: DATETIME
  
  INDEX on (projectId, active)
}
```

### 4.4 Modified Event Entity
```typescript
{
  id: UUID (VARCHAR(36))
  projectId: UUID (foreign key to Project) // NEW
  type: VARCHAR(100)
  payload: JSON
  source: VARCHAR(100)
  
  // Client tracking
  clientEventId: VARCHAR(255) (nullable) // Client's event ID
  clientTimestamp: DATETIME (nullable)
  
  receivedAt: DATETIME
  processedAt: DATETIME (nullable)
  
  INDEX on (projectId, type, receivedAt)
  UNIQUE INDEX on (projectId, clientEventId)
}
```

### 4.5 Modified Notification Entity
```typescript
{
  id: UUID (VARCHAR(36))
  projectId: UUID (foreign key to Project) // NEW
  ruleId: UUID (foreign key)
  eventId: UUID (foreign key)
  recipients: JSON
  title: VARCHAR(255)
  message: TEXT
  sound: VARCHAR(255)
  action: JSON
  delivered: TINYINT(1)
  pusherEventSent: TINYINT(1)
  acknowledgedBy: JSON
  
  // Delivery tracking
  deliveryAttempts: INT (default 0)
  lastDeliveryAttempt: DATETIME (nullable)
  deliveryError: TEXT (nullable)
  
  createdAt: DATETIME
  deliveredAt: DATETIME (nullable)
  
  INDEX on (projectId, createdAt)
}
```

### 4.6 Modified AuditLog Entity
```typescript
{
  id: UUID (VARCHAR(36))
  projectId: UUID (foreign key to Project) // NEW - null for platform actions
  action: VARCHAR(100)
  userId: UUID (nullable)
  resourceType: VARCHAR(50)
  resourceId: UUID
  metadata: JSON
  ipAddress: VARCHAR(45)
  userAgent: TEXT
  timestamp: DATETIME
  
  INDEX on (projectId, timestamp)
  INDEX on (projectId, userId, timestamp)
}
```

### 4.7 ProjectApiKey Entity (NEW)
```typescript
{
  id: UUID (VARCHAR(36))
  projectId: UUID (foreign key to Project)
  name: VARCHAR(255) (e.g., "Production Server", "Staging")
  key: VARCHAR(64) (unique, indexed)
  secret: VARCHAR(128) (hashed)
  permissions: JSON ['events:write', 'users:manage', 'notifications:read']
  status: ENUM ('active', 'revoked')
  lastUsedAt: DATETIME (nullable)
  expiresAt: DATETIME (nullable)
  createdBy: UUID
  createdAt: DATETIME
  
  INDEX on (projectId, status)
  UNIQUE INDEX on (key)
}
```

### 4.8 UsageMetrics Entity (NEW)
```typescript
{
  id: UUID (VARCHAR(36))
  projectId: UUID (foreign key to Project)
  period: DATE (YYYY-MM-DD for daily, YYYY-MM for monthly)
  periodType: ENUM ('daily', 'monthly')
  
  eventsReceived: INT
  notificationsSent: INT
  notificationsDelivered: INT
  notificationsFailed: INT
  activeUsers: INT
  apiCalls: INT
  storageUsedBytes: BIGINT
  
  createdAt: DATETIME
  
  UNIQUE INDEX on (projectId, period, periodType)
}
```

### 4.9 PlatformAdmin Entity (NEW)
```typescript
{
  id: UUID (VARCHAR(36))
  email: VARCHAR(255) (unique)
  password: VARCHAR(255) (hashed)
  name: VARCHAR(255)
  role: ENUM ('super_admin', 'support', 'billing')
  status: ENUM ('active', 'disabled')
  lastLoginAt: DATETIME
  createdAt: DATETIME
  updatedAt: DATETIME
}
```

### 4.10 WebhookLog Entity (NEW)
```typescript
{
  id: UUID (VARCHAR(36))
  projectId: UUID (foreign key to Project)
  eventType: VARCHAR(100) (e.g., 'notification.delivered')
  payload: JSON
  responseStatus: INT (nullable)
  responseBody: TEXT (nullable)
  attemptNumber: INT
  success: TINYINT(1)
  error: TEXT (nullable)
  createdAt: DATETIME
  
  INDEX on (projectId, createdAt)
}
```

---

## 5. REST API Endpoints

### 5.1 Platform Management (Super Admin Only)
- `POST /api/v1/platform/projects` - Create new project
- `GET /api/v1/platform/projects` - List all projects
- `GET /api/v1/platform/projects/:id` - Get project details
- `PUT /api/v1/platform/projects/:id` - Update project
- `DELETE /api/v1/platform/projects/:id` - Delete/suspend project
- `GET /api/v1/platform/metrics` - Platform-wide metrics
- `POST /api/v1/platform/admins` - Create platform admin
- `GET /api/v1/platform/usage` - Usage analytics across all projects

### 5.2 Project Management (Project Admin)
- `GET /api/v1/projects/me` - Get current project details
- `PUT /api/v1/projects/me` - Update project settings
- `POST /api/v1/projects/me/api-keys` - Generate new API key
- `GET /api/v1/projects/me/api-keys` - List API keys
- `DELETE /api/v1/projects/me/api-keys/:id` - Revoke API key
- `PUT /api/v1/projects/me/branding` - Update branding
- `PUT /api/v1/projects/me/webhook` - Configure webhook
- `GET /api/v1/projects/me/usage` - Get usage metrics
- `GET /api/v1/projects/me/billing` - Billing information

### 5.3 Event Ingestion (API Key Auth)
- `POST /api/v1/events` - Send event (requires API key header)
- `POST /api/v1/events/batch` - Send multiple events
- `GET /api/v1/events/:id` - Get event status

### 5.4 User Management (Project-Scoped)
- `POST /api/v1/users` - Create user (API key or admin)
- `GET /api/v1/users` - List users (project-scoped)
- `GET /api/v1/users/:id` - Get user details
- `PUT /api/v1/users/:id` - Update user
- `DELETE /api/v1/users/:id` - Delete user
- `POST /api/v1/users/sync` - Bulk sync users from client system
- `POST /api/v1/users/:id/approve` - Approve pending user

### 5.5 Rules Management (Project-Scoped)
- `POST /api/v1/rules` - Create rule
- `GET /api/v1/rules` - List rules
- `GET /api/v1/rules/:id` - Get rule
- `PUT /api/v1/rules/:id` - Update rule
- `DELETE /api/v1/rules/:id` - Delete rule
- `POST /api/v1/rules/:id/test` - Test rule against sample event

### 5.6 Notifications (Project-Scoped)
- `GET /api/v1/notifications` - List notifications
- `GET /api/v1/notifications/:id` - Get notification
- `PUT /api/v1/notifications/:id/acknowledge` - Acknowledge
- `GET /api/v1/notifications/stats` - Notification statistics

### 5.7 Roles Management (Project-Scoped)
- `POST /api/v1/roles` - Create role
- `GET /api/v1/roles` - List roles
- `PUT /api/v1/roles/:id` - Update role
- `DELETE /api/v1/roles/:id` - Delete role

### 5.8 Audit & Analytics (Project-Scoped)
- `GET /api/v1/audit` - Query audit logs
- `GET /api/v1/audit/export` - Export audit logs
- `GET /api/v1/analytics/delivery-rates` - Notification delivery analytics
- `GET /api/v1/analytics/user-engagement` - User engagement metrics

### 5.9 Sounds Management (Project-Scoped)
- `POST /api/v1/sounds` - Upload sound
- `GET /api/v1/sounds` - List sounds
- `DELETE /api/v1/sounds/:id` - Delete sound

### 5.10 Webhooks (Platform → Client)
- `POST {client_webhook_url}` - Delivery confirmations, events

---

## 6. Multi-Tenant Authentication

### 6.1 API Key Authentication (Server-to-Server)
Headers required for event ingestion:
```
X-API-Key: project_abc123_key
X-API-Secret: project_abc123_secret
Content-Type: application/json
```

Validation flow:
1. Extract API key from header
2. Query ProjectApiKey table
3. Verify secret hash matches
4. Check permissions and status
5. Attach projectId to request context
6. Apply rate limits based on project plan

### 6.2 JWT Authentication (Admin/User)
- Platform admins: `Authorization: Bearer {platform_admin_token}`
- Project admins: `Authorization: Bearer {project_admin_token}`
- End users: `Authorization: Bearer {user_token}`

JWT payload includes:
```json
{
  "sub": "user_id",
  "projectId": "project_id",
  "roles": ["admin", "finance"],
  "type": "user|project_admin|platform_admin",
  "iat": 1234567890,
  "exp": 1234567890
}
```

### 6.3 Tenant Isolation Middleware
Every request automatically filters by `projectId`:
```typescript
// Automatically injected in all queries
@Query() where: { projectId: context.projectId }
```

---

## 7. Event Ingestion Flow (Multi-Tenant)

### 7.1 Client Application → Platform
```typescript
// Client's backend sends event
POST /api/v1/events
Headers: {
  "X-API-Key": "pk_live_abc123",
  "X-API-Secret": "sk_live_xyz789"
}
Body: {
  "type": "pending_transaction",
  "clientEventId": "tx_client_12345", // Optional deduplication
  "payload": {
    "userId": "user_44", // Client's user ID
    "amount": 5000,
    "currency": "NGN",
    "meta": {}
  },
  "timestamp": "2025-12-03T10:30:00Z"
}
```

### 7.2 Platform Processing
1. Authenticate API key → resolve projectId
2. Validate event schema
3. Check project quotas (events/month)
4. Store event with projectId
5. Publish to Redis Streams: `project:{projectId}:events`
6. Background worker processes event
7. Evaluate project-scoped rules
8. Create notifications for matching users
9. Deliver via Pusher + push notifications
10. Send webhook to client (if configured)
11. Update usage metrics

---

## 8. Project Onboarding Flow

### 8.1 Self-Service Registration
1. Visit platform website → Sign up
2. Create account (becomes project owner)
3. Fill project details (name, description)
4. Select plan (free trial → paid)
5. Platform generates:
   - Project ID
   - Initial API key pair
   - Pusher credentials (or use shared with namespace)
6. Redirect to client admin dashboard
7. Complete setup wizard:
   - Upload logo
   - Configure webhook
   - Create first rule
   - Test with sample event
8. SDK integration guide with code samples

### 8.2 API Key Generation
```
API Key Format: pk_{env}_{random}
API Secret Format: sk_{env}_{random}

Example:
pk_live_a1b2c3d4e5f6
sk_live_x9y8z7w6v5u4
```

---

## 9. Quota Management & Billing

### 9.1 Plan Tiers
```typescript
{
  free: {
    eventsPerMonth: 1000,
    notificationsPerMonth: 5000,
    users: 100,
    rules: 5,
    sounds: 3,
    webhook: false,
    customDomain: false
  },
  starter: {
    eventsPerMonth: 50000,
    notificationsPerMonth: 100000,
    users: 1000,
    rules: 25,
    sounds: 10,
    webhook: true,
    customDomain: false,
    price: 49 // USD/month
  },
  professional: {
    eventsPerMonth: 500000,
    notificationsPerMonth: 1000000,
    users: 10000,
    rules: 100,
    sounds: 50,
    webhook: true,
    customDomain: true,
    price: 199
  },
  enterprise: {
    eventsPerMonth: "unlimited",
    notificationsPerMonth: "unlimited",
    users: "unlimited",
    rules: "unlimited",
    sounds: "unlimited",
    webhook: true,
    customDomain: true,
    dedicatedSupport: true,
    sla: true,
    price: "custom"
  }
}
```

### 9.2 Usage Enforcement
- Real-time quota checks on event ingestion
- Soft limit: warning at 80% usage
- Hard limit: reject requests at 100%
- Email notifications to billing contact
- Grace period before suspension

### 9.3 Billing Integration
- Stripe for subscription management
- Monthly billing cycle
- Overage charges for exceeded quotas
- Webhook for payment failures → suspend project

---

## 10. Multi-Tenant Module Structure

```
src/
├── modules/
│   ├── platform/           # NEW - Platform management
│   │   ├── projects/
│   │   ├── admins/
│   │   ├── metrics/
│   │   └── billing/
│   ├── tenant/             # NEW - Tenant isolation
│   │   ├── middleware/
│   │   ├── guards/
│   │   └── decorators/
│   ├── api-keys/           # NEW - API key management
│   ├── webhooks/           # NEW - Webhook delivery
│   ├── usage/              # NEW - Usage tracking
│   ├── auth/               # Modified for multi-tenant
│   ├── rules/              # Project-scoped
│   ├── events/             # Project-scoped
│   ├── notifications/      # Project-scoped
│   ├── users/              # Project-scoped
│   ├── roles/              # Project-scoped
│   ├── audit/              # Project-scoped
│   └── sounds/             # Project-scoped
├── common/
│   ├── guards/
│   │   ├── api-key.guard.ts
│   │   ├── tenant.guard.ts
│   │   └── jwt-auth.guard.ts
│   ├── decorators/
│   │   ├── current-project.decorator.ts
│   │   └── require-api-key.decorator.ts
│   ├── middleware/
│   │   └── tenant-context.middleware.ts
│   └── interceptors/
│       └── quota-check.interceptor.ts
└── sdk/                    # NEW - Client SDK generation
    ├── templates/
    └── generator/
```

---

## 11. Mobile SDK Integration

### 11.1 SDK Features
- Easy initialization with API key
- User registration/authentication
- Pusher channel subscription
- Notification reception and display
- Sound playback
- Webview integration
- Acknowledgment callbacks

### 11.2 SDK Usage Example (React Native)
```javascript
import NotificationSDK from '@your-platform/notification-sdk';

// Initialize
const sdk = NotificationSDK.init({
  apiKey: 'pk_live_abc123',
  projectId: 'project_123'
});

// Register user
await sdk.users.register({
  email: 'user@example.com',
  externalUserId: 'user_44',
  roles: ['user']
});

// Listen for notifications
sdk.notifications.onReceived((notification) => {
  sdk.sounds.play(notification.sound);
  showInAppBanner(notification);
});

// Acknowledge
sdk.notifications.acknowledge(notificationId);
```

---

## 12. White-Label Admin Panel

### 12.1 Branding Support
- Upload project logo
- Custom primary color
- Custom domain (CNAME: admin.clientdomain.com → platform)
- Email templates with project branding
- Customizable notification templates

### 12.2 Admin Panel Features
- Dashboard (usage, notifications, users)
- Rule builder (visual + code editor)
- User management
- Role management
- Analytics & reports
- API key management
- Webhook configuration
- Sound library
- Settings

---

## 13. Webhooks (Platform → Client)

### 13.1 Webhook Events
```typescript
{
  "event": "notification.delivered",
  "projectId": "project_123",
  "timestamp": "2025-12-03T10:30:00Z",
  "data": {
    "notificationId": "notif_456",
    "userId": "user_44",
    "eventId": "event_789",
    "status": "delivered",
    "deliveredAt": "2025-12-03T10:30:05Z"
  },
  "signature": "sha256=..." // HMAC signature for verification
}
```

### 13.2 Event Types
- `notification.delivered`
- `notification.failed`
- `notification.acknowledged`
- `user.registered`
- `quota.warning` (80% usage)
- `quota.exceeded`

---

## 14. Security Enhancements

### 14.1 API Key Security
- Secrets hashed with bcrypt
- Keys rotate-able without downtime
- Permission scoping per key
- IP whitelisting (enterprise)
- Rate limiting per key
- Automatic revocation after X failed attempts

### 14.2 Tenant Isolation
- Row-level security (projectId filtering)
- Separate Redis namespaces
- Separate Pusher apps or channels
- Storage path isolation
- Query-level tenant guards

### 14.3 Webhook Security
- HMAC signature verification
- Retry logic with exponential backoff
- Timeout configuration
- IP whitelisting option

---

## 15. Implementation Priority (Revised)

### Phase 1: Core Multi-Tenant Foundation
1. Project setup with TypeORM + Redis
2. Project entity and platform admin auth
3. API key authentication system
4. Tenant isolation middleware
5. Basic event ingestion (API key auth)

### Phase 2: Notification Engine
6. Multi-tenant rules engine
7. Project-scoped users and roles
8. Notification creation and delivery
9. Pusher integration (namespaced)
10. Basic admin panel (project-scoped)

### Phase 3: Platform Features
11. Usage tracking and quotas
12. Webhook delivery system
13. Platform admin dashboard
14. Billing integration (Stripe)
15. White-label branding

### Phase 4: Advanced Features
16. Mobile SDK (iOS/Android)
17. Push notification fallback (FCM/APNs)
18. Analytics and reporting
19. Self-service project registration
20. Advanced rule builder UI

---

## 16. Deployment Architecture

### 16.1 Multi-Tenant Scaling
- Horizontal scaling of API servers
- Dedicated Redis instances per tier (free/paid)
- Database read replicas
- CDN for sound assets
- Queue workers per project (enterprise)
- Regional deployments

### 16.2 Monitoring
- Per-project metrics dashboards
- Alerting for quota breaches
- Delivery rate monitoring
- API latency per project
- Error tracking with project context

---

## 17. Migration Path for Existing Clients

For clients already using the original single-tenant version:
1. Create Project entity for existing client
2. Generate API keys
3. Backfill projectId on existing data
4. Update API calls to include API key headers
5. Deploy updated mobile app with SDK
6. Switch DNS for admin panel

---

## 18. API Documentation & Developer Portal

### 18.1 Features
- Interactive API docs (Swagger)
- SDKs in multiple languages
- Code samples for common scenarios
- Webhook testing tools
- Sandbox environment
- Migration guides
- Video tutorials
- Community forum

### 18.2 Example Code Snippets
```bash
# Send event via cURL
curl -X POST https://api.platform.com/api/v1/events \
  -H "X-API-Key: pk_live_abc123" \
  -H "X-API-Secret: sk_live_xyz789" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "order.completed",
    "payload": {
      "orderId": "ord_123",
      "amount": 5000
    }
  }'
```

---

## 19. Success Metrics

Track per project:
- Event ingestion rate
- Notification delivery rate
- Average delivery latency
- User engagement (acknowledgment rate)
- API error rate
- Webhook success rate

Platform-wide:
- Total projects
- Monthly recurring revenue (MRR)
- Churn rate
- Average events per project
- Support ticket volume

---

This specification now supports a fully multi-tenant B2B SaaS model where multiple client applications can independently integrate, manage users, and send notifications through a unified platform with complete data isolation and white-label capabilities.