For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: 将打回改为本单终态;进度不再出现独立「打回」节点与多轮轴;已处理含打回;已打回/已撤销/已拒绝均可复制表单开新实例(无旧单关联)。
Architecture: 引擎侧修正 list_tasks/build_progress_items,废弃同实例 resubmit 与 source_instance_id 业务写入;前端统一「复制并重新发起」走 copyFromInstanceId 预填后 start。
Tech Stack: FastAPI / SQLAlchemy / Vue 3 / Element Plus;单测 backend/tests/test_oa_engine.py
Spec: docs/superpowers/specs/2026-07-15-oa-return-copy-new-instance-design.md
Files:
backend/app/services/oa_engine.py (list_tasks, build_progress_items, return_task 注释)Modify: backend/tests/test_oa_engine.py
[ ] Step 1: list_tasks 的 kind=="done" 改为 status.in_(("approved", "rejected", "returned"))
[ ] Step 2: build_progress_items:删除对 returns_by_round / kind=return 的追加;在终态分支增加 returned → _terminal_item("returned", "已打回", inst);轮次循环可保留字段但前端不再标「第 N 轮」(引擎仍可只投当前已有任务)
[ ] Step 3: 单测:
test_done_list_includes_returned:任务 status=returned 出现在 donetest_progress_return_no_duplicate_return_kind:task returned + return event 时 progress 无 kind==return,仅有 task.status=returned,且有 terminal returnedtest_resubmit_starts_new_round 为 test_resubmit_raises_deprecated[ ] Step 4: pytest backend/tests/test_oa_engine.py -q 通过后 commit
Files:
backend/app/services/oa_engine.py (start_instance, get_instance_detail, resubmit_instance)Modify: backend/app/api/oa_approval.py(resubmit 路由返回 410/业务错误或保留但引擎抛错)
[ ] Step 1: resubmit_instance 改为直接 raise OaEngineError("同实例再次提交已废弃,请复制表单重新发起")
[ ] Step 2: start_instance 不再将 source_instance_id 写入实例(参数可忽略)
[ ] Step 3: get_instance_detail 不再查/返回有意义的 resubmittedInstanceId 关联跳转(置空);sourceInstanceId 恒返回空字符串(兼容前端字段)
[ ] Step 4: 更新测试 + commit
Files:
web-admin/src/views/oa-approval/instances/detail.vueweb-admin/src/views/oa-approval/_placeholder/RuntimeList.vueweb-admin/src/views/oa-approval/start/index.vueModify: web-admin/src/api/oaApproval.ts(可选保留 fetchResubmit 不再使用)
[ ] Step 1: 详情:returned 文案「已打回」;三种终态显示「复制并重新发起」→ start?appId=©FromInstanceId=;去掉同单 resubmit、原单/重提单提示、轮次标题、kind===return 标签
[ ] Step 2: RuntimeList:mine 在 returned|cancelled|rejected 显示同一按钮;文案「已打回」;query 用 copyFromInstanceId
[ ] Step 3: start:读 copyFromInstanceId 预填 formData;submit 不传 sourceInstanceId
[ ] Step 4: commit
./scripts/update-graph.sh backend(若改了 backend)Self-review: Spec §3–§7 均有对应 Task;无 TBD;copyFromInstanceId 命名前后一致。