[Lint 04] fix: burn down frontend eslint errors; make CI lint blocking - #235
Merged
willchen96 merged 2 commits intoJul 22, 2026
Merged
Conversation
Ported from #46 onto current main, extended for this tree: backend job runs npm ci, tests (--if-present, so it is safe to merge in any order relative to the test-harness PR) and tsc build; frontend job runs tests, eslint as an advisory step (main currently carries 23 lint errors — flip to blocking once burned down), and a production next build with placeholder NEXT_PUBLIC_* env (verified locally that the build succeeds and contacts nothing); evals job runs node evals/run.mjs when present, else skips. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Takes frontend/npm run lint from 23 errors / 40 warnings to 0 errors / 40 warnings, then removes continue-on-error from the CI lint step so it gates merges. Errors fixed outright: - @typescript-eslint/no-explicit-any (5, ChatView.tsx): dropped redundant (msg as any) casts — Message already declares files, workflow, and error with the exact shapes the props expect. - react/no-unescaped-entities (1, support/page.tsx): "We'll" -> "We'll". Targeted disables (17, all react-hooks/set-state-in-effect): every site is an intentional effect-driven state pattern — SSR/hydration mount gates (Modal, useSelectedModel), reset-on-prop/identity-change (CaseLawPanel x3, ChatView chat switch, CitationQuotesHeader, ChatHistoryContext logout, useFetchDocxBytes), sync fast paths of async fetch/check effects (CaseLawPanel, MfaLoginGate x2), DOM-measured state (ChatView scroll button, message-visibility restore), and timed UI latches (PreResponseWrapper, TRChatPanel, AskInputPopup auto-submit). Rewriting any of them would change runtime behavior, so each carries a // eslint-disable-next-line with a one-line reason instead of a fix or a repo-wide rule change. CI: lint step is now blocking; comments updated to say the backlog is at zero. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
QA Runner seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
willchen96
approved these changes
Jul 22, 2026
willchen96
approved these changes
Jul 22, 2026
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.
Summary
Follow-up to #232: burns the frontend eslint error backlog down from 23 errors / 40 warnings to 0 errors / 40 warnings, then flips the CI lint step from advisory (
continue-on-error: true) to a blocking gate. All edits are minimal and behavior-preserving — no rule is disabled repo-wide.Changes
@typescript-eslint/no-explicit-anyChatView.tsxused(msg as any).files/.workflow/.error, but theMessageinterface (shared/types.ts) already declares all three fields with exactly the shapes theUserMessage/AssistantMessageprops expect. Casts removed; plain property access type-checks cleanly (verified bynext build, which runs tsc).react/no-unescaped-entitiessupport/page.tsx:We'll→We'll.react-hooks/set-state-in-effect// eslint-disable-next-linewith a one-line reason at each site (details below). Every occurrence is an intentional effect-driven state pattern; any "real" fix (derive-during-render, key-based remount,useSyncExternalStore) would change runtime behavior, so per-site disables were the safe call.The 17
set-state-in-effectdisables and their reasonsmodals/Modal.tsx:64hasMountedmust flip after first client mounthooks/useSelectedModel.ts:19hooks/useFetchDocxBytes.ts:52documentIdis removed, inside the fetch effectcontexts/ChatHistoryContext.tsx:76assistant/CaseLawPanel.tsx:219assistant/CaseLawPanel.tsx:272assistant/CaseLawPanel.tsx:276assistant/CaseLawPanel.tsx:324assistant/ChatView.tsx:86assistant/ChatView.tsx:522assistant/ChatView.tsx:556assistant/CitationQuotesHeader.tsx:50assistant/PreResponseWrapper.tsx:32assistant/AskInputPopup.tsx:245submit()sets state as part of the side effectshared/MfaLoginGate.tsx:24shared/MfaLoginGate.tsx:67tabular/TRChatPanel.tsx:167CI
.github/workflows/ci.yml: removedcontinue-on-error: truefrom the frontend lint step and rewrote the step comment (and the header note) — lint is now a blocking gate since the error backlog is at zero. Warnings do not fail the step.Why
#232 landed the lint step as advisory-only because main carried 23 inherited eslint errors and a blocking gate would have turned every PR red on debt it didn't create. With the backlog at zero, the gate can hold the line: any new eslint error fails CI at the PR, instead of accreting silently.
Testing
cd frontend && npm run lint— exits 0: 0 errors, 40 warnings (was 23 errors / 40 warnings; warnings are pre-existing, mostlyno-unused-varsonnoderef params andno-explicit-anywarnings in test-adjacent code).npm test— notestscript exists on this branch (predates the vitest harness PR); CI'snpm test --if-presentno-ops, as designed in [CI 03] ci: build and test workflow for backend and frontend #232.NEXT_PUBLIC_SUPABASE_URL=https://placeholder.supabase.co NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY=sb_publishable_placeholder NEXT_PUBLIC_API_BASE_URL=http://localhost:3001 npm run build— passes (compiles + type-checks all routes), confirming theChatView.tsxcast removals are type-safe.🤖 Generated with Claude Code