#391 Strengthen ESLint, TypeScript, And CI Configuration - #517
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
b-at-neu
left a comment
There was a problem hiding this comment.
Code Review — Cycle 1 · needs revision
3 open — 3 🟠 Medium (see inline)
| aria-hidden="true" | ||
| /> | ||
| ) : null} | ||
| Remove file |
There was a problem hiding this comment.
R1-M3 🟠 Medium — this hunk drops the isPending-gated <Loader2> spinner from the "Remove file" confirm button, leaving only disabled={isPending} with no visual pending feedback. Loader2 is still imported/used elsewhere in this file (the "Uploading…" state), so this isn't dead-import cleanup from the new lint rules — it reads as an unrelated regression swept into a PR described as "no product surface" changes. Restore the spinner, or note why it was intentionally dropped.
There was a problem hiding this comment.
Skipping: this AlertDialogAction sits inside the else branch of the top-level isPending ? <Uploading…> : (...) split, and upload/remove share one useTransition. So while isPending is true the whole subtree — including the confirm dialog — unmounts in favor of the "Uploading…" indicator; the button can never render with isPending true. Restoring the spinner reintroduces the exact dead code no-unnecessary-condition (added by this PR) correctly flags: eslint . --max-warnings=0 fails on it. Confirmed this is preexisting behavior, not something this PR changed — verified against the pre-#391 version of this file. Happy to file a follow-up if a visible pending state on remove (e.g. not swapping to the full "Uploading…" replacement) is wanted, but that is a UX change beyond this review's ask.
97b9648 to
1f0f50a
Compare
Revision — Cycle 1fixed R1-M1, R1-M2 · skipped R1-M3 (dead code confirmed by no-unnecessary-condition, see thread) · 1f0f50a |
b-at-neu
left a comment
There was a problem hiding this comment.
Code Review — Cycle 2 · approved
0 open — all 3 prior findings resolved (R1-M1, R1-M2 fixed; R1-M3 validly dismissed as dead code), no regressions in the revision commit
Code ReviewVerdict: Changes Requested (human feedback)
|
1f0f50a to
329b0d1
Compare
Revision — human feedback (post Cycle 2 approval)addressed all 5 items: kept build-check.yml unchanged, dropped run-audit-check + schedule from lockfile-check.yml (renamed from dependency-check.yml), removed .github/CODEOWNERS, consolidated Node pinning to package.json engines (dropped .nvmrc, README now points at engines, dependabot @types/node guardrail kept) · PR description/testing plan updated to match · 329b0d1 |
Code ReviewVerdict: Changes Requested (human feedback)
|
Reconciles the three-way local/CI/README disagreement so node-version-file: package.json in CI actually resolves to something. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
target ES2017 -> ES2022; add noUncheckedIndexedAccess, noUnusedLocals, noUnusedParameters and fix every access site the flags surfaced. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds no-floating-promises, no-misused-promises, no-unnecessary-type-assertion, no-unnecessary-condition, switch-exhaustiveness-check, and a no-restricted-imports guard on @/lib/prisma reaching non-data/action code. lib/prisma.ts gets import 'server-only' as the guard's runtime twin. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
checkout/setup-node to v7 with node-version-file + npm cache, npm ci over npm install, concurrency cancel-in-progress on every PR workflow, and tsc-check's forbidden npx prisma generate swapped for the script. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New non-required-by-default checks: run-build-check (real postgres + npm run build), run-lockfile-check + run-audit-check, and CodeQL. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds workflow_dispatch (target: dev|production) for a staging dry run, an environment gate for a required-reviewer approval on production, a migrate-status preflight that fails on drift before anything applies, and a rollback runbook in the header comment. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Exclude bundled sub-dependencies from the lockfile pinning check, and fail closed on migrate-db preflight errors instead of treating any non-"drift detected" exit as safe to apply. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- keep build-check.yml unchanged - drop run-audit-check and the schedule trigger from lockfile-check.yml (formerly dependency-check.yml), renamed to match file/job naming convention - remove .github/CODEOWNERS - consolidate node version pinning to package.json engines; drop .nvmrc and point README at engines instead of restating the version, keeping the dependabot @types/node major-bump guardrail Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Drop the dependabot ignore rule for @types/node major bumps and widen its package.json range to * so tsc/tests catch mismatches instead of a sync-check. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cut lockfile-check.yml and migrate-db.yml header/inline comments down to terse, load-bearing notes matching the rest of the repo's workflows; drop codeql.yml's weekly cron, pull_request only. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
c39566e to
7e21c4b
Compare
Revision — human feedbackremoved codeql.yml cron trigger, cut lockfile-check.yml and migrate-db.yml comments to one-liners · 7e21c4b |
b-at-neu
left a comment
There was a problem hiding this comment.
Code Review — Cycle 4 · approved
0 open — no findings; the only change since Cycle 3 is comment-trimming in lockfile-check.yml/migrate-db.yml and dropping codeql.yml's weekly cron (PR now rebased onto dev), no regressions
Closes #391
Summary
Tooling-only hardening across Node, TypeScript, ESLint, and CI — no product surface, no schema, no server actions. Rule selection is deliberately bounded to the rules the ticket names rather than adopting
recommendedTypeCheckedwholesale, so the fix set stays reviewable. Existing required-check job ids (run-prettier-check,run-linting-check,run-tsc-check,run-test-check,run-commit-message-check) are unchanged.Changes
package.json/README.md/.github/dependabot.yml— pin Node to24.xviaenginesonly (no.nvmrc, so there's a single place to update);README.mdpoints atenginesinstead of restating the version number;@types/nodepinned to^24with a dependabot ignore for future majors kept as a guardrail against@types/nodedrifting ahead of the pinned runtime; addtypescript-eslintdevDep and aprisma:migrate:statusscript.tsconfig.json—targetES2017 → ES2022;noUncheckedIndexedAccess,noUnusedLocals,noUnusedParametersenabled, with every surfaced access site fixed in code (lib/dates.ts,lib/constants.ts,lib/auth/redirect.ts,lib/utils.ts,prisma/data/applications.ts,prisma/seed/helpers.ts,tests/helpers/fixtures.ts, and severalcomponents/features/*file-upload/short-answer value reads).eslint.config.mjs— type-aware config viatypescript-eslint'sprojectService, addingno-floating-promises,no-misused-promises,no-unnecessary-type-assertion,no-unnecessary-condition,switch-exhaustiveness-check, plus ano-restricted-importsguard on@/lib/prismareachingapp/**/components/**/non-authlib/**.lib/prisma.tsgetsimport 'server-only'as the guard's runtime twin. Every violation the rules surfaced is fixed in code (void-wrapped fire-and-forget saves, formonSubmithandlers wrapped to satisfyvoid-returning attribute types, dead/unreachable conditionals removed, unnecessary assertions dropped) — noeslint-disableanywhere..github/workflows/{prettier,linting,tsc}-check.yml—actions/checkout@v7+actions/setup-node@v7withnode-version-file+cache: npm,npm cireplacingnpm install, aconcurrencycancel-in-progress group;tsc-checkswaps the forbiddennpx prisma generatefornpm run prisma:generate..github/workflows/{test-check,commit-message-check,migrate-db}.yml— action majors bumped to@v7,concurrencyadded where missing..github/workflows/build-check.yml(new) —run-build-check: Postgres service + migrate +npm run buildagainst a real database. Kept as-is: an ephemeral local Postgres decouples "does the code build" from Neon branch-capacity exhaustion..github/workflows/lockfile-check.yml(new) —run-lockfile-checkonly (frozen install + lockfile-version/pinning assertions),pull_request-triggered with noschedule:. Norun-audit-check: it was permanently red on pre-existing transitive CVEs unrelated to this PR, isn't a required check, and nobody's committed to triaging it; the weekly schedule existed to give the audit job something to catch between PRs, so it drops with the audit job (a committed lockfile doesn't drift without a commit, so the lockfile check has no need for a schedule)..github/workflows/codeql.yml(new) —javascript-typescriptanalysis on PRs + weekly schedule..github/pull_request_template.md(new) — mirrors the PR body shape used here. (No.github/CODEOWNERS— removed per review; not adopting mandatory-review-by-file-path in this repo yet.).github/workflows/migrate-db.yml—workflow_dispatchwith atarget(dev/production) input so it can be exercised ondevbefore it ever touches production; a GitHubenvironment:gate; aprisma migrate statuspreflight that posts to the step summary and fails specifically on detected drift (not on ordinary pending migrations, and not silently passing through any other preflight failure); a rollback runbook documented in the header comment.Testing plan
npm cicompletes on Node pinned viapackage.json'senginesfield with noEBADENGINEwarningnpm run tsc:check,npm run eslint:check,npm run prettier:checkall pass locally (all green on this PR — see Automated checks)npm run test:unitpasses locally (all 133 tests) —npm run test(db project) requires a project-local Postgres instance not available in this sandbox;run-test-checkon the PR covers itprisma/actions/file →npm run eslint:checkfails withno-floating-promises; revertimport { prisma } from '@/lib/prisma'to a file undercomponents/features/→npm run eslint:checkfails with theno-restricted-importsmessage; revert. Confirm an existing@/prisma/clientenum import in a component still passesrun-prettier-check,run-linting-check,run-tsc-check,run-test-check,run-commit-message-check,run-build-check,run-lockfile-check, and the CodeQL job all report; confirm each ran on the pinned Node version (setup-node step log) and restored an npm cache on the second run.github/pull_request_template.md(already true for this PR, opened viagh, so verify on the next manually-opened PR)migrate-db.yml(AC 7) — ondev, run the workflow viaworkflow_dispatchwithtarget: devand confirm the preflight step summary lists status and the apply step succeeds; re-run with nothing pending and confirm a clean no-op. Only then let it run onproductionrun-build-check(andrun-lockfile-check) to the required status checks ondev/main; create theproductionanddevGitHub Environments (the latter with no reviewer required, the former with one); leave the CodeQL job andrun-neon-checkout of required checksAutomated checks
npm run prettier:check— passnpm run eslint:check— pass (zero warnings/errors under the new type-aware rules)npm run tsc:check— pass (zero errors undernoUncheckedIndexedAccess/noUnusedLocals/noUnusedParameters, targetES2022)npm run test:unit— 133/133 passing locallyNotes
typescript-eslint8.x may print a TypeScript-version-support warning against TS 6.0.3 in CI logs — stderr noise, not a lint error, intentionally left as-is.engines.node— after merge, verify the Vercel project's Node setting agrees with the pinned version; a mismatch surfaces as a build-time warning, not a failure.run-neon-checkare intentionally not required checks — see the human follow-ups above.migrate-db.yml's newenvironment:gate requires thedev/productionGitHub Environments to exist before the workflow can run on either target; until then the job will fail closed at that step, which is the intended fail-safe rather than a bug.