From f9508d17def3a3f0d3f6f50576e74ad47a60a641 Mon Sep 17 00:00:00 2001 From: Leopoldadmin Date: Fri, 3 Jul 2026 16:49:57 +0000 Subject: [PATCH] fix(plugin): add GET and PATCH /api/v1/plugins/{name}/config endpoints Bug 4: Plugin config field existed but had no API endpoints. Added GET /api/v1/plugins/{name}/config to retrieve config as JSON and PATCH /api/v1/plugins/{name}/config to update it. Uses PluginConfigUpdate Pydantic model for request validation. --- app/routes/plugins.py | 57 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/app/routes/plugins.py b/app/routes/plugins.py index d30f018..4633b10 100644 --- a/app/routes/plugins.py +++ b/app/routes/plugins.py @@ -1,8 +1,9 @@ -"""Plugin routes — list, install, activate, deactivate, uninstall, manifest schema.""" +"""Plugin routes — list, install, activate, deactivate, uninstall, manifest schema, config.""" from __future__ import annotations from fastapi import APIRouter, Depends, HTTPException, Query +from pydantic import BaseModel from sqlalchemy.ext.asyncio import AsyncSession from app.core.db import get_db @@ -13,6 +14,11 @@ from app.services.plugin_service import get_plugin_service router = APIRouter(prefix="/api/v1/plugins", tags=["plugins"]) +class PluginConfigUpdate(BaseModel): + """Request body for updating plugin configuration.""" + config: dict + + @router.get("") async def list_plugins( db: AsyncSession = Depends(get_db), @@ -33,6 +39,55 @@ async def get_manifest_schema( return service.get_manifest_schema() +@router.get("/{name}/config") +async def get_plugin_config( + name: str, + db: AsyncSession = Depends(get_db), + current_user: dict = Depends(require_admin), +): + """Get the configuration for a specific plugin. + + Returns the plugin's config field as a JSON object. + """ + service = get_plugin_service() + try: + config = await service.get_plugin_config(db, name) + return {"name": name, "config": config} + except ValueError as exc: + raise HTTPException( + 404, detail={"detail": str(exc), "code": "plugin_not_found"} + ) from None + + +@router.patch("/{name}/config") +async def update_plugin_config( + name: str, + body: PluginConfigUpdate, + db: AsyncSession = Depends(get_db), + current_user: dict = Depends(require_admin), +): + """Update the configuration for a specific plugin. + + Stores the config as a JSON string in the plugin's config field. + """ + import uuid as uuid_mod + + service = get_plugin_service() + try: + result = await service.update_plugin_config( + db, + name, + config=body.config, + tenant_id=uuid_mod.UUID(current_user["tenant_id"]), + user_id=uuid_mod.UUID(current_user["user_id"]), + ) + return result + except ValueError as exc: + raise HTTPException( + 404, detail={"detail": str(exc), "code": "plugin_not_found"} + ) from None + + @router.post("/{name}/install") async def install_plugin( name: str,