11 KiB

BFF Architecture

This document outlines the folder structure and architectural boundaries in the BFF (Backend for Frontend).


Quick Reference

Aspect Location
Controllers apps/bff/src/modules/<module>/<module>.controller.ts
Services apps/bff/src/modules/<module>/services/
Integrations apps/bff/src/integrations/<provider>/
Domain mappers import from "@customer-portal/domain/<module>/providers"

Key pattern: Controllers → Services → Integration Services → Domain Mappers → Domain Types


Folder Structure

apps/bff/src/
├── app/                    # Application bootstrap
│   └── bootstrap.ts        # App initialization and setup
├── core/                   # Framework configuration (NestJS setup)
│   ├── config/             # App configuration and environment validation
│   ├── exceptions/         # Global exception filters
│   ├── health/             # Health check endpoints
│   ├── http/               # HTTP interceptors and middleware
│   ├── logging/            # Logger configuration
│   ├── rate-limiting/      # Rate limiter setup
│   ├── security/           # Security guards, CSRF, etc.
│   └── utils/              # Core utilities
├── infra/                  # External service adapters
│   ├── audit/              # Audit logging
│   ├── cache/              # Cache service abstractions
│   ├── database/           # Prisma database access
│   ├── email/              # Email service
│   ├── mappers/            # Generic data mappers
│   ├── queue/              # Job queue service
│   ├── realtime/           # WebSocket/SSE handlers
│   ├── redis/              # Redis client configuration
│   └── utils/              # Infra utilities
├── integrations/           # External API integrations
│   ├── freebit/            # Freebit API client
│   ├── salesforce/         # Salesforce API client
│   ├── sftp/               # SFTP file transfers
│   └── whmcs/              # WHMCS API client
├── modules/                # Feature modules (business logic)
│   ├── auth/               # Authentication module
│   ├── billing/            # Billing and invoices
│   ├── currency/           # Currency management
│   ├── health/             # Health checks
│   ├── id-mappings/        # ID mapping service
│   ├── me-status/          # User status endpoint
│   ├── notifications/      # Notification management
│   ├── orders/             # Order management
│   ├── realtime/           # Real-time events
│   ├── services/           # Service catalog
│   ├── subscriptions/      # Subscription management
│   ├── support/            # Support tickets
│   ├── users/              # User management
│   └── verification/       # Identity verification
├── types/                  # Type declarations
├── app.module.ts           # Root NestJS module
└── main.ts                 # Application entry point

Architectural Boundaries

Core (src/core/)

Purpose: NestJS framework configuration and cross-cutting concerns.

Contains:

  • App configuration and environment validation (config/)
  • Global exception filters and error handling (exceptions/)
  • HTTP interceptors, middleware, and guards (http/)
  • Logger setup and configuration (logging/)
  • Rate limiting configuration (rate-limiting/)
  • Security guards, CSRF protection, cookie handling (security/)
  • Core utilities used across the app (utils/)

Rules:

  • Core modules should not import from modules/ or integrations/
  • Core provides the foundation that other layers build upon
  • Keep framework-specific code here

Infra (src/infra/)

Purpose: Adapters for external services and infrastructure.

Contains:

  • Database access via Prisma (database/)
  • Cache abstractions for Redis (cache/)
  • Redis client configuration (redis/)
  • Email service (email/)
  • Job queue management (queue/)
  • WebSocket/SSE real-time handlers (realtime/)
  • Audit logging (audit/)
  • Generic data mappers (mappers/)

Rules:

  • Infra modules provide abstractions over external dependencies
  • Should not contain business logic
  • Can be imported by modules/ and integrations/

Integrations (src/integrations/)

Purpose: External API clients for third-party services.

Contains:

  • WHMCS API client and transformers
  • Salesforce API client and event handlers
  • Freebit API client for SIM management
  • SFTP client for file transfers

Rules:

  • Each integration is a self-contained NestJS module
  • Integrations fetch data and transform to domain types
  • Use domain mappers from @customer-portal/domain/*/providers
  • Should not contain business logic beyond data transformation
  • Integrations can use infra/ for caching, logging, etc.

Modules (src/modules/)

Purpose: Business logic and feature implementation.

Contains:

  • Controllers (thin, validation only)
  • Services (business logic, orchestration)
  • Feature-specific utilities

Rules:

  • Controllers validate input and call services
  • Services orchestrate integrations and apply business rules
  • Can import from core/, infra/, and integrations/
  • Should not directly use external APIs (use integrations)

Data Flow

┌─────────────┐     ┌─────────────┐     ┌───────────────┐     ┌─────────────┐
│  Controller │ ──▶ │   Service   │ ──▶ │  Integration  │ ──▶ │ External API│
│  (modules/) │     │  (modules/) │     │(integrations/)│     │             │
└─────────────┘     └─────────────┘     └───────────────┘     └─────────────┘
       │                   │                    │
       │                   │                    │
       ▼                   ▼                    ▼
   Validates           Orchestrates         Transforms
   input (DTO)         business logic       to domain types

Import Rules

// ✅ Allowed
// Modules can import from core, infra, integrations
import { ConfigService } from "@/core/config";
import { CacheService } from "@/infra/cache";
import { WhmcsService } from "@/integrations/whmcs";

// ✅ Allowed - Domain types and mappers
import type { Invoice } from "@customer-portal/domain/billing";
import { Whmcs } from "@customer-portal/domain/billing/providers";

// ❌ Forbidden - Cross-module imports
import { BillingService } from "@/modules/billing"; // in another module

// ❌ Forbidden - Direct external API calls in modules
import axios from "axios"; // Use integrations instead

Best Practices

  1. Controllers are thin: Only validation, no business logic
  2. Services orchestrate: Combine integrations, apply business rules
  3. Integrations transform: Fetch external data, map to domain types
  4. Infra abstracts: Provide clean interfaces over infrastructure
  5. Core configures: Set up the NestJS framework

API Endpoint Inventory

Public Endpoints (No Auth Required)

Method Path Module Description
GET /api/health health Health check
GET /api/catalog services Public product catalog
GET /api/catalog/:category services Products by category
POST /api/auth/login auth User login
POST /api/auth/signup auth User registration
POST /api/auth/get-started auth Unified get-started flow
POST /api/auth/refresh auth Refresh access token
POST /api/auth/forgot-password auth Request password reset
POST /api/auth/reset-password auth Complete password reset
GET /api/address/lookup address Japan Post address lookup

Account Endpoints (Auth Required)

Method Path Module Description
GET /api/me me-status Current user status
GET /api/me/profile users User profile
PATCH /api/me/profile users Update profile
PATCH /api/me/address users Update address
GET /api/invoices billing List invoices
GET /api/invoices/:id billing Invoice detail
GET /api/payment-methods billing Payment methods
GET /api/payment-methods/summary billing Has payment method check
POST /api/auth/sso-link auth WHMCS SSO link
GET /api/orders orders List orders
GET /api/orders/:id orders Order detail
POST /api/orders orders Create order
GET /api/subscriptions subscriptions List subscriptions
GET /api/subscriptions/:id subscriptions Subscription detail
POST /api/subscriptions/:id/actions subscriptions Subscription actions
GET /api/cases support List support cases
GET /api/cases/:id support Case detail
POST /api/cases support Create case
POST /api/cases/:id/messages support Add case message
GET /api/notifications notifications User notifications
PATCH /api/notifications/:id/read notifications Mark as read
POST /api/verification/residence-card verification Submit ID verification