/** * Company Response Mapper * * Transforms API response schemas (CompanyResponse, CompanyListResponse) to Company domain objects. * This mapper handles the response schema → domain transformation for company operations. * * @layer Infrastructure - API Client * @module Company Response Mapper */ import { type CompanyResponse, type CompanyListResponse, companyResponseSchema, companyListResponseSchema, } from '@archer/api-interface'; import { Company, CompanyType } from '@domain/entities/Company'; import type { PaginationMeta } from '../../shared/types'; /** * Maps CompanyType enum values from API interface to dashboard domain * * API: platform_admin, client, supplier, partner * Dashboard: INDIVIDUAL, CORPORATE */ const mapCompanyTypeFromApi = ( type: 'platform_admin' | 'client' | 'supplier' | 'partner', ): CompanyType => { switch (type) { case 'platform_admin': return CompanyType.CORPORATE; case 'client': return CompanyType.INDIVIDUAL; case 'supplier': case 'partner': // New types - map to INDIVIDUAL for now (future: add SUPPLIER/PARTNER to dashboard) return CompanyType.INDIVIDUAL; default: return CompanyType.INDIVIDUAL; } }; /** * Company Response Mapper * * Handles transformation from API response schemas to Company domain objects. * Uses Zod validation to ensure response data matches expected schema. */ export class CompanyResponseMapper { /** * Transforms CompanyResponse schema to Company domain object * * @param response - CompanyResponse schema from API * @returns Company domain entity * @throws ZodError if validation fails * * @example * ```typescript * const response = { * id: '123', * name: 'Acme Corp', * type: 'platform_admin', * createdAt: '2025-01-01T00:00:00Z', * updatedAt: '2025-01-01T00:00:00Z' * }; * * const company = CompanyResponseMapper.toCompany(response); * // Company domain entity with type: CompanyType.CORPORATE * ``` */ static toCompany(response: CompanyResponse): Company { // Validate response with Zod schema const validatedResponse = companyResponseSchema.parse(response); return Company.fromPersistence({ id: validatedResponse.id, name: validatedResponse.name, type: mapCompanyTypeFromApi((validatedResponse as any).type), address: validatedResponse.address ?? undefined, vatId: validatedResponse.vatId ?? undefined, website: validatedResponse.website ?? undefined, industry: validatedResponse.industry ?? undefined, size: validatedResponse.size ?? undefined, billingEmail: validatedResponse.billingEmail ?? undefined, legalForm: validatedResponse.legalForm ?? undefined, taxNumber: validatedResponse.taxNumber ?? undefined, registerCourt: validatedResponse.registerCourt ?? undefined, registerNumber: validatedResponse.registerNumber ?? undefined, directorName: validatedResponse.directorName ?? undefined, preferredCurrency: validatedResponse.preferredCurrency ?? null, currencyLockedAt: validatedResponse.currencyLockedAt ?? null, isProfileComplete: validatedResponse.isProfileComplete, missingProfileFields: validatedResponse.missingProfileFields, createdAt: validatedResponse.createdAt, updatedAt: validatedResponse.updatedAt, }); } /** * Transforms CompanyListResponse schema to array of Company domain objects with pagination * * @param response - CompanyListResponse schema from API * @returns Object containing companies array and pagination metadata * @throws ZodError if validation fails * * @example * ```typescript * const response = { * rows: [ * { id: '1', name: 'Company A', type: 'client', createdAt: ..., updatedAt: ... }, * { id: '2', name: 'Company B', type: 'platform_admin', createdAt: ..., updatedAt: ... } * ], * totalRows: 2, * page: 1, * limit: 10, * totalPages: 1 * }; * * const result = CompanyResponseMapper.toCompanyList(response); * // { * // companies: [Company, Company], * // pagination: { page: 1, limit: 10, total: 2, totalPages: 1 } * // } * ``` */ static toCompanyList(response: CompanyListResponse): { companies: Company[]; pagination: PaginationMeta; } { // Validate response with Zod schema const validatedResponse = companyListResponseSchema.parse(response); return { companies: validatedResponse.rows.map((item) => this.toCompany(item)), pagination: { page: validatedResponse.page, limit: validatedResponse.limit, total: validatedResponse.totalRows, totalPages: validatedResponse.totalPages, }, }; } }