Skip to content

Add ESLint with flat config, lint script, and CI enforcement#289

Open
jeremyzilar wants to merge 8 commits into
stagingfrom
BDMS-837
Open

Add ESLint with flat config, lint script, and CI enforcement#289
jeremyzilar wants to merge 8 commits into
stagingfrom
BDMS-837

Conversation

@jeremyzilar

@jeremyzilar jeremyzilar commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

What this does

Adds ESLint to OcotilloUI. There was no linting at all before this PR. This is Ticket 1.2 from Epic 1 (Code Health).

What was added

  • eslint.config.ts — flat config at the repo root, covering TypeScript, React, React Hooks, and Prettier compatibility
  • npm run lint and npm run lint:fix scripts in package.json
  • A Lint step in CI_vitest.yml that fails the build on any ESLint error
  • LINTING.md documenting the ruleset and how to run it locally
  • .vscode/settings.json — format on save via Prettier
  • .vscode/extensions.json — recommends the Prettier and ESLint extensions when someone opens the repo

Rule philosophy

Most violations are set to warn rather than error so we aren't blocked by pre-existing issues on day one. The only things that will fail CI are genuine bugs, hooks called conditionally, hooks called outside of components, and similar react-hooks/rules-of-hooks violations.

The React Compiler rules (shipped as part of eslint-plugin-react-hooks v7) are also set to warn. We are not currently using the React Compiler, and fixing all 49 violations isn't worth doing as part of a lint setup ticket. The decision is documented in the-brain at docs/product/decisions/react-compiler.md.

What was fixed to get to zero errors

Running the linter on the existing codebase produced 97 errors. All of them are resolved in this PR:

  • Auto-fixed (npm run lint:fix): 29 prefer-const and irregular whitespace violations across providers, resources, and pages
  • React Compiler rules: demoted from error to warn (49 violations — pre-existing patterns, not new problems)
  • JSX comments: two bare // comment lines inside JSX children in routes/ocotillo.tsx, wrapped in {/* */}
  • Unescaped entities: literal " and ' characters in JSX text in GameResults.tsx and TypographyPage.tsx, replaced with " and '
  • Function type: replaced bare Function types in utils/Link.tsx with explicit signatures
  • Hooks called outside components:
    • lexicon/list.tsxuseExport was called inside a headerButtons render function; extracted as a proper LexiconHeaderButtons component
    • utils/Link.tsxuseLink was called inside linkColumn; moved out and passed as a parameter, callers updated
    • components/card/RecentWaterLevelObservations.tsxuseMemo was called after an early return; moved above it
    • components/MapComponent.tsxuseRef was called inside a ?? expression (conditional); split into an unconditional useRef call followed by the conditional assignment

Warnings remaining

725 warnings remain. They are not blocking anything and will be addressed incrementally:

Rule Count Plan
@typescript-eslint/no-explicit-any 328 Fix as part of TypeScript strict mode work (Ticket 1.3)
@typescript-eslint/no-unused-vars 231 Fix as part of dead code removal (Ticket 1.1)
react-refresh/only-export-components 82 Fix when touching those files
React Compiler rules 49 Fix when adopting the compiler (see decision doc)
react-hooks/exhaustive-deps 32 Fix as part of ongoing component work
@typescript-eslint/no-empty-object-type 2 Fix when touching those files

Installs eslint, typescript-eslint, eslint-plugin-react, eslint-plugin-react-hooks,
eslint-plugin-react-refresh, and eslint-config-prettier. Adds eslint.config.ts at
the repo root with recommended rules for TypeScript and React, with most violations
set to warn initially so the codebase can be cleaned up incrementally.

Adds npm run lint and lint:fix scripts to package.json and a Lint step to
CI_vitest.yml that fails the build on errors. Adds LINTING.md documenting the
ruleset and how to run it locally.
@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-837-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-837-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

- Demote all react-hooks compiler rules (set-state-in-effect, refs, purity, etc)
  to warn — violations are pre-existing and non-critical at current scale.
  See react-compiler.md in the-brain for the full decision.
- Fix react/jsx-no-comment-textnodes in routes/ocotillo.tsx
- Fix react/no-unescaped-entities in GameResults.tsx and TypographyPage.tsx
- Replace bare Function types with explicit signatures in utils/Link.tsx
- Extract LexiconHeaderButtons as a proper component so useExport is called
  at component scope, not inside a render function
- Fix conditional useRef in MapComponent by always calling useRef and
  choosing between internal and external ref after
- Fix useMemo called after early return in RecentWaterLevelObservations
- Fix useLink called inside linkColumn by passing Link as a parameter;
  callers (SampleList, WellScreenList) now call useLink at component top level
- Replace non-breaking spaces with regular spaces in ControlledSelectWithChipsField
- Fix split let declaration/assignment in geothermal-data-provider
@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-837-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

@jeremyzilar jeremyzilar added the enhancement New feature or request label Jun 10, 2026
…ontexts and hooks

Moved SupportPanelContext to its own file so AppShell only exports components.
Moved useSidebar and SidebarContext to use-sidebar.ts so sidebar.tsx only exports components.
Removed unused vars from AppSidebar that belonged to ShellHeader.
Updated ReportBugButton to import SupportPanelContext from its new location.
@jeremyzilar jeremyzilar requested a review from jirhiker June 10, 2026 23:33
@jeremyzilar jeremyzilar marked this pull request as ready for review June 10, 2026 23:33
@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-837-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

Comment thread .github/workflows/CI_vitest.yml Outdated
run: npm ci

- name: Lint
run: npm run lint

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can linting be its only GitHub workflow? It might be confusing to see the Vite test workflow fail, only to find it's actually a linting error later.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Great point!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done ✅

sx={{ px: 2, py: 2, textAlign: 'center' }}
>
No games found for "{term}".
No games found for "{term}".

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👀

@TylerAdamMartinez

Copy link
Copy Markdown
Contributor

@jeremyzilar, where's the completed decision document for the React Compiler located?

@jeremyzilar

Copy link
Copy Markdown
Contributor Author

@TylerAdamMartinez You can find the doc here: https://github.com/DataIntegrationGroup/the-brain/blob/main/docs/product/decisions/react-compiler.md

@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-837-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

@chasetmartin chasetmartin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nice work, this will be great. I'll resist the urge to include an ESLint meme 😂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants