chore(ts-migration): make the tsconfig root set authoritative

Phase 12 prerequisite. `exclude` still carried `src/components/ui`,
`src/api` and `src/lib` from `jsconfig.json`; each was meant to come off
as its tree was converted, in Phases 4, 5 and 6, and all three were
missed.

The miss was quiet by construction. Excluding a file only keeps it out of
the ROOT set — anything an included file imports is pulled in anyway — so
318 of 321 files were being checked regardless, and the omission cost
nothing visible. The three that were not checked are the ones nothing
under `src` imports: `api/seed.ts`, `api/attendanceSeed.ts` and
`lib/skills/positionFlow.ts`. They are not dead code. `scripts/` loads
them, `seed.ts` from six separate places, and they held four real errors
that no previous count in this migration has included.

All four were one cause. `MODULE_TABLE` is 36 rows of mixed literals, so
it infers as an array of the UNION of its column types and destructuring
a row gives every field `string | number | string[]` —
`SKILL_CATEGORY[skill_id]` then refuses a key that might be an array. It
is now written as the tuple it is. The migration plan predicted this
class of error for three other tables by name.

Doing this before the ratchet rather than after: a strictness flag
measured against an incomplete root set produces a number that grows
again later for reasons unrelated to the flag, and the whole method here
is that each step's error count means one thing.

  root set    321 files, was 318
  typecheck   0 errors, with every file in src now checked
  lint        exit 0
  npm test    1684/1691, the same 7 failures
  build       exit 0, identical bundle hash 74d17e2d…
  seed.ts     emitted JS identical

`allowJs`, `checkJs` and `jsconfig.json` are deliberately left alone —
they come off at final cleanup, after strictness.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBG1wnuRfJKCstGB8Fekr8
This commit is contained in:
2026-09-18 16:54:27 +05:30
parent 78f1b44c2e
commit 21133a6064
2 changed files with 25 additions and 10 deletions

View File

@@ -1222,7 +1222,17 @@ const COURSES = [
* what Owliver checks. `required_level` is the rung below, which is what makes
* the ladder a ladder rather than a menu.
*/
const MODULE_TABLE = [
/**
* One training module per row: skill, rung, title, minutes, challenge type,
* description, and the criteria it is marked against.
*
* Written out as a tuple because a bare array of mixed literals infers as an
* array of the UNION of its column types, so destructuring a row below gives
* every field `string | number | string[]` — and `SKILL_CATEGORY[skill_id]`
* then refuses a key that might be an array. The tuple says which column is
* which, which is what the reader already assumes.
*/
const MODULE_TABLE: [string, string, string, number, string, string, string[]][] = [
/* Server — the full four-rung ladder. */
['server', 'beginner', 'Server Fundamentals', 18, 'roleplay', 'Sequence of service, tray discipline, and the first ninety seconds at a table.', ['Greets and sets expectations', 'Follows the service sequence', 'Handles the tray safely']],
['server', 'beginner', 'Workplace Safety', 14, 'photo_identify', 'Spot the hazard before it becomes an incident — spills, traffic, hot pass.', ['Identifies floor hazards', 'Spots obstruction risks', 'Knows when to stop service']],

View File

@@ -71,14 +71,19 @@
"include": ["src/**/*"],
/* Unchanged from jsconfig, and temporary. These three trees hold the densest
logic in the app — the transport layer, every hook, and the vendored UI
primitives — and none of it has ever been checked. Each exclusion is
removed by the phase that converts the tree behind it, so the error count
rises deliberately and in one identifiable place at a time.
/* `src/components/ui`, `src/api` and `src/lib` used to be listed here, from
jsconfig, and each was meant to come off as its tree was converted. They
were missed, and the miss was quiet by construction: excluding a file only
keeps it out of the ROOT set, and anything an included file imports is
pulled in anyway, so 318 of the 321 files were being checked regardless.
Note that excluding a file only keeps it out of the root set: one that an
included file imports is still checked, which is why errors from `src/api`
and `src/lib` already show up today. */
"exclude": ["node_modules", "dist", "src/components/ui", "src/api", "src/lib"]
The three that were not are the ones nothing under `src` imports —
`api/seed.ts`, `api/attendanceSeed.ts` and `lib/skills/positionFlow.ts`.
They are not dead: `scripts/` loads them, `seed.ts` from six places. They
were simply invisible to `tsc`, and held four real errors.
Removed before the strictness ratchet rather than after, because a flag
measured against an incomplete root set gives a number that grows again
later for reasons that have nothing to do with the flag. */
"exclude": ["node_modules", "dist"]
}