diff --git a/wwwroot/api/task_tree.dspy b/wwwroot/api/task_tree.dspy index d522d2a..c01ca54 100644 --- a/wwwroot/api/task_tree.dspy +++ b/wwwroot/api/task_tree.dspy @@ -25,14 +25,32 @@ _state_zh = { 'failed': '失败', 'waiting': '等待中', 'submitted': '已提交', 'review': '审核中', 'rejected': '已驳回', 'paused': '已暂停', 'cancelled': '已取消', } -# 阶段顺序(role 规范名 → 中文名) -_phase_order = [ - ('agent.requirement', '需求阶段'), - ('agent.design', '设计阶段'), - ('agent.develop', '开发阶段'), - ('agent.test', '测试阶段'), - ('agent.deploy', '部署阶段'), -] +# 阶段顺序:从产线角色集(SDL_ROLES)动态生成,用 next_role 链推导线性角色(自动排除 qc 门禁)。 +def _get_phase_order(): + try: + from pipeline_core import list_roles + roles = list_roles("sdlc_general") or [] + role_map = {r.name: r for r in roles} + next_set = {getattr(r, 'next_role', '') for r in roles if getattr(r, 'next_role', '')} + heads = [r for r in roles if r.name not in next_set and getattr(r, 'next_role', '')] + order = [] + seen = set() + cur = heads[0] if heads else None + while cur and cur.name not in seen: + seen.add(cur.name) + desc = getattr(cur, 'description', '') or cur.name + order.append((cur.name, desc)) + cur = role_map.get(getattr(cur, 'next_role', '')) + return order + except Exception: + return [ + ('agent.requirement', '需求阶段'), + ('agent.design', '设计阶段'), + ('agent.develop', '开发阶段'), + ('agent.deploy_test', '测试环境部署'), + ('agent.test', '测试阶段'), + ('agent.deploy_prod', '生产环境部署'), + ] def _iter_of(task): @@ -128,7 +146,7 @@ async with DBPools().sqlorContext(dbname) as sor: r = (getattr(t, 'role', '') or '').strip() role_cnt[r] = role_cnt.get(r, 0) + 1 nodes = [] - for rn, rzh in _phase_order: + for rn, rzh in _get_phase_order(): if rn in role_cnt: nodes.append({ "id": "iter:{}:phase:{}".format(iter_id, rn),