2025-09-02 16:09:17 +09:00
# Modular Provisioning Architecture - Clean & Maintainable
## ✅ **Perfect Architectural Symmetry Achieved**
I've restructured the provisioning system to **match the exact same clean modular pattern** as your order creation workflow. Now both systems follow identical architectural principles!
## 🏗️ **Side-by-Side Architecture Comparison**
### **Order Creation (Existing) ↔ Order Provisioning (New)**
2025-09-09 18:19:54 +09:00
| **Order Creation** | **Order Provisioning** | **Purpose** |
| ------------------- | -------------------------- | ----------------------------------- |
| `OrderValidator` | `ProvisioningValidator` | Validates requests & business rules |
| `OrderBuilder` | `WhmcsOrderMapper` | Transforms/maps data structures |
| `OrderItemBuilder` | _(integrated in mapper)_ | Handles item-level processing |
| `OrderOrchestrator` | `ProvisioningOrchestrator` | Coordinates the complete workflow |
| `OrdersController` | `PlatformEventsSubscriber` | Event handling (no inbound HTTP) |
2025-09-02 16:09:17 +09:00
## 📁 **Clean File Structure**
```
apps/bff/src/orders/
├── controllers/
2025-09-06 10:01:44 +09:00
│ └── orders.controller.ts # Customer-facing operations
├── queue/
│ ├── provisioning.queue.ts # Enqueue provisioning jobs
│ └── provisioning.processor.ts # Worker processes jobs
2025-09-02 16:09:17 +09:00
├── services/
│ # Order Creation (existing)
│ ├── order-validator.service.ts # Request & business validation
2025-09-09 18:19:54 +09:00
│ ├── order-builder.service.ts # Order header construction
2025-09-02 16:09:17 +09:00
│ ├── order-item-builder.service.ts # Order items construction
│ ├── order-orchestrator.service.ts # Creation workflow coordination
│ │
│ # Order Provisioning (new - matching structure)
│ ├── provisioning-validator.service.ts # Provisioning validation
│ ├── whmcs-order-mapper.service.ts # SF → WHMCS mapping
│ ├── provisioning-orchestrator.service.ts # Provisioning workflow coordination
│ └── order-provisioning.service.ts # Main provisioning interface
```
## 🎯 **Modular Provisioning Services**
2025-09-09 18:19:54 +09:00
### **1. ProvisioningValidator**
2025-09-02 16:09:17 +09:00
**Purpose**: Validates all provisioning prerequisites
2025-09-09 18:19:54 +09:00
2025-09-02 16:09:17 +09:00
- ✅ Salesforce order validation
2025-09-09 18:19:54 +09:00
- ✅ Payment method validation
2025-09-02 16:09:17 +09:00
- ✅ Client mapping validation
- ✅ Idempotency checking
- ✅ Request payload validation
### **2. WhmcsOrderMapper**
2025-09-09 18:19:54 +09:00
2025-09-02 16:09:17 +09:00
**Purpose**: Maps Salesforce OrderItems → WHMCS format
2025-09-09 18:19:54 +09:00
2025-09-02 16:09:17 +09:00
- ✅ Product ID mapping (`WHMCS_Product_Id__c` )
- ✅ Billing cycle mapping (Service=monthly, Activation=onetime)
- ✅ Config options mapping
- ✅ Custom fields mapping
- ✅ Order notes generation with SF tracking
### **3. ProvisioningOrchestrator**
2025-09-09 18:19:54 +09:00
2025-09-02 16:09:17 +09:00
**Purpose**: Coordinates complete provisioning workflow
2025-09-09 18:19:54 +09:00
2025-09-02 16:09:17 +09:00
- ✅ **Step-by-step execution** with error handling
- ✅ **Progress tracking** for each step
- ✅ **Automatic rollback** on failures
- ✅ **Comprehensive logging** at each step
- ✅ **Context management** throughout workflow
**Provisioning Steps**:
2025-09-09 18:19:54 +09:00
2025-09-02 16:09:17 +09:00
1. `validation` - Validate all prerequisites
2. `sf_status_update` - Update SF to "Activating"
3. `order_details` - Get SF order with items
4. `mapping` - Map items to WHMCS format
5. `whmcs_create` - Create WHMCS order
6. `whmcs_accept` - Accept/provision WHMCS order
7. `sf_success_update` - Update SF to "Provisioned"
### **4. OrderProvisioningService**
2025-09-09 18:19:54 +09:00
2025-09-02 16:09:17 +09:00
**Purpose**: Clean main interface (like OrderOrchestrator)
2025-09-09 18:19:54 +09:00
2025-09-02 16:09:17 +09:00
- ✅ **Delegates to modular components**
- ✅ **Simple, focused responsibility**
- ✅ **Consistent error handling**
- ✅ **Clean result formatting**
## 🔄 **The Complete Modular Flow**
```
2025-09-06 10:01:44 +09:00
PlatformEventsSubscriber (OrderProvisionRequested__e)
↓ (enqueues job)
2025-09-09 18:19:54 +09:00
OrderProvisioningService
2025-09-02 16:09:17 +09:00
↓ (coordinates workflow)
2025-09-09 18:19:54 +09:00
ProvisioningValidator
2025-09-02 16:09:17 +09:00
↓ (validates prerequisites)
ProvisioningOrchestrator
↓ (executes step-by-step)
WhmcsOrderMapper + WhmcsOrderService + SalesforceService
↓ (performs actual operations)
Result Summary
```
## 🎯 **Key Benefits of Modular Architecture**
### **Maintainability**:
2025-09-09 18:19:54 +09:00
2025-09-02 16:09:17 +09:00
- **Single Responsibility**: Each service has one clear purpose
- **Easy Testing**: Each component can be unit tested independently
- **Easy Debugging**: Clear separation makes issues easy to isolate
- **Easy Extension**: Add new steps without touching existing code
### **Code Quality**:
2025-09-09 18:19:54 +09:00
2025-09-02 16:09:17 +09:00
- **Consistent Patterns**: Same structure as order creation
- **Reusable Components**: Services can be reused in different contexts
- **Clean Interfaces**: Clear contracts between components
- **Proper Error Handling**: Each layer handles its own concerns
### **Developer Experience**:
2025-09-09 18:19:54 +09:00
2025-09-02 16:09:17 +09:00
- **Familiar Structure**: Developers already know the pattern
- **Easy Navigation**: Clear file organization
- **Predictable Behavior**: Consistent patterns across codebase
- **Self-Documenting**: Service names clearly indicate purpose
## 📊 **Comparison: Before vs After**
### **Before (Monolithic)**:
2025-09-09 18:19:54 +09:00
2025-09-02 16:09:17 +09:00
```typescript
// OrderProvisioningService - 339 lines doing everything
class OrderProvisioningService {
async provisionOrder() {
// 1. Validate SF order (inline)
2025-09-09 18:19:54 +09:00
// 2. Check payment method (inline)
2025-09-02 16:09:17 +09:00
// 3. Map items (inline)
// 4. Create WHMCS order (inline)
// 5. Accept WHMCS order (inline)
// 6. Update Salesforce (inline)
// 7. Handle errors (inline)
// = 300+ lines of mixed concerns
}
}
```
### **After (Modular)**:
2025-09-09 18:19:54 +09:00
2025-09-02 16:09:17 +09:00
```typescript
// OrderProvisioningService - 118 lines, focused interface
class OrderProvisioningService {
async provisionOrder() {
const payload = this.validator.validateRequestPayload(request);
const context = await this.orchestrator.executeProvisioning(sfOrderId, payload, key);
return this.orchestrator.getProvisioningSummary(context);
}
}
// + ProvisioningValidator (150 lines)
2025-09-09 18:19:54 +09:00
// + WhmcsOrderMapper (200 lines)
2025-09-02 16:09:17 +09:00
// + ProvisioningOrchestrator (300 lines)
// = Same functionality, much cleaner separation
```
## 🚀 **Usage Examples**
### **Testing Individual Components**:
2025-09-09 18:19:54 +09:00
2025-09-02 16:09:17 +09:00
```typescript
2025-09-09 18:19:54 +09:00
describe("ProvisioningValidator", () => {
it("should validate payment method", async () => {
2025-09-02 16:09:17 +09:00
const result = await validator.validateProvisioningRequest(orderId, key);
expect(result.clientId).toBeDefined();
});
});
2025-09-09 18:19:54 +09:00
describe("WhmcsOrderMapper", () => {
it("should map SF items to WHMCS format", async () => {
2025-09-02 16:09:17 +09:00
const result = await mapper.mapOrderItemsToWhmcs(sfItems);
2025-09-09 18:19:54 +09:00
expect(result.whmcsItems[0].billingCycle).toBe("monthly");
2025-09-02 16:09:17 +09:00
});
});
```
### **Extending Functionality**:
2025-09-09 18:19:54 +09:00
2025-09-02 16:09:17 +09:00
```typescript
// Easy to add new provisioning steps
class ProvisioningOrchestrator {
private initializeSteps() {
return [
// ... existing steps
2025-09-09 18:19:54 +09:00
{ step: "esim_activation", status: "pending" }, // NEW STEP
{ step: "email_notification", status: "pending" }, // NEW STEP
2025-09-02 16:09:17 +09:00
];
}
}
```
## 🎉 **Perfect Architectural Consistency**
Your codebase now has **perfect symmetry** :
2025-09-09 18:19:54 +09:00
2025-09-02 16:09:17 +09:00
- **Order Creation**: Modular, clean, maintainable ✅
- **Order Provisioning**: Modular, clean, maintainable ✅
- **Same Patterns**: Developers can work on either system easily ✅
- **High Quality**: Production-ready, testable, extensible ✅
This is exactly the kind of clean, maintainable architecture that scales well and makes developers productive! 🚀