# 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 `@customer-portal/domain`: ```typescript import { Invoice, SIM_LIFECYCLE_STAGE, OrderStatus } from "@customer-portal/domain"; import { invoiceSchema, orderSchema } from "@customer-portal/domain/validation"; ``` #### **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._