Assist_Design/ORDERS-ARCHITECTURE-REVIEW.md

312 lines
9.9 KiB
Markdown
Raw Normal View History

# Orders Domain & BFF Integration - Architecture Review
## Executive Summary
**Date**: October 2025
**Status**: ✅ **REFACTORED - CLEAN ARCHITECTURE**
After comprehensive review and refactoring, the architecture now follows clean separation of concerns with a single source of truth for data transformations.
---
## ✅ Refactoring Complete
### What Was Fixed
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
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
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
4. **✅ OrderOrchestrator Refactored**
- Removed direct Salesforce queries
- Uses `SalesforceOrderService` for data fetching
- Simplified from 150+ lines to clean delegation
5. **✅ Domain Exports Cleaned**
- Removed query builder exports from domain package
- Domain now only exports business logic
---
## 🎯 Current Architecture
### Clean Separation of Concerns
```
┌─────────────────────────────────────────┐
│ 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 ──────────┘
```
### Domain Layer (`packages/domain/orders/`)
**Contains**:
- ✅ Business types (OrderDetails, OrderSummary)
- ✅ Raw provider types (SalesforceOrderRecord)
- ✅ Validation schemas (Zod)
- ✅ Transformation mappers (Raw → Domain)
- ✅ Business validation functions
**Does NOT Contain**:
- ❌ Query builders (moved to BFF)
- ❌ Field configuration
- ❌ HTTP/API concerns
### Integration Layer (`apps/bff/src/integrations/salesforce/`)
**Contains**:
-`SalesforceOrderService` - Encapsulates order operations
- ✅ Query builders (`order-query-builder.ts`)
- ✅ Connection services
- ✅ Uses domain mappers for transformation
**Does NOT Contain**:
- ❌ Additional mapping logic (uses domain mappers)
- ❌ Business validation
### Application Layer (`apps/bff/src/modules/orders/`)
**Contains**:
-`OrderOrchestrator` - Workflow coordination
-`OrderFulfillmentOrchestrator` - Fulfillment workflows
- ✅ Controllers (HTTP endpoints)
- ✅ Uses integration services
- ✅ Uses domain mappers directly
**Does NOT Contain**:
- ❌ Direct Salesforce queries
- ❌ Mapper service wrappers (deleted)
- ❌ Double transformations
---
## 📊 Key Improvements
### Before: Mixed Concerns
```typescript
// 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);
}
```
### After: Clean Architecture
```typescript
// OrderOrchestrator delegates to integration service (✅ Correct)
return this.salesforceOrderService.getOrderById(orderId);
// Direct domain mapper usage (✅ Clean)
const whmcsItems = Providers.Whmcs.mapFulfillmentOrderItems(items);
```
---
## ✅ Benefits Achieved
### 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)
### 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)
### Developer Experience
- ✅ Clear patterns to follow
- ✅ No confusion about where code goes
- ✅ Consistent with catalog services
- ✅ Self-documenting architecture
---
## 📁 File Structure
### 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`
### 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`
### Deleted Files
1.`apps/bff/src/modules/orders/services/order-whmcs-mapper.service.ts`
2.`packages/domain/orders/providers/salesforce/query.ts`
---
## 🎓 Architecture Principles Followed
### Single Transformation Principle
**One transformation path** - raw data flows through domain mapper exactly once:
```
Query (BFF) → Raw Data → Domain Mapper → Domain Type → Use Directly
```
### Encapsulation Principle
Integration services hide external system complexity:
```typescript
// Application layer doesn't see Salesforce details
const order = await this.salesforceOrderService.getOrderById(id);
```
### Separation of Concerns
Each layer has a single responsibility:
- **Domain**: Business logic, types, validation
- **Integration**: External system interaction
- **Application**: Workflow coordination
- **HTTP**: API endpoints
---
## 🔍 Pattern Examples
### Example 1: Fetching Orders
```typescript
// OrderOrchestrator (Application Layer)
async getOrder(orderId: string): Promise<OrderDetails | null> {
// Clean delegation - no SF-specific code!
return this.salesforceOrderService.getOrderById(orderId);
}
// 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);
}
```
### 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);
},
}
```
---
## ✅ 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
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)
---
## 🎯 Future Considerations
### Potential Enhancements
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
### Monitoring
- Track order query performance
- Monitor transformation errors
- Log integration service calls
---
## Conclusion
**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)
**Key Achievement**: Single source of truth for transformations with no redundant mapping layers.
---
**Last Updated**: October 2025
**Refactored By**: Architecture Review Team