Complete L1 router and template migration

- Full implementation of runs, recipes, cache routers with templates
- Auth and storage routers fully migrated
- Jinja2 templates for all L1 pages
- Service layer for auth and storage

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
giles
2026-01-11 07:46:15 +00:00
parent 383dbf6e03
commit 022f88bf0c
20 changed files with 2771 additions and 135 deletions

View File

@@ -33,14 +33,44 @@ def create_app() -> FastAPI:
# Include routers
from .routers import auth, storage, api, recipes, cache, runs, home
# API routers
# Home and auth routers (root level)
app.include_router(home.router, tags=["home"])
app.include_router(auth.router, prefix="/auth", tags=["auth"])
# Feature routers
app.include_router(storage.router, prefix="/storage", tags=["storage"])
app.include_router(api.router, prefix="/api", tags=["api"])
app.include_router(recipes.router, tags=["recipes"])
app.include_router(cache.router, tags=["cache"])
app.include_router(runs.router, tags=["runs"])
app.include_router(home.router, tags=["home"])
# Runs router - handles both /runs and /run/{id} patterns
app.include_router(runs.router, prefix="/runs", tags=["runs"])
# Also mount at /run for single-run detail URLs
from fastapi import APIRouter
run_detail_router = APIRouter()
@run_detail_router.get("/{run_id}")
async def run_detail_redirect(run_id: str, request):
from .routers.runs import run_detail
return await run_detail(run_id, request)
app.include_router(run_detail_router, prefix="/run", tags=["runs"])
# Recipes router - handles both /recipes and /recipe/{id} patterns
app.include_router(recipes.router, prefix="/recipes", tags=["recipes"])
recipe_detail_router = APIRouter()
@recipe_detail_router.get("/{recipe_id}")
async def recipe_detail_redirect(recipe_id: str, request):
from .routers.recipes import get_recipe
return await get_recipe(recipe_id, request)
app.include_router(recipe_detail_router, prefix="/recipe", tags=["recipes"])
# Cache router - handles /cache and /media
app.include_router(cache.router, prefix="/cache", tags=["cache"])
# Also mount media list at /media for convenience
from fastapi import APIRouter as MediaRouter
media_router = MediaRouter()
@media_router.get("")
async def media_list_redirect(request, offset: int = 0, limit: int = 24):
from .routers.cache import list_media
return await list_media(request, offset, limit)
app.include_router(media_router, prefix="/media", tags=["media"])
return app