fix(backend): 权限漏洞修复 + 业务逻辑审查修复

1. 宏观状态越权修复 (products.py + product_service.py):
   - update_overall_status 增加权限校验:仅 SUPER_ADMIN 或当前操作该产品主线任务的人可修改,否则 403

2. 任务撤回越权修复 (task_service.py + tasks.py):
   - recall_task 增加校验:操作人必须等于上游任务负责人(谁发出的谁撤回),否则 403
   - 管理员 (SUPER_ADMIN/SUPERVISOR) 直接放行

3. 驳回上游溯源修复 (task_service.py - reject_task):
   - 将 TaskLog (action_type=create) 提升为优先溯源方式,解决协助分支转交后驳回找不到正确发起人的 Bug
   - 保留 parent_task.assignee_id + task.assignee_id 两级兜底

4. complete_task 父节点继承修复:
   - 修复 task_type == 'MAIN' 永不匹配的 Bug(模型无此值)
   - 改为 not parent_task_id or task_type in (TRANSFER, RECOVERY)
This commit is contained in:
2026-08-11 15:05:30 +08:00
parent d40a8d480e
commit 88dc7381f6
4 changed files with 120 additions and 22 deletions

View File

@ -60,6 +60,7 @@ async def get_task(
async def create_task_endpoint(
data: TaskCreate,
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(get_current_user),
):
"""创建任务"""
return await task_service.create_task(db, data)
@ -70,6 +71,7 @@ async def update_task_endpoint(
task_id: str,
data: TaskUpdate,
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(get_current_user),
):
"""更新任务"""
return await task_service.update_task(db, uuid.UUID(task_id), data)
@ -137,12 +139,16 @@ async def recall_task_endpoint(
task_id: str,
operator_id: str | None = Query(None),
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(get_current_user),
):
"""
**撤回转交:删除 PENDING 子任务,恢复父任务为 WIP。**
适用场景:转交后发现选错人,在对方接收前撤回。
"""
return await task_service.recall_task(db, uuid.UUID(task_id), operator_id)
return await task_service.recall_task(
db, uuid.UUID(task_id), operator_id,
operator_role=current_user.get("role"),
)
# ============================================================
@ -161,6 +167,7 @@ async def spawn_subtask_endpoint(
data: SpawnRequest,
operator_id: str | None = Query(None),
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(get_current_user),
):
"""
**派发协助分支:在当前任务下创建并行子任务,父任务状态保持不变。**
@ -263,6 +270,7 @@ async def create_subtask_endpoint(
task_id: str,
data: SubtaskCreate,
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(get_current_user),
):
"""
**创建子任务:支持无限层级嵌套。**
@ -297,6 +305,7 @@ async def add_task_record_endpoint(
task_id: str,
data: TaskRecordCreate,
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(get_current_user),
):
"""追加进度记录(备注+图片),不改变任务状态"""
return await task_service.add_task_record(db, uuid.UUID(task_id), data)