Assist_Design/docs/SYSTEM-ARCHITECTURE.md

572 lines
20 KiB
Markdown

# System Architecture
**Customer Portal - Comprehensive System Design**
---
## Table of Contents
1. [System Overview](#system-overview)
2. [Architecture Principles](#architecture-principles)
3. [Monorepo Structure](#monorepo-structure)
4. [Application Layers](#application-layers)
5. [Domain Layer](#domain-layer)
6. [Technology Stack](#technology-stack)
7. [Data Flow & Integration](#data-flow--integration)
8. [Deployment Architecture](#deployment-architecture)
---
## System Overview
The Customer Portal is a modern full-stack application built with clean architecture principles. It provides customers with a self-service portal to manage their telecommunications services, billing, and support cases.
### High-Level Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ Customer Portal │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ │ │ │ │
│ │ Portal │──────────────│ BFF │ │
│ │ (Next.js) │ REST/ │ (NestJS) │ │
│ │ │ GraphQL │ │ │
│ └──────────────┘ └──────┬───────┘ │
│ │ │
│ ┌────────────────────────────────────┴─────────────────┐ │
│ │ Domain Package │ │
│ │ (Shared Types, Schemas, Validators) │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌───────────────────┼───────────────────┐
│ │ │
┌───────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ │ │ │ │ │
│ Salesforce │ │ WHMCS │ │ Freebit │
│ CRM │ │ Billing │ │ SIM Mgmt │
│ │ │ │ │ │
└──────────────┘ └─────────────┘ └─────────────┘
```
### Key Components
- **Portal (Frontend)**: Next.js 14+ with App Router, React 18, TypeScript
- **BFF (Backend for Frontend)**: NestJS with clean architecture layers
- **Domain Package**: Framework-agnostic shared types and business logic
- **External Systems**: Salesforce (CRM), WHMCS (Billing), Freebit (SIM management)
---
## Architecture Principles
### 1. Clean Architecture
The system follows clean architecture principles with clear separation of concerns:
- **Presentation Layer**: UI components, pages, controllers
- **Application Layer**: Use cases, orchestration, business workflows
- **Domain Layer**: Business entities, rules, and logic
- **Infrastructure Layer**: External integrations, databases, APIs
### 2. Domain-Driven Design
- Business domains organized as independent modules
- Ubiquitous language shared across technical and business teams
- Bounded contexts with clear interfaces
- Domain events for cross-domain communication
### 3. Single Responsibility
- Each module, service, and component has one clear purpose
- Clear boundaries between concerns
- No circular dependencies
- Minimal coupling between layers
### 4. Type Safety
- Strong TypeScript typing throughout the stack
- Runtime validation with Zod schemas
- Single source of truth for types
- Contract-first API design
### 5. Security First
- No sensitive data exposure [[memory:6689308]]
- Production-ready error handling
- PII redaction in logs
- Row-level security for data access
---
## Monorepo Structure
```
customer-portal/
├── apps/
│ ├── portal/ # Next.js frontend application
│ └── bff/ # NestJS backend-for-frontend
├── packages/
│ ├── domain/ # Shared domain types and business logic
│ ├── logging/ # Centralized logging utilities
│ └── validation/ # Shared validation schemas
├── docker/ # Docker configurations
├── scripts/ # Build and deployment scripts
└── docs/ # Documentation
```
### Workspace Organization
The monorepo uses pnpm workspaces for efficient package management:
- **Isolated dependencies**: Each app manages its own dependencies
- **Shared packages**: Common code reused across apps
- **Atomic changes**: Related changes across multiple packages in single commits
- **Type safety**: TypeScript project references for fast builds
---
## Application Layers
### Portal Architecture (Next.js)
```
apps/portal/src/
├── app/ # Next.js App Router
│ ├── (public)/ # Public marketing and auth routes
│ ├── (authenticated)/ # Authenticated portal routes
│ └── api/ # API routes (if needed)
├── components/ # Shared UI components
│ ├── ui/ # Basic UI elements (atoms)
│ ├── molecules/ # Component combinations
│ ├── organisms/ # Complex UI sections
│ └── templates/ # Page layouts
├── features/ # Feature modules
│ ├── auth/ # Authentication
│ ├── billing/ # Invoices and payments
│ ├── catalog/ # Product catalog
│ ├── orders/ # Order management
│ ├── subscriptions/ # Service management
│ ├── support/ # Support cases
│ └── dashboard/ # Customer dashboard
├── lib/ # Core utilities
│ ├── api/ # API client with Zod validation
│ ├── hooks/ # Shared React hooks
│ └── utils/ # Utility functions
├── providers/ # React context providers
└── styles/ # Global styles and design tokens
```
**Key Principles:**
- **Feature-First Organization**: Related code grouped by business feature
- **Atomic Design**: UI components organized hierarchically
- **Server-First**: Leverage Next.js server components where possible
- **Type Safety**: Full TypeScript coverage with strict mode
- **Performance**: Code splitting, lazy loading, optimized bundles
### BFF Architecture (NestJS)
```
apps/bff/src/
├── modules/ # Feature modules
│ ├── auth/ # Authentication
│ ├── billing/ # Invoice and payment management
│ ├── catalog/ # Product catalog
│ ├── orders/ # Order processing
│ ├── subscriptions/ # Subscription management
│ └── support/ # Support cases
├── integrations/ # External service integrations
│ ├── salesforce/ # Salesforce CRM
│ │ ├── services/ # API services
│ │ ├── utils/ # Query builders (SOQL)
│ │ └── events/ # Platform events (Pub/Sub)
│ ├── whmcs/ # WHMCS billing
│ │ ├── services/ # API services
│ │ └── utils/ # Request builders
│ └── freebit/ # Freebit SIM management
│ └── services/ # API services
├── core/ # Core services
│ ├── config/ # Configuration management
│ ├── logging/ # Logging setup
│ └── database/ # Database connections
├── common/ # Shared resources
│ ├── guards/ # Auth guards
│ ├── interceptors/ # Request/response interceptors
│ ├── filters/ # Exception filters
│ └── pipes/ # Validation pipes
└── main.ts # Application entry point
```
**Key Principles:**
- **Modular Architecture**: Features organized as NestJS modules
- **Integration Layer**: External services abstracted behind clean interfaces
- **Single Transformation**: Domain mappers transform data once
- **Infrastructure Concerns**: Separated from business logic
- **Event-Driven**: Platform Events for Salesforce integration
---
## Domain Layer
The domain package provides framework-agnostic types and business logic shared across applications.
### Domain Structure
```
packages/domain/
├── billing/
│ ├── contract.ts # Normalized types (provider-agnostic)
│ ├── schema.ts # Zod validation schemas
│ └── providers/ # Provider-specific adapters
│ └── whmcs/
│ ├── raw.types.ts # WHMCS API response types
│ └── mapper.ts # Transform WHMCS → Domain
├── subscriptions/
│ ├── contract.ts
│ ├── schema.ts
│ └── providers/
│ └── whmcs/
├── orders/
│ ├── contract.ts
│ ├── schema.ts
│ └── providers/
│ ├── salesforce/ # Read orders from Salesforce
│ └── whmcs/ # Create orders in WHMCS
├── catalog/
│ ├── contract.ts
│ ├── schema.ts
│ └── providers/
│ └── salesforce/ # Product catalog
├── customer/
│ ├── contract.ts
│ ├── schema.ts
│ └── providers/
│ ├── salesforce/
│ └── whmcs/
├── sim/
│ ├── contract.ts
│ ├── schema.ts
│ └── providers/
│ └── freebit/ # SIM management
└── common/
├── types.ts # Common types (Address, Money, etc.)
├── api.ts # API response wrappers
└── schema.ts # Common schemas
```
### Provider Pattern
The domain layer uses a provider pattern to abstract external system details:
```typescript
// Domain contract (provider-agnostic)
export interface Invoice {
id: number;
status: InvoiceStatus;
amount: Money;
dueDate: Date;
// ... normalized fields
}
// Provider-specific raw type
export interface WhmcsInvoiceRaw {
invoiceid: string;
status: string;
total: string;
// ... WHMCS-specific fields
}
// Provider mapper
export function transformWhmcsInvoice(raw: unknown): Invoice {
const validated = whmcsInvoiceRawSchema.parse(raw);
const result: Invoice = {
id: parseInt(validated.invoiceid),
status: mapWhmcsStatus(validated.status),
amount: {
value: parseFloat(validated.total),
currency: validated.currencycode
},
// ... map all fields
};
return invoiceSchema.parse(result); // Validate domain model
}
```
**Benefits:**
- **Provider Isolation**: External API details don't leak into application code
- **Single Transformation**: Map once using domain mappers
- **Type Safety**: Runtime validation at boundaries
- **Testability**: Easy to mock and test transformations
- **Scalability**: Add new providers without changing application code
---
## Technology Stack
### Frontend
- **Framework**: Next.js 14+ (App Router)
- **Language**: TypeScript 5+
- **UI Library**: React 18
- **Styling**: Tailwind CSS
- **State Management**: React Query (TanStack Query)
- **Form Handling**: React Hook Form
- **Validation**: Zod
- **HTTP Client**: Fetch API with Zod validation
### Backend
- **Framework**: NestJS 10+
- **Language**: TypeScript 5+
- **Runtime**: Node.js 20+
- **Validation**: Zod + class-validator
- **ORM**: Prisma
- **Caching**: Redis
- **Queue**: BullMQ (Redis-backed)
- **Logging**: Pino
- **Testing**: Jest
### Infrastructure
- **Database**: PostgreSQL 15+
- **Cache**: Redis 7+
- **Container**: Docker
- **Orchestration**: Docker Compose
- **Reverse Proxy**: Nginx
- **CI/CD**: GitHub Actions (assumed)
### External Services
- **Salesforce**: CRM and order management
- REST API
- Platform Events (Pub/Sub gRPC)
- SOQL queries
- **WHMCS**: Billing and provisioning
- REST API
- Webhooks for events
- **Freebit**: SIM card management
- REST API
---
## Data Flow & Integration
### Order Processing Flow
```
1. Customer creates order in Portal
├─> Portal validates selections
└─> POST /api/orders → BFF
2. BFF creates Salesforce Order
├─> Validates customer data
├─> Creates Order record
├─> Creates OrderItems
└─> Status: Draft
3. Customer/Admin approves Order in Salesforce
└─> Record-Triggered Flow publishes OrderProvisionRequested__e
4. BFF receives Platform Event
├─> PlatformEventsSubscriber enqueues job
└─> BullMQ provisioning queue
5. Provisioning Worker processes job
├─> OrderFulfillmentService orchestrates
├─> Creates WHMCS order (AddOrder)
├─> Accepts WHMCS order (AcceptOrder → creates services)
└─> Updates Salesforce Order status
6. Customer sees updated status in Portal
└─> GET /api/orders/{id} → Shows provisioned services
```
### Catalog Data Flow
```
┌──────────────┐
│ Salesforce │
│ Product2 │
└──────┬───────┘
│ SOQL Query
┌──────▼──────────────────────────┐
│ BFF Catalog Service │
│ • Query products │
│ • Filter by Portal_Catalog__c │
│ • Transform with domain mapper │
└──────┬──────────────────────────┘
│ Domain Types
┌──────▼───────────────┐
│ Cache (Redis) │
│ TTL: 5-15 min │
└──────┬───────────────┘
│ REST API
┌──────▼───────┐
│ Portal │
│ Catalog │
└──────────────┘
```
### Authentication Flow
```
1. User submits login credentials
├─> Portal: POST /auth/login
2. BFF validates credentials
├─> Check against database
├─> Verify WHMCS account link (optional)
3. Issue tokens
├─> Access Token (JWT, 15 min)
├─> Refresh Token (stored in Redis, 7 days)
4. Return tokens to client
├─> Access Token in response body
├─> Refresh Token in httpOnly cookie
5. Client makes authenticated requests
├─> Include Access Token in Authorization header
6. Token refresh
├─> Portal: POST /auth/refresh
├─> BFF validates Refresh Token
├─> Issues new Access Token
└─> Rotates Refresh Token (token family)
```
---
## Deployment Architecture
### Production Environment
```
┌─────────────────────────────────────────────────────────┐
│ Load Balancer │
└────────────────────┬────────────────────────────────────┘
┌────────────┴────────────┐
│ │
┌───────▼────────┐ ┌─────────▼────────┐
│ Portal │ │ BFF │
│ (Next.js) │ │ (NestJS) │
│ • SSR/SSG │ │ • REST API │
│ • Static │ │ • WebSockets │
└───────┬────────┘ └─────────┬────────┘
│ │
│ ┌──────────┴──────────┐
│ │ │
│ ┌───────▼────────┐ ┌───────▼────────┐
│ │ PostgreSQL │ │ Redis │
│ │ (Primary DB) │ │ (Cache+Queue) │
│ └────────────────┘ └────────────────┘
┌───────┴──────────────────────────────────────┐
│ External Services │
│ • Salesforce (CRM) │
│ • WHMCS (Billing) │
│ • Freebit (SIM Management) │
└──────────────────────────────────────────────┘
```
### Scalability Considerations
- **Horizontal Scaling**: Multiple BFF instances behind load balancer
- **Stateless Design**: JWT tokens, no server-side sessions
- **Redis Clustering**: Distributed cache and queue
- **Database Read Replicas**: Separate read/write connections
- **CDN**: Static assets served via CDN
- **Queue Workers**: Separate processes for background jobs
### Monitoring & Observability
- **Structured Logging**: Pino with correlation IDs
- **Metrics**: Response times, error rates, API latency
- **Health Checks**: `/health` endpoints for both apps
- **Error Tracking**: Centralized error logging
- **Performance Monitoring**: Real-time performance metrics
---
## Design Decisions
### Why Monorepo?
- **Shared Code**: Easy to share types, utilities, and business logic
- **Atomic Changes**: Update frontend and backend in sync
- **Consistent Tooling**: Single ESLint, TypeScript, and Prettier config
- **Developer Experience**: Single repository, single checkout
### Why BFF Pattern?
- **Frontend-Specific**: API tailored to portal needs
- **Aggregation**: Combine multiple backend services
- **Security**: Backend handles sensitive operations
- **Performance**: Caching and optimization close to frontend
### Why Domain Package?
- **Single Source of Truth**: Types defined once, used everywhere
- **Provider Abstraction**: External systems isolated from application
- **Type Safety**: Runtime validation with Zod
- **Testability**: Business logic separate from infrastructure
### Why Platform Events (Not Webhooks)?
- **Security**: No inbound connections from Salesforce
- **Reliability**: Durable replay with replayId tracking
- **Scalability**: High-volume event processing
- **Real-time**: Near-instant event delivery
---
## Future Considerations
### Planned Enhancements
- **GraphQL API**: Consider GraphQL for complex data fetching
- **Event Sourcing**: Event log for audit trail
- **CQRS**: Separate read/write models for complex domains
- **Microservices**: Split BFF into domain-specific services
- **Real-time Updates**: WebSocket for live order status
### Technical Debt
- **Legacy Migration**: Some validation logic being migrated to domain
- **Test Coverage**: Increase unit and integration test coverage
- **Performance**: Optimize database queries and caching strategy
- **Documentation**: Continue documenting API contracts and flows
---
**Last Updated**: October 2025
**Status**: Active - Production System