Files
xiaoxia-saas/packages/application/assets.py
T
xiaoxia 0422967229 refactor: Remove workspace concept - Projects now directly under User
BREAKING CHANGES:
- Removed Workspace, WorkspaceMember, WorkspaceInvitation entities
- Project now has owner_user_id instead of workspace_id
- Added shared_users list to Project for collaboration
- Subscription/quota moved from Workspace to User level

Changes:
- packages/domain/entities.py: Removed Workspace entities, updated Project
- packages/adapters/sqlalchemy_impl/models.py: Updated models
- packages/application/: Removed workspace use cases, updated other use cases
- packages/ports/: Removed workspace repository interfaces
- apps/api/: Updated routes, schemas, dependencies, router
- alembic/versions/007_remove_workspace_concept.py: Database migration

New APIs:
- POST /projects/{id}/share: Share project with user
- DELETE /projects/{id}/share/{user_id}: Unshare project
2026-06-26 19:16:54 +08:00

65 lines
2.1 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
from packages.domain import Asset, AssetStatus, ClassificationStatus
from packages.ports.asset_repository import AssetRepository
@dataclass(slots=True)
class CreateAssetCommand:
project_id: str
library_id: str
name: str
storage_key: str
mime_type: str
metadata: dict[str, object] | None = None
file_size: int = 0
thumbnail_url: str | None = None
duration: float | None = None
width: int | None = None
height: int | None = None
fps: float | None = None
codec: str | None = None
status: AssetStatus = AssetStatus.UPLOADING
classification_status: ClassificationStatus = ClassificationStatus.PENDING
quality_score: float | None = None
uploaded_by_user_id: str = ""
class ListAssetsUseCase:
def __init__(self, asset_repository: AssetRepository):
self.asset_repository = asset_repository
def execute(self, library_id: str) -> list[Asset]:
if not library_id.strip():
raise ValueError("library_id 不能为空")
return self.asset_repository.find_by_library(library_id.strip())
class CreateAssetUseCase:
def __init__(self, asset_repository: AssetRepository):
self.asset_repository = asset_repository
def execute(self, command: CreateAssetCommand) -> Asset:
asset = Asset.create(
project_id=command.project_id,
library_id=command.library_id,
name=command.name,
storage_key=command.storage_key,
mime_type=command.mime_type,
metadata=command.metadata,
file_size=command.file_size,
thumbnail_url=command.thumbnail_url,
duration=command.duration,
width=command.width,
height=command.height,
fps=command.fps,
codec=command.codec,
status=command.status,
classification_status=command.classification_status,
quality_score=command.quality_score,
uploaded_by_user_id=command.uploaded_by_user_id,
)
return self.asset_repository.create(asset)