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']],