Public: anyone can read this; the crew can change it.
The /api/v1/repos/:owner/:name/app routes move out of src/http/api.ts into src/http/api/app.ts, unchanged #7480
Check · Review · Land · Live done — Landed and live in production.
Every `router.add(…, "/api/v1/repos/:owner/:name/app…")` in `src/http/api.ts` now lives in the new `src/http/api/app.ts` as `appRoutes(router)`, in the same shape as `app_notes.ts`. `api.ts` calls it once, where the block used to be. **`api.ts` lost 309 lines net (5,012 → 4,703).** The handler bodies were cut and pasted unchanged.
shipped production is serving it deploy e71d959
Every router.add(…, "/api/v1/repos/:owner/:name/app…") in src/http/api.ts now lives in the new src/http/api/app.ts as appRoutes(router), in the same shape as app_notes.ts. api.ts calls it once, where the block used to be. api.ts lost 309 lines net (5,012 → 4,703). The handler bodies were cut and pasted unchanged.
The issue says there are 11 routes, but there are 16, and all of them move:
…/app: GET, POST, PATCH, DELETE…/app/members: GET, PUT…/app/domains: GET, POST, plus…/:host/checkPOST and…/:hostDELETE…/app/env: GET, plus…/env/:varPUT and DELETE…/app/:env:redeployPOST,stopPOST,openGET
What to look at:
- Helpers that moved too:
appPatchandmembersAnswerwere only used by these routes, so they moved with them. The importsapi.tsno longer needs were dropped. - Helpers that stayed:
appJsonandappLimitResponseare also used by/api/v1/apps, so they stay inapi.tsand are now exported.app.tsimports them along withloadRepo, the same wayapp_notes.tsanduser.tsalready do. - One ordering change: the
egressGrantRoutes,promptRoutesandsecretRoutescalls used to sit between the domain routes and the env routes. They now come right afterappRoutes(router). None of their paths overlap…/app, so matching is unaffected; only the order the routes are listed in changes. Sorted, the route table fromapiRoutesis the same before and after (270 routes, no diff).
Not done: the …/app/notes routes stay in app_notes.ts and the /api/v1/apps routes stay in api.ts. Neither is part of this issue.
Checks: bun x tsc --noEmit is clean. scripts/fast.ts named 927 test files, more than fits here, so I picked 33 files covering these routes and the tests that walk the route table, OpenAPI coverage, route timing, the security floor, cross-origin checks and the router. All 288 tests pass and no test was changed.
🤖 Generated with Claude Code
Clean move. All 16 …/app handlers, appPatch and membersAnswer are byte-for-byte what was removed from api.ts. Every scope check (admin on writes and on domains/env reads, rw on redeploy/stop, ro on the members read) is still in front of the body it guards. Body reads still go through respond.ts body(). Nothing new reaches user text.
Route order: the only reorder is egressGrantRoutes/promptRoutes/secretRoutes. None of their paths (/egress-grants, /prompts, /api/v1/secrets/…) overlap …/app. appNoteRoutes still registers ahead of /app/:env/*, so /app/notes cannot be caught by :env.
The api.ts ⇄ api/app.ts import cycle follows the pattern user.ts and app_notes.ts already use. It is safe because the imports are only used inside handlers.
Preview: I checked against production, both as a guest. GET app → 404, GET app/members → 401, POST app/production/stop → 401, DELETE app/domains/x.com → 401, GET app/nope/open → 404. The answers are identical, and / → 200.
No behaviour is added, so no new test is owed. No README or terminal change is needed for a pure move. It serves the direction by shrinking the 5k-line api.ts that every pull clashes on.
Every
router.add(…, "/api/v1/repos/:owner/:name/app…")insrc/http/api.tsnow lives in the newsrc/http/api/app.tsasappRoutes(router), in the same shape asapp_notes.ts.api.tscalls it once, where the block used to be.api.tslost 309 lines net (5,012 → 4,703). The handler bodies were cut and pasted unchanged.The issue says there are 11 routes, but there are 16, and all of them move:
…/app: GET, POST, PATCH, DELETE…/app/members: GET, PUT…/app/domains: GET, POST, plus…/:host/checkPOST and…/:hostDELETE…/app/env: GET, plus…/env/:varPUT and DELETE…/app/:env:redeployPOST,stopPOST,openGETWhat to look at:
appPatchandmembersAnswerwere only used by these routes, so they moved with them. The importsapi.tsno longer needs were dropped.appJsonandappLimitResponseare also used by/api/v1/apps, so they stay inapi.tsand are now exported.app.tsimports them along withloadRepo, the same wayapp_notes.tsanduser.tsalready do.egressGrantRoutes,promptRoutesandsecretRoutescalls used to sit between the domain routes and the env routes. They now come right afterappRoutes(router). None of their paths overlap…/app, so matching is unaffected; only the order the routes are listed in changes. Sorted, the route table fromapiRoutesis the same before and after (270 routes, no diff).Not done: the
…/app/notesroutes stay inapp_notes.tsand the/api/v1/appsroutes stay inapi.ts. Neither is part of this issue.Checks:
bun x tsc --noEmitis clean.scripts/fast.tsnamed 927 test files, more than fits here, so I picked 33 files covering these routes and the tests that walk the route table, OpenAPI coverage, route timing, the security floor, cross-origin checks and the router. All 288 tests pass and no test was changed.🤖 Generated with Claude Code
Closes #7446