Priority: High · Area: CI / type safety · Est. effort: 6–10 h
📌 Problem
.github/workflows/ci.yml runs npm ci, npm run lint, npm run build, npm run test. That is a real pipeline — but it has a specific blind spot.
npm run build is next build, which type-checks only the modules reachable from the application's build graph. Test files are not in that graph. package.json defines no typecheck script, so tsc --noEmit never runs against the whole project.
The result: npx tsc --noEmit reports 9 errors, all in test files, and CI is green.
src/components/SettlementTable.test.tsx 5 errors
src/components/MetricsBar.test.tsx 4 errors
Both are TS2345 — arguments not assignable to the expected parameter type. These are not cosmetic: they mean the tests are passing values that do not match the real contracts they claim to exercise, which is tracked as its own issue for each file.
🎯 Design decision required
State and defend:
- Fix-then-gate, or gate-then-fix? With only 9 errors in 2 files, clearing them and adding the gate in one PR is realistic. If you disagree, argue for the ratchet.
- Scope of the gate. Should
tsc --noEmit cover test files, or should tests be excluded from the project's type-checking? Excluding them is a real option some projects choose — but argue it honestly, because these 9 errors are exactly the kind of defect exclusion would hide.
- Relationship to
next build. Should the gate be a separate typecheck step, or is a tsconfig change enough to make next build cover everything? Say which and why.
🧩 Requirements and context
- Fixing the 9 errors properly is in scope. They point at real mismatches between test doubles and production contracts.
MetricsBar.test.tsx and SettlementTable.test.tsx each have a dedicated issue in this repo describing the specific defect — coordinate, and if those land first, this issue is just the gate.
- Do not add
@ts-ignore/@ts-expect-error or a tsconfig exclusion to reach zero. That would hide precisely what the gate exists to reveal.
- Add a
typecheck script and wire it into CI as a step distinct from build, so a type failure is distinguishable from a bundling failure.
- All 59 test files must still pass.
🛠️ Suggested execution
- Run
npx tsc --noEmit and paste all 9 errors.
- Fix them, or confirm the per-file issues have landed.
- Add the
typecheck script and the CI step.
- Prove it fires — introduce a deliberate type error in a test file on a scratch branch, show the failing run, revert.
- Confirm the full suite passes.
✅ Acceptance criteria
🚫 Out of scope
- Coverage enforcement — separate issue.
- Adding accessibility or e2e tests — separate issues.
- Refactoring components.
🧪 Verification
npm ci
npx tsc --noEmit
npm run lint
npm run build
npm test
📤 What your PR must include
- The 9 errors, before.
- Your fix-vs-gate sequencing and test-file scope decisions.
- A link to a run failing on a test-file type error.
- Confirmation the full suite passes.
Closes #<n>.
🔒 Security notes
The gap is not the nine errors — it is that a whole category of code is outside type-checking while CI reports green. Test files are where mocks assert what production contracts look like; a type error there means the tests and the application disagree about a shape, and the tests still pass. That is how a component can be thoroughly "tested" against an interface it never actually receives.
📋 Guidelines
- Minimum 95% test coverage on changed lines
- Clear documentation
- Timeframe: 96 hours from assignment
- One logical change per commit; no merge commits
💬 Join our community
Working on this, or want to sanity-check your approach before you start? Come and ask — the maintainers are there and happy to help.
Telegram: https://t.me/Grainlify
Priority: High · Area: CI / type safety · Est. effort: 6–10 h
📌 Problem
.github/workflows/ci.ymlrunsnpm ci,npm run lint,npm run build,npm run test. That is a real pipeline — but it has a specific blind spot.npm run buildisnext build, which type-checks only the modules reachable from the application's build graph. Test files are not in that graph.package.jsondefines notypecheckscript, sotsc --noEmitnever runs against the whole project.The result:
npx tsc --noEmitreports 9 errors, all in test files, and CI is green.Both are
TS2345— arguments not assignable to the expected parameter type. These are not cosmetic: they mean the tests are passing values that do not match the real contracts they claim to exercise, which is tracked as its own issue for each file.🎯 Design decision required
State and defend:
tsc --noEmitcover test files, or should tests be excluded from the project's type-checking? Excluding them is a real option some projects choose — but argue it honestly, because these 9 errors are exactly the kind of defect exclusion would hide.next build. Should the gate be a separatetypecheckstep, or is atsconfigchange enough to makenext buildcover everything? Say which and why.🧩 Requirements and context
MetricsBar.test.tsxandSettlementTable.test.tsxeach have a dedicated issue in this repo describing the specific defect — coordinate, and if those land first, this issue is just the gate.@ts-ignore/@ts-expect-erroror a tsconfig exclusion to reach zero. That would hide precisely what the gate exists to reveal.typecheckscript and wire it into CI as a step distinct frombuild, so a type failure is distinguishable from a bundling failure.🛠️ Suggested execution
npx tsc --noEmitand paste all 9 errors.typecheckscript and the CI step.✅ Acceptance criteria
npx tsc --noEmitexits 0.typecheckscript exists and runs in CI as a step separate frombuild.next buildmisses (link the run).@ts-ignore,@ts-expect-erroror tsconfig exclusion was added.🚫 Out of scope
🧪 Verification
npm ci npx tsc --noEmit npm run lint npm run build npm test📤 What your PR must include
Closes #<n>.🔒 Security notes
The gap is not the nine errors — it is that a whole category of code is outside type-checking while CI reports green. Test files are where mocks assert what production contracts look like; a type error there means the tests and the application disagree about a shape, and the tests still pass. That is how a component can be thoroughly "tested" against an interface it never actually receives.
📋 Guidelines
💬 Join our community
Working on this, or want to sanity-check your approach before you start? Come and ask — the maintainers are there and happy to help.
Telegram: https://t.me/Grainlify