Lint first pass: no-unused-vars, no-explicit-any, no-require-imports (#1593) - #1615
Open
ArendPeter wants to merge 5 commits into
Open
ArendPeter wants to merge 5 commits into
ArendPeter wants to merge 5 commits into
Conversation
✅ Deploy Preview for bettervoting ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
…ports, and unused imports repo-wide
Resolves Equal-Vote#1593 (first pass). Fixes all four rules to zero violations across
shared, backend, and frontend:
- no-unused-vars: removed dead imports/locals; added a codebase-wide
underscore-prefix ignore convention to eslint.base.mjs for params kept only
for interface/signature conformance.
- no-require-imports: converted require() to import across the app, except
where require() is genuinely required (lazy-loaded deps, a pre-import
sanity check, standalone CJS scripts) — those get a disable comment instead.
- no-explicit-any: replaced with real types (Express Request/Response,
library types where installed) or with proper narrowing; kept
only where the underlying dependency has no usable types (multer,
Kysely migrations, an unreconciled pg-boss API drift), each with a comment.
- Removed a build/** blind spot in the frontend eslint config that was
linting the compiled bundle instead of source.
Along the way, fixed two behavior bugs a code review caught in the
no-explicit-any pass: a privilege-escalation gap where a missing JWT email
claim could match an empty admin_ids/audit_ids/credential_ids entry, and an
auth-check reorder in claimElectionController that changed behavior for an
already-owning temp-id user. Also extracted a getErrorMessage/hasErrorCode
helper (errorUtils.ts) to replace ~18 duplicated unknown-catch narrowings.
Verified: tsc --noEmit, eslint, and the full test suite pass clean on all
three packages after every batch of changes.
Not fixed here (pre-existing, out of scope for this pass, blocks the
pre-commit hook's stricter --fix bar): no-var (158 instances), prefer-const
(autofixed by the hook), and a handful of other rule categories across the
files this touched — see follow-up.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SxX59NANLcLWzKZQ7dXSF
7af4ef1 fixed a privilege-escalation gap (missing JWT email claim matching an empty admin_ids/audit_ids/credential_ids entry) and an auth-check null-safety change in claimElectionController alongside unrelated lint fixes. Those are real behavior changes and shouldn't ride along in a lint-only commit, so pull them back out here; they can be reintroduced and reviewed in their own PR. Uses type assertions to restore the original pre-fix runtime behavior while keeping the real typing (no re-introduction of `any`, so no-explicit-any/no-unused-vars/no-require-imports stay clean). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JeDZuhdL1Kaz7Tm8osdpRj
ArendPeter
force-pushed
the
lint-first-pass
branch
from
September 11, 2026 21:02
cd04865 to
dacf6c4
Compare
ArendPeter
marked this pull request as ready for review
September 12, 2026 04:33
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.
Human Summary
This PR aims to apply some basic linting across the whole project to minimize the amount of linting work that's necessary on upcoming PRs.
It also temporarily disables linting. In order to get this PR through and while updating the linting, there are also some bugs that are fixed, which are detailed further in the AI summary below.
Summary
Closes #1593. Repo-wide first pass fixing four ESLint rule categories to zero violations across
shared,backend, andfrontend:@typescript-eslint/no-unused-vars(including unused imports)@typescript-eslint/no-explicit-any@typescript-eslint/no-require-importsKey changes:
eslint.base.mjs: recognize the codebase's existing leading-underscore convention (argsIgnorePattern/varsIgnorePattern/caughtErrorsIgnorePattern: "^_") for intentionally-unused bindings.packages/frontend/eslint.config.js: excludebuild/**from linting (was producing thousands of false positives against the compiled bundle).anywith real types orunknown+ narrowing throughout; keptanyonly where a dependency genuinely lacks usable types (multer, a stale pg-boss integration, SendGrid's varying response shape, a generic array-lookup helper), each flagged with an inline comment explaining why.packages/backend/src/errorUtils.ts(getErrorMessage,hasErrorCode) to replace ~18 duplicatederr instanceof Error ? err.message : String(err)blocks.packages/backend/src/untyped-modules.d.tsforjsonwebtoken/multerambient declarations; set"ts-node": {"files": true}inpackages/backend/tsconfig.jsonsogenerate:openapistill picks them up.interfaces inpackages/sharedtotypealiases (no-empty-object-type).Temporarily disables the
lint:diffCI step (.github/workflows/node.js.yml) — pre-existing lint debt outside the four target rules (mainlyno-var, ~158 instances across 65 backend files) is still present in files this PR touches and wasn't in scope for this pass; re-enable once that's addressed in a follow-up.Not in scope for this pass (left as known debt):
no-varand other rule categories not listed above.Test plan
npx tsc --noEmitclean inshared,backend,frontendnpx eslint .— zero violations for the four target rules in all three packagesnpm run build -ws— all three packages build clean/code-reviewpass run against the diff; both findings above fixed and re-verified🤖 Generated with Claude Code
https://claude.ai/code/session_018SxX59NANLcLWzKZQ7dXSF