fix(plugins): FastAPI-Route-Matching — /plugins/{name} (d9aed51) verschlang literale Routen /active-manifests, /manifest, /updates (404 'Plugin not found'); Reihenfolge korrigiert: statische Routen jetzt vor /{name}. Folge war: Sidebar ohne Plugin-Menüeinträge in Produktion (nur Kontakte/Dashboard/System). +2 Regressionstests
This commit is contained in:
+50
-50
@@ -44,46 +44,24 @@ async def list_plugins(
|
||||
return {"plugins": plugins, "total": len(plugins)}
|
||||
|
||||
|
||||
@router.get("/{name}")
|
||||
async def get_plugin_detail(
|
||||
name: str,
|
||||
@router.get("/active-manifests")
|
||||
async def get_active_manifests(
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: dict = Depends(require_permission("plugins:read")),
|
||||
# ARCH-003 fix: every authenticated user needs the UI manifests for the
|
||||
# dynamic sidebar/routes — the data is pure UI metadata; actual data
|
||||
# access stays protected by each endpoint's own permission.
|
||||
current_user: dict = Depends(get_current_user),
|
||||
):
|
||||
"""Get detail for a single plugin: manifest metadata + DB status.
|
||||
"""Get UI manifests for all active plugins.
|
||||
|
||||
BUG-024 fix: this endpoint was missing entirely (404).
|
||||
Returns menu_items, page_routes, detail_tabs, settings_pages, and
|
||||
dashboard_widgets contributed by each active plugin. Used by the
|
||||
frontend PluginRegistry to dynamically register routes, sidebar items,
|
||||
settings pages, and detail tabs.
|
||||
"""
|
||||
registry = get_registry()
|
||||
plugin = registry.get_plugin(name)
|
||||
if plugin is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail={"detail": f"Plugin '{name}' not found", "code": "not_found"},
|
||||
)
|
||||
|
||||
m = plugin.manifest
|
||||
record = registry.get_db_status(name)
|
||||
return {
|
||||
"name": m.name,
|
||||
"version": m.version,
|
||||
"display_name": getattr(m, "display_name", None) or m.name,
|
||||
"description": getattr(m, "description", None),
|
||||
"author": getattr(m, "author", None),
|
||||
"is_core": bool(getattr(m, "is_core", False)),
|
||||
"permissions": list(m.permissions),
|
||||
"depends_on": list(getattr(m, "depends_on", []) or []),
|
||||
"status": {
|
||||
"installed": record is not None,
|
||||
"active": bool(record.active) if record is not None else False,
|
||||
"version_installed": getattr(record, "version", None),
|
||||
},
|
||||
"menu_items": len(getattr(m, "menu_items", []) or []),
|
||||
"page_routes": len(getattr(m, "page_routes", []) or []),
|
||||
"detail_tabs": len(getattr(m, "detail_tabs", []) or []),
|
||||
"settings_pages": len(getattr(m, "settings_pages", []) or []),
|
||||
"dashboard_widgets": len(getattr(m, "dashboard_widgets", []) or []),
|
||||
}
|
||||
service = get_plugin_service()
|
||||
manifests = await service.get_active_manifests(db)
|
||||
return {"plugins": manifests, "total": len(manifests)}
|
||||
|
||||
|
||||
@router.get("/manifest")
|
||||
@@ -134,24 +112,46 @@ async def check_plugin_updates(
|
||||
return {"updates": updates, "total": len(updates)}
|
||||
|
||||
|
||||
@router.get("/active-manifests")
|
||||
async def get_active_manifests(
|
||||
@router.get("/{name}")
|
||||
async def get_plugin_detail(
|
||||
name: str,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
# ARCH-003 fix: every authenticated user needs the UI manifests for the
|
||||
# dynamic sidebar/routes — the data is pure UI metadata; actual data
|
||||
# access stays protected by each endpoint's own permission.
|
||||
current_user: dict = Depends(get_current_user),
|
||||
current_user: dict = Depends(require_permission("plugins:read")),
|
||||
):
|
||||
"""Get UI manifests for all active plugins.
|
||||
"""Get detail for a single plugin: manifest metadata + DB status.
|
||||
|
||||
Returns menu_items, page_routes, detail_tabs, settings_pages, and
|
||||
dashboard_widgets contributed by each active plugin. Used by the
|
||||
frontend PluginRegistry to dynamically register routes, sidebar items,
|
||||
settings pages, and detail tabs.
|
||||
BUG-024 fix: this endpoint was missing entirely (404).
|
||||
"""
|
||||
service = get_plugin_service()
|
||||
manifests = await service.get_active_manifests(db)
|
||||
return {"plugins": manifests, "total": len(manifests)}
|
||||
registry = get_registry()
|
||||
plugin = registry.get_plugin(name)
|
||||
if plugin is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail={"detail": f"Plugin '{name}' not found", "code": "not_found"},
|
||||
)
|
||||
|
||||
m = plugin.manifest
|
||||
record = registry.get_db_status(name)
|
||||
return {
|
||||
"name": m.name,
|
||||
"version": m.version,
|
||||
"display_name": getattr(m, "display_name", None) or m.name,
|
||||
"description": getattr(m, "description", None),
|
||||
"author": getattr(m, "author", None),
|
||||
"is_core": bool(getattr(m, "is_core", False)),
|
||||
"permissions": list(m.permissions),
|
||||
"depends_on": list(getattr(m, "depends_on", []) or []),
|
||||
"status": {
|
||||
"installed": record is not None,
|
||||
"active": bool(record.active) if record is not None else False,
|
||||
"version_installed": getattr(record, "version", None),
|
||||
},
|
||||
"menu_items": len(getattr(m, "menu_items", []) or []),
|
||||
"page_routes": len(getattr(m, "page_routes", []) or []),
|
||||
"detail_tabs": len(getattr(m, "detail_tabs", []) or []),
|
||||
"settings_pages": len(getattr(m, "settings_pages", []) or []),
|
||||
"dashboard_widgets": len(getattr(m, "dashboard_widgets", []) or []),
|
||||
}
|
||||
|
||||
|
||||
@router.get("/{name}/config")
|
||||
|
||||
Reference in New Issue
Block a user