Assist_Design/ARCHITECTURE-CLEANUP-ANALYSIS.md

367 lines
10 KiB
Markdown

# Architecture Cleanup Analysis
**Date**: October 8, 2025
**Status**: Plan Mostly Implemented - Minor Cleanup Needed
## Executive Summary
The refactoring plan in `\d.plan.md` has been **~85% implemented**. The major architectural improvements have been completed:
**Completed:**
- Centralized DB mappers in `apps/bff/src/infra/mappers/`
- Deleted `FreebitMapperService`
- Moved Freebit utilities to domain layer
- WHMCS services now use domain mappers directly
- All redundant wrapper services removed
**Remaining Issues:**
1. **Pub/Sub event types still in BFF** (should be in domain)
2. **Empty transformer directories** (should be deleted)
3. **Business error codes in BFF** (should be in domain)
---
## Detailed Findings
### ✅ 1. DB Mappers Centralization - COMPLETE
**Status**: ✅ Fully Implemented
**Location**: `apps/bff/src/infra/mappers/`
```
apps/bff/src/infra/mappers/
├── index.ts ✅
├── user.mapper.ts ✅
└── mapping.mapper.ts ✅
```
**Evidence:**
- `mapPrismaUserToDomain()` properly maps Prisma → Domain
- `mapPrismaMappingToDomain()` properly maps Prisma → Domain
- Old `user-mapper.util.ts` has been deleted
- Services are using centralized mappers
**✅ This is production-ready and follows clean architecture.**
---
### ✅ 2. Freebit Integration - COMPLETE
**Status**: ✅ Fully Implemented
**What was done:**
1. ✅ Deleted `apps/bff/src/integrations/freebit/services/freebit-mapper.service.ts`
2. ✅ Created `packages/domain/sim/providers/freebit/utils.ts` with:
- `normalizeAccount()`
- `validateAccount()`
- `formatDateForApi()`
- `parseDateFromApi()`
3. ✅ Exported utilities from `packages/domain/sim/providers/freebit/index.ts`
4. ✅ Services now use domain mappers directly:
- `Freebit.transformFreebitAccountDetails()`
- `Freebit.transformFreebitTrafficInfo()`
- `Freebit.normalizeAccount()`
**✅ This is production-ready and follows clean architecture.**
---
### ✅ 3. WHMCS Services Using Domain Mappers - COMPLETE
**Status**: ✅ Fully Implemented
**Evidence from `apps/bff/src/integrations/whmcs/services/whmcs-invoice.service.ts`:**
```typescript
// Line 213: Using domain mappers directly
const defaultCurrency = this.currencyService.getDefaultCurrency();
const transformed = Providers.Whmcs.transformWhmcsInvoice(whmcsInvoice, {
defaultCurrencyCode: defaultCurrency.code,
defaultCurrencySymbol: defaultCurrency.prefix || defaultCurrency.suffix,
});
```
**Evidence from `whmcs-payment.service.ts`:**
```typescript
import { Providers } from "@customer-portal/domain/payments";
// Using domain mappers directly
```
**✅ Services are correctly using domain mappers with currency context.**
---
### ❌ 4. Pub/Sub Event Types Still in BFF - NEEDS MIGRATION
**Status**: ❌ **Not Implemented**
**Current Location**: `apps/bff/src/integrations/salesforce/types/pubsub-events.types.ts`
**Problem**: These are **provider-specific raw types** for Salesforce Platform Events, but they're still in the BFF layer.
**Current types:**
```typescript
// In apps/bff/src/integrations/salesforce/types/pubsub-events.types.ts
export interface SalesforcePubSubSubscription {
topicName: string;
}
export interface SalesforcePubSubEventPayload {
OrderId__c?: string;
OrderId?: string;
[key: string]: unknown;
}
export interface SalesforcePubSubEvent {
payload: SalesforcePubSubEventPayload;
replayId?: number;
}
export interface SalesforcePubSubError {
details?: string;
metadata?: SalesforcePubSubErrorMetadata;
[key: string]: unknown;
}
export type SalesforcePubSubCallbackType = "data" | "event" | "grpcstatus" | "end" | "error";
```
**🔴 RECOMMENDATION:**
These are **Salesforce provider types** and should be moved to the domain layer:
**New Location**: `packages/domain/orders/providers/salesforce/pubsub.types.ts`
**Rationale:**
- These are **raw provider types** (like `WhmcsInvoice`, `FreebitAccountDetailsRaw`)
- They represent Salesforce Platform Events structure
- Domain layer already has `packages/domain/orders/providers/salesforce/`
- They're used for order provisioning events
**Migration Path:**
```
1. Create: packages/domain/orders/providers/salesforce/pubsub.types.ts
2. Move types from BFF
3. Export from: packages/domain/orders/providers/salesforce/index.ts
4. Update imports in: apps/bff/src/integrations/salesforce/events/pubsub.subscriber.ts
```
---
### ⚠️ 5. Empty WHMCS Transformers Directory - CLEANUP NEEDED
**Status**: ⚠️ **Partially Cleaned**
**Current State**: The directory exists but is empty
```
apps/bff/src/integrations/whmcs/transformers/
├── services/ (empty)
├── utils/ (empty)
└── validators/ (empty)
```
**Evidence:**
- ✅ Transformer services deleted
- ✅ Not referenced in `whmcs.module.ts`
- ✅ Not imported anywhere
-**But directory still exists**
**🟡 RECOMMENDATION:**
Delete the entire `transformers/` directory:
```bash
rm -rf apps/bff/src/integrations/whmcs/transformers/
```
**Impact**: Zero - nothing uses it anymore.
---
### ❌ 6. Business Error Codes in BFF - NEEDS MIGRATION
**Status**: ❌ **Not Implemented**
**Current Location**: `apps/bff/src/modules/orders/services/order-fulfillment-error.service.ts`
**Problem**: Business error codes are defined in BFF:
```typescript
export enum OrderFulfillmentErrorCode {
PAYMENT_METHOD_MISSING = "PAYMENT_METHOD_MISSING",
ORDER_NOT_FOUND = "ORDER_NOT_FOUND",
WHMCS_ERROR = "WHMCS_ERROR",
MAPPING_ERROR = "MAPPING_ERROR",
VALIDATION_ERROR = "VALIDATION_ERROR",
SALESFORCE_ERROR = "SALESFORCE_ERROR",
PROVISIONING_ERROR = "PROVISIONING_ERROR",
}
```
**🔴 RECOMMENDATION:**
Move to domain layer as these are **business error codes**:
**New Location**: `packages/domain/orders/constants.ts` or `packages/domain/orders/errors.ts`
**Rationale:**
- These represent business-level error categories
- Not infrastructure concerns
- Could be useful for other consumers (frontend, webhooks, etc.)
- Part of the domain's error vocabulary
---
### ✅ 7. Infrastructure-Specific Types - CORRECTLY PLACED
**Status**: ✅ **Correct**
Some types in BFF modules are **correctly placed** as they are infrastructure concerns:
**Example: `apps/bff/src/modules/invoices/types/invoice-service.types.ts`:**
```typescript
export interface InvoiceServiceStats {
totalInvoicesRetrieved: number;
totalPaymentLinksCreated: number;
totalSsoLinksCreated: number;
averageResponseTime: number;
lastRequestTime?: Date;
lastErrorTime?: Date;
}
export interface InvoiceHealthStatus {
status: "healthy" | "unhealthy";
details: {
whmcsApi?: string;
mappingsService?: string;
error?: string;
timestamp: string;
};
}
```
**✅ These are BFF-specific monitoring/health check types and belong in BFF.**
---
## Summary of Remaining Work
### High Priority
| Issue | Location | Action | Effort |
|-------|----------|--------|--------|
| **Pub/Sub Types** | `apps/bff/src/integrations/salesforce/types/pubsub-events.types.ts` | Move to `packages/domain/orders/providers/salesforce/` | 15 min |
| **Error Codes** | `apps/bff/src/modules/orders/services/order-fulfillment-error.service.ts` | Move enum to `packages/domain/orders/errors.ts` | 10 min |
### Low Priority (Cleanup)
| Issue | Location | Action | Effort |
|-------|----------|--------|--------|
| **Empty Transformers** | `apps/bff/src/integrations/whmcs/transformers/` | Delete directory | 1 min |
---
## Architecture Score
### Before Refactoring: 60/100
- ❌ Redundant wrapper services everywhere
- ❌ Scattered DB mappers
- ❌ Unclear boundaries
### Current State: 85/100
- ✅ Centralized DB mappers
- ✅ Direct domain mapper usage
- ✅ Clean integration layer
- ✅ No redundant wrappers
- ⚠️ Minor cleanup needed
### Target State: 100/100
- All business types in domain
- All provider types in domain
- Clean BFF focusing on orchestration
---
## Recommended Actions
### Immediate (30 minutes)
1. **Move Pub/Sub Types to Domain**
```bash
# Create new file
mkdir -p packages/domain/orders/providers/salesforce
# Move types
mv apps/bff/src/integrations/salesforce/types/pubsub-events.types.ts \
packages/domain/orders/providers/salesforce/pubsub.types.ts
# Update exports and imports
```
2. **Move Order Error Codes to Domain**
```typescript
// Create: packages/domain/orders/errors.ts
export const ORDER_FULFILLMENT_ERROR_CODE = {
PAYMENT_METHOD_MISSING: "PAYMENT_METHOD_MISSING",
ORDER_NOT_FOUND: "ORDER_NOT_FOUND",
WHMCS_ERROR: "WHMCS_ERROR",
MAPPING_ERROR: "MAPPING_ERROR",
VALIDATION_ERROR: "VALIDATION_ERROR",
SALESFORCE_ERROR: "SALESFORCE_ERROR",
PROVISIONING_ERROR: "PROVISIONING_ERROR",
} as const;
export type OrderFulfillmentErrorCode =
typeof ORDER_FULFILLMENT_ERROR_CODE[keyof typeof ORDER_FULFILLMENT_ERROR_CODE];
```
3. **Delete Empty Transformers Directory**
```bash
rm -rf apps/bff/src/integrations/whmcs/transformers/
```
### Documentation (10 minutes)
4. **Update Success Criteria in `\d.plan.md`**
- Mark completed items as done
- Document remaining work
---
## Conclusion
The refactoring plan has been **successfully implemented** with only minor cleanup needed:
**🎉 Achievements:**
- Clean architecture boundaries established
- Domain layer is the single source of truth for business logic
- BFF layer focuses on orchestration and infrastructure
- No redundant wrapper services
- Centralized DB mappers
**🔧 Final Touch-ups Needed:**
- Move pub/sub types to domain (15 min)
- Move error codes to domain (10 min)
- Delete empty directories (1 min)
**Total remaining effort: ~30 minutes to achieve 100% cleanliness.**
---
## Files to Check
### ✅ Already Clean
- `apps/bff/src/infra/mappers/` - Centralized DB mappers
- `apps/bff/src/integrations/freebit/services/` - Using domain mappers
- `apps/bff/src/integrations/whmcs/services/` - Using domain mappers
- `packages/domain/sim/providers/freebit/` - Contains utilities and mappers
### ❌ Needs Attention
- `apps/bff/src/integrations/salesforce/types/pubsub-events.types.ts` - Move to domain
- `apps/bff/src/modules/orders/services/order-fulfillment-error.service.ts` - Move enum to domain
- `apps/bff/src/integrations/whmcs/transformers/` - Delete empty directory