Repository navigation
API: split app.ts into route modules, one Gemini client, remove dead code - #22
Merged
Merged
Conversation
app.ts held every route, its helpers and the middleware in one 87 KB file.
It is now the app shell (CORS, body caps, tracing, auth, LLM rate limits,
GET /, route mounting, error handler: 243 lines), with:
- http.ts: what the middleware and the routes share (env type, tenant
policy, rate limiting, the prompt cap, skill-observation writes)
- routes/{score,coach,assist,wiki,prompts,metrics,teams,onboard}.ts: one
Hono sub-app per area, mounted after the middleware so every route still
gets auth, body caps, tracing and rate limits
Code moved verbatim (apart from `app.<verb>` → `<router>.<verb>` and
`export` on the shared helpers), so behaviour is unchanged: the 38
Postgres integration tests, which drive every route and cross-check the
GET / catalog, pass unchanged. apps/api/README.md documents the layout.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wiki-bootstrap-job.ts built its own GoogleGenAI client, so the rich bootstrap (the biggest fan-out of LLM calls in the API) bypassed the retry policy and never appeared in Langfuse traces. It now calls gemini.generateText, which goes through the same tracedGenerate/withRetry path as the request handlers: 429/5xx are retried with backoff, timeouts are still never retried (90 s per call, as before). generateText does not apply the 4 000-char cap meant for short structured answers, because folder narratives are several thousand words; a new test pins both properties. Removed as dead code: extractLearning (gemini.ts), EXTRACT_MODEL (gemma-4-31b-it) and the extract-prompt module in packages/scoring with its tests. They served the Stop hook that was removed in PR #5; nothing has imported them since. The README's "Gemma for async learning extraction" claim goes with them; every call uses gemini-3-flash-preview. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ecutable Next 16.3 generates AGENTS.md and CLAUDE.md in apps/dashboard on every `next dev` unless `agentRules: false` is set; they showed up as untracked files for anyone running the dashboard. apps/mcp-server/bin/cli.mjs has a shebang and is the package's `bin`, but was committed as 100644 (npm fixed the mode on install, leaving a dirty tree). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…utes/ The README said gemma-4-31b-it handled "async learning extraction" and "diff narration, rich bootstrap". Learning extraction was never wired up (removed in the previous commits) and /diff and the bootstrap use gemini-3-flash-preview. Also points the route table at the new layout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced Oct 1, 2026
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
apps/api/src/app.tswas a 2,277-line, 87 KB file holding every route, its helpers and all middleware. Every later change in the API (keyless demo mode, the demo-team switch, both coming in follow-up PRs) has to touch it.wiki-bootstrap-job.tsbuilt a separateGoogleGenAI, so the API's largest fan-out of LLM calls skippedgemini.ts's retry policy and never showed up in Langfuse traces.extractLearning,EXTRACT_MODEL(gemma-4-31b-it) and theextract-promptmodule served the Stop hook removed in PR Removed hook #5; nothing has imported them since. The README still said Gemma handled "async learning extraction" and "diff narration, rich bootstrap"; both usegemini-3-flash-preview.next dev(Next 16.3) writesAGENTS.md/CLAUDE.mdintoapps/dashboard, andbin/cli.mjswas committed without the executable bit. Both left a dirty tree after a normal install or run.What changed
63b18db).app.tsbecomes the app shell (243 lines): CORS, body caps, tracing, auth and LLM rate-limit middleware,GET /, route mounting, error handler.http.tsholds what the middleware and routes share.routes/{score,coach,assist,wiki,prompts,metrics,teams,onboard}.tsare Hono sub-apps mounted after the middleware.app.<verb>→<router>.<verb>andexporton the shared helpers.apps/api/README.mddocuments the layout.f897485).gemini.generateText()runs one call throughtracedGenerate+withRetry, and the bootstrap's three passes use it. Behaviour change: 429/5xx are now retried with backoff (timeouts still never retried, 90 s per call as before), and the calls are traced. Long-form answers are not capped at the 4 000 chars meant for short structured answers.EXTRACT_MODELandextractLearningare deleted, along with their 9 tests.93e9281).agentRules: falseinnext.config.mjs;cli.mjsis now 100755.0918f3f). Model lines matchmodels.mjs; the route table points atsrc/routes/.Verification
All on this branch, Node 22.23.3:
npm run typechecknpm run lintnpm testgenerateTexttest); scoring 35 (was 44: −9 tests of the deleted extract module); other workspaces unchangedTRAILHEAD_IT_DATABASE_URL=… npm --workspace=apps/api run test:integration(Postgres 16)GET /lacks coverage, so a route lost in the split would show here.npm --workspace=apps/dashboard run buildsrc/index.tsagainst a fresh schemaGET /200,GET /wiki/tree200,POST /score400 on a bad body (as before), SIGTERM drainsnext devwithagentRules: falseAGENTS.md/CLAUDE.mdno longer generatedThe new test asserts that
generateTextmakes exactly one request through the shared client and returns a 12 000-char answer uncapped.Notes
This is the base of a stack. #23 (keyless demo mode) and the PRs after it build on this branch, so please merge this one first.