feat(routes): FastAPI prefixes, ASP.NET endpoint groups, wrapped server actions on the Screens tab

- python.ts postExtract: APIRouter(prefix=) and literal include_router(prefix=) composed down the include tree (module import, alias, local); a computed prefix leaves that mount alone; full-stack-fastapi-template 23 routes named by path
- csharp.ts: handler-first MapPost(Handler[, "path"]) under the endpoint-group class, the app's $"/api/{groupName}" head read in postExtract, RoutePrefix honoured; detection covers Endpoints/ files; CleanArchitecture 10 routes
- tier-synthesizer: a type argument between a client call and its parentheses (useSWR<T>(…), ky.get<T>(…)); recorded callee without it
- screens.ts: a file-scope navigation attributed to the value spanning it; a value nothing calls attributed to the functions mentioning it in importing files (request-time source read, bounded); steps.ts lends navigates edges to a value root
- tests: servers fixture (FastAPI prefixed routers, ASP.NET endpoint group end to end), frameworks.test.ts (group form, RoutePrefix), cross-tier (generic useSWR)
- docs: CHANGELOG, plan, playbook rows

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REFyW9hmNrxhwN5wxRoAkC
This commit is contained in:
Colby McHenry
2026-08-28 14:52:40 -05:00
co-authored by Claude Fable 5
parent 9c6bc23b21
commit bc45e9071d
11 changed files with 487 additions and 14 deletions
+8 -1
View File
@@ -167,12 +167,14 @@ beforeAll(async () => {
write(
'apps/web/components/orders.tsx',
"'use client'\n" +
"import useSWR from 'swr'\n" +
'export function Orders() {\n' +
" const { data } = useSWR<Order[]>('/api/v1/orders', fetcher)\n" +
' async function loadOrders() {\n' +
" const res = await fetch('/api/v1/orders')\n" +
' return res.json()\n' +
' }\n' +
' return null\n' +
' return data\n' +
'}\n'
);
write(
@@ -345,6 +347,11 @@ describe('express mounts: a mounted routers routes are named by the path a re
expect(edges).toHaveLength(1);
expect(edges[0]!.target).toBe(route('GET /api/v1/orders').id);
expect((edges[0]!.metadata as Record<string, unknown>).registeredAt).toBe('apps/api/src/orders.routes.ts:4');
// `useSWR<Order[]>('/api/v1/orders')` — a type argument between the name and the call.
const hook = synthesized(sym('Orders'), 'http-client');
expect(hook).toHaveLength(1);
expect(hook[0]!.target).toBe(route('GET /api/v1/orders').id);
expect((hook[0]!.metadata as Record<string, unknown>).callee).toBe('useSWR');
});
});