Assist_Design/docs/_archive/customer-domain/CUSTOMER-DOMAIN-FINAL-CLEANUP.md

4.8 KiB

Customer Domain - Final Cleanup

Problems Identified

1. Unnecessary Infra Mapper (BFF)

Current:

BFF: @prisma/client User → user.mapper.ts → domain/customer/providers/portal → UserAuth

Problem: Double mapping! BFF adapter just converts Prisma type to domain raw type, then calls domain mapper.

Better:

BFF: @prisma/client User → directly use domain/customer/providers/portal/mapper → UserAuth

The BFF mapper is redundant - we should use the domain mapper directly.

2. Unused Legacy WHMCS Types

Never used in BFF:

  • CustomerEmailPreferences (0 occurrences)
  • CustomerUser (sub-users, 0 occurrences)
  • CustomerStats (billing stats, 0 occurrences)
  • Customer (full WHMCS schema - only used internally in WHMCS mapper)

Schemas for unused types:

  • customerEmailPreferencesSchema (~40 lines)
  • customerUserSchema (~25 lines)
  • customerStatsSchema (~50 lines)
  • customerSchema (~35 lines)

Total bloat: ~150 lines of unused code!

3. Not Following Schema-First in Domain Mapper

Current: packages/domain/customer/providers/portal/mapper.ts

// Manually constructs object - NO SCHEMA!
export function mapPrismaUserToUserAuth(raw: PrismaUserRaw): UserAuth {
  return {
    id: raw.id,
    email: raw.email,
    // ... manual construction
  };
}

Should be:

// Use schema for validation!
export function mapPrismaUserToUserAuth(raw: PrismaUserRaw): UserAuth {
  return userAuthSchema.parse({
    id: raw.id,
    email: raw.email,
    // ...
  });
}

Cleanup Plan

Step 1: Remove Unused Types

File: packages/domain/customer/types.ts

Remove:

  • customerEmailPreferencesSchema + type
  • customerUserSchema + type
  • customerStatsSchema + type
  • customerSchema + type (full WHMCS schema)
  • Helper functions for these types

Keep only:

  • userAuthSchemaUserAuth
  • userSchemaUser
  • customerDataSchemaCustomerData
  • customerAddressSchemaCustomerAddress
  • addressFormSchemaAddressFormData

Step 2: Update Customer Index Exports

File: packages/domain/customer/index.ts

Remove exports:

  • CustomerEmailPreferences
  • CustomerUser
  • CustomerStats
  • Customer
  • All related schemas

Step 3: Clean WHMCS Mapper (Internal Use Only)

File: packages/domain/customer/providers/whmcs/mapper.ts

Since Customer type is removed, the WHMCS mapper can:

  • Either define types inline (internal to mapper)
  • Or export minimal WhmcsCustomer type just for mapper use

Step 4: Use Schema in Portal Mapper

File: packages/domain/customer/providers/portal/mapper.ts

import { userAuthSchema } from "../../types";
import type { PrismaUserRaw } from "./types";
import type { UserAuth } from "../../types";

export function mapPrismaUserToUserAuth(raw: PrismaUserRaw): UserAuth {
  return userAuthSchema.parse({
    id: raw.id,
    email: raw.email,
    role: raw.role,
    mfaEnabled: !!raw.mfaSecret,
    emailVerified: raw.emailVerified,
    lastLoginAt: raw.lastLoginAt?.toISOString(),
    createdAt: raw.createdAt.toISOString(),
    updatedAt: raw.updatedAt.toISOString(),
  });
}

Step 5: Eliminate BFF Infra Mapper

Delete: apps/bff/src/infra/mappers/user.mapper.ts

Update all 7 usages to directly import from domain:

// OLD (double mapping - BAD!)
import { mapPrismaUserToDomain } from "@bff/infra/mappers";
const userAuth = mapPrismaUserToDomain(prismaUser);

// NEW (direct - GOOD!)
import { mapPrismaUserToUserAuth } from "@customer-portal/domain/customer/providers/portal";
const userAuth = mapPrismaUserToUserAuth(prismaUser);

Files to update (7 total):

  1. apps/bff/src/modules/auth/presentation/strategies/jwt.strategy.ts
  2. apps/bff/src/modules/auth/infra/workflows/workflows/whmcs-link-workflow.service.ts
  3. apps/bff/src/modules/auth/infra/workflows/workflows/signup-workflow.service.ts
  4. apps/bff/src/modules/auth/infra/workflows/workflows/password-workflow.service.ts
  5. apps/bff/src/modules/auth/infra/token/token.service.ts
  6. apps/bff/src/modules/auth/application/auth.facade.ts
  7. Any other imports of mapPrismaUserToDomain

Result

Before:

  • 342 lines in types.ts (lots of unused code)
  • BFF infra mapper (unnecessary layer)
  • Manual object construction (no schema validation)

After:

  • ~190 lines in types.ts (lean, only what's used)
  • Direct domain mapper usage (proper architecture)
  • Schema-validated mapping (type safe + runtime safe)

Types kept:

// User entity types
User            // Complete user
UserAuth        // Auth state
UserRole        // Role enum

// Address
CustomerAddress     // Address structure
AddressFormData     // Form validation

// Profile data (internal)
CustomerData        // WHMCS profile fields

Clean, minimal, schema-first! 🎯