diff --git a/backend/api/cloud/schemas.py b/backend/api/cloud/schemas.py index 1066321..75a6271 100644 --- a/backend/api/cloud/schemas.py +++ b/backend/api/cloud/schemas.py @@ -9,7 +9,7 @@ from __future__ import annotations from datetime import datetime from typing import List, Optional -from pydantic import BaseModel, field_validator +from pydantic import BaseModel, Field, field_validator # ── Capability / item schemas ───────────────────────────────────────────────── @@ -75,7 +75,7 @@ class ConnectionRenameRequest(BaseModel): Only display_name is accepted — mass assignment prevention. """ - display_name: str + display_name: str = Field(..., max_length=255) @field_validator("display_name") @classmethod diff --git a/backend/services/cloud_items.py b/backend/services/cloud_items.py index c8467cf..4730d69 100644 --- a/backend/services/cloud_items.py +++ b/backend/services/cloud_items.py @@ -229,6 +229,7 @@ async def get_or_create_folder_state( uid_fs = user_id if isinstance(user_id, uuid.UUID) else uuid.UUID(str(user_id)) result = await session.execute( select(CloudFolderState).where( + CloudFolderState.user_id == uid_fs, CloudFolderState.connection_id == cid_fs, CloudFolderState.parent_ref == parent_ref, ) diff --git a/backend/tasks/cloud_tasks.py b/backend/tasks/cloud_tasks.py index 9bbc147..aed2faf 100644 --- a/backend/tasks/cloud_tasks.py +++ b/backend/tasks/cloud_tasks.py @@ -107,7 +107,7 @@ async def _run(user_id: str, connection_id: str, parent_ref: str | None) -> dict error_message="Credential decryption failed. Re-connect the account.", ) await session.commit() - raise _TerminalProviderError(f"Credential decryption failed: {exc}") from exc + raise _TerminalProviderError("Credential decryption failed. Re-connect the account.") from exc # Build adapter and fetch listing try: @@ -133,9 +133,9 @@ async def _run(user_id: str, connection_id: str, parent_ref: str | None) -> dict error_message="Authentication failed. Re-connect the account.", ) await session.commit() - raise _TerminalProviderError(f"Auth error: {exc}") from exc + raise _TerminalProviderError("Authentication failed. Re-connect the account.") from exc # Transient failure — let Celery retry - raise _TransientProviderError(f"Provider error: {exc}") from exc + raise _TransientProviderError("Provider error. Will retry.") from exc # Reconcile listing into durable cloud_items rows await reconcile_cloud_listing( diff --git a/frontend/src/api/cloud.js b/frontend/src/api/cloud.js index 8582b31..62b8961 100644 --- a/frontend/src/api/cloud.js +++ b/frontend/src/api/cloud.js @@ -30,11 +30,12 @@ export function updateDefaultStorage(backend) { } /** - * Browse a cloud folder by connection UUID and folder path. - * connectionId is always a UUID; folderId is a path string (default 'root'). + * Browse a cloud folder by connection UUID and optional parent_ref. + * connectionId is always a UUID; parentRef is a provider path string (default ''). */ -export function getCloudFoldersByConnectionId(connectionId, folderId) { - return request(`/api/cloud/connections/${connectionId}/folders/${folderId}`) +export function getCloudFoldersByConnectionId(connectionId, parentRef = '') { + const qs = parentRef ? `?parent_ref=${encodeURIComponent(parentRef)}` : '' + return request(`/api/cloud/connections/${connectionId}/items${qs}`) } /** @deprecated Use getCloudFoldersByConnectionId instead. */