From ea53ed9ce0bcedf0175657d4d8669a97452d1bd4 Mon Sep 17 00:00:00 2001 From: Chris Coutinho Date: Tue, 16 Jun 2026 02:03:26 +0200 Subject: [PATCH] =?UTF-8?q?fix(vector-sync):=20address=20round-7=20?= =?UTF-8?q?=E2=80=94=20only=20log=20purge=20endpoint=20when=20enabled?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - app.py: move the /api/v1/vector-sync/purge mention out of the unconditional management-endpoints log and into the vector_sync_enabled block, so operators without Qdrant don't see an endpoint that 404s - vector_sync route: comment why doc_types isn't whitelisted against INDEXED_DOC_TYPES (unknown type = harmless zero-match no-op) Co-Authored-By: Claude Opus 4.8 (1M context) --- nextcloud_mcp_server/api/vector_sync.py | 3 +++ nextcloud_mcp_server/app.py | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/nextcloud_mcp_server/api/vector_sync.py b/nextcloud_mcp_server/api/vector_sync.py index 3944de33..4d49ed77 100644 --- a/nextcloud_mcp_server/api/vector_sync.py +++ b/nextcloud_mcp_server/api/vector_sync.py @@ -80,6 +80,9 @@ async def purge_doc_types_route(request: Request) -> JSONResponse: if not isinstance(raw, list) or not all(isinstance(d, str) for d in raw): return _bad_request("doc_types must be a list of strings") doc_types = [d for d in raw if d] + # No whitelist against INDEXED_DOC_TYPES on purpose: an unknown type yields a + # zero-match Qdrant filter (harmless no-op), and the canonical set lives with + # the indexer — the route shouldn't need a server update to purge a new type. # Bound the batch: there are only a handful of real indexed types, so a huge # list is abuse — cap it rather than fan out unbounded count+delete calls. if len(doc_types) > _MAX_PURGE_DOC_TYPES: diff --git a/nextcloud_mcp_server/app.py b/nextcloud_mcp_server/app.py index 3d419a28..39c383b8 100644 --- a/nextcloud_mcp_server/app.py +++ b/nextcloud_mcp_server/app.py @@ -2435,6 +2435,7 @@ def get_app(transport: str = "streamable-http", enabled_apps: list[str] | None = methods=["POST"], ) ) + logger.info("Vector-sync admin endpoint enabled: /api/v1/vector-sync/purge") # Access and scope management endpoints (ADR-022) routes.append( Route( @@ -2457,7 +2458,7 @@ def get_app(transport: str = "streamable-http", enabled_apps: list[str] | None = "/api/v1/users/{user_id}/app-password, /api/v1/users/{user_id}/access, " "/api/v1/users/{user_id}/scopes, /api/v1/scopes, " "/api/v1/vector-viz/search, /api/v1/search, /api/v1/apps, " - "/api/v1/webhooks, /api/v1/vector-sync/purge, /api/v1/pdf-preview" + "/api/v1/webhooks, /api/v1/pdf-preview" ) # Note: Metrics endpoint is NOT exposed on main HTTP port for security reasons.