From ccd28868d15f0df18783a1d610986438e14d38b5 Mon Sep 17 00:00:00 2001 From: Aaron Lee Date: Mon, 13 Jul 2026 17:00:03 -0400 Subject: [PATCH 1/8] feat: warn admins when editing contractor profile/address after W-9 signing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds an SDK Alert (warning) above the Contractor Profile and Address edit forms when the contractor already has a signed W-9 on file. Signals to the admin that any edit to name/SSN/EIN or address will require re-collecting a new W-9. Alert is derived from the documents endpoint via a new `useContractorHasSignedW9` Suspense hook — the presence of a signed W-9 naturally covers both the self_onboarding_review and onboarding_completed cases without threading state through the flow machine. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Contractor/Address/Address.test.tsx | 44 +++++++++ src/components/Contractor/Address/Address.tsx | 15 ++++ .../Profile/ContractorProfile.test.tsx | 90 ++++++++++++++++++- .../Contractor/Profile/ContractorProfile.tsx | 16 ++++ .../shared/useContractorHasSignedW9.ts | 14 +++ src/i18n/en/Contractor.Address.json | 4 + src/i18n/en/Contractor.Profile.json | 8 +- src/i18n/types.d.ts | 12 +++ 8 files changed, 200 insertions(+), 3 deletions(-) create mode 100644 src/components/Contractor/shared/useContractorHasSignedW9.ts diff --git a/src/components/Contractor/Address/Address.test.tsx b/src/components/Contractor/Address/Address.test.tsx index 445b2af32..d174b232e 100644 --- a/src/components/Contractor/Address/Address.test.tsx +++ b/src/components/Contractor/Address/Address.test.tsx @@ -9,6 +9,10 @@ import { handleGetContractorAddress, handleUpdateContractorAddress, } from '@/test/mocks/apis/contractor_address' +import { + buildContractorDocumentsList, + handleGetContractorDocuments, +} from '@/test/mocks/apis/contractor_documents' import { setupApiTestMocks } from '@/test/mocks/apiServer' import { contractorEvents } from '@/shared/constants' import { renderWithProviders } from '@/test-utils/renderWithProviders' @@ -431,4 +435,44 @@ describe('Contractor/Address', () => { ).toBeInTheDocument() }) }) + + describe('W-9 edit warning', () => { + beforeEach(() => { + setupApiTestMocks() + server.use(handleGetContractorAddress(() => HttpResponse.json(emptyAddressResponse))) + }) + + it('renders the warning when the contractor has a signed W-9 on file', async () => { + server.use( + handleGetContractorDocuments(() => + HttpResponse.json( + buildContractorDocumentsList([ + { + uuid: 'signed-w9-uuid', + title: 'W-9', + name: 'taxpayer_identification_form_w_9', + requires_signing: true, + signed_at: '2025-01-01T00:00:00Z', + }, + ]), + ), + ), + ) + + renderWithProviders(
{}} />) + + expect( + await screen.findByText('Editing this address will require a new W-9'), + ).toBeInTheDocument() + }) + + it('does not render the warning when the W-9 is unsigned', async () => { + renderWithProviders(
{}} />) + + await screen.findByText('Home address') + expect( + screen.queryByText('Editing this address will require a new W-9'), + ).not.toBeInTheDocument() + }) + }) }) diff --git a/src/components/Contractor/Address/Address.tsx b/src/components/Contractor/Address/Address.tsx index baf54795d..1472061c2 100644 --- a/src/components/Contractor/Address/Address.tsx +++ b/src/components/Contractor/Address/Address.tsx @@ -15,6 +15,7 @@ import { useI18n, useComponentDictionary } from '@/i18n' import type { ResourceDictionary } from '@/types/Helpers' import { contractorEvents, type EventType } from '@/shared/constants' import type { OnEventType } from '@/components/Base/useBase' +import { useContractorHasSignedW9 } from '@/components/Contractor/shared/useContractorHasSignedW9' // The hook defaults to the API contract, which treats every address field as // optional. The SDK's address form has always required a complete mailing @@ -78,6 +79,18 @@ export function Address({ onEvent, FallbackComponent, ...rootProps }: AddressPro ) } +function ContractorAddressW9Warning({ contractorId }: { contractorId: string }) { + const hasSignedW9 = useContractorHasSignedW9(contractorId) + const { t } = useTranslation('Contractor.Address') + const Components = useComponentContext() + if (!hasSignedW9) return null + return ( + + {t('w9EditWarning.body')} + + ) +} + function AddressRoot({ contractorId, defaultValues, @@ -117,6 +130,8 @@ function AddressRoot({
void handleSubmit()}> + +
diff --git a/src/components/Contractor/Profile/ContractorProfile.test.tsx b/src/components/Contractor/Profile/ContractorProfile.test.tsx index 7198370b7..8b97ccb32 100644 --- a/src/components/Contractor/Profile/ContractorProfile.test.tsx +++ b/src/components/Contractor/Profile/ContractorProfile.test.tsx @@ -9,6 +9,10 @@ import { handleGetContractor, handleUpdateContractor, } from '@/test/mocks/apis/contractors' +import { + buildContractorDocumentsList, + handleGetContractorDocuments, +} from '@/test/mocks/apis/contractor_documents' import { setupApiTestMocks } from '@/test/mocks/apiServer' import { contractorEvents } from '@/shared/constants' import { renderWithProviders } from '@/test-utils/renderWithProviders' @@ -369,7 +373,7 @@ describe('Contractor profile component behavior', () => { await screen.findByText('Contractor profile') expect(screen.getByLabelText('First Name')).toHaveValue('John') - await user.click(screen.getByRole('button', { name: 'Update Contractor' })) + await user.click(screen.getByRole('button', { name: 'Continue' })) await waitFor(() => { expect(updateResolver).toHaveBeenCalledTimes(1) @@ -546,4 +550,88 @@ describe('Contractor profile component behavior', () => { }) }) }) + + describe('W-9 edit warning', () => { + beforeEach(() => { + setupApiTestMocks() + server.use( + handleGetContractor(() => + HttpResponse.json({ + uuid: 'contractor_id', + version: 'version-1', + type: 'Individual', + wage_type: 'Fixed', + start_date: '2024-01-01', + first_name: 'John', + last_name: 'Doe', + has_ssn: true, + has_ein: false, + is_active: true, + file_new_hire_report: false, + onboarding_status: 'self_onboarding_review', + }), + ), + ) + }) + + it('renders the warning when the contractor has a signed W-9 on file', async () => { + server.use( + handleGetContractorDocuments(() => + HttpResponse.json( + buildContractorDocumentsList([ + { + uuid: 'signed-w9-uuid', + title: 'W-9', + name: 'taxpayer_identification_form_w_9', + requires_signing: true, + signed_at: '2025-01-01T00:00:00Z', + }, + ]), + ), + ), + ) + + renderWithProviders( + , + ) + + expect( + await screen.findByText('Editing this profile will require a new W-9'), + ).toBeInTheDocument() + }) + + it('does not render the warning when the W-9 is unsigned', async () => { + renderWithProviders( + , + ) + + await screen.findByText('Contractor profile') + expect( + screen.queryByText('Editing this profile will require a new W-9'), + ).not.toBeInTheDocument() + }) + + it('does not fetch documents or render the warning in create mode', async () => { + const documentsResolver = vi.fn(() => + HttpResponse.json(buildContractorDocumentsList()), + ) + server.use(handleGetContractorDocuments(documentsResolver)) + + renderWithProviders() + + await screen.findByText('Contractor profile') + expect( + screen.queryByText('Editing this profile will require a new W-9'), + ).not.toBeInTheDocument() + expect(documentsResolver).not.toHaveBeenCalled() + }) + }) }) diff --git a/src/components/Contractor/Profile/ContractorProfile.tsx b/src/components/Contractor/Profile/ContractorProfile.tsx index cd42142e9..8da969cba 100644 --- a/src/components/Contractor/Profile/ContractorProfile.tsx +++ b/src/components/Contractor/Profile/ContractorProfile.tsx @@ -21,6 +21,7 @@ import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentCon import { useI18n } from '@/i18n' import { useComponentDictionary } from '@/i18n/I18n' import { componentEvents, ContractorOnboardingStatus } from '@/shared/constants' +import { useContractorHasSignedW9 } from '@/components/Contractor/shared/useContractorHasSignedW9' // Once the contractor has finished self-onboarding (or the record is otherwise // under admin review / completed), the admin needs to view and edit SSN/EIN even @@ -150,6 +151,18 @@ export function ContractorProfile(props: ContractorProfileProps) { ) } +function ContractorProfileW9Warning({ contractorId }: { contractorId: string }) { + const hasSignedW9 = useContractorHasSignedW9(contractorId) + const { t } = useTranslation('Contractor.Profile') + const Components = useComponentContext() + if (!hasSignedW9) return null + return ( + + {t('w9EditWarning.body')} + + ) +} + function ContractorProfileRoot({ companyId, contractorId, @@ -261,6 +274,9 @@ function ContractorProfileReady({ void handleSubmit()}> + {mode === 'update' && contractor.data.contractor?.uuid && ( + + )}
{t('title')} diff --git a/src/components/Contractor/shared/useContractorHasSignedW9.ts b/src/components/Contractor/shared/useContractorHasSignedW9.ts new file mode 100644 index 000000000..b96933c4a --- /dev/null +++ b/src/components/Contractor/shared/useContractorHasSignedW9.ts @@ -0,0 +1,14 @@ +import { useContractorDocumentsGetAllSuspense } from '@gusto/embedded-api/react-query/contractorDocumentsGetAll' +import { isW9Document } from '@/components/Contractor/Documents/SignatureForm/useContractorSignatureForm' + +/** + * Returns `true` when the contractor has a W-9 with a `signedAt` timestamp on + * file. Fetches via Suspense — must be rendered inside a Suspense boundary + * (SDK `BaseBoundaries` supplies one). + * + * @internal + */ +export function useContractorHasSignedW9(contractorId: string): boolean { + const { data } = useContractorDocumentsGetAllSuspense({ contractorUuid: contractorId }) + return (data.documents ?? []).some(doc => isW9Document(doc) && !!doc.signedAt) +} diff --git a/src/i18n/en/Contractor.Address.json b/src/i18n/en/Contractor.Address.json index bf8a20c71..9d961e4a4 100644 --- a/src/i18n/en/Contractor.Address.json +++ b/src/i18n/en/Contractor.Address.json @@ -3,6 +3,10 @@ "businessAddressDescription": "Contractor's business address, within the United States.", "homeAddressTitle": "Home address", "homeAddressDescription": "Contractor's home mailing address, within the United States.", + "w9EditWarning": { + "label": "Editing this address will require a new W-9", + "body": "This contractor has already signed a W-9. If you change this address, you'll need to have them sign a new W-9." + }, "street1": "Street 1", "street2": "Street 2", "city": "City", diff --git a/src/i18n/en/Contractor.Profile.json b/src/i18n/en/Contractor.Profile.json index e7622edb6..d796e668a 100644 --- a/src/i18n/en/Contractor.Profile.json +++ b/src/i18n/en/Contractor.Profile.json @@ -1,6 +1,10 @@ { "title": "Contractor profile", "subtitle": "This information will be used for payments and on tax documents, so double-check that it's accurate.", + "w9EditWarning": { + "label": "Editing this profile will require a new W-9", + "body": "This contractor has already signed a W-9. If you change these details, you'll need to have them sign a new W-9." + }, "selfOnboarding": { "title": "Complete your profile", "individualDescription": "Please verify your name and provide your Social Security Number.", @@ -66,8 +70,8 @@ "buttons": { "cancel": "Cancel", "create": "Create Contractor", - "update": "Update Contractor", + "update": "Continue", "creating": "Creating…", - "updating": "Updating…" + "updating": "Saving…" } } diff --git a/src/i18n/types.d.ts b/src/i18n/types.d.ts index b4effef41..cbfcbebac 100644 --- a/src/i18n/types.d.ts +++ b/src/i18n/types.d.ts @@ -1710,6 +1710,12 @@ export namespace Translations { homeAddressTitle: string /** @defaultValue `"Contractor's home mailing address, within the United States."` */ homeAddressDescription: string + w9EditWarning: { + /** @defaultValue `"Editing this address will require a new W-9"` */ + label: string + /** @defaultValue `"This contractor has already signed a W-9. If you change this address, you'll need to have them sign a new W-9."` */ + body: string + } /** @defaultValue `"Street 1"` */ street1: string /** @defaultValue `"Street 2"` */ @@ -2352,6 +2358,12 @@ export namespace Translations { title: string /** @defaultValue `"This information will be used for payments and on tax documents, so double-check that it's accurate."` */ subtitle: string + w9EditWarning: { + /** @defaultValue `"Editing this profile will require a new W-9"` */ + label: string + /** @defaultValue `"This contractor has already signed a W-9. If you change these details, you'll need to have them sign a new W-9."` */ + body: string + } selfOnboarding: { /** @defaultValue `"Complete your profile"` */ title: string From 3c6e9629ce0199063d64039cd15e2e2e3f0253a4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 13 Jul 2026 21:04:53 +0000 Subject: [PATCH 2/8] chore: update derived files --- docs/reference/Translations/index.md | 10 ++++++++-- src/i18n/types.d.ts | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/reference/Translations/index.md b/docs/reference/Translations/index.md index c4dd6100a..474f0d093 100644 --- a/docs/reference/Translations/index.md +++ b/docs/reference/Translations/index.md @@ -1249,6 +1249,9 @@ Translation keys for the `Contractor.Address` i18n namespace. | `validations.street1` | `"Street address is required"` | | `validations.zip` | `"Please provide valid zip code"` | | `validations.zipInvalid` | `"Please enter a valid ZIP code"` | +| `w9EditWarning` | | +| `w9EditWarning.body` | `"This contractor has already signed a W-9. If you change this address, you'll need to have them sign a new W-9."` | +| `w9EditWarning.label` | `"Editing this address will require a new W-9"` | | `zip` | `"Zip"` | *** @@ -1697,8 +1700,8 @@ Translation keys for the `Contractor.Profile` i18n namespace. | `buttons.cancel` | `"Cancel"` | | `buttons.create` | `"Create Contractor"` | | `buttons.creating` | `"Creating…"` | -| `buttons.update` | `"Update Contractor"` | -| `buttons.updating` | `"Updating…"` | +| `buttons.update` | `"Continue"` | +| `buttons.updating` | `"Saving…"` | | `fields` | | | `fields.businessName` | | | `fields.businessName.label` | `"Business Name"` | @@ -1748,6 +1751,9 @@ Translation keys for the `Contractor.Profile` i18n namespace. | `validations.ssn` | `"SSN is required for individual contractors"` | | `validations.ssnFormat` | `"SSN must be valid format"` | | `validations.startDate` | `"Start date is required"` | +| `w9EditWarning` | | +| `w9EditWarning.body` | `"This contractor has already signed a W-9. If you change these details, you'll need to have them sign a new W-9."` | +| `w9EditWarning.label` | `"Editing this profile will require a new W-9"` | *** diff --git a/src/i18n/types.d.ts b/src/i18n/types.d.ts index cbfcbebac..d2470e739 100644 --- a/src/i18n/types.d.ts +++ b/src/i18n/types.d.ts @@ -2463,11 +2463,11 @@ export namespace Translations { cancel: string /** @defaultValue `"Create Contractor"` */ create: string - /** @defaultValue `"Update Contractor"` */ + /** @defaultValue `"Continue"` */ update: string /** @defaultValue `"Creating…"` */ creating: string - /** @defaultValue `"Updating…"` */ + /** @defaultValue `"Saving…"` */ updating: string } } From 821b62f5739b1c2abe80d0d65756c7ea4fc7c292 Mon Sep 17 00:00:00 2001 From: Aaron Lee Date: Mon, 13 Jul 2026 17:26:45 -0400 Subject: [PATCH 3/8] test(e2e): update button label to match new "Continue" copy The contractor profile update button was renamed from "Update Contractor" to "Continue" in Contractor.Profile.json; align the 03-onboarding-edit spec so the button assertion matches. Co-Authored-By: Claude Opus 4.7 (1M context) --- e2e/tests/contractor/03-onboarding-edit.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/tests/contractor/03-onboarding-edit.spec.ts b/e2e/tests/contractor/03-onboarding-edit.spec.ts index 0181550a0..a5d48b095 100644 --- a/e2e/tests/contractor/03-onboarding-edit.spec.ts +++ b/e2e/tests/contractor/03-onboarding-edit.spec.ts @@ -45,6 +45,6 @@ test.describe('ContractorOnboardingFlow - edit re-entry from list lifecycle', () await expect(page.getByRole('radio', { name: /^business$/i })).toBeChecked() await expect(page.getByLabel(/business name/i)).toHaveValue(/Acme Consulting/i) - await expect(page.getByRole('button', { name: /update contractor/i })).toBeVisible() + await expect(page.getByRole('button', { name: /^continue$/i })).toBeVisible() }) }) From c063e04551a05e6f675503b76cde0f879bc02bf9 Mon Sep 17 00:00:00 2001 From: Aaron Lee Date: Tue, 14 Jul 2026 15:56:28 -0400 Subject: [PATCH 4/8] feat(i18n): rephrase W-9 edit warning to reference retaining an updated Form W-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrites the Contractor.Profile and Contractor.Address w9EditWarning copy so it makes clear that edits require the employer to retain an updated and signed Form W-9 reflecting the corrected information — the operational obligation, not just "sign a new W-9." Co-Authored-By: Claude Opus 4.7 (1M context) --- src/components/Contractor/Address/Address.test.tsx | 6 ++---- .../Contractor/Profile/ContractorProfile.test.tsx | 10 +++------- src/i18n/en/Contractor.Address.json | 4 ++-- src/i18n/en/Contractor.Profile.json | 4 ++-- src/i18n/types.d.ts | 8 ++++---- 5 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/components/Contractor/Address/Address.test.tsx b/src/components/Contractor/Address/Address.test.tsx index d174b232e..d23ce555c 100644 --- a/src/components/Contractor/Address/Address.test.tsx +++ b/src/components/Contractor/Address/Address.test.tsx @@ -462,7 +462,7 @@ describe('Contractor/Address', () => { renderWithProviders(
{}} />) expect( - await screen.findByText('Editing this address will require a new W-9'), + await screen.findByText('Changes will require an updated Form W-9'), ).toBeInTheDocument() }) @@ -470,9 +470,7 @@ describe('Contractor/Address', () => { renderWithProviders(
{}} />) await screen.findByText('Home address') - expect( - screen.queryByText('Editing this address will require a new W-9'), - ).not.toBeInTheDocument() + expect(screen.queryByText('Changes will require an updated Form W-9')).not.toBeInTheDocument() }) }) }) diff --git a/src/components/Contractor/Profile/ContractorProfile.test.tsx b/src/components/Contractor/Profile/ContractorProfile.test.tsx index 8b97ccb32..65a0766df 100644 --- a/src/components/Contractor/Profile/ContractorProfile.test.tsx +++ b/src/components/Contractor/Profile/ContractorProfile.test.tsx @@ -600,7 +600,7 @@ describe('Contractor profile component behavior', () => { ) expect( - await screen.findByText('Editing this profile will require a new W-9'), + await screen.findByText('Changes will require an updated Form W-9'), ).toBeInTheDocument() }) @@ -614,9 +614,7 @@ describe('Contractor profile component behavior', () => { ) await screen.findByText('Contractor profile') - expect( - screen.queryByText('Editing this profile will require a new W-9'), - ).not.toBeInTheDocument() + expect(screen.queryByText('Changes will require an updated Form W-9')).not.toBeInTheDocument() }) it('does not fetch documents or render the warning in create mode', async () => { @@ -628,9 +626,7 @@ describe('Contractor profile component behavior', () => { renderWithProviders() await screen.findByText('Contractor profile') - expect( - screen.queryByText('Editing this profile will require a new W-9'), - ).not.toBeInTheDocument() + expect(screen.queryByText('Changes will require an updated Form W-9')).not.toBeInTheDocument() expect(documentsResolver).not.toHaveBeenCalled() }) }) diff --git a/src/i18n/en/Contractor.Address.json b/src/i18n/en/Contractor.Address.json index 9d961e4a4..014e2efdd 100644 --- a/src/i18n/en/Contractor.Address.json +++ b/src/i18n/en/Contractor.Address.json @@ -4,8 +4,8 @@ "homeAddressTitle": "Home address", "homeAddressDescription": "Contractor's home mailing address, within the United States.", "w9EditWarning": { - "label": "Editing this address will require a new W-9", - "body": "This contractor has already signed a W-9. If you change this address, you'll need to have them sign a new W-9." + "label": "Changes will require an updated Form W-9", + "body": "This contractor has already signed a Form W-9. If you edit this address, you'll need to retain an updated and signed version of Form W-9 reflecting the corrected information." }, "street1": "Street 1", "street2": "Street 2", diff --git a/src/i18n/en/Contractor.Profile.json b/src/i18n/en/Contractor.Profile.json index d796e668a..7a1e61258 100644 --- a/src/i18n/en/Contractor.Profile.json +++ b/src/i18n/en/Contractor.Profile.json @@ -2,8 +2,8 @@ "title": "Contractor profile", "subtitle": "This information will be used for payments and on tax documents, so double-check that it's accurate.", "w9EditWarning": { - "label": "Editing this profile will require a new W-9", - "body": "This contractor has already signed a W-9. If you change these details, you'll need to have them sign a new W-9." + "label": "Changes will require an updated Form W-9", + "body": "This contractor has already signed a Form W-9. If you edit these details, you'll need to retain an updated and signed version of Form W-9 reflecting the corrected information." }, "selfOnboarding": { "title": "Complete your profile", diff --git a/src/i18n/types.d.ts b/src/i18n/types.d.ts index d2470e739..d19263e1c 100644 --- a/src/i18n/types.d.ts +++ b/src/i18n/types.d.ts @@ -1711,9 +1711,9 @@ export namespace Translations { /** @defaultValue `"Contractor's home mailing address, within the United States."` */ homeAddressDescription: string w9EditWarning: { - /** @defaultValue `"Editing this address will require a new W-9"` */ + /** @defaultValue `"Changes will require an updated Form W-9"` */ label: string - /** @defaultValue `"This contractor has already signed a W-9. If you change this address, you'll need to have them sign a new W-9."` */ + /** @defaultValue `"This contractor has already signed a Form W-9. If you edit this address, you'll need to retain an updated and signed version of Form W-9 reflecting the corrected information."` */ body: string } /** @defaultValue `"Street 1"` */ @@ -2359,9 +2359,9 @@ export namespace Translations { /** @defaultValue `"This information will be used for payments and on tax documents, so double-check that it's accurate."` */ subtitle: string w9EditWarning: { - /** @defaultValue `"Editing this profile will require a new W-9"` */ + /** @defaultValue `"Changes will require an updated Form W-9"` */ label: string - /** @defaultValue `"This contractor has already signed a W-9. If you change these details, you'll need to have them sign a new W-9."` */ + /** @defaultValue `"This contractor has already signed a Form W-9. If you edit these details, you'll need to retain an updated and signed version of Form W-9 reflecting the corrected information."` */ body: string } selfOnboarding: { From 3c6c2d46505ca73d81e1dec9d368c1fce63dd92f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 14 Jul 2026 20:00:57 +0000 Subject: [PATCH 5/8] chore: update derived files --- docs/reference/Translations/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/reference/Translations/index.md b/docs/reference/Translations/index.md index 474f0d093..04773a8eb 100644 --- a/docs/reference/Translations/index.md +++ b/docs/reference/Translations/index.md @@ -1250,8 +1250,8 @@ Translation keys for the `Contractor.Address` i18n namespace. | `validations.zip` | `"Please provide valid zip code"` | | `validations.zipInvalid` | `"Please enter a valid ZIP code"` | | `w9EditWarning` | | -| `w9EditWarning.body` | `"This contractor has already signed a W-9. If you change this address, you'll need to have them sign a new W-9."` | -| `w9EditWarning.label` | `"Editing this address will require a new W-9"` | +| `w9EditWarning.body` | `"This contractor has already signed a Form W-9. If you edit this address, you'll need to retain an updated and signed version of Form W-9 reflecting the corrected information."` | +| `w9EditWarning.label` | `"Changes will require an updated Form W-9"` | | `zip` | `"Zip"` | *** @@ -1752,8 +1752,8 @@ Translation keys for the `Contractor.Profile` i18n namespace. | `validations.ssnFormat` | `"SSN must be valid format"` | | `validations.startDate` | `"Start date is required"` | | `w9EditWarning` | | -| `w9EditWarning.body` | `"This contractor has already signed a W-9. If you change these details, you'll need to have them sign a new W-9."` | -| `w9EditWarning.label` | `"Editing this profile will require a new W-9"` | +| `w9EditWarning.body` | `"This contractor has already signed a Form W-9. If you edit these details, you'll need to retain an updated and signed version of Form W-9 reflecting the corrected information."` | +| `w9EditWarning.label` | `"Changes will require an updated Form W-9"` | *** From b7ea2467146998d2b5e5f7cf6ef003db29896c99 Mon Sep 17 00:00:00 2001 From: Aaron Lee Date: Wed, 15 Jul 2026 14:16:14 -0400 Subject: [PATCH 6/8] feat(i18n): rewrite W-9 edit warning body copy Rewords the body to reflect the retention obligation: the employer must update and retain a new signed Form W-9 reflecting the corrected information whenever the contractor's profile or address is corrected after signing. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/i18n/en/Contractor.Address.json | 2 +- src/i18n/en/Contractor.Profile.json | 2 +- src/i18n/types.d.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/i18n/en/Contractor.Address.json b/src/i18n/en/Contractor.Address.json index 014e2efdd..43ee149e8 100644 --- a/src/i18n/en/Contractor.Address.json +++ b/src/i18n/en/Contractor.Address.json @@ -5,7 +5,7 @@ "homeAddressDescription": "Contractor's home mailing address, within the United States.", "w9EditWarning": { "label": "Changes will require an updated Form W-9", - "body": "This contractor has already signed a Form W-9. If you edit this address, you'll need to retain an updated and signed version of Form W-9 reflecting the corrected information." + "body": "This contractor has already signed a form W-9. If you are making corrections, you’re also required to update and retain a new signed version of Form W-9 reflecting the corrected information." }, "street1": "Street 1", "street2": "Street 2", diff --git a/src/i18n/en/Contractor.Profile.json b/src/i18n/en/Contractor.Profile.json index 7a1e61258..3618c3771 100644 --- a/src/i18n/en/Contractor.Profile.json +++ b/src/i18n/en/Contractor.Profile.json @@ -3,7 +3,7 @@ "subtitle": "This information will be used for payments and on tax documents, so double-check that it's accurate.", "w9EditWarning": { "label": "Changes will require an updated Form W-9", - "body": "This contractor has already signed a Form W-9. If you edit these details, you'll need to retain an updated and signed version of Form W-9 reflecting the corrected information." + "body": "This contractor has already signed a form W-9. If you are making corrections, you’re also required to update and retain a new signed version of Form W-9 reflecting the corrected information." }, "selfOnboarding": { "title": "Complete your profile", diff --git a/src/i18n/types.d.ts b/src/i18n/types.d.ts index d19263e1c..491ed9696 100644 --- a/src/i18n/types.d.ts +++ b/src/i18n/types.d.ts @@ -1713,7 +1713,7 @@ export namespace Translations { w9EditWarning: { /** @defaultValue `"Changes will require an updated Form W-9"` */ label: string - /** @defaultValue `"This contractor has already signed a Form W-9. If you edit this address, you'll need to retain an updated and signed version of Form W-9 reflecting the corrected information."` */ + /** @defaultValue `"This contractor has already signed a form W-9. If you are making corrections, you’re also required to update and retain a new signed version of Form W-9 reflecting the corrected information."` */ body: string } /** @defaultValue `"Street 1"` */ @@ -2361,7 +2361,7 @@ export namespace Translations { w9EditWarning: { /** @defaultValue `"Changes will require an updated Form W-9"` */ label: string - /** @defaultValue `"This contractor has already signed a Form W-9. If you edit these details, you'll need to retain an updated and signed version of Form W-9 reflecting the corrected information."` */ + /** @defaultValue `"This contractor has already signed a form W-9. If you are making corrections, you’re also required to update and retain a new signed version of Form W-9 reflecting the corrected information."` */ body: string } selfOnboarding: { From 6b7fcb58563f8d31e6eee1eedc447479ce18c417 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 15 Jul 2026 18:21:29 +0000 Subject: [PATCH 7/8] chore: update derived files --- docs/reference/Translations/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference/Translations/index.md b/docs/reference/Translations/index.md index 04773a8eb..9c9a291c2 100644 --- a/docs/reference/Translations/index.md +++ b/docs/reference/Translations/index.md @@ -1250,7 +1250,7 @@ Translation keys for the `Contractor.Address` i18n namespace. | `validations.zip` | `"Please provide valid zip code"` | | `validations.zipInvalid` | `"Please enter a valid ZIP code"` | | `w9EditWarning` | | -| `w9EditWarning.body` | `"This contractor has already signed a Form W-9. If you edit this address, you'll need to retain an updated and signed version of Form W-9 reflecting the corrected information."` | +| `w9EditWarning.body` | `"This contractor has already signed a form W-9. If you are making corrections, you’re also required to update and retain a new signed version of Form W-9 reflecting the corrected information."` | | `w9EditWarning.label` | `"Changes will require an updated Form W-9"` | | `zip` | `"Zip"` | @@ -1752,7 +1752,7 @@ Translation keys for the `Contractor.Profile` i18n namespace. | `validations.ssnFormat` | `"SSN must be valid format"` | | `validations.startDate` | `"Start date is required"` | | `w9EditWarning` | | -| `w9EditWarning.body` | `"This contractor has already signed a Form W-9. If you edit these details, you'll need to retain an updated and signed version of Form W-9 reflecting the corrected information."` | +| `w9EditWarning.body` | `"This contractor has already signed a form W-9. If you are making corrections, you’re also required to update and retain a new signed version of Form W-9 reflecting the corrected information."` | | `w9EditWarning.label` | `"Changes will require an updated Form W-9"` | *** From c81d1d6e89ec5f7c566a6c3557e8aca829733275 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 15 Jul 2026 21:17:51 +0000 Subject: [PATCH 8/8] fix: add missing contractor documents mock to Profile tests --- src/components/Contractor/Profile/ContractorProfile.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/Contractor/Profile/ContractorProfile.test.tsx b/src/components/Contractor/Profile/ContractorProfile.test.tsx index 3ffe31333..f17cb076f 100644 --- a/src/components/Contractor/Profile/ContractorProfile.test.tsx +++ b/src/components/Contractor/Profile/ContractorProfile.test.tsx @@ -431,6 +431,7 @@ describe('Contractor profile component behavior', () => { onboarding_status: postSaveStatus, }), ), + handleGetContractorDocuments(() => HttpResponse.json(buildContractorDocumentsList())), ) renderWithProviders( @@ -438,7 +439,7 @@ describe('Contractor profile component behavior', () => { ) await screen.findByText('Contractor profile') - await user.click(screen.getByRole('button', { name: 'Update Contractor' })) + await user.click(screen.getByRole('button', { name: 'Continue' })) await waitFor(() => { expect(onEvent).toHaveBeenCalledWith(