Skip to content

feat(scripts): add a contract details schema canary - #1481

Merged
gabrielseco merged 9 commits into
mainfrom
feat/schema-canary-node
Oct 12, 2026
Merged

gabrielseco merged 9 commits into
mainfrom
feat/schema-canary-node

Conversation

@gabrielseco

@gabrielseco gabrielseco commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Adds npm run schema-canary, a script that checks every EOR country's live contract details form against the sandbox: it builds and validates each schema with our form code.

Why

  • We can't count on every backend schema change being versioned, so we check the schemas partners actually load, with the form code this repo ships.

What changed

Toggle details

For every country with eor_onboarding: true in /v1/countries:

  1. seed: creates a sandbox employment, so the schema is fetched with a real employment_id like the flow does. Archived afterwards, also when a later setup step fails.
  2. pinned: builds the version the example app pins, with the strategy from getContractDetailsStrategy, and validates. Fails the run.
  3. latest: the same at json_schema_version=latest. Warning only.

Submitting filled values and reading them back comes next, in #1491.

Local only in this PR; CI comes in #1493.

Screenshots

N/A

Related Resources

Testing

  • Tested against the example/ app in a browser: N/A, this is a script.

  • Feature flag: N/A

  • Unit tests: scripts/schema-canary/lib.test.ts.

  • Locally: npm run schema-canary -- --country=FRA (needs .env.sandbox).

🤖 Generated with Claude Code


Note

Low Risk
New dev/ops script and tests only; no runtime library or app behavior changes, though it uses sandbox OAuth credentials when run locally.

Overview
Adds npm run schema-canary, a sandbox-only CLI that smoke-tests live contract_details JSON schemas for every EOR onboarding country using the same headless form build/validate path as Onboarding.

For each country it seeds a sandbox employment (basic info → eligibility → optional engagement), fetches the form with a real employment_id, runs pinned (library-shipped version) and latest checks via getContractDetailsStrategy / buildHeadlessForm, then archives the employment. CLI flags support --country, --checks, --concurrency, optional JSON report and failure output, plus GitHub step summary when GITHUB_STEP_SUMMARY is set.

Exit behavior: pinned failures and seed errors fail the run; latest failures are warnings only. An empty SCHEMA_CANARY_SKIP_LIST and unit tests in scripts/schema-canary/lib.test.ts cover reporting and gating logic. CI wiring is out of scope for this PR.

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

gabrielseco and others added 2 commits October 8, 2026 16:37
…React

buildHeadlessForm, parseValuesForValidation and withFieldsetObjects move
from useHeadlessForm into src/common/headlessForm.ts, so a script can run
the exact build and validate path the hook uses. useHeadlessForm calls
them with no change in behaviour.

An oxlint rule keeps the two builders importable only by useHeadlessForm,
scripts/ and tests, so they don't become a second way to build forms.

Onboarding gets CONTRACT_DETAILS_STRATEGY and
getContractDetailsStrategy(country), so the flow and anything that needs
to mirror it pick the useHeadlessForm strategy from the same function.

No public API changes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
npm run schema-canary checks every EOR country from /v1/countries
against the sandbox gateway:

- seed: creates a sandbox employment, so the schema is fetched with a
  real employment_id like the flow does; archived afterwards, including
  when a later setup step fails.
- pinned: builds the contract_details version the example app pins with
  the same useHeadlessForm strategy Onboarding uses, and validates.
- latest: the same at json_schema_version=latest, warning only.
- submit: fills the schema, runs the values through the SDK's build,
  validation, money conversion and parsing, sends the flow's PATCH, then
  reads the employment back and fails on any value saved differently or
  not at all.

Forced values (const equal to default) are skipped in the read-back only
when missing. KNOWN_UNSAVED_FIELDS lists per-country fields the backend
drops (GBR overtime_eligible) and fails once they are saved again, so
the entry gets removed when the fix ships.

CONTRACT_DETAILS_SEEDS moves to scripts/contract-details-seeds.ts,
shared with seed-onboarding. Runs locally with .env.sandbox; CI comes in
the next PR.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

📦 Bundle Size Report

Metric Current Previous Change Status
Total (gzip) 230.47 kB 230.47 kB 0 B (0%) 🟢
Total (raw) 641.93 kB 641.93 kB 0 B (0%) 🟢
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: 230.47 kB / 350 kB (65.8%)
  • ✅ Total raw: 641.93 kB / 850 kB (75.5%)
  • ✅ CSS gzipped: 21.94 kB / 25 kB (87.8%)

Largest Files (Top 5)

  1. index.esm-wIkXrqU6.js - 11.4 kB (0 B (0%))
  2. styles.css - 10.97 kB (0 B (0%))
  3. index.css - 10.97 kB (0 B (0%))
  4. internals-D6148AAY.js - 6.13 kB (0 B (0%))
  5. hooks-ThU7CDLI.js - 5.85 kB (0 B (0%))
View All Files (291 total)
File Size (gzip) Change
index.esm-wIkXrqU6.js 11.4 kB 0 B (0%)
styles.css 10.97 kB 0 B (0%)
index.css 10.97 kB 0 B (0%)
internals-D6148AAY.js 6.13 kB 0 B (0%)
hooks-ThU7CDLI.js 5.85 kB 0 B (0%)
sdk.gen-BRPiw4M1.js 5.58 kB 0 B (0%)
index.js 5.51 kB 0 B (0%)
flows/Onboarding/hooks.js 4.65 kB 0 B (0%)
utils-CUgvJHl4.js 4.07 kB 0 B (0%)
FieldSetField-QbfQb5Lp.js 4.04 kB 0 B (0%)

✅ Bundle size check passed

@github-actions

github-actions Bot commented Oct 8, 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-q9s6hfvmo-remotecom.vercel.app
Latest Commit:b18a1da

Deployed with vercel-action

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Deploy preview for remote-flows ready!

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

Deployed with vercel-action

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

📊 Coverage Report

⚪ Coverage unchanged

Metric Current Previous Change Status
Lines 89.53% 89.53% 0% ⚪
Statements 89.40% 89.40% 0% ⚪
Functions 88.41% 88.41% 0% ⚪
Branches 81.14% 81.14% 0% ⚪

Detailed Breakdown

Lines Coverage
  • Covered: 5385 / 6015
  • Coverage: 89.53%
  • Change: 0% (0 lines)
Statements Coverage
  • Covered: 5450 / 6096
  • Coverage: 89.40%
  • Change: 0% (0 statements)
Functions Coverage
  • Covered: 1426 / 1613
  • Coverage: 88.41%
  • Change: 0% (0 functions)
Branches Coverage
  • Covered: 3339 / 4115
  • Coverage: 81.14%
  • Change: 0% (0 branches)

✅ Coverage check passed

@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.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@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.

The canary in this PR now only builds and validates the pinned and latest
schemas. The submit check (fill, PATCH, read back) moves to a stacked PR so
each one is smaller to review.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@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 3 potential issues.

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 bfd13ee. Configure here.

Comment thread scripts/schema-canary.ts Resolved
Comment thread scripts/schema-canary.ts Resolved
- Reject unknown --checks values and an empty country list (unknown
  --country or an empty /v1/countries payload), and exit 1 from
  decideExitCode when no row passed or failed, so a misconfigured or
  empty run can no longer report green.
- Wrap each live contract_details schema with
  withJobTitleEligibilityRiskAcknowledgement, matching what the
  Onboarding flow actually builds.
- Trim the seedEmploymentForCountry JSDoc to a caller-facing line.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Base automatically changed from refactor/headless-form-build to main October 12, 2026 08:22
Take main's braced guards in src/common now that #1480 is merged, and
apply the curly lint rule to scripts/schema-canary.ts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@gabrielseco
gabrielseco merged commit 64ba48d into main Oct 12, 2026
14 checks passed
@gabrielseco
gabrielseco deleted the feat/schema-canary-node branch October 12, 2026 08:30
gabrielseco added a commit that referenced this pull request Oct 12, 2026
Take main's braced parseArgs guard now that #1481 is merged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@gabrielseco gabrielseco mentioned this pull request Oct 12, 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