The fixture generator was a version behind the seeder, and the gap was
the `users` key.
`internal/seeder` unmarshals `seed.json` into `{demoUser, users,
entities}` and writes every account in `users`, falling back to
`demoUser` alone when the key is absent. `fixtureFrom` never emitted it —
its comment still claimed the Go loader "ignores the rest", which stopped
being true when the seeder gained the field. So `npm run seed:check`
reported stale on every run, and that is the seventh suite failure, the
one that pre-dates the TypeScript migration.
What made this worth investigating rather than regenerating: the
committed fixture was NOT wrong. It carries two accounts — the demo
administrator and `employer@krow.app` — and running `npm run seed:fixture`
against the old generator would have written a fixture without them.
`krow-backend/docs/deploy-9d3192a.md` says so in as many words, and tells
anyone deploying not to run it.
The accounts are not deleted from a live database by that — the only
DELETE in the seeder is the shift-record prune, and `upsertUser`'s ON
CONFLICT deliberately leaves `password_hash` alone. The damage lands on
the next fresh environment, where `user_employer` would simply never be
created, leaving nobody to sign in as to reach the employer console —
which is the exact gap `seeder.go` records the account as having been
added to close.
The matching frontend half already existed, unmerged, on
`feat/krow-employee-pages` (7a4b61d). That branch is a 53-file console
restructure that renames the same files this migration renamed, so it is
not mergeable here. Only the three files that carry the contract are
taken: `EMPLOYER_USER`, `seedData.User` naming both accounts, and the
generator emitting `users`.
The proof is that nothing had to be written. With the generator corrected
its output is byte-identical to the fixture already committed in
krow-backend — 168,293 bytes, `cmp` clean — so `seed.json` was never
opened for writing, and its md5 and mtime are untouched.
typecheck 0 errors
seed:check "seed.json is in step with src/api/seed.js", exit 0
npm test 1685/1691, up from 1684 — the fixture check now reads
"24 applications, byte-identical". The remaining 6 are
exactly the documented dca1842 baseline failures.
lint exit 0, 0 errors, 289 warnings
build exit 0, bundle 74d17e2d… unchanged
The bundle being unchanged is itself a check: `demoUser.ts` IS in the
production bundle, and `EMPLOYER_USER` is a new export of it. Nothing in
the app imports it, so it is tree-shaken out and not one byte reaches the
shipped code.
No baseline artifact touched. krow-backend not modified.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBG1wnuRfJKCstGB8Fekr8
Phases 0-3 of the JS/JSX -> TS/TSX migration. No runtime behaviour changes:
every converted file emits byte-identical JavaScript, verified file by file.
Phase 0 - harness hardening, before any rename:
- scripts/ssr-resolve.mjs wraps `ssrLoadModule` so the ~170 literal module
paths in the check scripts resolve .js/.jsx/.ts/.tsx. Without it the first
rename would have silently destroyed the 1642-check suite that guards the
Owliver flow.
- eslint.config.js gains a TypeScript block. Its `files` globs listed only
{js,mjs,cjs,jsx}, so a renamed file would have dropped out of the run while
`eslint .` went on exiting 0 - the quietest failure mode available.
- MIGRATION_BASELINE.md records the measured starting point, including the
pre-existing seed-fixture failure and the already-broken standalone
owliver-baseline.mjs, so neither is later mistaken for migration damage.
Phase 1 - tsconfig.json succeeds jsconfig.json, carrying every option across at
its old value. `types` moves from [] to ["vite/client"], which fixes the eight
import.meta errors; @types/node is deliberately excluded so setTimeout stays a
number in browser code. allowJs and checkJs stay on, strict stays off.
Phase 2 - src/types/{api,entities,user}.ts. Transport envelope, error shape,
the entity-name union (the same 18 names are written down twice today, in
httpClient and base44Client, with nothing checking they agree), and the user
record. Every field transcribed from the API contract, the migrations and the
/me projection in me.go - not inferred. Entity record shapes are deliberately
absent: derivable, but nothing consumes them yet.
Phase 3 - nine leaf utilities renamed to .ts with annotations added only where
they could be established from existing usage. Entity records are typed `any`
with a comment naming what they are, rather than a guessed interface.
Verified: tsc 64 errors (65 before; one pre-existing TS2559 genuinely fixed,
none introduced), lint unchanged at 0 errors, skill-check 1641/1642 with only
the known failure, Owliver baseline section 59/59 green, production build
succeeds with the API origin inlined.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBG1wnuRfJKCstGB8Fekr8