From 36ac1d0df9526da6754c4d0c350370602a7d1039 Mon Sep 17 00:00:00 2001 From: leocrm-bot Date: Thu, 2 Jul 2026 14:37:30 +0200 Subject: [PATCH] fix: register plugin routes in create_app BEFORE SPA catch-all MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Plugin routes now registered in create_app (sync context) before SPA catch-all - Previously plugin routes were added in lifespan (async) AFTER SPA catch-all - FastAPI matches routes in registration order — catch-all was shadowing plugin routes - Fixes: Calendar/Mail/DMS/Tags/Permissions returning 404 despite being in OpenAPI --- app/main.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/app/main.py b/app/main.py index 59408a3..142fe0d 100644 --- a/app/main.py +++ b/app/main.py @@ -186,6 +186,25 @@ def create_app() -> FastAPI: app.include_router(ai_copilot.router) app.include_router(workflows.router) + # ─── Register plugin routes (before SPA catch-all) ────────────────── + registry = get_registry() + try: + registry.discover_builtins() + for name in registry._plugins: + plugin = registry.get_plugin(name) + if plugin is None: + continue + for route_def in plugin.manifest.routes: + try: + router_module = importlib.import_module(route_def.module) + router = getattr(router_module, route_def.router_attr) + app.include_router(router) + logger.info(f"Registered plugin routes: {name}") + except Exception as exc: + logger.warning(f"Failed to register routes for plugin {name}: {exc}") + except Exception as exc: + logger.warning(f"Plugin discovery failed: {exc}") + # ─── Serve frontend static files (SPA) ─────────────────────────────── # Mount built frontend assets (JS, CSS, images) frontend_dist = os.path.join(os.path.dirname(__file__), "..", "frontend", "dist")