# Domain Toolkit

Utility functions and helpers for the domain layer. This package contains **utilities only**, not validation.

## Purpose

The toolkit provides pure utility functions for common operations like:
- String manipulation
- Date/time formatting
- Currency formatting
- URL parsing and manipulation
- Type guards and assertions

**Important**: For validation functions (e.g., `isValidEmail`, `isValidUuid`), use `packages/domain/common/validation.ts` instead.

## Structure

```
toolkit/
├── formatting/          # Formatting utilities
│   ├── currency.ts      # Currency formatting (e.g., formatCurrency)
│   ├── date.ts          # Date formatting (e.g., formatDate, formatRelativeTime)
│   ├── phone.ts         # Phone number formatting
│   └── text.ts          # Text manipulation (e.g., truncate, capitalize)
│
├── typing/              # Type utilities
│   ├── assertions.ts    # Type assertions (e.g., assertNonNull)
│   ├── guards.ts        # Type guards (e.g., isString, isNumber)
│   └── helpers.ts       # Type helper functions
│
└── validation/          # Validation utilities (NOT validation itself)
    ├── email.ts         # Email utilities (getEmailDomain, normalizeEmail)
    ├── url.ts           # URL utilities (ensureProtocol, getHostname)
    ├── string.ts        # String utilities (isEmpty, hasMinLength)
    └── helpers.ts       # Validation helpers (sanitizePagination, isInRange)
```

## Important Distinction: Validation vs Utilities

### ❌ Validation (NOT in toolkit)

Validation determines if input is valid or invalid:

```typescript
// These are VALIDATION functions → Use common/validation.ts
isValidEmail(email)      // Returns true/false
isValidUuid(id)          // Returns true/false
isValidUrl(url)          // Returns true/false
validateUrlOrThrow(url)  // Throws if invalid
```

**Location**: `packages/domain/common/validation.ts`

### ✅ Utilities (IN toolkit)

Utilities transform, extract, or manipulate data:

```typescript
// These are UTILITY functions → Use toolkit
getEmailDomain(email)      // Extracts domain from email
normalizeEmail(email)      // Lowercases and trims
ensureProtocol(url)        // Adds https:// if missing
getHostname(url)           // Extracts hostname
```

**Location**: `packages/domain/toolkit/`

## Usage Examples

### Formatting

```typescript
import { formatCurrency, formatDate } from "@customer-portal/domain/toolkit/formatting";

const price = formatCurrency(1000, "JPY");  // "¥1,000"
const date = formatDate(new Date());         // "2025-10-08"
```

### Type Guards

```typescript
import { isString, isNumber } from "@customer-portal/domain/toolkit/typing";

if (isString(value)) {
  // TypeScript knows value is string here
  console.log(value.toUpperCase());
}
```

### URL Utilities

```typescript
import { ensureProtocol, getHostname } from "@customer-portal/domain/toolkit/validation/url";

const fullUrl = ensureProtocol("example.com");  // "https://example.com"
const host = getHostname("https://example.com/path");  // "example.com"
```

### Email Utilities

```typescript
import { getEmailDomain, normalizeEmail } from "@customer-portal/domain/toolkit/validation/email";

const domain = getEmailDomain("user@example.com");  // "example.com"
const normalized = normalizeEmail(" User@Example.COM ");  // "user@example.com"
```

## When to Use What

| Task | Use | Example |
|------|-----|---------|
| Validate email format | `common/validation.ts` | `isValidEmail(email)` |
| Extract email domain | `toolkit/validation/email.ts` | `getEmailDomain(email)` |
| Validate URL format | `common/validation.ts` | `isValidUrl(url)` |
| Add protocol to URL | `toolkit/validation/url.ts` | `ensureProtocol(url)` |
| Format currency | `toolkit/formatting/currency.ts` | `formatCurrency(amount, "JPY")` |
| Format date | `toolkit/formatting/date.ts` | `formatDate(date)` |

## Best Practices

1. **Use validation functions for validation**
   ```typescript
   // ✅ Good
   import { isValidEmail } from "@customer-portal/domain/common/validation";
   if (!isValidEmail(email)) throw new Error("Invalid email");
   
   // ❌ Bad - don't write custom validation
   if (!email.includes("@")) throw new Error("Invalid email");
   ```

2. **Use utility functions for transformations**
   ```typescript
   // ✅ Good
   import { normalizeEmail } from "@customer-portal/domain/toolkit/validation/email";
   const clean = normalizeEmail(email);
   
   // ❌ Bad - don't duplicate utility logic
   const clean = email.trim().toLowerCase();
   ```

3. **Don't mix validation and utilities**
   ```typescript
   // ❌ Bad - mixing concerns
   function processEmail(email: string) {
     if (!email.includes("@")) return null;  // Validation
     return email.toLowerCase();              // Utility
   }
   
   // ✅ Good - separate concerns
   import { isValidEmail } from "@customer-portal/domain/common/validation";
   import { normalizeEmail } from "@customer-portal/domain/toolkit/validation/email";
   
   function processEmail(email: string) {
     if (!isValidEmail(email)) return null;
     return normalizeEmail(email);
   }
   ```

## Migration Notes

If you're refactoring existing code:

1. **Validation functions** → Move to `common/validation.ts`
2. **Utility functions** → Keep in or move to `toolkit/`
3. **Business logic** → Move to domain-specific `validation.ts` files

## Related Documentation

- [Validation Patterns Guide](../../../docs/validation/VALIDATION_PATTERNS.md) - How to implement validation
- [Domain Layer Design](../../../docs/DOMAIN-LAYER-DESIGN.md) - Overall domain architecture
- [Common Validation](../common/validation.ts) - Validation functions

## Questions?

If you're unsure whether something belongs in toolkit or common/validation:

- **Ask**: "Does this determine if input is valid/invalid?"
  - YES → It's validation → Use `common/validation.ts`
  - NO → It's a utility → Use `toolkit/`

- **Ask**: "Does this transform or extract data?"
  - YES → It's a utility → Use `toolkit/`
  - NO → Might be validation → Use `common/validation.ts`

