update: workspace lazy load

This commit is contained in:
tao.chen
2026-08-12 18:36:17 +08:00
parent c6c2481b96
commit 495018de34
3 changed files with 152 additions and 2 deletions
+74
View File
@@ -623,6 +623,7 @@ async def get_workspace_tree(
select(StorageObjects.relative_path, StorageObjects.object_type).where(
StorageObjects.workspace_id == context.workspace.workspace_id,
StorageObjects.object_status == "available",
StorageObjects.is_deleted == 0,
StorageObjects.relative_path.like(like_prefix),
)
)
@@ -664,6 +665,74 @@ async def get_workspace_tree(
},
)
sorted_dirs = sorted(directories.values(), key=lambda item: item["path"])
return {
"request_id": context.request_id,
"data": {"directories": sorted_dirs},
"meta": {"directory_count": len(sorted_dirs)},
}
@router.get("/api/v1/workspace-directories")
async def list_workspace_directories(
parent_path: str = Query(default=""),
context: RequestContext = Depends(request_context),
session: AsyncSession = Depends(database_session),
) -> dict[str, Any]:
"""List direct child directories of a workspace path.
Empty ``parent_path`` returns the directories immediately under the
user's scoped root. Only available, non-deleted StorageObjects are
considered.
"""
scoped_prefix = user_relative_path(context)
parent = normalize_user_path(parent_path)
target_prefix = f"{scoped_prefix}/{parent}" if parent else scoped_prefix
descendant_prefix = f"{target_prefix}/"
rows = (
await session.execute(
select(StorageObjects.relative_path, StorageObjects.object_type).where(
StorageObjects.workspace_id == context.workspace.workspace_id,
StorageObjects.object_status == "available",
StorageObjects.is_deleted == 0,
StorageObjects.relative_path.like(f"{descendant_prefix}%"),
~StorageObjects.relative_path.like(f"{descendant_prefix}%/%"),
)
)
).all()
directories: dict[str, dict[str, Any]] = {}
for relative, _object_type in rows:
if not relative or not relative.startswith(descendant_prefix):
continue
suffix = relative[len(descendant_prefix) :]
if "/" in suffix:
continue
child_path = f"{parent}/{suffix}" if parent else suffix
directories.setdefault(
child_path,
{
"path": child_path,
"name": suffix,
"parent_path": parent,
"has_children": False,
},
)
for directory in directories.values():
child_prefix = f"{target_prefix}/{directory['path']}/"
has_children = await session.scalar(
select(StorageObjects.storage_object_id).where(
StorageObjects.workspace_id == context.workspace.workspace_id,
StorageObjects.object_status == "available",
StorageObjects.is_deleted == 0,
StorageObjects.relative_path.like(f"{child_prefix}%"),
~StorageObjects.relative_path.like(f"{child_prefix}%/%"),
).limit(1)
)
directory["has_children"] = has_children is not None
sorted_dirs = sorted(directories.values(), key=lambda item: item["path"])
return {
"request_id": context.request_id,
"data": {"directories": sorted_dirs},
@@ -1160,6 +1229,11 @@ async def delete_script(
detail=exc.detail,
) from exc
if storage_object:
storage_object.object_status = "deleted"
storage_object.is_deleted = 1
storage_object.deleted_at = datetime.now(UTC).replace(tzinfo=None)
script.status = "deleted"
script.deleted_at = datetime.now(UTC).replace(tzinfo=None)
return {