chore(web): lint findings to zero errors + CI lint gate - #116
Merged
Conversation
typedRoutes: true (stable in Next 16; `next typegen` already runs in CI before tsc since #114). A typo'd <Link>/router.push target now fails the build instead of 404ing at runtime — the failure class behind the recent RSC/routing incidents. - lib/routes.ts: registry helpers return `Route`; withQuery validates the base path literal. New: deviceBlockUrl (OpsEventsSection previously hand-built /admin/security/device-block against the registry rule), route() to compile-check dynamic-section literals (nav configs, section index redirects), trustedRoute() as the single named seam for runtime-data hrefs (backend-emitted notification deep links, persisted post-login return URL). - Nav types (NavItem, ExpandableSubItem, PageSectionItem) carry Route hrefs — every sidebar/navbar entry is compile-checked. - ClientRedirect is generic so dynamic-section literals infer. Verified: tsc clean; negative test (typo'd static + dynamic routes) fails compilation as intended; 611/611 vitest; static export builds with an unchanged route list. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Package deal — fixes only land together with the gate, otherwise they drift right back. CI web job now runs `eslint . --max-warnings 163`: errors fail outright, the warning cap is a ratchet (lower it when fixing warnings, never raise it). Fixed to zero (mechanical categories, behavior unchanged): - no-unused-vars (49): dead imports/locals removed; where a prop is part of a live call-site contract, only the destructured binding dropped - no-explicit-any (29): real structural types for event payloads (EnrollmentEvent.data et al -> Record<string, unknown> + per-event interfaces), SignalR passthroughs typed via the library's own signatures; five consumer files got typing-only follow-through - no-unescaped-entities (15), prefer-const, jsx-no-comment-textnodes - no-require-imports (5): scripts/**/*.js override — Node CJS scripts, require() is correct there - one stale eslint-disable directive removed Deliberately NOT fixed inline: the React-Compiler hooks rules new in eslint-plugin-react-hooks v6 (set-state-in-effect 93, refs 26, static-components 14, purity 6, immutability 5, preserve-manual-memoization 3) are demoted to warn in eslint.config.mjs — each is a per-site behavioral refactor in auth/SignalR-adjacent code, to be burned down incrementally under the ratchet. Verified: eslint 0 errors / 163 warnings (gate command exits 0), tsc clean, vitest 611/611, static export builds. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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
Stacked on #115 — merge #115 first, then this one (after #115 lands, the net diff of this PR is the lint changes only).
Package deal: fixes only land together with the CI gate, otherwise they drift right back. The CI web job now runs
npm run lint -- --max-warnings 163: errors fail outright, the warning cap is a ratchet (lower it when fixing warnings, never raise it).Fixed to zero (mechanical categories, behavior unchanged):
no-unused-vars(49): dead imports/locals removed; where a prop is part of a live call-site contract, only the destructured binding was droppedno-explicit-any(29): real structural types for event payloads (EnrollmentEvent.dataet al →Record<string, unknown>+ per-event interfaces); SignalR passthroughs typed via the library''s own signaturesno-unescaped-entities(15),prefer-const,jsx-no-comment-textnodesno-require-imports(5):scripts/**/*.jsoverride — Node CJS scripts,require()is correct thereeslint-disabledirective removedDeliberately NOT fixed inline: the React-Compiler hooks rules new in eslint-plugin-react-hooks v6 (
set-state-in-effect93,refs26,static-components14,purity6,immutability5,preserve-manual-memoization3) are demoted towarnineslint.config.mjs— each is a per-site behavioral refactor in auth/SignalR-adjacent code, to be burned down incrementally under the ratchet. No per-siteeslint-disableallowed or added.Verification
tsc --noEmitclean, vitest 611/611, static export builds🤖 Generated with Claude Code