2025-10-08 11:11:05 +09:00
# Orders Domain & BFF Integration - Architecture Review
## Executive Summary
2025-10-08 11:45:47 +09:00
**Date**: October 2025
**Status**: ✅ **REFACTORED - CLEAN ARCHITECTURE**
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
After comprehensive review and refactoring, the architecture now follows clean separation of concerns with a single source of truth for data transformations.
2025-10-08 11:11:05 +09:00
---
2025-10-08 11:45:47 +09:00
## ✅ Refactoring Complete
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
### What Was Fixed
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
1. ** ✅ Query Builders Moved to BFF Integration**
- FROM: `packages/domain/orders/providers/salesforce/query.ts`
- TO: `apps/bff/src/integrations/salesforce/utils/order-query-builder.ts`
- **Reason**: SOQL is infrastructure, not business logic
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
2. ** ✅ SalesforceOrderService Created**
- **Location**: `apps/bff/src/integrations/salesforce/services/salesforce-order.service.ts`
- Encapsulates all Salesforce order operations
- Uses domain mappers for transformation
- Returns domain types
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
3. ** ✅ Redundant Mapper Service Removed**
- **Deleted**: `apps/bff/src/modules/orders/services/order-whmcs-mapper.service.ts`
- **Reason**: Only wrapped domain mappers, provided no value
- Now use `Providers.Whmcs.mapFulfillmentOrderItems()` directly
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
4. ** ✅ OrderOrchestrator Refactored**
- Removed direct Salesforce queries
- Uses `SalesforceOrderService` for data fetching
- Simplified from 150+ lines to clean delegation
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
5. ** ✅ Domain Exports Cleaned**
- Removed query builder exports from domain package
- Domain now only exports business logic
2025-10-08 11:11:05 +09:00
---
2025-10-08 11:45:47 +09:00
## 🎯 Current Architecture
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
### Clean Separation of Concerns
2025-10-08 11:11:05 +09:00
```
2025-10-08 11:45:47 +09:00
┌─────────────────────────────────────────┐
│ Controller (HTTP) │
│ - API endpoints │
│ - Request/Response formatting │
└──────────────────┬──────────────────────┘
│
┌──────────────────▼──────────────────────┐
│ Orchestrator (Application) │
│ - Coordinates workflows │
│ - Uses Integration Services │
│ - Works with Domain Types │
└──────────────────┬──────────────────────┘
│
┌──────────────┴──────────────┐
│ │
┌───▼───────────┐ ┌──────────────▼──────────┐
│ Domain │ │ Integration │
│ (Business) │ │ (Infrastructure) │
│ │ │ │
│ • Types │ │ • SalesforceOrderService │
│ • Schemas │ │ • Query Builders │
│ • Mappers ────┼──┤ • Connections │
│ • Validators │ │ • API Clients │
└───────────────┘ └──────────────────────────┘
Flow: Query (BFF) → Raw Data → Domain Mapper → Domain Type → Use Directly
└────────── Single transformation, no duplication ──────────┘
2025-10-08 11:11:05 +09:00
```
2025-10-08 11:45:47 +09:00
### Domain Layer (`packages/domain/orders/`)
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
**Contains**:
- ✅ Business types (OrderDetails, OrderSummary)
- ✅ Raw provider types (SalesforceOrderRecord)
- ✅ Validation schemas (Zod)
- ✅ Transformation mappers (Raw → Domain)
- ✅ Business validation functions
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
**Does NOT Contain**:
- ❌ Query builders (moved to BFF)
- ❌ Field configuration
- ❌ HTTP/API concerns
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
### Integration Layer (`apps/bff/src/integrations/salesforce/`)
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
**Contains**:
- ✅ `SalesforceOrderService` - Encapsulates order operations
- ✅ Query builders (`order-query-builder.ts` )
- ✅ Connection services
- ✅ Uses domain mappers for transformation
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
**Does NOT Contain**:
- ❌ Additional mapping logic (uses domain mappers)
- ❌ Business validation
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
### Application Layer (`apps/bff/src/modules/orders/`)
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
**Contains**:
- ✅ `OrderOrchestrator` - Workflow coordination
- ✅ `OrderFulfillmentOrchestrator` - Fulfillment workflows
- ✅ Controllers (HTTP endpoints)
- ✅ Uses integration services
- ✅ Uses domain mappers directly
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
**Does NOT Contain**:
- ❌ Direct Salesforce queries
- ❌ Mapper service wrappers (deleted)
- ❌ Double transformations
2025-10-08 11:11:05 +09:00
---
2025-10-08 11:45:47 +09:00
## 📊 Key Improvements
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
### Before: Mixed Concerns
2025-10-08 11:11:05 +09:00
```typescript
2025-10-08 11:45:47 +09:00
// OrderOrchestrator building SOQL directly (❌ Wrong)
const soql = `SELECT ${buildOrderSelectFields().join(", ")} FROM Order...` ;
const result = await this.sf.query(soql);
const order = DomainMapper.transform(result);
// OrderWhmcsMapper wrapping domain mapper (❌ Redundant)
mapOrderItemsToWhmcs(items) {
return Providers.Whmcs.mapFulfillmentOrderItems(items);
}
2025-10-08 11:11:05 +09:00
```
2025-10-08 11:45:47 +09:00
### After: Clean Architecture
2025-10-08 11:11:05 +09:00
```typescript
2025-10-08 11:45:47 +09:00
// OrderOrchestrator delegates to integration service (✅ Correct)
return this.salesforceOrderService.getOrderById(orderId);
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
// Direct domain mapper usage (✅ Clean)
const whmcsItems = Providers.Whmcs.mapFulfillmentOrderItems(items);
2025-10-08 11:11:05 +09:00
```
---
2025-10-08 11:45:47 +09:00
## ✅ Benefits Achieved
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
### Architecture Cleanliness
- ✅ Single source of truth for transformations (domain mappers)
- ✅ Clear separation: domain = business, BFF = infrastructure
- ✅ No redundant mapping layers
- ✅ Query logic in correct layer (BFF integration)
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
### Code Quality
- ✅ Easier to test (clear boundaries)
- ✅ Easier to maintain (no duplication)
- ✅ Easier to understand (one transformation path)
- ✅ Easier to swap providers (integration services encapsulate)
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
### Developer Experience
- ✅ Clear patterns to follow
- ✅ No confusion about where code goes
- ✅ Consistent with catalog services
- ✅ Self-documenting architecture
2025-10-08 11:11:05 +09:00
---
2025-10-08 11:45:47 +09:00
## 📁 File Structure
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
### Created Files
1. ✅ `apps/bff/src/integrations/salesforce/services/salesforce-order.service.ts`
2. ✅ `apps/bff/src/integrations/salesforce/utils/order-query-builder.ts`
3. ✅ `docs/BFF-INTEGRATION-PATTERNS.md`
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
### Modified Files
1. ✅ `apps/bff/src/modules/orders/services/order-orchestrator.service.ts`
2. ✅ `apps/bff/src/modules/orders/services/order-fulfillment-orchestrator.service.ts`
3. ✅ `apps/bff/src/modules/orders/orders.module.ts`
4. ✅ `apps/bff/src/integrations/salesforce/salesforce.module.ts`
5. ✅ `packages/domain/orders/providers/salesforce/index.ts`
6. ✅ `packages/domain/orders/index.ts`
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
### Deleted Files
1. ✅ `apps/bff/src/modules/orders/services/order-whmcs-mapper.service.ts`
2. ✅ `packages/domain/orders/providers/salesforce/query.ts`
2025-10-08 11:11:05 +09:00
---
2025-10-08 11:45:47 +09:00
## 🎓 Architecture Principles Followed
### Single Transformation Principle
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
**One transformation path** - raw data flows through domain mapper exactly once:
2025-10-08 11:11:05 +09:00
```
2025-10-08 11:45:47 +09:00
Query (BFF) → Raw Data → Domain Mapper → Domain Type → Use Directly
2025-10-08 11:11:05 +09:00
```
2025-10-08 11:45:47 +09:00
### Encapsulation Principle
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
Integration services hide external system complexity:
```typescript
// Application layer doesn't see Salesforce details
const order = await this.salesforceOrderService.getOrderById(id);
```
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
### Separation of Concerns
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
Each layer has a single responsibility:
- **Domain**: Business logic, types, validation
- **Integration**: External system interaction
- **Application**: Workflow coordination
- **HTTP**: API endpoints
2025-10-08 11:11:05 +09:00
---
2025-10-08 11:45:47 +09:00
## 🔍 Pattern Examples
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
### Example 1: Fetching Orders
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
```typescript
// OrderOrchestrator (Application Layer)
async getOrder(orderId: string): Promise< OrderDetails | null > {
// Clean delegation - no SF-specific code!
return this.salesforceOrderService.getOrderById(orderId);
}
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
// SalesforceOrderService (Integration Layer)
async getOrderById(orderId: string): Promise< OrderDetails | null > {
// 1. Build query (infrastructure)
const soql = buildOrderQuery(orderId);
// 2. Execute query
const rawData = await this.sf.query(soql);
// 3. Use domain mapper (single transformation!)
return Providers.Salesforce.transformSalesforceOrderDetails(rawData);
}
```
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
### Example 2: Order Fulfillment
```typescript
// OrderFulfillmentOrchestrator
{
id: "mapping",
description: "Map OrderItems to WHMCS format",
execute: () => {
// Use domain mapper directly - no service wrapper!
const result = OrderProviders.Whmcs.mapFulfillmentOrderItems(
context.orderDetails.items
);
return Promise.resolve(result);
},
}
```
2025-10-08 11:11:05 +09:00
---
## ✅ What's Already Good
1. ✅ Core business types (OrderDetails, OrderSummary) are in domain
2. ✅ Validation schemas are in domain
3. ✅ Business constants (ORDER_TYPE, ORDER_STATUS) are in domain
2025-10-08 11:45:47 +09:00
4. ✅ Domain mappers provide single transformation
5. ✅ Raw provider types (SalesforceOrderRecord) are in domain
6. ✅ Catalog services already follow this pattern
---
## 📖 Related Documentation
- [BFF Integration Patterns ](./docs/BFF-INTEGRATION-PATTERNS.md )
- [Domain Package README ](./packages/domain/README.md )
- [Schema-First Approach ](./packages/domain/SCHEMA-FIRST-COMPLETE.md )
2025-10-08 11:11:05 +09:00
---
2025-10-08 11:45:47 +09:00
## 🎯 Future Considerations
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
### Potential Enhancements
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
1. **Field Configuration** : Currently not used - consider removing or implementing consistently
2. **Query Caching** : Add caching layer in integration services
3. **Query Optimization** : Review SOQL queries for performance
4. **Integration Tests** : Add tests for SalesforceOrderService
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
### Monitoring
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
- Track order query performance
- Monitor transformation errors
- Log integration service calls
2025-10-08 11:11:05 +09:00
---
## Conclusion
2025-10-08 11:45:47 +09:00
**Status**: ✅ **COMPLETE**
The architecture now follows clean separation of concerns:
- **Domain**: Pure business logic (no infrastructure)
- **Integration**: External system encapsulation (SF, WHMCS)
- **Application**: Workflow coordination (orchestrators)
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
**Key Achievement**: Single source of truth for transformations with no redundant mapping layers.
---
2025-10-08 11:11:05 +09:00
2025-10-08 11:45:47 +09:00
**Last Updated**: October 2025
**Refactored By**: Architecture Review Team
2025-10-08 11:11:05 +09:00