Skip to content

Commit adc1dee

Browse files
Yerazeclaude
andcommitted
ci(types): type-check test files via tsconfig.tests.json (non-blocking) (#3962 task 1.2)
283 pre-existing mock/signature-drift errors baselined; flip the CI steps to blocking when the count reaches 0. Full strict kept (see epic doc for why noImplicitAny stays on and tests/ dir is excluded). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AphLfgUJWaFNAgU5UXdJ4n
1 parent 64081b6 commit adc1dee

5 files changed

Lines changed: 47 additions & 6 deletions

File tree

.github/workflows/ci.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ jobs:
7676
- name: Run type checking
7777
run: npm run typecheck
7878

79+
- name: Type-check tests (non-blocking)
80+
if: matrix.node-version == '24.x'
81+
run: npm run typecheck:tests
82+
# NON-BLOCKING: ~283 pre-existing test-type errors (mock/signature drift).
83+
# Flip to blocking (remove continue-on-error) once `npm run typecheck:tests` is clean (0 errors).
84+
# Tracking: remediation epic #3962 Task 1.2.
85+
continue-on-error: true
86+
7987
- name: Run tests
8088
run: npm run test:run
8189

.github/workflows/pr-tests.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ jobs:
9090
echo "Running TypeScript compiler..."
9191
npm run typecheck
9292
93+
- name: Type-check tests (non-blocking)
94+
run: npm run typecheck:tests
95+
# NON-BLOCKING: ~283 pre-existing test-type errors. Flip to blocking (drop continue-on-error)
96+
# when `npm run typecheck:tests` reports 0. Tracking: #3962 Task 1.2.
97+
continue-on-error: true
98+
9399
- name: Run unit tests
94100
run: |
95101
echo "Running test suite..."

docs/internal/dev-notes/REMEDIATION_EPIC.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ Each unchecked phase = one worktree → architect spec → implementation → re
1616

1717
- [x] **P0-docs** — Merge `docs/remediation-plan` (REMEDIATION_PLAN.md + this file) to main.
1818
- [x] **0.1** — Process-level safety net: `unhandledRejection`/`uncaughtException` handlers in `server.ts`, logging with full context and routing through `gracefulShutdown()`. Exit: deliberate `Promise.reject()` in dev logs and shuts down gracefully.
19-
- [ ] **0.2** — Trust-proxy default → `false` when `TRUST_PROXY` unset; keep startup warning; release-notes/README documentation for proxied deployments.
20-
- [ ] **0.3** — Pin `meshcore.js` fork dependency to a commit SHA; lockfile regenerated; `npm ci` reproducible.
21-
- [ ] **0.4** — Strip/gate the hot-path `console.log`s in `src/services/api.ts` (CSRF token status + token prefix on every mutation); kept diagnostics behind a debug flag.
22-
- [ ] **0.5**`@typescript-eslint/no-floating-promises` as `error` for non-test code; violations fixed or explicitly `void`/`.catch()`ed.
23-
- [ ] **1.1**`withSourceScope` fails closed: omitting `sourceId` throws; explicit `ALL_SOURCES` sentinel for the documented global-by-design consumers (channel decryption, estimated positions, automations); full call-site audit.
24-
- [ ] **1.2** — Type-check the tests: `tsconfig.tests.json` (strict, `noImplicitAny` off initially), wired into CI non-blocking first; flip to blocking once clean.
19+
- [x] **0.2** — Trust-proxy default → `false` when `TRUST_PROXY` unset; keep startup warning; release-notes/README documentation for proxied deployments.
20+
- [x] **0.3** — Pin `meshcore.js` fork dependency to a commit SHA; lockfile regenerated; `npm ci` reproducible.
21+
- [x] **0.4** — Strip/gate the hot-path `console.log`s in `src/services/api.ts` (CSRF token status + token prefix on every mutation); kept diagnostics behind a debug flag.
22+
- [x] **0.5**`@typescript-eslint/no-floating-promises` as `error` for non-test code; violations fixed or explicitly `void`/`.catch()`ed.
23+
- [x] **1.1**`withSourceScope` fails closed: omitting `sourceId` throws; explicit `ALL_SOURCES` sentinel for the documented global-by-design consumers (channel decryption, estimated positions, automations); full call-site audit.
24+
- [x] **1.2** — Type-check the tests: `tsconfig.tests.json` (full strict — see phase log deviation), wired into CI non-blocking first; flip to blocking once clean.
2525
- [ ] **1.3** — Integration-grade route-test harness: in-memory SQLite + real Express app with real `requirePermission`/session/auth wiring; 3–5 representative route test files converted (source-scoped permission coverage); no mass conversion.
2626
- [ ] **1.4** — Lint ratchets: `no-explicit-any``error` with checked-in baseline; forbid raw `fetch(` in `src/components/**`/`src/pages/**` (baselined); `react-hooks/exhaustive-deps` + `prefer-const``error`.
2727
- [ ] **1.5** — Response-envelope convention: `ok(res, data)` / `fail(res, status, code, msg)` helper for the `{ success, error, code }` envelope; documented in CLAUDE.md; new/modified handlers must use it.
@@ -39,3 +39,10 @@ Record per-phase: PR link, deviations from plan, follow-ups.
3939

4040
- **P0-docs** — PR #3966 merged (plan + epic doc on main). No deviations.
4141
- **0.1** — PR #3967 merged (processSafetyNet.ts + idempotent gracefulShutdown with exitCode param). Deviation: NodeJS.* type annotations replaced with inference/unknown due to ESLint no-undef.
42+
- **0.2** — PR #3968 merged (trust-proxy default → false + docs/CHANGELOG BREAKING entry). No deviations.
43+
- **0.3** — PR #3969 merged (SHA pin b98fc338, matched existing lockfile resolution). No deviations.
44+
- **0.4** — PR #3970 merged (token-prefix leak removed; diagnostics → logger.warn/debug). No guard test added (no api.test.ts exists; nothing asserted on the removed lines).
45+
- **0.5** — PR #3972 merged (418 violations: 409 `void`, 9 `.catch(logger.error)`; rule scoped to src non-test). Deviation: "npm run lint exits 0" unmet — 367 pre-existing errors in tests/-dir files; CI lint is non-blocking (continue-on-error) — make blocking in 1.4. mqttBridgeManager "deferred parent broker attach" test observed flaky in CI (passes on rerun).
46+
- **1.1** — PR #3976 merged (ALL_SOURCES unique-symbol sentinel; runtime throw + Tier-2 required params; 3 real leaks fixed: server.ts getNodeCount refresh, deleteNode→deleteNeighborInfoInvolvingNode, meshtasticManager pending-DM fetch). Review-loop correction: implementer's repo-body `?? ALL_SOURCES` normalization (silent fail-open) reverted; explicit per-call-site decisions instead. CI: Quick Tests outgrew its 15-min cap (#3385 redux) → raised to 25 min in this PR.
47+
**Follow-up findings (1.1 architect §10, epic backlog):** hand-rolled fail-open `if (sourceId)` filters bypass the helper — all of `meshcore.ts`, `notifications.ts` subscriptions, parts of `channels.ts`, `nodes.ts:getAllNodesSqlite`; legacy `*Sync`/`*Sqlite` twins partially covered (Phase 3.4 deletes them); facade `getNode(nodeNum)` single-source-assumption chain (revisit with Phase 2).
48+
- **1.2** — PR TBD (tsconfig.tests.json + `typecheck:tests` script + non-blocking CI steps in ci.yml/pr-tests.yml). Deviations: (a) kept FULL strict incl. noImplicitAny — plan's "noImplicitAny off" injects ~50 false-positive errors into prod src via evolving-any inference; (b) top-level `tests/` dir NOT included — its files pull @types/node into the program and poison frontend inference (~60 spurious errors). Baseline: 283 errors, all in src test files, 0 prod. Flip-to-blocking when count reaches 0 (burndown is a follow-up; top ~8 files hold ~150 errors).

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"preview": "vite preview",
1616
"lint": "eslint .",
1717
"typecheck": "tsc --noEmit",
18+
"typecheck:tests": "tsc -p tsconfig.tests.json --noEmit",
1819
"test": "vitest",
1920
"test:ui": "vitest --ui",
2021
"test:run": "vitest run",

tsconfig.tests.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
// Type-checks the Vitest test files alongside the production sources they
3+
// import, so mock shapes can't silently drift from real signatures
4+
// (remediation epic #3962, Task 1.2). Run via `npm run typecheck:tests`.
5+
//
6+
// NOTE: deliberately does NOT include the top-level `tests/` directory —
7+
// adding those files pulls @types/node into the whole program and changes
8+
// inference inside production frontend files (~60 spurious implicit-any
9+
// errors in src/components). If `tests/` should ever be type-checked, give
10+
// it its own config with its own `types` set.
11+
"extends": "./tsconfig.json",
12+
"compilerOptions": {
13+
"noEmit": true,
14+
"noUnusedLocals": false,
15+
"noUnusedParameters": false
16+
},
17+
"include": ["src", "src/**/*.test.ts", "src/**/*.test.tsx"],
18+
"exclude": ["node_modules", "dist"]
19+
}

0 commit comments

Comments
 (0)