Skip to content

fix(lint): apply approved lint fixes and Prettier formatting - #10

Merged
guarzo merged 4 commits into
mainfrom
tooling-lint-fixes
Aug 3, 2026
Merged

fix(lint): apply approved lint fixes and Prettier formatting#10
guarzo merged 4 commits into
mainfrom
tooling-lint-fixes

Conversation

@guarzo

@guarzo guarzo commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Stage 1b. Three commits, deliberately separable:

  1. 30cd610 config only — rule adjustments, no source file touched. 125 → 31.
  2. e54eeb1 source fixes — 31 → 2. One real bug, two inline rule-limitation disables, test cleanup.
  3. 4cbb1eb mechanical Prettier reformat — 63 files, +830/-356, nothing hand-edited.

Review 1 and 2; skim 3.

One thing changed from the plan you approved

You approved autofixing no-unnecessary-type-assertion. I ran it and it broke tsc on all five src/ occurrences. The rule judges an assertion in isolation, where literal types survive, and misses that the value is then widened by its context:

  • src/services/accounts.tsas "valid" | "needs_reauth". Without it the object-literal property widens to string and no longer satisfies the drizzle insert type.
  • src/jobs/discord-roles.tsas Record<string, number> (x4). Without it the return branches infer as a union carrying notInGuild?: undefined, which fails the index signature on JobResult["counts"].

All five were load-bearing. I reverted them and disabled the rule instead. Returning object literals into a wider declared type is the dominant shape of the job handlers, so it would keep misfiring — and a rule whose --fix breaks the build is worse than no rule, given lint:fix is a wired script.

The 16 test-side occurrences of the same rule were genuinely redundant and typecheck cleanly without the assertions, so those fixes are kept.

This is the exact failure mode you flagged when you said you didn't want a linter dictating a rewrite. It only got caught because the typecheck ran after the autofix.

Real bug fixed

src/app/admin/accounts/actions.ts

-const note = String(formData.get("note") ?? "");
+const raw = formData.get("note");
+const note = typeof raw === "string" ? raw : "";

FormData.get() returns string | File | null. A File stringifies to "[object File]", which would be persisted as the admin note and written to the audit log.

Also different from plan

no-unused-vars with ^_ killed 4 of 9, not all 9. The other 5 were genuine dead code, now removed: unused imports bootstrapAdminGrant, session, EveSsoError, and two unused const a = bindings (the await login(ch()) side effect each existed for is preserved). The apparent extra references to session and EveSsoError were a module path string and a test name.

Verification

$ npm run format:check   → exit=0   All matched files use Prettier code style!
$ npm run lint           → exit=0   2 problems (0 errors, 2 warnings)
$ npm run typecheck      → exit=0
$ npm test               → exit=0   39 files, 271 tests passed
$ npm run build          → exit=0

The 2 remaining warnings are the two @next/next/no-img-element you chose to leave as warnings.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved validation for account notes, rejecting missing or invalid note values while preserving valid entries.
  • Refactor
    • Improved code readability through consistent formatting and simplified type handling.
    • Removed unused test code and unnecessary type assertions.
  • Tests
    • Updated fixtures, assertions, and mocks for improved maintainability.
    • Preserved existing test coverage and behavior.
  • Chores
    • Refined linting rules and documented safe lint suppressions.

guarzo added 3 commits August 3, 2026 13:45
…nges

Config-only. Takes 125 problems to 31 without touching a single source file.

- no-unused-vars: ignore the `^_` prefix. `_req`, `_url`, `_init` are already
  this codebase's "deliberately unused" marker.
- require-await, no-unsafe-assignment, no-unsafe-member-access,
  no-base-to-string: off for tests/ and e2e/ only. All 85 require-await hits are
  test doubles declared `async` to match the interface they stand in for; zero
  are in src/, so the rules keep their full value where it matters.

- no-unnecessary-type-assertion: DISABLED, with evidence. It flagged 5
  assertions in src/ as unnecessary; its autofix broke `tsc` on all 5. The rule
  judges an assertion in isolation, where literal types survive, and misses that
  the value is then widened by its context:
    src/services/accounts.ts  `as "valid" | "needs_reauth"` — without it the
      property widens to `string` and fails the drizzle insert type.
    src/jobs/discord-roles.ts `as Record<string, number>` (x4) — without it the
      return branches infer `notInGuild?: undefined` etc., failing the index
      signature on JobResult["counts"].
  Returning object literals into a wider declared type is the dominant shape of
  the job handlers, so this would keep misfiring. A rule whose --fix breaks the
  build is worse than no rule: `lint:fix` is a wired script anyone may run.
Takes 31 problems to 2 (both intentional warnings).

Real fix:
- src/app/admin/accounts/actions.ts — `String(formData.get("note") ?? "")`.
  FormData.get() returns string | File | null, so a File would stringify to
  "[object File]" and be persisted as the admin note *and* written to the audit
  log. Now rejects anything that isn't a string. Surfaced by no-base-to-string.

Rule limitations, disabled inline with the reasoning at the call site:
- src/jobs/contacts.ts — `if (stepErr) throw stepErr` is a deliberate rethrow of
  a caught `unknown` captured across two try/catch blocks so add/edit failures
  don't block removals. only-throw-error's allowRethrowing option only covers
  `throw` sited directly inside a catch, so it does not apply.
- scripts/wanderer-smoke.ts — the throw inside `finally` is caught by an
  enclosing try/catch *within* that finally, so it can never escape or mask the
  original error. no-unsafe-finally is lexical and cannot see this.

Test cleanup (mechanical, no behaviour change):
- 16 genuinely redundant type assertions removed by `eslint --fix`. Unlike the
  five in src/, these typecheck cleanly without them.
- Dead imports: bootstrapAdminGrant, session (accounts.test.ts), EveSsoError
  (eve-sso.test.ts). The apparent extra references were a module path string and
  a test *name*, not uses.
- Two unused `const a =` bindings dropped; the `await login(ch())` side effect
  each one existed for is preserved.

Left as warnings by decision: 2x @next/next/no-img-element (login and account
pages). These render external avatar URLs, where next/image needs remote-pattern
config and buys little.
Pure `npm run format` output, isolated in its own commit so the preceding two
commits stay reviewable. 63 files, +830/-356.

No hand edits are mixed in: `npm run format:check` is clean at this commit and
`git diff` against the parent is entirely reflowing. Markdown is excluded via
.prettierignore, so the docs are untouched.
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e6886dee-657b-44d3-8839-7d9666e02883

📥 Commits

Reviewing files that changed from the base of the PR and between 4a94560 and 8993694.

📒 Files selected for processing (4)
  • eslint.config.mjs
  • src/app/admin/accounts/actions.ts
  • src/jobs/discord-roles.ts
  • src/services/accounts.ts

📝 Walkthrough

Walkthrough

The pull request standardizes formatting across application and test files, adds TypeScript and test-specific ESLint overrides, removes redundant test assertions, and validates that saveNoteAction receives a string note.

Changes

Formatting and lint alignment

Layer / File(s) Summary
Lint rules and tooling
eslint.config.mjs, scripts/wanderer-smoke.ts, drizzle.config.ts
Adds scoped ESLint exceptions, documents a safe no-unsafe-finally suppression, and reformats configuration expressions.
Application code formatting and input handling
src/app/..., src/config.ts, src/jobs/..., src/lib/..., src/services/..., src/db/schema.ts
Reformats application code and makes saveNoteAction reject missing or non-string note values with invalid_note.
Test and E2E alignment
e2e/*, tests/*
Reformats fixtures, calls, assertions, and imports. Removes unused declarations and redundant type assertions.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

Poem

A rabbit checks each tidy line,
While lint rules glow and tests align.
Notes accept strings, clear and neat,
Old casts leave on quiet feet.
The code now hops in ordered trails.
“Reviewed!” the rabbit wiggles its tails.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the PR's primary lint fixes and Prettier formatting changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch tooling-lint-fixes
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch tooling-lint-fixes

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@eslint.config.mjs`:
- Line 80: Remove the global "`@typescript-eslint/no-unnecessary-type-assertion`"
disable from the ESLint configuration and keep the rule enabled for TypeScript
files. Add line-scoped suppressions only at the five documented assertions that
eslint --fix incorrectly changes, preserving enforcement everywhere else.

In `@src/app/admin/accounts/actions.ts`:
- Around line 50-63: Update saveNoteAction to reject non-string or missing
formData.get("note") values before starting the transaction, rather than
converting them to an empty string. Preserve an explicit empty string as the
valid request to clear the note, and continue passing valid string notes to
setStatusNote.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7a2989c8-7248-46d4-962e-8f9369fd37ef

📥 Commits

Reviewing files that changed from the base of the PR and between 05abfd5 and 4a94560.

📒 Files selected for processing (65)
  • drizzle.config.ts
  • e2e/account.spec.ts
  • e2e/admin.spec.ts
  • eslint.config.mjs
  • scripts/wanderer-smoke.ts
  • src/app/account/page.tsx
  • src/app/admin/accounts/actions.ts
  • src/app/admin/accounts/page.tsx
  • src/app/admin/audit/page.tsx
  • src/app/admin/sync/page.tsx
  • src/app/auth/discord/link/route.ts
  • src/app/auth/eve/callback/route.ts
  • src/config.ts
  • src/core/role-diff.ts
  • src/db/schema.ts
  • src/jobs/contacts.ts
  • src/jobs/membership.ts
  • src/jobs/purge.ts
  • src/jobs/wanderer.ts
  • src/lib/discord/oauth.ts
  • src/lib/discord/rest.ts
  • src/lib/esi/client.ts
  • src/lib/esi/sso.ts
  • src/lib/wanderer/client.ts
  • src/services/account-view.ts
  • src/services/accounts.ts
  • src/services/admin-accounts.ts
  • src/services/discord-link.ts
  • src/services/oauth-tx.ts
  • src/services/session.ts
  • src/services/tokens.ts
  • tests/account-view.test.ts
  • tests/accounts.test.ts
  • tests/admin-accounts.test.ts
  • tests/audit-query.test.ts
  • tests/auth-routes.test.ts
  • tests/config.test.ts
  • tests/contacts-diff.test.ts
  • tests/contacts-job.test.ts
  • tests/db-schema.test.ts
  • tests/deprovision-flow.test.ts
  • tests/desired.test.ts
  • tests/discord-link.test.ts
  • tests/discord-oauth.test.ts
  • tests/discord-rest.test.ts
  • tests/discord-roles-job.test.ts
  • tests/dispatcher.test.ts
  • tests/errors.test.ts
  • tests/esi-client.test.ts
  • tests/eve-sso.test.ts
  • tests/helpers/config.ts
  • tests/helpers/db.ts
  • tests/membership-job.test.ts
  • tests/ops-webhook.test.ts
  • tests/outbox.test.ts
  • tests/purge-job.test.ts
  • tests/role-diff.test.ts
  • tests/session.test.ts
  • tests/sync-run.test.ts
  • tests/tier.test.ts
  • tests/token-health-job.test.ts
  • tests/tokens.test.ts
  • tests/wanderer-client.test.ts
  • tests/wanderer-job.test.ts
  • tests/worker-queues.test.ts
💤 Files with no reviewable changes (1)
  • src/lib/wanderer/client.ts

Comment thread eslint.config.mjs Outdated
Comment thread src/app/admin/accounts/actions.ts
…n-string note

Replace the blanket disable of @typescript-eslint/no-unnecessary-type-assertion
with five line-scoped suppressions at the documented false positives, so the
rule keeps enforcing everywhere else. Verified load-bearing: stripping the five
directives yields exactly five errors, and the rule still fires on a freshly
injected redundant assertion.

saveNoteAction now rejects a non-string formData note instead of coercing it to
"". Coercion silently cleared the note (setStatusNote maps "" to null) and wrote
a status.note_changed audit entry for an edit nobody requested. An explicit ""
remains the valid way to clear it.

Also ignore next-env.d.ts: it is generated by next build/dev and gitignored, and
its triple-slash reference fails lint on any machine that has built.
@guarzo
guarzo merged commit 906aac4 into main Aug 3, 2026
1 check was pending
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant