Assist_Design/ARCHITECTURE_RECOMMENDATION.md
2025-08-28 16:57:57 +09:00

4.0 KiB

Order Services Architecture Recommendation

1. Controller Layer (orders.controller.ts)

Responsibility: API contract and basic validation

  • DTO validation (format, types, required fields)
  • Authentication/authorization
  • HTTP response handling
  • Minimal business logic

2. Orchestrator Layer (order-orchestrator.service.ts)

Responsibility: Workflow coordination and transaction management

  • Coordinates the order creation flow
  • Manages transaction boundaries
  • Handles high-level error scenarios
  • Calls other services in correct sequence

3. Validator Layer (order-validator.service.ts)

Responsibility: ALL validation logic (business + technical)

class OrderValidator {
  // API-level validation (move from DTO)
  validateRequestFormat(body: any): CreateOrderBody
  
  // Business validation (current)
  validateUserMapping(userId: string): Promise<UserMapping>
  validatePaymentMethod(userId: string, clientId: number): Promise<void>
  validateSKUs(skus: string[], pricebookId: string): Promise<void>
  validateBusinessRules(orderType: string, skus: string[]): void
  validateInternetDuplication(userId: string, clientId: number): Promise<void>
  
  // Complete validation (orchestrates all checks)
  async validateCompleteOrder(userId: string, body: any): Promise<{
    validatedBody: CreateOrderBody,
    userMapping: UserMapping
  }>
}

4. Builder Layer (order-builder.service.ts)

Responsibility: Data transformation and mapping

  • Transform business data to Salesforce format
  • Apply business rules to field mapping
  • Handle conditional field logic

5. ItemBuilder Layer (order-item-builder.service.ts)

Responsibility: Order item creation and pricing

  • Create order line items
  • Handle pricing calculations
  • Manage product metadata

Benefits of This Structure:

Single Responsibility Principle

  • Each service has one clear purpose
  • Easy to test and maintain
  • Clear boundaries

Validator as Single Source of Truth

  • All validation logic in one place
  • Easy to find and modify validation rules
  • Consistent error handling

Orchestrator for Workflow Management

  • Clear sequence of operations
  • Transaction management
  • Error recovery logic

Testability

  • Each layer can be unit tested independently
  • Mock dependencies easily
  • Clear input/output contracts

Implementation Changes:

Move DTO validation to Validator:

// Before: Controller has DTO validation
@Body() body: CreateOrderDto

// After: Controller accepts any, Validator validates
@Body() body: any

Enhanced Validator:

async validateCompleteOrder(userId: string, rawBody: any) {
  // 1. Format validation (was DTO)
  const body = this.validateRequestFormat(rawBody);
  
  // 2. Business validation (current)
  const userMapping = await this.validateUserMapping(userId);
  await this.validatePaymentMethod(userId, userMapping.whmcsClientId);
  
  // 3. SKU validation (move here)
  const pricebookId = await this.findPricebookId();
  await this.validateSKUs(body.skus, pricebookId);
  this.validateBusinessRules(body.orderType, body.skus);
  
  // 4. Order-specific validation
  if (body.orderType === "Internet") {
    await this.validateInternetDuplication(userId, userMapping.whmcsClientId);
  }
  
  return { validatedBody: body, userMapping, pricebookId };
}

Simplified Orchestrator:

async createOrder(userId: string, rawBody: any) {
  // 1. Complete validation
  const { validatedBody, userMapping, pricebookId } = 
    await this.validator.validateCompleteOrder(userId, rawBody);
  
  // 2. Build order
  const orderFields = this.builder.buildOrderFields(validatedBody, userMapping, pricebookId);
  
  // 3. Create in Salesforce
  const created = await this.sf.sobject("Order").create(orderFields);
  
  // 4. Create items
  await this.itemBuilder.createOrderItemsFromSKUs(created.id, validatedBody.skus, pricebookId);
  
  return { sfOrderId: created.id, status: "Created" };
}