2025-12-29 18:21:48 +09:00
|
|
|
# BFF Architecture
|
|
|
|
|
|
|
|
|
|
This document outlines the folder structure and architectural boundaries in the BFF (Backend for Frontend).
|
|
|
|
|
|
2026-01-15 16:31:15 +09:00
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 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
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2025-12-29 18:21:48 +09:00
|
|
|
## 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
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
// ✅ 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
|
2026-01-15 16:31:15 +09:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 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 |
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Related Documentation
|
|
|
|
|
|
|
|
|
|
- [Integration Patterns](./integration-patterns.md) - How integrations work
|
|
|
|
|
- [DB Mappers](./db-mappers.md) - Database mapping patterns
|
|
|
|
|
- [Validation](./validation.md) - Zod validation setup
|
|
|
|
|
- [Architecture Decisions](../../decisions/README.md) - Why these patterns exist
|