# New Domain Architecture

## Overview

The `@customer-portal/domain` package is now a **unified domain layer** following the **Provider-Aware Structure** pattern. It consolidates all types, schemas, and provider-specific logic into a single, well-organized package.

## 🎯 Goals

1. **Single Source of Truth**: One place for all domain contracts, schemas, and transformations
2. **Provider Isolation**: Raw provider types and mappers co-located within each domain
3. **Clean Exports**: Simple, predictable import paths
4. **Type Safety**: Runtime validation with Zod + TypeScript inference
5. **Maintainability**: Easy to find and update domain logic

## 📁 Structure

```
packages/domain/
├── billing/
│   ├── contract.ts              # Invoice, InvoiceItem, InvoiceList
│   ├── schema.ts                # Zod schemas
│   ├── providers/
│   │   └── whmcs/
│   │       ├── raw.types.ts     # WHMCS-specific types
│   │       └── mapper.ts        # Transform WHMCS → Invoice
│   └── index.ts                 # Public exports
├── subscriptions/
│   ├── contract.ts              # Subscription, SubscriptionList
│   ├── schema.ts
│   ├── providers/
│   │   └── whmcs/
│   │       ├── raw.types.ts
│   │       └── mapper.ts
│   └── index.ts
├── payments/
│   ├── contract.ts              # PaymentMethod, PaymentGateway
│   ├── schema.ts
│   ├── providers/
│   │   └── whmcs/
│   │       ├── raw.types.ts
│   │       └── mapper.ts
│   └── index.ts
├── sim/
│   ├── contract.ts              # SimDetails, SimUsage, SimTopUpHistory
│   ├── schema.ts
│   ├── providers/
│   │   └── freebit/
│   │       ├── raw.types.ts
│   │       └── mapper.ts
│   └── index.ts
├── orders/
│   ├── contract.ts              # OrderSummary, OrderDetails, FulfillmentOrder
│   ├── schema.ts
│   ├── providers/
│   │   ├── whmcs/
│   │   │   ├── raw.types.ts     # WHMCS AddOrder API types
│   │   │   └── mapper.ts        # Transform FulfillmentOrder → WHMCS
│   │   └── salesforce/
│   │       ├── raw.types.ts     # Salesforce Order/OrderItem
│   │       └── mapper.ts        # Transform Salesforce → OrderDetails
│   └── index.ts
├── services/
│   ├── contract.ts              # CatalogProduct, InternetPlan, SimProduct, VpnProduct
│   ├── schema.ts
│   ├── providers/
│   │   └── salesforce/
│   │       ├── raw.types.ts     # Salesforce Product2
│   │       └── mapper.ts        # Transform Product2 → CatalogProduct
│   └── index.ts
├── common/
│   ├── types.ts                 # IsoDateTimeString, branded types, API wrappers
│   └── index.ts
├── toolkit/
│   ├── formatting/              # Currency, date, phone, text formatters
│   ├── validation/              # Email, URL, string validators
│   ├── typing/                  # Type guards, assertions, helpers
│   └── index.ts
├── package.json
├── tsconfig.json
└── index.ts                     # Main entry point
```

## 📦 Usage

### Import Contracts

```typescript
// Import domain contracts
import type { Invoice, InvoiceList } from "@customer-portal/domain/billing";
import type { Subscription } from "@customer-portal/domain/subscriptions";
import type { SimDetails } from "@customer-portal/domain/sim";
import type { OrderSummary } from "@customer-portal/domain/orders";
import type { InternetPlanCatalogItem } from "@customer-portal/domain/services";
```

### Import Schemas

```typescript
// Import Zod schemas for runtime validation
import { invoiceSchema, invoiceListSchema } from "@customer-portal/domain/billing";
import { simDetailsSchema } from "@customer-portal/domain/sim";

// Validate at runtime
const invoice = invoiceSchema.parse(rawData);
```

### Import Provider Mappers

```typescript
// Import provider-specific mappers
import { WhmcsBillingMapper } from "@customer-portal/domain/billing";
import { FreebitSimMapper } from "@customer-portal/domain/sim";
import { WhmcsOrderMapper, SalesforceOrderMapper } from "@customer-portal/domain/orders";

// Transform provider data to normalized domain contracts
const invoice = WhmcsBillingMapper.transformWhmcsInvoice(whmcsInvoiceData);
const simDetails = FreebitSimMapper.transformFreebitAccountDetails(freebitAccountData);
const order = SalesforceOrderMapper.transformOrderToDetails(salesforceOrderRecord, items);
```

### Import Utilities

```typescript
// Import toolkit utilities
import { Formatting, Validation, Typing } from "@customer-portal/domain/toolkit";

// Use formatters
const formatted = Formatting.formatCurrency(10000, "JPY");
const date = Formatting.formatDate(isoString);

// Use validators
const isValid = Validation.isValidEmail(email);

// Use type guards
if (Typing.isDefined(value)) {
  // TypeScript knows value is not null/undefined
}
```

## 🔄 Data Flow

### Inbound (Provider → Domain)

```
External API Response
      ↓
Raw Provider Types (providers/*/raw.types.ts)
      ↓
Provider Mapper (providers/*/mapper.ts)
      ↓
Zod Schema Validation (schema.ts)
      ↓
Domain Contract (contract.ts)
      ↓
Application Code (BFF, Portal)
```

### Outbound (Domain → Provider)

```
Application Intent
      ↓
Domain Contract (contract.ts)
      ↓
Provider Mapper (providers/*/mapper.ts)
      ↓
Raw Provider Payload (providers/*/raw.types.ts)
      ↓
External API Request
```

## 🎨 Design Principles

### 1. **Co-location**

- Domain contracts, schemas, and provider logic live together
- Easy to find related code
- Clear ownership and responsibility

### 2. **Provider Isolation**

- Raw types and mappers nested in `providers/` subfolder
- Each provider is self-contained
- Easy to add/remove providers

### 3. **Type Safety**

- Zod schemas for runtime validation
- TypeScript types inferred from schemas
- Branded types for stronger type checking

### 4. **Clean Exports**

- Barrel exports (`index.ts`) control public API
- Provider mappers exported as namespaces (`WhmcsBillingMapper.*`)
- Predictable import paths

### 5. **Minimal Dependencies**

- Only depends on `zod` for runtime validation
- No circular dependencies
- Self-contained domain logic

## 📋 Domain Reference

### Billing

- **Contracts**: `Invoice`, `InvoiceItem`, `InvoiceList`
- **Providers**: WHMCS
- **Use Cases**: Display invoices, payment history, invoice details

### Subscriptions

- **Contracts**: `Subscription`, `SubscriptionList`
- **Providers**: WHMCS
- **Use Cases**: Display active services, manage subscriptions

### Payments

- **Contracts**: `PaymentMethod`, `PaymentGateway`
- **Providers**: WHMCS
- **Use Cases**: Payment method management, gateway configuration

### SIM

- **Contracts**: `SimDetails`, `SimUsage`, `SimTopUpHistory`
- **Providers**: Freebit
- **Use Cases**: SIM management, usage tracking, top-up history

### Orders

- **Contracts**: `OrderSummary`, `OrderDetails`, `FulfillmentOrderDetails`
- **Providers**: WHMCS (provisioning), Salesforce (order management)
- **Use Cases**: Order fulfillment, order history, order details

### Services

- **Contracts**: `InternetPlanCatalogItem`, `SimCatalogProduct`, `VpnCatalogProduct`
- **Providers**: Salesforce (Product2)
- **Use Cases**: Product catalog display, product selection, service browsing

### Common

- **Types**: `IsoDateTimeString`, `UserId`, `AccountId`, `OrderId`, `ApiResponse`, `PaginatedResponse`
- **Use Cases**: Shared utility types across all domains

### Toolkit

- **Formatting**: Currency, date, phone, text formatters
- **Validation**: Email, URL, string validators
- **Typing**: Type guards, assertions, helpers
- **Use Cases**: UI formatting, input validation, type safety

## 🚀 Migration Guide

### From Old Structure

**Before:**

```typescript
import type { Invoice } from "@customer-portal/contracts/billing";
import { invoiceSchema } from "@customer-portal/schemas/business/billing.schema";
import { transformWhmcsInvoice } from "@customer-portal/integrations-whmcs/mappers/billing.mapper";
```

**After:**

```typescript
import type { Invoice } from "@customer-portal/domain/billing";
import { invoiceSchema } from "@customer-portal/domain/billing";
import { WhmcsBillingMapper } from "@customer-portal/domain/billing";

const invoice = WhmcsBillingMapper.transformWhmcsInvoice(data);
```

### Benefits

- **Fewer imports**: Everything in one package
- **Clearer intent**: Mapper namespace indicates provider
- **Better DX**: Autocomplete shows all related exports
- **Type safety**: Contracts + schemas + mappers always in sync

## ✅ Completed Domains

- ✅ Billing (WHMCS provider)
- ✅ Subscriptions (WHMCS provider)
- ✅ Payments (WHMCS provider)
- ✅ SIM (Freebit provider)
- ✅ Orders (WHMCS + Salesforce providers)
- ✅ Catalog (Salesforce provider)
- ✅ Common (shared types)
- ✅ Toolkit (utilities)

## 📝 Next Steps

1. **Update BFF imports** to use `@customer-portal/domain/*`
2. **Update Portal imports** to use `@customer-portal/domain/*`
3. **Delete old packages**: `contracts`, `schemas`, `integrations`
4. **Update ESLint rules** to prevent imports from old packages
5. **Update documentation** to reference new structure

## 🔗 Related Documentation

- [Provider-Aware Structure](./DOMAIN-STRUCTURE.md)
- [Type Cleanup Summary](./TYPE-CLEANUP-SUMMARY.md)
- [Architecture Overview](./ARCHITECTURE.md)
