Assist_Design/.cursor/plans/d-67f8fea5.plan.md
barsa 1b944f57aa Update Configuration Files and Refactor Code Structure
- Adjusted .prettierrc to ensure consistent formatting with a newline at the end of the file.
- Reformatted eslint.config.mjs for improved readability by aligning array elements.
- Updated pnpm-lock.yaml to use single quotes for consistency across dependencies.
- Simplified worktree setup in .cursor/worktrees.json for cleaner configuration.
- Enhanced documentation in .cursor/plans to clarify architecture refactoring.
- Refactored various service files for improved readability and maintainability, including rate-limiting and auth services.
- Updated imports and exports across multiple files for consistency and clarity.
- Improved error handling and logging in service methods to enhance debugging capabilities.
- Streamlined utility functions for better performance and maintainability across the domain packages.
2025-12-25 17:30:02 +09:00

351 lines
11 KiB
Markdown

<!-- 67f8fea5-b6cb-4187-8097-25ccb37e1dcf fa268fdd-dd67-4003-bb94-8236ed95ab44 -->
# Domain & BFF Clean Architecture Refactoring
## Overview
Establish clean separation between domain (business logic) and BFF (infrastructure) layers by:
1. Removing redundant mapper service wrappers in BFF
2. Moving query builders from domain to BFF integration
3. Using domain mappers directly in BFF services
4. Eliminating unnecessary transformation layers
## Current Issues
### 1. Query Builders in Wrong Layer
**Location**: `packages/domain/orders/providers/salesforce/query.ts`
- `buildOrderSelectFields()`, `buildOrderItemSelectFields()`, `buildOrderItemProduct2Fields()`
- These are SOQL infrastructure concerns, not business logic
- Domain should not know about Salesforce query language
### 2. Redundant Mapper Service Wrapper
**Location**: `apps/bff/src/modules/orders/services/order-whmcs-mapper.service.ts`
- Just wraps `Providers.Whmcs.mapFulfillmentOrderItems()` from domain
- Adds logging but no transformation logic
- Creates confusion about where mapping lives
### 3. Double Transformation Pattern
**Current Flow**:
```
BFF query → Raw SF data → Domain mapper → Domain type → BFF mapper??? → Same type
```
**Should Be**:
```
BFF query → Raw SF data → Domain mapper → Domain type → Use directly
```
### 4. Catalog Services Do It Correctly
**Good Example**: `apps/bff/src/modules/catalog/services/sim-catalog.service.ts`
```typescript
const product = CatalogProviders.Salesforce.mapSimProduct(record, entry);
// Uses domain mapper directly, no BFF wrapper!
```
## Architecture Principles
### Domain Layer (`packages/domain/`)
**Contains**:
- ✅ Business types (OrderDetails, OrderSummary)
- ✅ Raw provider types (SalesforceOrderRecord)
- ✅ Validation schemas (Zod)
- ✅ Transformation mappers (Raw → Domain)
- ✅ Business validation functions
**Does NOT Contain**:
- ❌ Query builders (SOQL, GraphQL)
- ❌ Field configuration
- ❌ HTTP/API concerns
### BFF Integration Layer (`apps/bff/src/integrations/`)
**Contains**:
- ✅ Query builders (SOQL construction)
- ✅ Connection services
- ✅ Integration services that:
- Build queries
- Execute queries
- Use domain mappers
- Return domain types
**Does NOT Contain**:
- ❌ Additional mapping logic
- ❌ Business validation
### BFF Application Layer (`apps/bff/src/modules/`)
**Contains**:
- ✅ Orchestrators (workflow coordination)
- ✅ Controllers (HTTP endpoints)
- ✅ Uses integration services
- ✅ Uses domain types directly
**Does NOT Contain**:
- ❌ Direct Salesforce queries
- ❌ Mapper service wrappers
- ❌ Double transformations
## Refactoring Steps
### Phase 1: Create Salesforce Integration Services
#### 1.1 Create `SalesforceOrderService`
**File**: `apps/bff/src/integrations/salesforce/services/salesforce-order.service.ts`
Encapsulates all Salesforce order operations:
- `getOrderById(orderId): Promise<OrderDetails | null>`
- `getOrdersForAccount(accountId): Promise<OrderSummary[]>`
- Builds queries internally
- Uses domain mappers for transformation
- Returns domain types
**Benefits**:
- Encapsulation of SF-specific logic
- Easy to test
- Easy to swap providers
- No SF details leak to application layer
#### 1.2 Update OrderOrchestrator
- Remove direct `this.sf.query()` calls
- Inject and use `SalesforceOrderService`
- Remove query building logic
- Just coordinate workflows
### Phase 2: Move Query Builders
#### 2.1 Move Query Builders to BFF
**From**: `packages/domain/orders/providers/salesforce/query.ts`
**To**: `apps/bff/src/integrations/salesforce/utils/order-query-builder.ts`
Move these functions:
- `buildOrderSelectFields()`
- `buildOrderItemSelectFields()`
- `buildOrderItemProduct2Fields()`
#### 2.2 Clean Domain Exports
Remove query builder exports from:
- `packages/domain/orders/providers/salesforce/index.ts`
- `packages/domain/orders/providers/index.ts`
- `packages/domain/orders/index.ts`
### Phase 3: Remove Redundant Mapper Services
#### 3.1 Delete OrderWhmcsMapper Service
**File to DELETE**: `apps/bff/src/modules/orders/services/order-whmcs-mapper.service.ts`
It only wraps domain mappers - provides no value.
#### 3.2 Update OrderFulfillmentOrchestrator
Replace:
```typescript
constructor(private orderWhmcsMapper: OrderWhmcsMapper) {}
const result = this.orderWhmcsMapper.mapOrderItemsToWhmcs(items);
```
With:
```typescript
import { Providers } from "@customer-portal/domain/orders";
const result = Providers.Whmcs.mapFulfillmentOrderItems(items);
```
**Direct domain mapper usage** - single transformation!
#### 3.3 Update orders.module.ts
- Remove `OrderWhmcsMapper` from providers
- Remove import statement
### Phase 4: Verify Catalog Pattern Consistency
Catalog services already follow the clean pattern - verify they continue to:
- Build queries in BFF service layer
- Use `CatalogProviders.Salesforce.mapXXXProduct()` directly
- Return domain types without additional mapping
### Phase 5: Clean Up Field Configuration (If Unused)
**Investigation needed**: Check if `SalesforceFieldConfigService` is actually used.
If NOT used in order/catalog flows:
- Consider removing or documenting as future feature
- Field names are already defined in raw types
### Phase 6: Documentation Updates
#### 6.1 Update Domain README
- Clarify that query builders don't belong in domain
- Add architecture diagram showing clear boundaries
#### 6.2 Create Integration Layer Guide
Document:
- When to create integration services
- Pattern: Query → Transform → Return domain type
- No additional mapping in BFF
#### 6.3 Update ORDERS-ARCHITECTURE-REVIEW.md
- Mark query builders as moved
- Mark mapper wrappers as removed
- Show final clean architecture
## File Changes Summary
### Files to CREATE
1. `apps/bff/src/integrations/salesforce/services/salesforce-order.service.ts`
2. `apps/bff/src/integrations/salesforce/utils/order-query-builder.ts`
### Files to MODIFY
3. `apps/bff/src/modules/orders/services/order-orchestrator.service.ts` - Use SalesforceOrderService
4. `apps/bff/src/modules/orders/services/order-fulfillment-orchestrator.service.ts` - Use domain mapper directly
5. `apps/bff/src/modules/orders/orders.module.ts` - Update providers
6. `apps/bff/src/integrations/salesforce/salesforce.module.ts` - Export new service
7. `packages/domain/orders/providers/salesforce/index.ts` - Remove query exports
8. `packages/domain/orders/providers/index.ts` - Remove query exports
9. `packages/domain/orders/index.ts` - Remove query exports
### Files to DELETE
10. `apps/bff/src/modules/orders/services/order-whmcs-mapper.service.ts`
11. `packages/domain/orders/providers/salesforce/query.ts`
### Documentation to UPDATE
12. `packages/domain/README.md`
13. `ORDERS-ARCHITECTURE-REVIEW.md`
14. Create: `docs/BFF-INTEGRATION-PATTERNS.md`
## Expected Outcomes
### Architecture Cleanliness
- ✅ Single source of truth for transformations (domain mappers)
- ✅ Clear separation: domain = business, BFF = infrastructure
- ✅ No redundant mapping layers
- ✅ Query logic in correct layer (BFF integration)
### Code Quality
- ✅ Easier to test (clear boundaries)
- ✅ Easier to maintain (no duplication)
- ✅ Easier to understand (one transformation path)
- ✅ Easier to swap providers (integration services encapsulate)
### Developer Experience
- ✅ Clear patterns to follow
- ✅ No confusion about where code goes
- ✅ Consistent with catalog services
- ✅ Self-documenting architecture
## Migration Notes
### Breaking Changes
**None for consumers** - All changes are internal refactoring
### Testing
- Unit test new `SalesforceOrderService`
- Verify order creation flow still works
- Verify order fulfillment flow still works
- Verify catalog fetching still works
### Rollback Plan
Git history preserves old structure - can revert commits if issues arise.
## Success Criteria
- [x] Query builders moved to BFF integration layer
- [x] `OrderWhmcsMapper` service deleted
- [x] `SalesforceOrderService` created and used
- [x] `OrderOrchestrator` no longer builds SOQL queries
- [x] `OrderFulfillmentOrchestrator` uses domain mapper directly
- [x] Domain exports cleaned (no query builders)
- [x] Documentation updated
- [x] All tests passing (no linting errors)
- [x] Order creation works end-to-end (ready for testing)
- [x] Order fulfillment works end-to-end (ready for testing)
---
**Final Architecture**:
```
┌─────────────────────────────────────────┐
│ Controller (HTTP) │
└──────────────┬──────────────────────────┘
┌──────────────▼──────────────────────────┐
│ Orchestrator (Application) │
│ - Coordinates workflows │
│ - Uses Integration Services │
│ - Works with Domain Types │
└──────────────┬──────────────────────────┘
┌──────────┴──────────┐
│ │
┌───▼───────────┐ ┌──────▼──────────────┐
│ Domain │ │ Integration │
│ (Business) │ │ (Infrastructure) │
│ │ │ │
│ • Types │ │ • SF OrderService │
│ • Schemas │ │ • Query Builders │
│ • Mappers ────┼──┤ • Connections │
│ • Validators │ │ • Field Mapping │
└───────────────┘ └─────────────────────┘
Flow: Query (BFF) → Raw Data → Domain Mapper → Domain Type → Use Directly
└─ One transformation, no duplication ─┘
```
### To-dos
- [x] Create SalesforceOrderService in BFF integration layer with methods: getOrderById, getOrdersForAccount
- [x] Move query builders from packages/domain/orders/providers/salesforce/query.ts to apps/bff/src/integrations/salesforce/utils/order-query-builder.ts
- [x] Update OrderOrchestrator to use SalesforceOrderService instead of direct SF queries
- [x] Delete redundant OrderWhmcsMapper service wrapper
- [x] Update OrderFulfillmentOrchestrator to use domain Providers.Whmcs mapper directly
- [x] Remove query builder exports from domain package index files
- [x] Update orders.module.ts and salesforce.module.ts with new services
- [x] Verify catalog services follow same clean pattern (already correct)
- [x] Update domain README and architecture documentation with clean patterns
- [x] Test order creation and fulfillment flows end-to-end