Repository navigation
chore: adopt stricter lint rules and ban z.coerce - #1837
Merged
Merged
Conversation
Port seven custom rules into .eslint/rules (registered under odc/): route-exports, unit-test-subject, require-disable-reason, no-coverage-ignore, multiline-arrow-body, class-name-composition and handler-names. Enable the core, typescript-eslint, react and jsx-a11y rules that report little or nothing today, import/enforce-node-protocol-usage, three vitest test-style rules, and the Playwright recommended set for testing/src with every rule at error. Ban z.coerce, which accepts inputs like '' and null. Ignore the generated apps/web/src/route-tree.ts, and update the docs that showed eslint-disable comments without a reason. The source is not fixed yet, so pnpm lint fails until the follow-up commits land. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…dule itself A test of an entrypoint with no exports, or of what loading a module does, imports the module itself (a side-effect import, `import * as`, or `await import()`) rather than names, so it had no name to title its describe after. odc/unit-test-subject now accepts the subject's file name there. It also requires whatever follows `Name.` in a title to be member names, so a title like `plugin.onLoad ?raw` no longer passes as a member of `plugin`. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…rors Every top-level describe is now titled after what it tests, every hook sits inside a describe, every toThrow names the error the code actually throws, and test() is it(). - Component tests import the component file rather than its folder's index.ts. - Route tests import Route and read its options, instead of capturing them through a mocked createFileRoute. - Store slice tests build their store from the slice creator they cover. - The WORD_LIST checks move to word-list.test.ts, and the $CreateRemoteAssignmentsData checks move from the gateway's router test to packages/schemas. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Run eslint --fix, as pnpm lint does, then prettier. Multi-line arrow bodies become blocks, Node built-ins are imported through the node: protocol, and the curly, prefer-template, object-shorthand, prefer-arrow-callback and JSX autofixes apply. prefer-arrow-callback now allows named functions. Its autofix had turned the named function passed to forwardRef into an arrow, losing each component's display name, and had made the vi.fn constructor mocks in two tests into arrows, which cannot be called with new. Those mocks are now named functions. The gateway's assignment handler now returns nothing from every branch, since the void-expression autofix had left it returning a response from only some. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…them z.coerce turned inputs like '' and null into valid values, so a null on a required date became 1970. Dates now go through $DateLike in packages/schemas/src/core, which accepts a Date or an ISO 8601 date-time (what JSON.stringify makes of a Date) and rejects everything else. Numbers are parsed strictly too: the audit query and the web app's network latency use libjs's $NumberLike, the gateway's ports accept only digit strings, and number-keyed form options accept only numeric keys. The ban now also covers the z3 and z4 aliases. The API now refuses some inputs it used to accept: a date given as a numeric timestamp, an empty string, a date without a time, or a date-time without a timezone. Every client in this repository already sends full ISO date-times. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Fix by hand what the new rules flag and eslint --fix cannot: block-bodied promise executors, void calls as statements, nested ternaries as lookups or early returns, handle-prefixed handler names, button types, strict equality, cn() for class names, and a parseInt radix. Every eslint-disable comment states its reason, or is gone where the code could satisfy the rule instead. perfectionist/sort-objects is off for the playground's example and template instruments and for instrument-stubs, as it already is for instrument-library, since instrument definitions are written in reading order. In the Playwright suite, getPageModel counts as an assertion for expect-expect, the users page object's selectOption is renamed selectPermissionOption so the plugin stops mistaking it for Playwright's own, and the playground slice tests bind setState instead of passing it unbound. Co-Authored-By: Claude Opus 5.5 <[email protected]>
`odc-cli instrument-records find --min-date 2024-01-31` sent `2024-01-31T00:00:00`, a date-time without a timezone, which the API now rejects with a 400 since minDate is parsed as $DateLike. A date given without a timezone is now read as UTC, as `subjects find --min-date` already does. Co-Authored-By: Claude Opus 5.5 <[email protected]>
The autofix of odc/multiline-arrow-body gave useSubjectsQuery.ts a block body, so the canonical example in apps/web/AGENTS.md now shows the same. Co-Authored-By: Claude Opus 5.5 <[email protected]>
# Conflicts: # apps/web/src/components/BulkRemoteAssignmentWizard/__tests__/BulkRemoteAssignmentWizard.test.tsx # apps/web/src/components/MailSettings/MailSettings.tsx # apps/web/src/utils/__tests__/bulk-assignments.test.ts # apps/web/src/utils/bulk-assignments.ts # eslint.config.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adopts the lint rules from the Clinivance platform's oxlint config that fit this repo, and fixes
everything they flag.
.eslint/rules/and registered asodc/*:route-exports,unit-test-subject,require-disable-reason,no-coverage-ignore,multiline-arrow-body,class-name-composition,handler-names.curly,eqeqeq,no-nested-ternaryandpreserve-caught-error;no-confusing-void-expressionandreturn-await;import/enforce-node-protocol-usage;testing/src, with every rule at error.z.coerceis banned, including through thez3/z4aliases.@vitest/eslint-pluginandeslint-plugin-playwright, through thecatalog.
Every
eslint-disablenow states its reason after--.perfectionist/sort-objectsis off for theplayground's example instruments and for
instrument-stubs, as it already was forinstrument-library.API change
Dates now parse through
$DateLikeinpackages/schemas/src/core, which accepts aDateor anISO 8601 date-time with a timezone. The API now answers 400 to a numeric timestamp, an empty string,
a date without a time, or a date-time without a timezone. It used to coerce all of these, so a
nullon a required date became 1970.Every client in this repo already sends ISO date-times.
odc-cli --min-datewas the exception, andnow sends UTC.
Commits
d8f1ecd57: the rules and config.ad240c3ad,c4b8fe2dc: the test-layout rules, and the unit tests they flagged.0efbf44ab:eslint --fixacross the repo. It is mechanical, so it can be skimmed.1520a9cf1: date and number parsing.83de59345: hand fixes for everything else.1a34ac7fe,5cd61934b: follow-ups in the CLI and the docs.Verification
pnpm lint: green.pnpm test:coverage: 418 files and 4,887 tests, at 100% on every metric. New tests cover:$DateLike, inpackages/schemas/src/core/__tests__/core.test.ts;packages/schemas/src/audit/__tests__/audit.test.ts;instrument.form.test.ts;minDatepipe, ininstrument-records.controller.test.ts;pnpm test:e2e: 278 of 327 passed locally. The other 49 all failed on the API's loginthrottle (429), which parallel workers trip on a local machine (Local end-to-end runs trip the API's login throttle #1835). Re-run with two workers,
48 passed.
subject-detail.spec.ts"should plot a selected measure" failed once, then passed in10 reruns.
Problems found along the way, filed separately: #1833, #1834, #1835, #1836.
Co-Authored-By: Claude Opus 5.5 [email protected]