diff --git a/apps/bff/Dockerfile b/apps/bff/Dockerfile index 0a8185b2..ebadef29 100644 --- a/apps/bff/Dockerfile +++ b/apps/bff/Dockerfile @@ -75,7 +75,8 @@ COPY pnpm-workspace.yaml package.json pnpm-lock.yaml ./ COPY packages/shared/package.json ./packages/shared/ COPY apps/bff/package.json ./apps/bff/ -# Install only production dependencies +# Install only production dependencies; run scripts (needed for bcrypt/prisma) but disable Husky +ENV HUSKY=0 RUN pnpm install --frozen-lockfile --prod # Copy built applications and Prisma client diff --git a/apps/bff/src/auth/auth.service.ts b/apps/bff/src/auth/auth.service.ts index db30a6c1..f4605ce3 100644 --- a/apps/bff/src/auth/auth.service.ts +++ b/apps/bff/src/auth/auth.service.ts @@ -258,18 +258,12 @@ export class AuthService { } // 3. Extract Customer Number from field ID 198 - const customerNumberField = clientDetails.customfields?.customfield.find( - field => field.id == 198 - ); + const customerNumberField = clientDetails.customfields?.find(field => field.id === 198); + const customerNumber = customerNumberField?.value?.trim(); - const customerNumber = customerNumberField?.value as string; - - if (!customerNumber || customerNumber.toString().trim() === "") { + if (!customerNumber) { throw new BadRequestException( - `Customer Number not found in WHMCS custom field 198. ` + - `Found field: ${JSON.stringify(customerNumberField)}. ` + - `Available custom fields: ${JSON.stringify(clientDetails.customfields || [])}. ` + - `Please contact support.` + `Customer Number not found in WHMCS custom field 198. Please contact support.` ); } diff --git a/apps/bff/src/vendors/whmcs/transformers/whmcs-data.transformer.ts b/apps/bff/src/vendors/whmcs/transformers/whmcs-data.transformer.ts index 63745913..14d6fc17 100644 --- a/apps/bff/src/vendors/whmcs/transformers/whmcs-data.transformer.ts +++ b/apps/bff/src/vendors/whmcs/transformers/whmcs-data.transformer.ts @@ -14,7 +14,7 @@ import { import { WhmcsInvoice, WhmcsProduct, - WhmcsCustomFields, + WhmcsCustomField, WhmcsInvoiceItems, WhmcsPaymentMethod, WhmcsPaymentGateway, @@ -147,15 +147,15 @@ export class WhmcsDataTransformer { * Transform custom fields from WHMCS format */ private transformCustomFields( - customFields?: WhmcsCustomFields + customFields?: WhmcsCustomField[] ): Record | undefined { - if (!customFields?.customfield || !Array.isArray(customFields.customfield)) { + if (!customFields || !Array.isArray(customFields)) { return undefined; } const result: Record = {}; - customFields.customfield.forEach(field => { + customFields.forEach(field => { if (field.name && field.value) { result[field.name] = field.value; } diff --git a/apps/bff/src/vendors/whmcs/types/whmcs-api.types.ts b/apps/bff/src/vendors/whmcs/types/whmcs-api.types.ts index 33cc4492..f5bcd2f0 100644 --- a/apps/bff/src/vendors/whmcs/types/whmcs-api.types.ts +++ b/apps/bff/src/vendors/whmcs/types/whmcs-api.types.ts @@ -38,21 +38,22 @@ export interface WhmcsClientResponse { datecreated: string; lastattempt?: string; lastlogin?: string; - customfields?: WhmcsCustomFields; + customfields?: WhmcsCustomField[]; }; } -// Custom Fields Structure -export interface WhmcsCustomFields { - customfield: Array<{ - id: number; - name: string; - translated_name: string; - value: string; - type: string; - }>; +// Custom Field Structure - Based on official WHMCS API documentation +export interface WhmcsCustomField { + id: number; + value: string; + // Legacy fields that may appear in some responses + name?: string; + translated_name?: string; + type?: string; } + + // Invoice Types export interface WhmcsInvoicesResponse { invoices: { @@ -153,7 +154,7 @@ export interface WhmcsProduct { packageid?: number; packagename?: string; configoptions?: Record; - customfields?: WhmcsCustomFields; + customfields?: WhmcsCustomField[]; firstpaymentamount: string; recurringamount: string; paymentmethod: string;