refactor: S06.2 backend router auto-discovery via ROUTER_CONFIGS manifest (replaces 18 explicit imports)
This commit is contained in:
+30
-68
@@ -21,25 +21,6 @@ import auth_service as auth_module
|
||||
import config
|
||||
from config import CORS_ORIGINS, TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID, VOLUME_ROOT, get_client_ip
|
||||
from rbac import require_page
|
||||
from routers import auth as auth_router
|
||||
from routers import (
|
||||
chat_summary,
|
||||
conversation_tracker,
|
||||
files,
|
||||
gitea,
|
||||
litellm,
|
||||
opc_agents,
|
||||
opc_projects,
|
||||
opc_tasks,
|
||||
opc_ws,
|
||||
passkey,
|
||||
security,
|
||||
system,
|
||||
terminal,
|
||||
totp,
|
||||
transmission,
|
||||
)
|
||||
|
||||
_tz_cst = timezone(timedelta(hours=8))
|
||||
|
||||
|
||||
@@ -271,57 +252,38 @@ async def _inject_user(request: Request, user=Depends(auth_module.get_current_us
|
||||
return user
|
||||
|
||||
|
||||
# Public auth endpoints
|
||||
app.include_router(auth_router.router, prefix="/api/auth", tags=["auth"])
|
||||
app.include_router(passkey.router, prefix="/api/auth", tags=["passkey"])
|
||||
app.include_router(totp.router, prefix="/api/auth", tags=["totp"])
|
||||
# Auto-discovered router registration (from ROUTER_CONFIGS manifest)
|
||||
from routers import ROUTER_CONFIGS, WS_ROUTES
|
||||
import importlib
|
||||
import re
|
||||
|
||||
# Protected endpoints with page-level RBAC
|
||||
app.include_router(
|
||||
gitea.router, prefix="/api/gitea", dependencies=[Depends(_inject_user), Depends(require_page("gitea"))]
|
||||
)
|
||||
app.include_router(
|
||||
files.router, prefix="/api/files", dependencies=[Depends(_inject_user)]
|
||||
)
|
||||
# Public file download endpoint (no auth required for token-based downloads)
|
||||
app.include_router(files.public_router, prefix="/api/files")
|
||||
app.include_router(
|
||||
system.router, prefix="/api/system", dependencies=[Depends(_inject_user), Depends(require_page("dashboard"))]
|
||||
)
|
||||
app.include_router(
|
||||
litellm.router, prefix="/api/litellm", dependencies=[Depends(_inject_user), Depends(require_page("dashboard"))]
|
||||
)
|
||||
app.include_router(
|
||||
chat_summary.router,
|
||||
prefix="/api/chat-summary",
|
||||
dependencies=[Depends(_inject_user), Depends(require_page("chat-digest"))],
|
||||
)
|
||||
app.include_router(
|
||||
conversation_tracker.router,
|
||||
prefix="/api/conversations",
|
||||
dependencies=[Depends(_inject_user), Depends(require_page("conversations"))],
|
||||
)
|
||||
app.include_router(
|
||||
security.router, prefix="/api/security", dependencies=[Depends(_inject_user), Depends(require_page("security"))]
|
||||
)
|
||||
app.include_router(
|
||||
transmission.router, dependencies=[Depends(_inject_user), Depends(require_page("transmission"))]
|
||||
)
|
||||
for cfg in ROUTER_CONFIGS:
|
||||
mod = importlib.import_module('routers.' + cfg['module'])
|
||||
router_attr = cfg.get('router_attr', 'router')
|
||||
router_obj = getattr(mod, router_attr)
|
||||
prefix = cfg.get('prefix')
|
||||
tags = cfg.get('tags')
|
||||
deps = cfg.get('deps', [])
|
||||
dep_objects = []
|
||||
for d in deps:
|
||||
if d == '_inject_user':
|
||||
dep_objects.append(Depends(_inject_user))
|
||||
elif d.startswith('require_page('):
|
||||
# Extract page name from require_page('gitea') or require_page(gitea)
|
||||
m = re.search(r'require_page\(["\'](.*?)["\']\)', d)
|
||||
page_name = m.group(1) if m else d.split('(')[1].rstrip(')')
|
||||
dep_objects.append(Depends(require_page(page_name)))
|
||||
kwargs = {'dependencies': dep_objects} if dep_objects else {}
|
||||
if prefix is not None:
|
||||
kwargs['prefix'] = prefix
|
||||
if tags:
|
||||
kwargs['tags'] = tags
|
||||
app.include_router(router_obj, **kwargs)
|
||||
|
||||
# OPC endpoints
|
||||
app.include_router(
|
||||
opc_tasks.router, prefix="/api/opc", dependencies=[Depends(_inject_user), Depends(require_page("opc"))]
|
||||
)
|
||||
app.include_router(
|
||||
opc_agents.router, prefix="/api/opc", dependencies=[Depends(_inject_user), Depends(require_page("opc"))]
|
||||
)
|
||||
app.include_router(
|
||||
opc_projects.router, prefix="/api/opc", dependencies=[Depends(_inject_user), Depends(require_page("opc"))]
|
||||
)
|
||||
|
||||
# WebSocket endpoint (auth handled inside handler via auth cookie; query token fallback temporary)
|
||||
app.add_api_websocket_route("/ws/terminal", terminal.ws_endpoint)
|
||||
app.add_api_websocket_route("/ws/opc", opc_ws.websocket_endpoint)
|
||||
for ws in WS_ROUTES:
|
||||
mod = importlib.import_module('routers.' + ws['module'])
|
||||
handler = getattr(mod, ws['handler'])
|
||||
app.add_api_websocket_route(ws['path'], handler)
|
||||
|
||||
# Mount static files (skip if directory doesn't exist, e.g., in test environments)
|
||||
import os
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
"""Router auto-discovery manifest.
|
||||
Each entry defines how a router module gets registered.
|
||||
"""
|
||||
ROUTER_CONFIGS = [
|
||||
{"module": "auth", "prefix": "/api/auth", "tags": ["auth"]},
|
||||
{"module": "passkey", "prefix": "/api/auth", "tags": ["passkey"]},
|
||||
{"module": "totp", "prefix": "/api/auth", "tags": ["totp"]},
|
||||
{"module": "gitea", "prefix": "/api/gitea", "deps": ["_inject_user", "require_page(\"gitea\")"]},
|
||||
{"module": "files", "prefix": "/api/files", "deps": ["_inject_user"]},
|
||||
{"module": "files", "router_attr": "public_router", "prefix": "/api/files"},
|
||||
{"module": "system", "prefix": "/api/system", "deps": ["_inject_user", "require_page(\"dashboard\")"]},
|
||||
{"module": "litellm", "prefix": "/api/litellm", "deps": ["_inject_user", "require_page(\"dashboard\")"]},
|
||||
{"module": "chat_summary", "prefix": "/api/chat-summary", "deps": ["_inject_user", "require_page(\"chat-digest\")"]},
|
||||
{"module": "conversation_tracker", "prefix": "/api/conversations", "deps": ["_inject_user", "require_page(\"conversations\")"]},
|
||||
{"module": "security", "prefix": "/api/security", "deps": ["_inject_user", "require_page(\"security\")"]},
|
||||
{"module": "transmission", "prefix": None, "deps": ["_inject_user", "require_page(\"transmission\")"]},
|
||||
{"module": "opc_tasks", "prefix": "/api/opc", "deps": ["_inject_user", "require_page(\"opc\")"]},
|
||||
{"module": "opc_agents", "prefix": "/api/opc", "deps": ["_inject_user", "require_page(\"opc\")"]},
|
||||
{"module": "opc_projects", "prefix": "/api/opc", "deps": ["_inject_user", "require_page(\"opc\")"]},
|
||||
]
|
||||
WS_ROUTES = [
|
||||
{"module": "terminal", "path": "/ws/terminal", "handler": "ws_endpoint"},
|
||||
{"module": "opc_ws", "path": "/ws/opc", "handler": "websocket_endpoint"},
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user