Skip to content

feat: DX ratchet — headless API-test runner, typecheck ratchet, first CI (TODO 15) - #126

Closed
lopugit wants to merge 4 commits into
mainfrom
claude/todo15-dx-ratchet-s1
Closed

feat: DX ratchet — headless API-test runner, typecheck ratchet, first CI (TODO 15)#126
lopugit wants to merge 4 commits into
mainfrom
claude/todo15-dx-ratchet-s1

Conversation

@lopugit

@lopugit lopugit commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Implements TODO 15 — 🛠️ DX ratchet: typecheck, a headless test runner, and CI.

What changes

Headless API-test runner (npm test): remix/scripts/run-api-tests.mjs runs the exact /tests-page suite definitions (apiTests.ts, 241 tests) through the exact runApiTest execution path — test == live cohesion, no parallel test framework. Zero new dependencies: Node ≥ 23 native type-stripping runs the app's TS directly; tt-alias-loader.mjs (a node:module resolve hook) handles the ~/ alias + extensionless TS relative imports; a cookie-jar fetch wrapper reproduces the browser's cookie-persisting auth chains. Supports --group=auth,health, --list, TT_TEST_BASE_URL.

Six stale expectations fixed: they predated the auth hardening — mongodb/populate expected 200/500 but is now (correctly) admin-gated 403; the quota/admin -guarded tests expected only 401 but an authenticated non-admin now gets 403; PUT-by-unknown-id 404s. Each updated expectation documents why the new status is a pass (the guard holding), not a laxening.

Typecheck ratchet (npm run typecheck:ratchet): tsc --noEmit has a known 121-error baseline (strictness lands progressively — this is the mechanism for that). The gate fails only when the count grows; when it shrinks it nags to run --update-baseline and lock in the progress. npm run typecheck remains the raw view.

Unit-test aggregate (npm run test:unit) over the four existing node --test suites — and registering the alias loader there fixes test:editorjs, which was entirely broken (failed at module resolution on an extensionless ./inlineHtmlText import before any test ran). 87/87 unit tests now pass.

CI (.github/workflows/ci.yml, the repo's first): two jobs — (1) build:client + typecheck ratchet + unit tests; (2) the full API suite against a real booted dev stack with a mongo:7 service container, with dev-stack logs dumped on failure.

Verification (local)

  • npm test against a worktree dev stack: 241/241 in 4.2s (parity caveat: the 6 previously-failing tests fail identically in a browser run with the same auth state — they were auth-state-dependent, now they pass in both).
  • npm run test:unit: 87/87 (includes the 12 resurrected editorjs tests).
  • npm run typecheck:ratchet: at baseline (121).
  • pnpm run build:client: clean.
  • The CI workflow itself can't be executed locally — first real run happens on this PR; the API-tests job mirrors the exact command sequence verified locally.

Left for follow-ups (as TODO 15 contemplates): progressively enabling noImplicitAny, unifying the two drifted ThingtimeTypes interfaces, finishing the Commander V1→V2 migration.

Session 1 of the parallel todo batch — claimed in TODO/SESSION-CLAIMS.md.

🤖 Generated with Claude Code

TODO item 15. The 241-test API suite only ran via the interactive /tests
page, tsc had no gate at all, and there was no CI.

- scripts/run-api-tests.mjs: runs the exact /tests suite definitions through
  the exact runApiTest execution path headlessly (test == live cohesion).
  Zero new dependencies: Node >= 23 strips TS types natively;
  scripts/tt-alias-loader.mjs resolves the `~/` alias + extensionless TS
  relative imports; a cookie-jar fetch wrapper reproduces the browser's
  cookie-persisting auth chains. `npm test`, with --group=<g,g> and --list.
- Six test expectations were stale from before the auth hardening (expecting
  401/200 where admin-gated endpoints now correctly 403, and PUT-by-id 404):
  updated to accept the hardened responses with the reason commented.
- scripts/typecheck-ratchet.mjs + typecheck-baseline.json: `tsc --noEmit`
  has a known 121-error baseline (strictness is being enabled
  progressively), so the gate fails only when the count GROWS; shrinking
  nags to ratchet the baseline down (--update-baseline). `npm run
  typecheck` stays as the raw view.
- test:unit aggregates the four existing node --test suites; registering the
  alias loader there fixes test:editorjs, which failed at module resolution
  (extensionless `./inlineHtmlText` import) - 87/87 unit tests now pass.
- .github/workflows/ci.yml: build:client + typecheck ratchet + unit tests,
  and the full API suite against a real dev stack + mongo:7 service.

Verified locally: 241/241 API tests in 4.2s against a worktree dev stack,
87/87 unit tests, ratchet at baseline (121), build:client clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
thingtime Ready Ready Preview, Comment Jul 26, 2026 9:29am

Request Review

Comment thread .github/workflows/ci.yml Fixed
Comment thread .github/workflows/ci.yml Fixed
…e.json's packageManager

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Could not auto-resolve conflicts with main — manual resolution needed. See the workflow run.

Conflicted files (as recorded by the merge step):

  • remix/package.json

Conflicted paths: remix/package.json

Resolved by the resolve-pr-conflicts workflow: https://github.com/lopugit/thingtime/actions/runs/30196272252

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

🤝 Merged main into claude/todo15-dx-ratchet-s1 — conflicts auto-resolved by the resolve-pr-conflicts workflow.

Conflicted files:

  • remix/package.json

Please review the merge commit before relying on it.

lopugit added a commit that referenced this pull request Jul 29, 2026
…te, single Web CI

Absorbs the best of the parallel PRs #119, #123, and #126 into this branch
(#121), so one PR carries TODO item 15:

- typecheck ratchet (from #126): scripts/typecheck-ratchet.mjs +
  typecheck-baseline.json (134 errors today) — CI fails only when the tsc
  error count grows, and --update-baseline locks in reductions.
- test:unit aggregate (from #119/#123), with the node --test suites loading
  through tsx instead of a hand-rolled resolve hook — fixes the previously
  broken ~/-alias suites and adds the scriptless mongodb/*.test.ts suite
  (109 unit tests, all passing).
- runner --list flag (parity with the other runners).
- TODO.md item-15 status note (from #123, updated).
- one workflow: api-tests.yml + the others' ci.yml variants become
  web-ci.yml — build + ratchet + unit tests, plus the headless 243-test API
  suite against a real Vite + Nitro + Mongo stack; path-filtered to remix/**,
  read-only token, node 24.

Verified locally: ratchet at baseline, 109/109 unit tests, 243/243 API tests
against a live dev stack.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lopugit

lopugit commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Consolidated into #121 at Lopu's request (one PR for TODO 15). Your typecheck ratchet (baseline + fail-only-on-regression + --update-baseline) was adopted nearly wholesale — baseline refreshed to 134 against current main. Credited in #121's body. Thanks!

@lopugit lopugit closed this Jul 29, 2026
lopugit added a commit that referenced this pull request Aug 7, 2026
dx: headless API test runner, typecheck ratchet, unit aggregate + Web CI (TODO 15, consolidates #119/#123/#126)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants