# Customer Portal Architecture

## 🏗️ **System Overview**

The Customer Portal is a modern monorepo with clean separation between frontend (Next.js) and backend (NestJS), designed for maintainability and scalability.

### **High-Level Structure**

```
apps/
  portal/              # Next.js frontend
  bff/                 # NestJS Backend-for-Frontend
packages/
  domain/              # Pure domain types, validation schemas, and utilities (isomorphic)
```

## 🎯 **Architecture Principles**

### **1. Separation of Concerns**

- **Dev vs Prod**: Clear separation with appropriate tooling
- **Services vs Apps**: Development runs apps locally, production containerizes everything
- **Configuration vs Code**: Environment variables for configuration, code for logic

### **2. Single Source of Truth**

- **One environment template**: `.env.example`
- **One Docker Compose** per environment
- **One script** per operation type

### **3. Clean Dependencies**

- **Portal**: Uses `@/lib/*` for shared utilities and services
- **BFF**: Feature-aligned modules with shared concerns in `src/common/`
- **Domain**: Framework-agnostic types and utilities

## 🚀 **Portal (Next.js) Architecture**

```
src/
  app/                 # App Router routes
  components/          # Design system (atomic design)
    atoms/             # Basic UI elements
    molecules/         # Component combinations
    organisms/         # Complex UI sections
    templates/         # Page layouts
  features/            # Feature modules (auth, billing, etc.)
  lib/                 # Core utilities and services
    api/               # Zod-aware fetch client + helpers
    hooks/             # Shared React hooks
    utils/             # Utility functions
  providers/           # Context providers
  styles/              # Global styles
```

### **Conventions**

- Use `@/lib/*` for shared frontend utilities and services
- Feature modules own their `components/`, `hooks/`, `services/`, and `types/`
- Cross-feature UI belongs in `components/` (atomic design)
- Avoid duplicate layers - no `core/` or `shared/` inside apps

## 🔧 **BFF (NestJS) Architecture**

```
src/
  modules/             # Feature-aligned modules
    auth/              # Authentication and authorization
    users/             # User management
    me-status/         # Aggregated customer status (dashboard + gating signals)
    id-mappings/       # Portal-WHMCS-Salesforce ID mappings
    services/          # Services catalog (browsing/purchasing)
    orders/            # Order creation and fulfillment
    invoices/          # Invoice management
    subscriptions/     # Service and subscription management
    currency/          # Currency handling
    support/           # Support case management
    realtime/          # Server-Sent Events API
    verification/      # ID verification
    notifications/     # User notifications
    health/            # Health check endpoints
  core/                # Core services and utilities
  infra/               # Infrastructure (database, cache, queue, email)
  integrations/        # External service integrations
    salesforce/        # Salesforce CRM integration
    whmcs/             # WHMCS billing integration
    freebit/           # Freebit SIM provider integration
    sftp/              # SFTP file transfer
  main.ts              # Application entry point
```

### **Conventions**

- Prefer `modules/*` over flat directories per domain
- Keep DTOs and validators in-module
- Reuse `packages/domain` for domain types
- External integrations in dedicated modules

### **API Boundary: Public vs Account**

- **Public APIs** (`/api/public/*`): strictly non-personalized endpoints intended for marketing pages and unauthenticated browsing.
- **Account APIs** (`/api/account/*`): authenticated endpoints that may return personalized responses (e.g. eligibility-gated catalogs, SIM family discount availability).

## 📦 **Shared Packages**

### **Domain Package (`packages/domain/`)**

The domain package is the single source of truth for shared types, validation schemas, and utilities across both the BFF and Portal applications.

```
packages/domain/
├── auth/           # Authentication types and validation
├── billing/        # Invoice and payment types
├── services/       # Services catalog types
├── checkout/       # Checkout flow types
├── common/         # Shared utilities and base types
├── customer/       # Customer profile types
├── dashboard/      # Dashboard data types
├── mappings/       # ID mapping types (Portal-WHMCS-SF)
├── notifications/  # Notification types
├── opportunity/    # Salesforce opportunity types
├── orders/         # Order types and Salesforce mappings
├── payments/       # Payment method types
├── providers/      # Provider-specific type definitions
├── realtime/       # SSE event types
├── salesforce/     # Salesforce API types
├── sim/            # SIM lifecycle and Freebit types
├── subscriptions/  # Subscription types
├── support/        # Support case types
├── toolkit/        # Utility functions
└── index.ts        # Public exports
```

#### **Key Principles**

- **Framework-agnostic**: No NestJS or React dependencies
- **Isomorphic**: Works in both Node.js and browser environments
- **Zod-first validation**: Schemas defined with Zod for runtime validation
- **Provider mappers**: Transform external API responses to domain types

#### **Usage**

Import via module entrypoints:

```typescript
import { invoiceSchema, type Invoice } from "@customer-portal/domain/billing";
import { orderSummarySchema, type OrderSummary } from "@customer-portal/domain/orders";
import { SIM_STATUS } from "@customer-portal/domain/sim";
```

#### **Integration with BFF**

The BFF integration layer (`apps/bff/src/integrations/`) uses domain mappers to transform raw provider data:

```
External API → Raw Response → Domain Mapper → Domain Type → Use Everywhere
```

This ensures a single transformation point and consistent types across the application.

### **Logging**

Centralized logging is implemented in the BFF using `nestjs-pino`:

- **Structured JSON logging** for production
- **Correlation IDs** for request tracing
- **Automatic PII redaction** for security

## 🔗 **Integration Architecture**

### **API Client**

- **Implementation**: Fetch wrapper using shared Zod schemas from `@customer-portal/domain`
- **Features**: CSRF protection, auth handling, consistent `ApiResponse` helpers
- **Location**: `apps/portal/src/lib/api/`

### **External Services**

- **WHMCS**: Billing system integration
- **Salesforce**: CRM and order management
- **Redis**: Caching and session storage
- **PostgreSQL**: Primary data store

## 🔒 **Security Architecture**

### **Authentication Flow**

- Portal-native authentication with JWT tokens
- Optional MFA support
- Secure token rotation with Redis backing

### **Error Handling**

- Never leak sensitive details to end users [[memory:6689308]]
- Centralized error mapping to user-friendly messages
- Comprehensive audit trails

### **Data Protection**

- PII minimization with encryption at rest/in transit
- Row-level security (users can only access their data)
- Idempotency keys on all mutating operations

## 🚀 **Development Workflow**

### **Path Aliases**

- **Portal**: `@/*`, `@/lib/*`, `@/features/*`, `@/components/*`
- **BFF**: `@/*` mapped to `apps/bff/src`
- **Domain**: Import via `@customer-portal/domain`

### **Code Quality**

- Strict TypeScript rules enforced repository-wide
- ESLint and Prettier for consistent formatting
- Pre-commit hooks for quality gates

### **Domain Build Hygiene**

The domain package (`packages/domain`) is consumed via committed `dist/` outputs.

- **Build**: `pnpm domain:build`
- **Verify dist drift** (CI-friendly): `pnpm domain:check-dist`

## 📈 **Performance & Scalability**

### **Caching Strategy**

- **Invoices**: 60-120s per page; bust on WHMCS webhook
- **Cases**: 30-60s; bust after create/update
- **Catalog**: 5-15m; manual bust on changes
- **Keys include user_id** to prevent cross-user leakage

### **Database Optimization**

- Connection pooling with Prisma
- Proper indexing on frequently queried fields
- Optional mirrors for external system data

---

_This architecture supports clean, maintainable code with clear separation of concerns and production-ready security._
