From 3fc4dcdb969f7c47cddf4e96c3162746c38d8644 Mon Sep 17 00:00:00 2001 From: Agent Zero Date: Fri, 17 Jul 2026 21:20:49 +0200 Subject: [PATCH] fix: add folder_id and sort_order to AIChatSession model, fix UUID conversion in routes, add migration 0003 --- .../ai_assistant/migrations/0003_sort_order.sql | 8 ++++++++ app/plugins/builtins/ai_assistant/models.py | 7 +++++++ app/plugins/builtins/ai_assistant/routes.py | 17 +++++++++++++++-- app/plugins/builtins/ai_assistant/schemas.py | 5 +++++ app/plugins/builtins/ai_assistant/services.py | 4 +++- 5 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 app/plugins/builtins/ai_assistant/migrations/0003_sort_order.sql diff --git a/app/plugins/builtins/ai_assistant/migrations/0003_sort_order.sql b/app/plugins/builtins/ai_assistant/migrations/0003_sort_order.sql new file mode 100644 index 0000000..f9c5462 --- /dev/null +++ b/app/plugins/builtins/ai_assistant/migrations/0003_sort_order.sql @@ -0,0 +1,8 @@ +-- Migration 0003: Add sort_order columns for drag&drop reordering + +ALTER TABLE ai_chat_sessions ADD COLUMN IF NOT EXISTS sort_order INTEGER NOT NULL DEFAULT 0; +ALTER TABLE ai_chat_folders ADD COLUMN IF NOT EXISTS sort_order INTEGER NOT NULL DEFAULT 0; + +CREATE INDEX IF NOT EXISTS ix_ai_sessions_folder ON ai_chat_sessions(folder_id); +CREATE INDEX IF NOT EXISTS ix_ai_sessions_sort ON ai_chat_sessions(sort_order); +CREATE INDEX IF NOT EXISTS ix_ai_folders_sort ON ai_chat_folders(sort_order); diff --git a/app/plugins/builtins/ai_assistant/models.py b/app/plugins/builtins/ai_assistant/models.py index 8f7650c..2921ecb 100644 --- a/app/plugins/builtins/ai_assistant/models.py +++ b/app/plugins/builtins/ai_assistant/models.py @@ -149,6 +149,12 @@ class AIChatSession(Base, TenantMixin): title: Mapped[str] = mapped_column(String(255), nullable=False, default="Neuer Chat") is_pinned: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False) is_sidebar: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False) + folder_id: Mapped[uuid.UUID | None] = mapped_column( + PGUUID(as_uuid=True), + ForeignKey("ai_chat_folders.id", ondelete="SET NULL"), + nullable=True, + ) + sort_order: Mapped[int] = mapped_column(Integer, nullable=False, default=0) # --- Chat Messages --- @@ -200,6 +206,7 @@ class AIChatFolder(Base, TenantMixin): nullable=True, ) user_id: Mapped[uuid.UUID] = mapped_column(PGUUID(as_uuid=True), nullable=False) + sort_order: Mapped[int] = mapped_column(Integer, nullable=False, default=0) # --- Chat Attachments --- diff --git a/app/plugins/builtins/ai_assistant/routes.py b/app/plugins/builtins/ai_assistant/routes.py index ff2c955..7e22914 100644 --- a/app/plugins/builtins/ai_assistant/routes.py +++ b/app/plugins/builtins/ai_assistant/routes.py @@ -457,11 +457,16 @@ async def create_session( if default_agent: agent_id = default_agent.id + folder_id = None + if data.folder_id: + folder_id = uuid.UUID(data.folder_id) + session = AIChatSession( user_id=user_id, agent_id=agent_id, title=data.title, is_sidebar=data.is_sidebar, + folder_id=folder_id, tenant_id=tenant_id, ) db.add(session) @@ -486,6 +491,11 @@ async def update_session( update_data = data.model_dump(exclude_unset=True) if "agent_id" in update_data and update_data["agent_id"]: update_data["agent_id"] = uuid.UUID(update_data["agent_id"]) + if "folder_id" in update_data: + if update_data["folder_id"]: + update_data["folder_id"] = uuid.UUID(update_data["folder_id"]) + else: + update_data["folder_id"] = None for field, val in update_data.items(): setattr(session, field, val) await db.commit() @@ -643,8 +653,11 @@ async def update_folder( raise HTTPException(status_code=404, detail="Folder not found") update_data = data.model_dump(exclude_unset=True) - if "parent_id" in update_data and update_data["parent_id"]: - update_data["parent_id"] = uuid.UUID(update_data["parent_id"]) + if "parent_id" in update_data: + if update_data["parent_id"]: + update_data["parent_id"] = uuid.UUID(update_data["parent_id"]) + else: + update_data["parent_id"] = None for field, val in update_data.items(): setattr(folder, field, val) await db.commit() diff --git a/app/plugins/builtins/ai_assistant/schemas.py b/app/plugins/builtins/ai_assistant/schemas.py index 52f1e28..4b9b183 100644 --- a/app/plugins/builtins/ai_assistant/schemas.py +++ b/app/plugins/builtins/ai_assistant/schemas.py @@ -163,6 +163,7 @@ class ChatSessionCreate(BaseModel): title: str = Field(default="Neuer Chat", max_length=255) agent_id: str | None = None is_sidebar: bool = False + folder_id: str | None = None class ChatSessionUpdate(BaseModel): @@ -170,6 +171,7 @@ class ChatSessionUpdate(BaseModel): is_pinned: bool | None = None agent_id: str | None = None folder_id: str | None = None + sort_order: int | None = None class ChatSessionResponse(BaseModel): @@ -181,6 +183,7 @@ class ChatSessionResponse(BaseModel): is_pinned: bool is_sidebar: bool folder_id: str | None = None + sort_order: int = 0 created_at: datetime | None = None updated_at: datetime | None = None @@ -215,6 +218,7 @@ class ChatFolderCreate(BaseModel): class ChatFolderUpdate(BaseModel): name: str | None = Field(None, min_length=1, max_length=255) parent_id: str | None = None + sort_order: int | None = None class ChatFolderResponse(BaseModel): @@ -223,6 +227,7 @@ class ChatFolderResponse(BaseModel): name: str parent_id: str | None = None user_id: str + sort_order: int = 0 created_at: datetime | None = None diff --git a/app/plugins/builtins/ai_assistant/services.py b/app/plugins/builtins/ai_assistant/services.py index 2178454..0e79e94 100644 --- a/app/plugins/builtins/ai_assistant/services.py +++ b/app/plugins/builtins/ai_assistant/services.py @@ -115,7 +115,8 @@ def session_to_response(session: AIChatSession) -> dict[str, Any]: "title": session.title, "is_pinned": session.is_pinned, "is_sidebar": session.is_sidebar, - "folder_id": str(session.folder_id) if hasattr(session, 'folder_id') and session.folder_id else None, + "folder_id": str(session.folder_id) if session.folder_id else None, + "sort_order": session.sort_order, "created_at": session.created_at.isoformat() if session.created_at else None, "updated_at": session.updated_at.isoformat() if session.updated_at else None, } @@ -141,6 +142,7 @@ def folder_to_response(folder: AIChatFolder) -> dict[str, Any]: "name": folder.name, "parent_id": str(folder.parent_id) if folder.parent_id else None, "user_id": str(folder.user_id), + "sort_order": folder.sort_order, "created_at": folder.created_at.isoformat() if folder.created_at else None, }