chore(lint): drive ESLint warnings to zero - #190
Merged
Conversation
Starting from 52 warnings. End state: 0 errors, 0 warnings. Mix of substantive fixes and one documented rule downgrade. Each category: Hoisting / stale-closure (17 warnings) — wrapped fetcher functions in useCallback and moved their declarations above the useEffects that call them. Adds proper dep arrays. Affected pages: - adif/page.tsx (fetchStations) - admin/storage/page.tsx (fetchConfigs) - admin/users/page.tsx (fetchUsers) - awards/dxcc/page.tsx (fetchDXCCSummary) - awards/was/page.tsx (loadStations) - new-contact/page.tsx (fetchStations, fetchCurrentUser) - stations/[id]/edit/page.tsx (fetchStation + 3 siblings) - stations/new/page.tsx (fetchDxccEntities, fetchStatesProvinces) - stations/page.tsx (fetchStations, fetchStationStats) - stats/page.tsx (fetchStations) - search/page.tsx (performSearch, debouncedSearch — moved above the useEffect that triggers it) Memoization warning (1) — search/page.tsx `debouncedSearch` was caught by react-hooks/preserve-manual-memoization because it depended on `searchTimeout` state and called `setSearchTimeout`, recreating itself on every tick. Replaced the state with a useRef so the callback's identity is stable. This is the React-19-compiler-recommended pattern for timer state. set-state-in-effect (33 warnings) — disabled. These all fired on the standard "fetch data on mount → setState with the result" pattern, which is normal React data-loading. Per-line suppression would add 33 comments across the codebase, noisier than the warning itself. eslint.config.mjs carries a comment explaining the decision and pointing at the path to re-enable (adopt SWR/TanStack Query, which obviates the pattern). Unused eslint-disable in storage.ts (1) — the comments suppressed no-unused-vars for parameters that already had `_` prefix. Added `argsIgnorePattern: "^_"` to the project ESLint config (standard JS/TS convention for "intentionally unused"), then dropped the now-redundant disable comments. Two follow-on `_mimeType` warnings disappeared too. Also picks up the same one-line null-guard in tests/database-integration .spec.ts as PRs #188/#189, so this branch's `tsc --noEmit` is clean independent of merge order. Verification: - npm run lint → 0 errors, 0 warnings - npx tsc --noEmit → clean - npm run build → succeeds Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…nup/lint-zero # Conflicts: # eslint.config.mjs
5 tasks
patrickrb
added a commit
that referenced
this pull request
May 11, 2026
Builds on #194. Resolves the schema-source-of-truth problem: the dev DB and the in-app installer were producing different schemas, and #194's introspect ran against the dev DB (subset). This PR locks in the in-app installer (install-database.sql + propagation-schema.sql + migrations) as canonical and regenerates schema.ts against that. What changed: - Built a temporary nextlog_canonical Postgres database, applied the canonical install scripts in order (install-database.sql then propagation-schema.sql then migrations/sync_qrz_lotw_fixes.sql then migrations/add_name_to_lotw_credentials.sql then system_settings table from migrate-schema endpoint). - drizzle-kit pull against that DB now yields 18 tables / 284 columns / 69 indexes / 19 foreign keys / 22 check constraints. Includes dxcc_entities, states_provinces, qsl_images, storage_config, admin_audit_log, system_settings, and the four propagation tables that #194 was missing. - Regenerated baseline migration: drizzle/migrations/0000_baseline_canonical_schema.sql. Produced by drizzle-kit generate (not introspect), so it is executable as-is rather than wrapped in block comments. The old dev-DB baseline (which also contained a malformed is_valid_api_key_format check constraint) is removed. - Same bytea customType helper applied to fix the two p12 cert columns Drizzle still introspects as unknown(). - Deleted postgres-init.sql. It was the Docker-bootstrap path that diverged from canonical (5 tables vs 13, plus the dev-only api_key_usage_logs table and is_valid_api_key_format function). Local dev DBs bootstrapped from it need to be wiped and reinstalled via the in-app installer for parity. Documented in CLAUDE.md. Still deferred (next follow-up): - Switching /api/install/database and /api/install/migrate-schema to use drizzle-kit migrate. Requires a backfill so existing prod installs get __drizzle_migrations seeded with "baseline applied" rather than re-running the baseline against an already-populated schema. - Deleting install-database.sql, propagation-schema.sql, postgres-lotw-migration.sql, migrations/*.sql. Safe only after the runtime path is on drizzle-kit migrate. Verification: - npm run typecheck clean (after applying the bytea customType fix) - npm run lint baseline unchanged (this branch is stacked on cleanup/migrations and predates #190's lint cleanup) - npm run build succeeds Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
patrickrb
added a commit
that referenced
this pull request
May 11, 2026
Builds on #194. Resolves the schema-source-of-truth problem: the dev DB and the in-app installer were producing different schemas, and #194's introspect ran against the dev DB (subset). This PR locks in the in-app installer (install-database.sql + propagation-schema.sql + migrations) as canonical and regenerates schema.ts against that. What changed: - Built a temporary nextlog_canonical Postgres database, applied the canonical install scripts in order (install-database.sql then propagation-schema.sql then migrations/sync_qrz_lotw_fixes.sql then migrations/add_name_to_lotw_credentials.sql then system_settings table from migrate-schema endpoint). - drizzle-kit pull against that DB now yields 18 tables / 284 columns / 69 indexes / 19 foreign keys / 22 check constraints. Includes dxcc_entities, states_provinces, qsl_images, storage_config, admin_audit_log, system_settings, and the four propagation tables that #194 was missing. - Regenerated baseline migration: drizzle/migrations/0000_baseline_canonical_schema.sql. Produced by drizzle-kit generate (not introspect), so it is executable as-is rather than wrapped in block comments. The old dev-DB baseline (which also contained a malformed is_valid_api_key_format check constraint) is removed. - Same bytea customType helper applied to fix the two p12 cert columns Drizzle still introspects as unknown(). - Deleted postgres-init.sql. It was the Docker-bootstrap path that diverged from canonical (5 tables vs 13, plus the dev-only api_key_usage_logs table and is_valid_api_key_format function). Local dev DBs bootstrapped from it need to be wiped and reinstalled via the in-app installer for parity. Documented in CLAUDE.md. Still deferred (next follow-up): - Switching /api/install/database and /api/install/migrate-schema to use drizzle-kit migrate. Requires a backfill so existing prod installs get __drizzle_migrations seeded with "baseline applied" rather than re-running the baseline against an already-populated schema. - Deleting install-database.sql, propagation-schema.sql, postgres-lotw-migration.sql, migrations/*.sql. Safe only after the runtime path is on drizzle-kit migrate. Verification: - npm run typecheck clean (after applying the bytea customType fix) - npm run lint baseline unchanged (this branch is stacked on cleanup/migrations and predates #190's lint cleanup) - npm run build succeeds Co-authored-by: Claude Opus 4.7 (1M context) <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
Starting state: 52 warnings. End state: 0 errors, 0 warnings.
Mix of substantive fixes and one documented rule downgrade — not a blanket suppression sweep.
Substantive fixes (19 warnings)
Hoisting / stale-closure (17) — wrapped fetcher functions in
useCallbackand moved their declarations above theuseEffects that call them, adding proper dep arrays. This is the canonical React fix for the stale-closure risk the React-19 compiler is warning about. Affected pages:adif,admin/storage,admin/users,awards/dxcc,awards/was,new-contact,stations/[id]/edit,stations/new,stations,stats,search.Memoization warning (1) —
search/page.tsx'sdebouncedSearchwas caught byreact-hooks/preserve-manual-memoizationbecause it depended onsearchTimeoutstate and calledsetSearchTimeout, recreating itself on every tick. Swapped the state for auseRefso the callback identity is stable. This is the compiler-recommended pattern for timer state.Unused eslint-disable in
storage.ts(1) — the disable comments suppressedno-unused-varsfor parameters that already had a_prefix. AddedargsIgnorePattern: "^_"to the project ESLint config (standard JS/TS convention for "intentionally unused"), then dropped the now-redundant disables.Documented rule downgrade (33 warnings)
react-hooks/set-state-in-effectis now off. All 33 hits fired on the standard "fetch data on mount → setState with the result" pattern. Per-line suppression would add 33 comments across the codebase — noisier than the warning itself. The config carries a comment explaining the decision and the path to re-enable: adopt SWR or TanStack Query, which obviates the pattern.This is the only rule I downgraded.
react-hooks/immutabilityandreact-hooks/preserve-manual-memoizationstay on (the substantive fixes above satisfied them).Notes for review
tests/database-integration.spec.tsas PRs chore(api): standardize JSON field casing on snake_case + add CLAUDE.md #188 and chore(logging): strip debug console.log noise + enforce no-console lint rule #189, so this branch'stsc --noEmitis clean independent of merge order. Will resolve as the same line when those land.Test plan
npm run lint→ 0 errors, 0 warningsnpx tsc --noEmit→ cleannpm run build→ succeeds/search, type a callsign, confirm debounced search still fires/statsand/awards/dxcc— confirm data loads (these touched useCallback wrapping)/stations/[id]/edit— confirm all dropdowns (DXCC, states, certificates) still load🤖 Generated with Claude Code