# Priority 2: Business Validation Consolidation Plan

**Objective**: Move business validation logic from service layers to domain schemas where appropriate.

---

## 🎯 Analysis Summary

### Current State

**Validation logic is scattered across multiple layers:**

1. **✅ Already in Domain** (Good)
   - Basic schema validation (format, required fields)
   - Some business rules in `orderBusinessValidationSchema`
   - Type validation

2. **⚠️ In BFF Services** (Should be moved)
   - Order SKU business rules (`validateBusinessRules`)
   - Invoice status validation
   - Pagination limits
   - SIM validation logic

3. **✅ Should Stay in Services** (Infrastructure concerns)
   - External API calls (WHMCS, Salesforce)
   - Database lookups
   - Payment method verification
   - User mapping validation
   - Duplicate order checks

---

## 📋 What Should Move to Domain

### 1. **Order Business Rules** (High Priority)

**Current**: `apps/bff/src/modules/orders/services/order-validator.service.ts:176-228`

```typescript
validateBusinessRules(orderType: string, skus: string[]): void {
  switch (orderType) {
    case "SIM": {
      // Check for SIM service plan
      const hasSimService = skus.some(...);
      // Check for activation fee
      const hasActivation = skus.some(...);
    }
    case "VPN": {
      // VPN activation check
    }
    case "Internet": {
      // Internet service check
    }
  }
}
```

**Should be**: Extended validation in `packages/domain/orders/schema.ts`

### 2. **Invoice Validation Constants** (Medium Priority)

**Current**: `apps/bff/src/modules/invoices/validators/invoice-validator.service.ts:14-23`

```typescript
private readonly validStatuses: readonly InvoiceStatus[] = [
  "Paid", "Unpaid", "Cancelled", "Overdue", "Collections"
] as const;
private readonly maxLimit = 100;
private readonly minLimit = 1;
```

**Should be**: In `packages/domain/billing/schema.ts`

### 3. **Common Validation Utilities**

- ID validation helpers
- Pagination limits
- Status validation

---

## ❌ What Should NOT Move to Domain

### Infrastructure/External Dependencies:

1. **User Mapping Validation** - requires DB lookup
2. **Payment Method Validation** - requires WHMCS API call
3. **Internet Duplication Check** - requires WHMCS API call
4. **SKU Existence Check** - requires Salesforce API call
5. **SIM Account Extraction** - complex WHMCS integration logic

These involve:
- External API calls
- Database queries
- Caching
- Rate limiting
- Retry logic
- Logging infrastructure

---

## 🔄 Implementation Plan

### Phase 1: Order Validation (High Priority)
1. Create advanced order validation schemas in domain
2. Move SKU business rules to domain
3. Update OrderValidator service to use domain schemas
4. Remove duplicate validation logic

### Phase 2: Invoice Validation (Medium Priority)
1. Move invoice constants to domain
2. Enhance invoice query schemas
3. Update InvoiceValidator to use domain constants

### Phase 3: Common Patterns (Low Priority)
1. Create shared validation helpers in domain/toolkit
2. Standardize pagination schemas
3. Create reusable validation utilities

---

## 📊 Expected Benefits

1. **Reusability**: Frontend can use same validation logic
2. **Consistency**: Same rules enforced everywhere
3. **Testability**: Pure validation logic easy to unit test
4. **Maintainability**: Single place to update business rules
5. **Type Safety**: TypeScript infers from schema

---

## 🚦 Decision Matrix

| Validation Type | Move to Domain? | Reason |
|----------------|-----------------|---------|
| SKU format rules | ✅ Yes | Pure business logic |
| Order type rules | ✅ Yes | Domain constraint |
| Invoice status list | ✅ Yes | Domain constant |
| Pagination limits | ✅ Yes | Application constant |
| User exists check | ❌ No | Database query |
| Payment method exists | ❌ No | External API |
| SKU exists in SF | ❌ No | External API |
| Internet duplication | ❌ No | External API |
| SIM account extraction | ❌ No | Complex integration |

---

## 📝 Implementation Notes

### Pattern: Domain Schema with Complex Validation

```typescript
// packages/domain/orders/validation.ts (NEW FILE)
import { z } from "zod";
import { orderBusinessValidationSchema } from "./schema";

/**
 * Extended order validation with SKU business rules
 */
export const orderWithSkuValidationSchema = orderBusinessValidationSchema.refine(
  (data) => {
    if (data.orderType === "SIM") {
      const hasSimService = data.skus.some(/* logic */);
      return hasSimService;
    }
    return true;
  },
  { message: "SIM orders must include a service plan", path: ["skus"] }
);
```

### Pattern: Domain Constants

```typescript
// packages/domain/billing/constants.ts (NEW FILE)
export const INVOICE_VALIDATION = {
  PAGINATION: {
    MIN_LIMIT: 1,
    MAX_LIMIT: 100,
    DEFAULT_LIMIT: 10,
  },
  VALID_STATUSES: ["Paid", "Unpaid", "Cancelled", "Overdue", "Collections"] as const,
} as const;
```

---

## ✅ Success Criteria

- [ ] Order SKU validation rules in domain
- [ ] Invoice constants in domain
- [ ] Frontend can reuse validation schemas
- [ ] Services delegate to domain schemas
- [ ] No duplication of business rules
- [ ] All tests pass

