# 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`