From eaa660e12f292b402cdd067ecf22ac5b086f28a8 Mon Sep 17 00:00:00 2001 From: FFXN Date: Fri, 27 Mar 2026 15:00:21 +0800 Subject: [PATCH] feat: add creators filter param when querying snippets list. --- api/controllers/console/snippets/payloads.py | 15 ++++++++++++++- api/controllers/console/workspace/snippets.py | 1 + api/services/snippet_service.py | 5 +++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/api/controllers/console/snippets/payloads.py b/api/controllers/console/snippets/payloads.py index 73492db8ae..2c7f8db81b 100644 --- a/api/controllers/console/snippets/payloads.py +++ b/api/controllers/console/snippets/payloads.py @@ -1,6 +1,6 @@ from typing import Any, Literal -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, field_validator class SnippetListQuery(BaseModel): @@ -10,6 +10,19 @@ class SnippetListQuery(BaseModel): limit: int = Field(default=20, ge=1, le=100) keyword: str | None = None is_published: bool | None = Field(default=None, description="Filter by published status") + creators: list[str] | None = Field(default=None, description="Filter by creator account IDs") + + @field_validator("creators", mode="before") + @classmethod + def parse_creators(cls, value: object) -> list[str] | None: + """Normalize creators filter from query string or list input.""" + if value is None: + return None + if isinstance(value, str): + return [creator.strip() for creator in value.split(",") if creator.strip()] or None + if isinstance(value, list): + return [str(creator).strip() for creator in value if str(creator).strip()] or None + return None class IconInfo(BaseModel): diff --git a/api/controllers/console/workspace/snippets.py b/api/controllers/console/workspace/snippets.py index 570ef0467f..13bfc37f71 100644 --- a/api/controllers/console/workspace/snippets.py +++ b/api/controllers/console/workspace/snippets.py @@ -67,6 +67,7 @@ class CustomizedSnippetsApi(Resource): limit=query.limit, keyword=query.keyword, is_published=query.is_published, + creators=query.creators, ) return { diff --git a/api/services/snippet_service.py b/api/services/snippet_service.py index 34866016bf..8db57cf487 100644 --- a/api/services/snippet_service.py +++ b/api/services/snippet_service.py @@ -49,6 +49,7 @@ class SnippetService: limit: int = 20, keyword: str | None = None, is_published: bool | None = None, + creators: list[str] | None = None, ) -> tuple[Sequence[CustomizedSnippet], int, bool]: """ Get paginated list of snippets with optional search. @@ -58,6 +59,7 @@ class SnippetService: :param limit: Number of items per page :param keyword: Optional search keyword for name/description :param is_published: Optional filter by published status (True/False/None for all) + :param creators: Optional filter by creator account IDs :return: Tuple of (snippets list, total count, has_more flag) """ stmt = ( @@ -74,6 +76,9 @@ class SnippetService: if is_published is not None: stmt = stmt.where(CustomizedSnippet.is_published == is_published) + if creators: + stmt = stmt.where(CustomizedSnippet.created_by.in_(creators)) + # Get total count count_stmt = select(func.count()).select_from(stmt.subquery()) total = db.session.scalar(count_stmt) or 0