0422967229
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
65 lines
2.1 KiB
Python
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)
|