Skip to content

feat(contract-document): render the contract details and create the contract document - #1329

Merged
jordividaller merged 17 commits into
mainfrom
feat/pbyr-4778-contract-document-details
Sep 23, 2026
Merged

jordividaller merged 17 commits into
mainfrom
feat/pbyr-4778-contract-document-details

Conversation

@jordividaller

@jordividaller jordividaller commented Sep 17, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Third part of the standalone Contract Document flow, after #1327. The flow now renders the country-specific contract details for a contractor and creates their contract document, with the same misclassification check as contractor onboarding. The preview step is reached but not rendered yet.

Why

Partners need to create a contract document for an existing contractor without going through the whole onboarding flow. The contract details step and its AI check already exist in contractor onboarding, so the logic is shared rather than duplicated: one implementation to fix, and both flows behave the same.

There is no pricing-plan step here, so the product is read off the employment's contractor type. It drives the same things it does in onboarding: the Contractor Services Agreement disclaimer, whether the start date can be backdated, and the misclassification wording.

What changed

Toggle details

Shared code, own commit (refactor(contract-documents): move the contract-details helpers to common)

  • The create mutation, buildContractDetailsJsfModify, the AI error handling and constants, the product identifiers and StatementOfWorkDisclaimer move to src/common/contract-documents/.
  • Contractor onboarding imports them from there. Thin re-exports stay at the old paths, so its tests are unchanged.
  • useContractorContractDetailsSchema now throws when the schema request fails, instead of returning the error envelope. This is visible to contractor onboarding too: the query reports an error rather than a blank form.

Contract Document flow

  • contract_details renders the form built from GET /v1/countries/{code}/contractor-contract-details?employment_id=…. The contractor's currencies and the schema's permission-gated default values come through the existing schema hook.
  • Initial values: the employment's current contract details, with the service start date prefilled with today as on the Remote platform.
  • Submitting creates the contract document, stores its id on the bag and moves to contract_preview. A skippable AI error shows the warning under the field, flips canSkipAiValidation, and the next submission sends skip_ai_checks: true. Editing any field clears the warning.
  • The bag's error covers the employment and the schema fetch. A failed contract-documents listing leaves contractDocuments undefined and does not block creation.

Public API (additive, src/index.tsx)

  • New components ContractDocumentForm and ContractDocumentSubmitButton.
  • New options.jsfModify.contract_details on the flow and the hook.
  • New bag keys: fieldValues, checkFieldUpdates, handleValidation, parseFormValues, onSubmit, initialValues, meta, productIdentifier, contractDocumentId, canSkipAiValidation, isSubmitting, error.
  • New types ContractDocumentContractDetailsPayload, ContractDocumentContractDetailsResponse, ContractDocumentOptions.
  • No change to the contractor onboarding types, props or hooks.

Closest look

  • src/flows/ContractDocument/hooks.tsx: payload building and the AI error branch.
  • src/common/api/contractor-contract-details.ts: the shared throw-on-error change.

Screenshots

Toggle screenshots
Before After

Related Resources

Testing

  • npm run ci and npm run size:check pass locally
  • MSW tests in src/flows/ContractDocument/tests/ContractDocumentForm.test.tsx: successful creation and move to the preview, values restored on back, disclaimer left out for a Contractor of Record, AI warning then retry with skip_ai_checks: true
  • Contractor onboarding tests unchanged and green
  • Tested against the example/ app in a browser: pick a contractor in the Contract Document demo, fill the contract details, submit; retry after an AI warning
  • Feature flag: N/A

🤖 Generated with Claude Code


Note

Medium Risk
Touches shared contract-creation and schema-fetch paths used by contractor onboarding, plus AI skip logic and employment-derived product rules that affect compliance UX and API payloads.

Overview
The standalone Contract Document flow now renders the country-specific contract details JSON-schema form, POSTs to create the document, and advances to contract preview (still a placeholder). New public pieces are ContractDocumentForm, ContractDocumentSubmitButton, optional options.jsfModify.contract_details, and a much richer flow bag (validation, submit, AI skip state, contractDocumentId, load errors, etc.).

Contract-details behavior is deduplicated with contractor onboarding: create mutation, JSF modifiers, AI error handling, product constants, and the CSA disclaimer live under src/common/contract-documents/; onboarding keeps thin re-exports. useContractorContractDetailsSchema now throws when the schema request fails (onboarding sees a query error instead of a silent blank form).

Product rules for the standalone flow come from employment.contractor_type (no pricing-plan step): disclaimer, backdating, COR vs CM misclassification copy, and skip_ai_checks on retry when AI returns a skippable services_and_deliverables error. The example app wires step navigation, errors, and AI “continue anyway” UX.

Tests cover happy path, back-navigation preserving values, COR without disclaimer, and AI warning → retry with skip_ai_checks: true.

Reviewed by Cursor Bugbot for commit 6135135. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread src/flows/ContractDocument/hooks.tsx Resolved
@jordividaller
jordividaller force-pushed the feat/pbyr-4778-contract-document-details branch from 853e0dc to 361601c Compare September 17, 2026 11:18

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Base automatically changed from feat/pbyr-4777-contract-document-employment-id to main September 17, 2026 12:20
@jordividaller
jordividaller force-pushed the feat/pbyr-4778-contract-document-details branch from 361601c to acb7da6 Compare September 17, 2026 12:25
@github-actions

github-actions Bot commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

📦 Bundle Size Report

Metric Current Previous Change Status
Total (gzip) 167.15 kB 165.18 kB +1.96 kB (+1.2%) 🔴
Total (raw) 555.06 kB 550.35 kB +4.71 kB (+0.9%) 🔴
CSS (gzip) 21.94 kB 21.94 kB 0 B (0%) 🟢
CSS (raw) 114.43 kB 114.43 kB 0 B (0%) 🟢

Size Limits

  • ✅ Total gzipped: 167.15 kB / 350 kB (47.8%)
  • ✅ Total raw: 555.06 kB / 850 kB (65.3%)
  • ✅ CSS gzipped: 21.94 kB / 25 kB (87.8%)

Largest Files (Top 5)

  1. CheckBoxField-0kUJOndr.js - 24.52 kB (new)
  2. ContractorOnboarding-DktLADPr.js - 13.54 kB (new)
  3. Onboarding-CmQkNXBv.js - 11.27 kB (new)
  4. Termination-D_Q3sJcN.js - 11.08 kB (new)
  5. styles.css - 10.97 kB (0 B (0%))
View All Files (75 total)
File Size (gzip) Change
CheckBoxField-0kUJOndr.js 24.52 kB new
ContractorOnboarding-DktLADPr.js 13.54 kB new
Onboarding-CmQkNXBv.js 11.27 kB new
Termination-D_Q3sJcN.js 11.08 kB new
styles.css 10.97 kB 0 B (0%)
index.css 10.97 kB 0 B (0%)
CostCalculator-CKma7qBd.js 10.68 kB new
internals-CgIAxjP9.js 8.23 kB new
index.js 5.04 kB new
JSONSchemaForm-CJj32Zlb.js 4.92 kB new

✅ Bundle size check passed

@github-actions

github-actions Bot commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

📊 Coverage Report

✅ Coverage increased! 🎉

Metric Current Previous Change Status
Lines 86.34% 86.19% +0.15% 🟢
Statements 85.91% 85.77% +0.14% 🟢
Functions 84.92% 84.73% +0.20% 🟢
Branches 77.77% 77.66% +0.11% 🟢

Detailed Breakdown

Lines Coverage
  • Covered: 4849 / 5616
  • Coverage: 86.34%
  • Change: +0.15% (69 lines)
Statements Coverage
  • Covered: 4933 / 5742
  • Coverage: 85.91%
  • Change: +0.14% (69 statements)
Functions Coverage
  • Covered: 1290 / 1519
  • Coverage: 84.92%
  • Change: +0.20% (14 functions)
Branches Coverage
  • Covered: 3001 / 3859
  • Coverage: 77.77%
  • Change: +0.11% (39 branches)

✅ Coverage check passed

@github-actions

github-actions Bot commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Deploy preview for remote-flows ready!

Project:remote-flows
Status: ✅  Deploy successful!
Preview URL:https://remote-flows-glfo8apvm-remotecom.vercel.app
Latest Commit:6135135

Deployed with vercel-action

@github-actions

github-actions Bot commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Deploy preview for adp-cost-calculator ready!

Project:adp-cost-calculator
Status: ✅  Deploy successful!
Preview URL:https://adp-cost-calculator-jnxjgjwem-remotecom.vercel.app
Latest Commit:6135135

Deployed with vercel-action

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread src/flows/ContractDocument/hooks.tsx Resolved

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread src/flows/ContractDocument/hooks.tsx Resolved

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d2be6d4. Configure here.

Comment thread src/flows/ContractDocument/hooks.tsx Resolved
@jordividaller
jordividaller force-pushed the feat/pbyr-4778-contract-document-details branch from fe113f5 to 780e4ea Compare September 22, 2026 09:41
Jordi Vidaller and others added 17 commits September 22, 2026 17:03
…mmon

The pieces the contract details step is built from move out of ContractorOnboarding so
the standalone ContractDocument flow can share them: the create-contract-document
mutation, `buildContractDetailsJsfModify`, the AI validation error extraction and
messages, the contractor product identifiers, `isCMOrCMPlus`,
`calculateProvisionalStartDateDescription` and `StatementOfWorkDisclaimer`.

No behaviour change: onboarding imports the moved symbols from their new home, the
public product identifiers are still exported from the ContractorOnboarding entry, and
the onboarding hook now calls the shared `extractAiValidationError` instead of its inline
copy.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ontract document

The `contract_details` step now renders the country-specific contract details form and
submitting it creates the contract document, then moves the flow to `contract_preview`.

The form is built from `GET /v1/countries/{code}/contractor-contract-details?employment_id=…`
through the shared `useContractorContractDetailsSchema`, so the currencies come from the
contractor and the schema's `default` values prefill the form. Initial values are completed
from the employment's current contract details and provisional start date. The standalone
flow has no pricing-plan step, so the product — Contractor of Record restrictions, the
Contractor Services Agreement disclaimer, the backdating rule — is read off the employment's
`contractor_type`.

The AI misclassification check behaves as in onboarding: a skippable rejection shows the
warning under the field, `canSkipAiValidation` turns true, and submitting again sends
`skip_ai_checks: true`.

New on the bag: `fieldValues`, `checkFieldUpdates`, `handleValidation`, `parseFormValues`,
`onSubmit`, `initialValues`, `meta`, `productIdentifier`, `contractDocumentId`,
`canSkipAiValidation`. New components: `ContractDocumentForm`,
`ContractDocumentSubmitButton`. `options.jsfModify.contract_details` is supported.

Part of pbyr-4778.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ord the start-date warning

`ContractDocumentForm` initialised from the employment every time it mounted, so going
back to the step after a submission dropped what had just been entered. It now reads the
step's stored values first, as the onboarding step does.

The start-date mismatch warning referred to the Basic Information step, which the
standalone flow does not have: the shared helper takes the label of the compared date,
and the flow names the contractor's current start date instead. Onboarding keeps its
wording.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`handleStepError` was called without field metadata, so API field errors surfaced raw
paths like `service_duration/expiration_date`. The hook now prettifies the parsed values
against the schema fields on submit, as the onboarding hook does, and exposes them as
`meta.fields` for the form to hand to `handleStepError`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ht submission

The metadata ref was replaced on submit, but the form's handler had already captured the
bag rendered before, whose `meta.fields` still pointed at the previous empty object. The
ref now holds one object mutated per step, as the onboarding hook does, so the handler
reads the labels computed for the submission it is reporting on.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…error response

The shared schema query resolved an error response as a success, so a 403 or 5xx built
an empty form and the flow reported itself ready with no fields and a live submit button.
The query now throws on `response.error`, as the countries and contract-documents queries
do.

Tests answer the schema endpoint by default so the standalone flow tests no longer run
through an unhandled request, and two behaviours are pinned: entered contract details are
restored when coming back from the preview, and a Contractor of Record is not shown the
Contractor Services Agreement disclaimer.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The standalone flow copied onboarding and prefilled the start date with the employment's
provisional start date. For an existing contractor that date is in the past, which on the
Plus and Contractor of Record plans immediately raised the backdating warning. The Remote
platform prefills today's date for a new contract document, so the flow does the same.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…andalone flow

The note compares the start date with the one given at the Basic Information step and
warns when they differ. In the standalone flow the contractor already exists and the field
is prefilled with today, so the note would show on nearly every open. The shared helper
is back to its onboarding-only signature.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ission when the form cannot load

Throwing from the schema query only left data undefined: the bag still reported
isLoading false with no fields, so the submit button stayed enabled and a click
sent an empty contract document. The bag now exposes the first error among the
employment, contract-documents and schema queries, and the submit button is
disabled while one is set.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ractor fallback

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ontractor

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ay as the start date

The employment query resolves with no employment on an error response, so the
bag reported no error and the submit button stayed enabled with an empty form.
The bag now surfaces that as an error. The stored contract details used to
override today's start date; today now wins, as the platform does and as the
README states.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ning

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… helpers from their old paths

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nts list cannot load

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@jordividaller
jordividaller force-pushed the feat/pbyr-4778-contract-document-details branch from a37a552 to 6135135 Compare September 22, 2026 15:05
@jordividaller jordividaller self-assigned this Sep 22, 2026
@jordividaller
jordividaller merged commit 27d4cbb into main Sep 23, 2026
13 checks passed
@jordividaller
jordividaller deleted the feat/pbyr-4778-contract-document-details branch September 23, 2026 07:53
@gabrielseco gabrielseco mentioned this pull request Sep 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants