Establishes the server-TypeScript foundation and migrates utils/money →
utils/money.mts with branded Cents/Dollars (mirroring the client), so the
cents↔dollars boundary — the origin of the reconciliation bug class — is a
compile error for any typed server caller.
Approach (no build step): Node 25 runs .ts natively (type-stripping).
Migrated modules use the explicit-ESM .mts extension (the project is
"type":"commonjs", which disables .ts ESM auto-detection) and are required
from the CJS callers via Node's require(esm) — verified working. Infra:
tsconfig.server.json (allowJs + checkJs:false → incremental like the
client), npm run typecheck:server, check:server extended to .mts, wired
into ci. 28 require sites repointed to money.mts.
typecheck:server clean; full server suite 225 + e2e probe 17/17 green.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
- analyticsService: only add a bill's expected_amount in months it actually
occurs (resolveDueDate), so annual / off-month quarterly bills no longer
inflate the expected-vs-actual line every month (QA-B5-03, same root as B5-01)
- add a Tracker<->Analytics reconciliation guard to e2e/api.probe.spec.js
- docs: archive QA-B5-03; cycle log
Co-Authored-By: Claude Opus 4.8 <[email protected]>