Commit Graph

6 Commits

Author SHA1 Message Date
null 8075b4e1e1 docs: close QA-B0-04 (@ts-nocheck 38->8) in QA plan + CODE_STANDARDS
Cycle Log row 3·typecheck; B0 counter steady state now <=8 with a
regression guard; CODE_STANDARDS records that all routes/server.cts are
checked and the 8 intentional exceptions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 07:20:13 -05:00
null 68ca7cbb43 feat(standards): enforcement ratchets — error-shape + no-console; client toApiError
- eslint: no-console error on all server dirs (sanctioned exceptions:
  utils/logger.cts sink, utils/env.cts bootstrap, utils/apiError.cts
  fallback); no-restricted-imports bans errorFormatter in routes/** so
  hand-rolled standardizeError bodies can't return (transactions/import
  are the two documented exception files)
- client/api.ts: 6 copy-pasted ApiError constructions collapsed into one
  toApiError() helper
- CODE_STANDARDS.md: 'Error responses' and 'Logging' flipped target ->
  ENFORCED, with the full documented-exceptions list and the client
  error-shape/mutation-pattern conventions written down

Lint 0 errors, client 52/52, typecheck clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 17:20:42 -05:00
null 35a0e4262e feat(db): Kysely typed-SQL POC — sync builder, proven parity (Pillar E)
De-risks the flagship. The app is synchronous (better-sqlite3) but Kysely
executes async, so db/kysely.cts uses Kysely as a TYPE-SAFE BUILDER only:
build the query (columns + user_id/deleted_at scoping + types checked at
compile time), `.compile()`, then run via sync helpers (all/get/run) on the
shared connection. No async ripple, no change to the sync model.

- Schema typed for `categories` (extend as adopted).
- tests/kyselyPoc.test.js proves byte-identical rows vs the raw SQL and
  that compiled SQL is parameterized (injection-safe).
- Pattern documented in CODE_STANDARDS; adopt for new/refactored queries;
  it type-enforces user-scoping (the biggest data-isolation win) and
  removes Row=any at the call site.

typecheck:server + check:server clean; 248/248 server tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 16:23:50 -05:00
null b4634a8080 feat(logging): redacted, level-gated logger; migrate all server console.* (Pillar D)
utils/logger.cts — console-compatible log.{debug,info,warn,error} with:
- level gating (LOG_LEVEL; debug in dev / info in prod), and
- REDACTION of secrets/PII (sensitive keys + bearer/JWT) so tokens,
  passwords, and encrypted values never reach the logs (financial app).
Backend is abstracted (console now, swappable to pino later).

Swept all 317 server-runtime console.* across 35 files → log.* + inserted
the import at correct scope. tests/logger.test.js pins the redaction
contract (4 tests). CODE_STANDARDS updated; raw console.* is now banned in
server code.

Verified: check:server + typecheck:server + lint clean; 240/240 server
tests; client 50/50; build; e2e probe 17/17; boot smoke logs flow through
the logger and graceful shutdown intact.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 16:05:18 -05:00
null a75ff1a466 refactor(routes): monthly-starting-amounts → throw pattern; doc exemplar
5 ad-hoc {error} validations → throw ValidationError(msg, field) (adds
proper code + field). CODE_STANDARDS references routes/categories.cts as
the canonical error-pattern example and notes converted/unconverted routes
emit identical output (terminal handler normalizes both). 236/236.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 15:03:52 -05:00
null 88674fa2f5 docs(standards): add CODE_STANDARDS.md + CONTRIBUTING.md
The living rulebook (formatting, modules, API/wire + error contract,
security, logging, data integrity, testing) so conventions are codified
and persist. CONTRIBUTING points at it and the CI gate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 14:28:05 -05:00