fix: 修复 3 个 P0 端点 500 错误根因(async/sync 不匹配 + edit_plan_id 残留) #114
@@ -18,7 +18,6 @@ depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.add_column("generation_tasks", sa.Column("edit_plan_id", sa.String(32), nullable=False, server_default=""))
|
||||
op.add_column("generation_tasks", sa.Column("template_id", sa.String(36), nullable=False, server_default=""))
|
||||
op.add_column("generation_tasks", sa.Column("asset_ids", mysql.JSON(), nullable=False, server_default="[]"))
|
||||
op.add_column("generation_tasks", sa.Column("title_ids", mysql.JSON(), nullable=False, server_default="[]"))
|
||||
@@ -33,4 +32,3 @@ def downgrade() -> None:
|
||||
op.drop_column("generation_tasks", "title_ids")
|
||||
op.drop_column("generation_tasks", "asset_ids")
|
||||
op.drop_column("generation_tasks", "template_id")
|
||||
op.drop_column("generation_tasks", "edit_plan_id")
|
||||
|
||||
@@ -84,7 +84,7 @@ def _ensure_library_has_ready_video_assets(assets) -> None:
|
||||
)
|
||||
|
||||
|
||||
async def _resolve_project_and_library(
|
||||
def _resolve_project_and_library(
|
||||
request: CreateGenerationTaskRequest,
|
||||
project_repository: Any,
|
||||
asset_library_repository: Any,
|
||||
@@ -104,7 +104,7 @@ async def _resolve_project_and_library(
|
||||
# 模板模式:project_id 未提供时,从 asset_ids 反查所属 project
|
||||
if not project_id and request.asset_ids:
|
||||
first_asset_id = request.asset_ids[0]
|
||||
asset = await asset_repository.find_by_id(first_asset_id)
|
||||
asset = asset_repository.find_by_id(first_asset_id)
|
||||
if asset is not None:
|
||||
project_id = asset.project_id
|
||||
if not asset_library_id:
|
||||
@@ -122,7 +122,7 @@ async def _resolve_project_and_library(
|
||||
|
||||
|
||||
@router.post("/tasks", response_model=GenerationTaskResponse)
|
||||
async def create_generation_task(
|
||||
def create_generation_task(
|
||||
request: CreateGenerationTaskRequest,
|
||||
authenticated_user: AuthenticatedUser = Depends(get_current_user),
|
||||
generation_task_repository: Any = Depends(get_generation_task_repository),
|
||||
@@ -130,7 +130,7 @@ async def create_generation_task(
|
||||
asset_library_repository: Any = Depends(get_asset_library_repository),
|
||||
asset_repository: Any = Depends(get_asset_repository),
|
||||
) -> GenerationTaskResponse:
|
||||
project_id, asset_library_id = await _resolve_project_and_library(
|
||||
project_id, asset_library_id = _resolve_project_and_library(
|
||||
request, project_repository, asset_library_repository, asset_repository, authenticated_user
|
||||
)
|
||||
|
||||
@@ -140,7 +140,7 @@ async def create_generation_task(
|
||||
if library is None or (project_id and library.project_id != project_id):
|
||||
raise HTTPException(status_code=404, detail=f"AssetLibrary {asset_library_id} not found")
|
||||
|
||||
assets = await asset_repository.find_by_library(asset_library_id)
|
||||
assets = asset_repository.find_by_library(asset_library_id)
|
||||
_ensure_library_has_ready_video_assets(assets)
|
||||
|
||||
use_case = CreateGenerationTaskUseCase(generation_task_repository)
|
||||
@@ -229,7 +229,6 @@ def retry_generation_task(
|
||||
asset_library_id=task.asset_library_id,
|
||||
strategy_id=task.strategy_id,
|
||||
voice_library_id=task.voice_library_id,
|
||||
edit_plan_id=task.edit_plan_id,
|
||||
template_id=task.template_id,
|
||||
asset_ids=task.asset_ids,
|
||||
title_ids=task.title_ids,
|
||||
|
||||
@@ -146,7 +146,6 @@ def retry_task_by_id(
|
||||
asset_library_id=task.asset_library_id,
|
||||
strategy_id=task.strategy_id,
|
||||
voice_library_id=task.voice_library_id,
|
||||
edit_plan_id=task.edit_plan_id,
|
||||
template_id=task.template_id,
|
||||
asset_ids=task.asset_ids,
|
||||
title_ids=task.title_ids,
|
||||
@@ -229,7 +228,6 @@ def retry_project_task(
|
||||
asset_library_id=task.asset_library_id,
|
||||
strategy_id=task.strategy_id,
|
||||
voice_library_id=task.voice_library_id,
|
||||
edit_plan_id=task.edit_plan_id,
|
||||
template_id=task.template_id,
|
||||
asset_ids=task.asset_ids,
|
||||
title_ids=task.title_ids,
|
||||
|
||||
@@ -11,7 +11,7 @@ class SQLAlchemyAssetRepository:
|
||||
def __init__(self, session: Session):
|
||||
self.session = session
|
||||
|
||||
async def find_by_library(
|
||||
def find_by_library(
|
||||
self,
|
||||
library_id: str,
|
||||
skip: int = 0,
|
||||
@@ -22,7 +22,7 @@ class SQLAlchemyAssetRepository:
|
||||
).offset(skip).limit(limit).all()
|
||||
return [self._to_domain(model) for model in models]
|
||||
|
||||
async def find_by_project(
|
||||
def find_by_project(
|
||||
self,
|
||||
project_id: str,
|
||||
skip: int = 0,
|
||||
@@ -33,7 +33,7 @@ class SQLAlchemyAssetRepository:
|
||||
).offset(skip).limit(limit).all()
|
||||
return [self._to_domain(model) for model in models]
|
||||
|
||||
async def find_by_id(self, asset_id: str) -> Asset | None:
|
||||
def find_by_id(self, asset_id: str) -> Asset | None:
|
||||
model = self.session.query(AssetModel).filter(AssetModel.id == asset_id).first()
|
||||
if model is None:
|
||||
return None
|
||||
@@ -42,7 +42,7 @@ class SQLAlchemyAssetRepository:
|
||||
def get(self, asset_id: str) -> Asset | None:
|
||||
return self.find_by_id(asset_id)
|
||||
|
||||
async def create(self, asset: Asset) -> Asset:
|
||||
def create(self, asset: Asset) -> Asset:
|
||||
now = datetime.now(timezone.utc)
|
||||
model = AssetModel(
|
||||
id=asset.id,
|
||||
@@ -70,7 +70,7 @@ class SQLAlchemyAssetRepository:
|
||||
self.session.commit()
|
||||
return asset
|
||||
|
||||
async def update(self, asset: Asset) -> Asset:
|
||||
def update(self, asset: Asset) -> Asset:
|
||||
model = self.session.query(AssetModel).filter(AssetModel.id == asset.id).first()
|
||||
if model is None:
|
||||
raise ValueError(f"Asset {asset.id} not found")
|
||||
@@ -92,7 +92,7 @@ class SQLAlchemyAssetRepository:
|
||||
self.session.commit()
|
||||
return asset
|
||||
|
||||
async def delete(self, asset_id: str) -> bool:
|
||||
def delete(self, asset_id: str) -> bool:
|
||||
model = self.session.query(AssetModel).filter(AssetModel.id == asset_id).first()
|
||||
if model:
|
||||
self.session.delete(model)
|
||||
@@ -100,7 +100,7 @@ class SQLAlchemyAssetRepository:
|
||||
return True
|
||||
return False
|
||||
|
||||
async def count_by_project(self, project_id: str) -> int:
|
||||
def count_by_project(self, project_id: str) -> int:
|
||||
return self.session.query(AssetModel).filter(
|
||||
AssetModel.project_id == project_id
|
||||
).count()
|
||||
|
||||
@@ -12,7 +12,6 @@ def _to_domain(model: GenerationTaskModel) -> GenerationTask:
|
||||
strategy_id=model.strategy_id,
|
||||
asset_library_id=model.asset_library_id,
|
||||
voice_library_id=model.voice_library_id,
|
||||
edit_plan_id=model.edit_plan_id,
|
||||
template_id=model.template_id,
|
||||
asset_ids=list(model.asset_ids or []),
|
||||
title_ids=list(model.title_ids or []),
|
||||
@@ -39,7 +38,6 @@ class SQLAlchemyGenerationTaskRepository:
|
||||
strategy_id=task.strategy_id,
|
||||
asset_library_id=task.asset_library_id,
|
||||
voice_library_id=task.voice_library_id,
|
||||
edit_plan_id=task.edit_plan_id,
|
||||
template_id=task.template_id,
|
||||
asset_ids=task.asset_ids,
|
||||
title_ids=task.title_ids,
|
||||
@@ -106,7 +104,6 @@ class SQLAlchemyGenerationTaskRepository:
|
||||
model.asset_library_id = task.asset_library_id
|
||||
model.strategy_id = task.strategy_id
|
||||
model.voice_library_id = task.voice_library_id
|
||||
model.edit_plan_id = task.edit_plan_id
|
||||
model.template_id = task.template_id
|
||||
model.asset_ids = task.asset_ids
|
||||
model.title_ids = task.title_ids
|
||||
|
||||
@@ -143,7 +143,6 @@ class GenerationTaskModel(Base):
|
||||
strategy_id = Column(String(32), nullable=False, default="")
|
||||
asset_library_id = Column(String(32), nullable=False, default="", index=True)
|
||||
voice_library_id = Column(String(32), nullable=False, default="")
|
||||
edit_plan_id = Column(String(32), nullable=False, default="")
|
||||
template_id = Column(String(36), nullable=False, default="", index=True)
|
||||
asset_ids = Column(JSON, nullable=False, default=list)
|
||||
title_ids = Column(JSON, nullable=False, default=list)
|
||||
|
||||
@@ -13,7 +13,6 @@ class CreateGenerationTaskCommand:
|
||||
asset_library_id: str = ""
|
||||
strategy_id: str = ""
|
||||
voice_library_id: str = ""
|
||||
edit_plan_id: str = ""
|
||||
template_id: str = ""
|
||||
asset_ids: list[str] = field(default_factory=list)
|
||||
title_ids: list[str] = field(default_factory=list)
|
||||
@@ -32,7 +31,6 @@ class CreateGenerationTaskUseCase:
|
||||
asset_library_id=command.asset_library_id,
|
||||
strategy_id=command.strategy_id,
|
||||
voice_library_id=command.voice_library_id,
|
||||
edit_plan_id=command.edit_plan_id,
|
||||
template_id=command.template_id,
|
||||
asset_ids=command.asset_ids,
|
||||
title_ids=command.title_ids,
|
||||
|
||||
@@ -21,7 +21,6 @@ class GenerationTask:
|
||||
asset_library_id: str
|
||||
strategy_id: str = ""
|
||||
voice_library_id: str = ""
|
||||
edit_plan_id: str = ""
|
||||
template_id: str = ""
|
||||
asset_ids: list[str] = field(default_factory=list)
|
||||
title_ids: list[str] = field(default_factory=list)
|
||||
@@ -43,7 +42,6 @@ class GenerationTask:
|
||||
*,
|
||||
strategy_id: str = "",
|
||||
voice_library_id: str = "",
|
||||
edit_plan_id: str = "",
|
||||
template_id: str = "",
|
||||
asset_ids: list[str] | None = None,
|
||||
title_ids: list[str] | None = None,
|
||||
@@ -60,7 +58,6 @@ class GenerationTask:
|
||||
asset_library_id=asset_library_id.strip(),
|
||||
strategy_id=strategy_id.strip(),
|
||||
voice_library_id=voice_library_id.strip(),
|
||||
edit_plan_id=edit_plan_id.strip(),
|
||||
template_id=template_id.strip(),
|
||||
asset_ids=list(asset_ids) if asset_ids else [],
|
||||
title_ids=list(title_ids) if title_ids else [],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""兼容层:旧素材仓储接口定义,保留给遗留异步适配器使用。"""
|
||||
"""素材仓储接口定义。"""
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
@@ -7,15 +7,15 @@ from packages.domain import Asset
|
||||
|
||||
class AssetRepository(ABC):
|
||||
@abstractmethod
|
||||
async def create(self, asset: Asset) -> Asset:
|
||||
def create(self, asset: Asset) -> Asset:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def find_by_id(self, asset_id: str) -> Asset | None:
|
||||
def find_by_id(self, asset_id: str) -> Asset | None:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def find_by_project(
|
||||
def find_by_project(
|
||||
self,
|
||||
project_id: str,
|
||||
skip: int = 0,
|
||||
@@ -24,7 +24,7 @@ class AssetRepository(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def find_by_library(
|
||||
def find_by_library(
|
||||
self,
|
||||
library_id: str,
|
||||
skip: int = 0,
|
||||
@@ -33,15 +33,15 @@ class AssetRepository(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def update(self, asset: Asset) -> Asset:
|
||||
def update(self, asset: Asset) -> Asset:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def delete(self, asset_id: str) -> bool:
|
||||
def delete(self, asset_id: str) -> bool:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def count_by_project(self, project_id: str) -> int:
|
||||
def count_by_project(self, project_id: str) -> int:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
|
||||
Reference in New Issue
Block a user