From 1cfc0f0fa8dbb719ab7e1620a6df804dbc5ce5a9 Mon Sep 17 00:00:00 2001 From: Nathnael Date: Tue, 21 Jul 2026 07:34:20 +0000 Subject: [PATCH] fix(onboarding): stop duplicate company-document upload on finalize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The documents step of CompanyProfileForm uploads company documents via onUploadDocuments() and then triggers submit synchronously in the same nextStep() call. The setDocumentFiles({}) that clears the staged files has not re-rendered by the time finishMutation's closure runs, so reading documentFiles there re-sent the exact same files and created a duplicate row per document. Drop the company-document upload from finishMutation — the documents step already persisted them. Licenses stay, since they have no auto-upload path. --- .../onboarding/OnboardingWizardDialog.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/edr-freight-web/portal/src/components/onboarding/OnboardingWizardDialog.tsx b/apps/edr-freight-web/portal/src/components/onboarding/OnboardingWizardDialog.tsx index f2c9992e3..55c63ac52 100644 --- a/apps/edr-freight-web/portal/src/components/onboarding/OnboardingWizardDialog.tsx +++ b/apps/edr-freight-web/portal/src/components/onboarding/OnboardingWizardDialog.tsx @@ -212,23 +212,23 @@ export default function OnboardingWizardDialog({ onError: (err) => setStartError(extractApiError(err).message), }); - // Finalize: upload per-role license files + company documents, then complete. + // Finalize: upload per-role license files, then complete. + // + // Company documents are deliberately NOT uploaded here. The documents step + // uploads them via `onUploadDocuments` and then triggers submit in the same + // synchronous `nextStep` call (CompanyProfileForm), so the `setDocumentFiles({})` + // that clears them has not re-rendered by the time this mutation's closure + // runs — reading `documentFiles` here would re-send the exact same files and + // create a duplicate row per document. Licenses have no such auto-upload, so + // they are uploaded here. const finishMutation = useMutation({ mutationFn: async () => { - const companyId = company?.company?.id; // Per-role business licenses (file model, resource=company_profiles). for (const [profileId, files] of Object.entries(licenseFiles)) { if (files.length > 0) { await companiesService.uploadProfileLicense(profileId, files); } } - // Nationality-based company documents (resource=companies). - const hasDocs = Object.values(documentFiles).some( - (f) => f !== null && (Array.isArray(f) ? f.length > 0 : true), - ); - if (companyId && hasDocs) { - await companiesService.uploadDocuments(companyId, documentFiles); - } return api.companies.completeOnboarding.call(); }, onSuccess: async () => {