外观
任务管理平台总 PRD
需求来源:lamolabs/lamolabs-docs#48。 本文定义产品范围、核心行为和边界;数据模型、状态机与流程落点见同目录技术方案。
1. 背景与问题
1.1 现状
团队当前使用 GitHub Issue 管理任务:创建 Issue → 指定责任人 → 在群里通知。
1.2 现有流程的痛点
| # | 痛点 | 说明 |
|---|---|---|
| 1 | 信息难以同步 | 任务状态散落在 Issue 和群消息中,缺乏统一视图 |
| 2 | 跨仓库任务查询复杂 | 任务分布在多个仓库,全局查询和维护困难 |
| 3 | 跨仓库关联任务无法自动关闭 | 关联任务完成后无法联动关闭 |
| 4 | 任务无法内外部隔离 | 内部任务与外部(如客户/合作方)任务混在一起 |
| 5 | 责任人/参与人维度单一 | 仅能设置单个责任人,无法设置相关人员(关注人/参与人)及流程卡口审批人 |
| 6 | 跨仓库子任务难以主子关联 | 子任务与主任务无法跨仓库建立父子关系 |
| 7 | 中间进度靠口头沟通 | PRD 评审、技术评审等关键节点无结构化记录 |
3. 产品定位
- 替代 GitHub Issue:任务管理完全迁移到本平台,GitHub 仅保留代码托管,Issue 不再作为任务载体。
- 任务类型统一化:外部工单、内部需求、开发任务等本质都是"任务",差异仅体现在两点:
- 可见范围不同(内部 / 外部 / 跨团队等,见 4.2 权限模型)。
- 主流程节点不同(不同任务类型走不同的状态机配置)。
- 任务类型可扩展,新增类型只需配置"可见范围 + 主流程节点",无需改动核心模型。
4. 目标用户与场景
4.1 角色定义
| 角色 | 范围 | 核心诉求 | 关键操作 |
|---|---|---|---|
| 开发者 | 内部 | 领取任务、推进进度、关联代码 | 更新状态、填写进度节点、关联 PR/提交 |
| 负责人 / PM | 内部 | 分配任务、掌握全局进度、组织评审 | 创建/分配任务、查看看板与报表、发起评审节点 |
| 外部人员(客户/合作方) | 外部 | 提交问题、跟踪处理进度 | 提交工单/反馈、补充信息、确认工单完成 |
4.2 权限模型
按企业级规范设计(RBAC + ABAC),核心是组织 → 团队 → 任务类型(角色矩阵)→ 单任务授权四层可见性隔离。
4.2.1 组织结构
- 组织(Organization):最高隔离边界,跨组织严禁相互访问任何任务。
- 团队(Team):组织下的协作单元,跨团队任务默认相互隔离(不可见)。
- 用户(User):与团队为多对多关系——一个用户可同时加入多个团队(在组织内)。
- 任务(Task):归属于某个团队,可见性由任务类型 + 显式授权共同决定。
4.2.2 可见性规则
可见性由组织 → 团队 → 任务类型(角色矩阵)→ 单任务授权四层叠加判定。
| 层级 | 场景 | 可见性 |
|---|---|---|
| 组织 | 跨组织 | 严禁访问(硬边界) |
| 组织 | 组织管理员 | 可查看本组织下所有任务 |
| 团队 | 跨团队任务 | 默认不可见 |
| 任务类型 | 同团队内按类型隔离 | 按角色 × 任务类型可见性矩阵判定:某角色仅可见其被授权的任务类型(如开发人员不可见测试任务) |
| 单任务授权 | 显式授权(突破类型/团队隔离) | 被添加为该任务的"相关人员"或"负责人"的成员、该任务的创建人,以及当前或已配置人工卡点的审批人;外部任务另由 submitter_id 标识提交人并授予该外部任务可见性,不会把提交人身份传播到关联的内部任务 |
| 外部任务 | 外部人员 | 外部提交人和被授权处理方可查看完整内容;团队/组织管理员可查看必要的任务元数据并执行管理操作,但默认不可读客户联系方式、反馈正文等外部内容。被授权处理方通常为团队管理员,支持配置用户 ID 列表;外部人员不可读写处理方信息 |
优先级:组织管理员管理例外 / 团队管理员的团队管理权限 > 创建人、负责人、相关人员和跨团队关联产生的单任务授权 > 任务类型角色矩阵 > 团队默认隔离。管理员的管理例外不等于外部任务的客户内容可见性,也不能绕过外部工单提交人专属卡点(见 9.1 决策 10)。
外部任务的管理员管理视图只返回任务 ID、类型、状态、所属团队、负责人和时间等元数据;无论 form_schema 如何声明,管理员都不能读取客户字段、内部字段、反馈正文、截图、评论正文或敏感审计值。上述内容只对提交人及处理方白名单返回。外部任务的负责人和相关人员必须来自处理方白名单,管理员不能通过添加相关人员扩大完整内容可见范围。管理员可以在此受限投影上执行分配、状态管理和审计操作,但不能代替提交人通过 submitter_only 卡点。
4.2.3 角色分级(组织内)
组织角色从组织架构角度划分,与任务级属性(如"任务负责人"字段,见 6.1.1)解耦——成员可担任任意任务的负责人,但"负责人"不是组织角色。
- 成员:组织内普通成员,操作自己参与的任务(可被指派为任意任务的负责人)。活动的团队成员自动拥有内置任务角色
member,无需额外创建USER_ROLE记录。 - 团队管理员:管理团队内成员与任务,可审批本团队任务的人工卡点(见 6.1.2)。
- 组织管理员:管理组织、团队、成员,查看组织下全部任务,可审批组织内任意任务的人工卡点;只有 active 的内部成员(
membership_type=member)可以获得该角色,外部访客不能成为组织管理员。 - 任务角色:组织可定义
developer、tester等功能角色,并将成员按团队授予一个或多个任务角色;任务类型的visible_roles引用这些角色,不把角色名称硬编码在核心模型中。member是由活动USER_TEAM关系派生的保留基础角色,USER_ROLE仅记录额外的功能角色。 - 组织管理员拥有全组织可见性,但任务角色本身不授予管理权限;管理权限仍由成员、团队管理员、组织管理员三类组织角色决定。
- 团队管理员对本团队任务拥有管理权限,不要求另行具备某个
USER_ROLE;组织管理员对组织内任务拥有管理权限。两类管理员可以越过任务类型角色矩阵执行管理操作,但仍受组织边界、外部任务内容脱敏和submitter_only卡点限制。
4.2.4 核心操作权限矩阵
下表是 PermissionService.canPerformAction 的最小可验收契约。除特别说明外,所有操作都必须先通过 4.2.2 的可见性判定;跨组织访问永远拒绝。
| 操作 | 普通成员 | 负责人 / 创建人 | 团队管理员 | 组织管理员 | 外部提交人 | 系统 |
|---|---|---|---|---|---|---|
| 创建内部任务 | 本团队可创建 | 本团队可创建 | 本团队可创建 | 任意团队可创建 | — | 仅限关联声明触发的同步创建 |
| 创建外部工单 | — | — | — | — | 可创建自己的工单 | — |
| 修改任务基本字段 | — | 可修改自己创建或负责的任务 | 本团队任务 | 组织内任意任务 | 仅可补充自己的工单 | — |
| 指派负责人 / 管理相关人员 | — | — | 本团队任务 | 组织内任意任务 | — | — |
| 手动状态流转 | active TASK_HANDLER 可领取并执行外部工单“待处理→处理中” | 可流转自己负责或创建的任务 | 本团队任务;外部工单的 active TASK_HANDLER 可领取并执行“待处理→处理中”,管理员仅可执行固定的管理补偿边 | 组织内任意任务;外部工单的 active TASK_HANDLER 可领取并执行“待处理→处理中”,管理员仅可执行固定的管理补偿边 | — | — |
| 审批人工卡点 | — | 仅当被配置为审批人 | 本团队任务 | 组织内任意任务 | 可确认或驳回自己的外部工单 | — |
| 建立任务关联 | — | 可操作自己负责或创建的任务 | 本团队任务 | 组织内任意任务 | — | — |
| 关闭任务 | — | 可关闭自己负责且已到终态的任务 | 本团队已到终态任务;外部工单不得绕过提交人确认 | 组织内已到终态任务;外部工单不得绕过提交人确认 | 可关闭自己且已到终态的外部工单 | — |
| 重新打开任务 | — | — | 本团队任务 | 组织内任意任务 | — | — |
| 归档任务 | — | — | — | 仅可在关闭满 2 个月后手动触发合规归档 | — | 关闭满 2 个月后批量归档 |
| 删除任务 | — | — | — | — | — | — |
外部工单的“待用户确认”是提交人专属人工卡点:团队管理员和组织管理员可以管理工单,但不能代替提交人确认或驳回。管理员只可执行固定的“管理补偿”边(例如关联任务完成事件丢失时,将工单重新送入“待用户确认”),不能直接进入终态或关闭任务。 “待用户确认”到“已完成”的确认边与回到“处理中”的驳回边都属于 trigger_mode=human_gate,统一通过 canApproveGate 鉴权;驳回不是 manual 状态流转,也不是独立的 reopen 操作。 矩阵中管理员对外部工单的“修改、指派、状态流转、关闭”均只针对上述受限管理投影,不包含客户内容,也不改变提交人专属卡点;外部工单不得把普通管理权限解释为跳过 submitter_only 的权限。 外部提交人在创建工单时只能提交标题、描述和允许的 shared 字段,不能提交 team_id、负责人、相关人员或处理方白名单;这些字段只能由内部管理员配置或由白名单处理方领取。
系统账号没有通用的“创建内部任务”权限;只有外部工单类型的 relation_declarations 明确声明同步创建内部任务时,平台才以绑定目标组织的 service 账号执行一次性 create_linked_task 操作,并在同一事务校验目标团队、目标类型版本和组织边界。该操作不允许客户端直接调用,也不授予 service 账号作为负责人、参与人或人工卡点审批人的权限。
关闭前置条件:
关闭任务不是绕过状态机的直接状态写入。canPerformAction(..., close)只有在任务当前STATE_NODE.exit_mode=terminal、所有进入终态前的guard和人工卡点均已通过时才允许执行;非终态任务必须先沿已声明的STATE_TRANSITION流转。若未来需要“取消”等非完成类终止动作,应单独建模为带审计的状态边,不能复用关闭权限。
5. 产品目标与成功指标
| # | 指标 | 类型 | 说明 |
|---|---|---|---|
| 1 | 跨任务查询耗时下降 | 定性 | 全局一次查询替代翻多个仓库,查询与维护成本显著降低 |
| 2 | 任务状态同步延迟下降 | 定性 | 状态实时可见于平台,替代"群里问/口头同步" |
| 3 | 状态节点结构化记录覆盖率 | 定性 | 所有主流程状态节点(含 PRD/技术评审等检查点)均有结构化记录,不再口头 |
| 4 | 任务漏跟/丢失/重复实现率下降 | 定性 | 统一任务视图 + 关联关系,减少漏跟、丢失与重复实现 |
| 5 | GitHub Issue 任务管理切换 | 量化(硬目标) | 新任务全部在平台创建,GitHub 不再新建 Issue 作为任务载体;存量 Issue 暂留 GitHub 不迁移(自然消亡) |
6. 核心功能
6.1 任务模型
6.1.1 任务核心字段
| 字段 | 说明 |
|---|---|
| 标题 / 描述 | 任务基本信息 |
| 任务类型 | 决定可见范围 + 主流程节点 + 表单展示(可扩展) |
| 所属团队 / 组织 | 决定可见性边界 |
| 负责人 | 唯一(单个,对应痛点 5);外部工单在“待处理”时允许暂空,处理方领取时原子写入 |
| 创建人 | 创建该任务的用户或受控系统服务账号;仅对当前任务产生创建人级授权 |
| 外部提交人 | 仅外部任务必填的 submitter_id;用于外部内容可见性与 submitter_only 卡点,不传播到关联的内部任务 |
| 相关人员 | 关注人/参与人,可跨团队(触发单任务可见性授权) |
| 主状态 | 当前所处状态机节点 |
| 检查点 | 自定义进度节点列表(见 6.1.3) |
| 关联关系 | 任务间的有向关联,用于表达主子任务、跨类型联动等逻辑(见 6.1.6) |
| 资源 | 任务挂载的相关资源(如代码仓库、PR、文档),按任务类型配置表单展示 |
| 截止时间 / 迭代 | 规范化的截止时间与迭代排期,用于跨类型时间筛选和排序 |
| 归档状态 | 任务仅可关闭/归档,不可删除;归档任务迁移至离线表(策略见 6.1.7) |
设计原则:模型中不区分主任务/子任务,所有任务都是平等的独立任务,主子关系通过"关联关系"在逻辑层表达(见 6.1.6)。
取消"仓库"作为任务组织维度:统一管理后不再有"跨仓库"概念,仓库降级为任务的相关资源之一,按任务类型配置不同的资源表单展示。
6.1.2 主状态机(可配置)
- 状态机不固定,按任务类型配置(对应痛点 7)。同一组织可为任务类型配置组织级默认流程,并通过团队级版本覆盖满足不同团队的流程差异;同一团队同一任务类型同时只能启用一个版本。
- 每个任务通过不可变的配置版本绑定一套状态机:状态节点 + 流转规则(允许的前置/后置状态)。新建任务记录
type_version_id,类型配置修改必须创建并发布新版本,不能改变已有任务正在使用的状态机或恢复节点。 - 节点离开方式(exit_mode)——自动流转逻辑下放到节点层,每个节点声明自己的离开方式:
| exit_mode | 说明 | 额外配置 |
|---|---|---|
manual | 手动推进(用户操作) | 无 |
auto | 自动流转(外部事件触发) | auto_trigger:pr_merged / children_done / related_task_done / ... |
human_gate | 人工卡点(审批人确认/驳回) | 无(审批人在任务实例层配置,见下) |
terminal | 终态,不允许继续流转 | 无 |
- 节点实例级参数(node_overrides):类型声明只管节点能力(exit_mode、auto_trigger),任务实例管节点参数(如 human_gate 的审批人)。存于
TASK.node_overrides(json),key = 节点 ID,value = 该节点在此任务下的参数对象。后续新增节点级实例参数时直接往 value 下加字段,无需改表结构。 - 人工卡点审批权限:仅审批人 / 团队管理员 / 组织管理员可审批,其余普通用户无权审批(见 4.2.3)。
- 流转规则(STATE_TRANSITION):描述"从哪到哪",并在每条出边上明确触发方式、自动触发器、操作者策略和 guard;节点的
exit_mode是默认值,出边可以为回退、外部联动或受限管理补偿声明例外触发方式。admin_recovery只能用于固定的人工补偿边,不得绕过submitter_only卡点或进入终态。自动流转事件在条件尚未满足时必须保留并重试,不能因首次消费而丢弃。 - 状态机必须且只能有一个初始节点;状态变更需记录操作人、时间,形成流转历史。
6.1.3 检查点 / 里程碑(自定义)
- 在状态机之外,任务可挂载若干自定义检查点(如 PRD 评审、技术评审)。
- 每个检查点记录:名称、时间、参与人、结论/备注。
- 检查点不强制顺序,用于结构化记录中间进度(对应痛点 7)。
6.1.4 任务类型配置(完全自定义)
任务类型是完全可配置的实体,类型身份在组织级定义(组织内共享),管理员可自由创建/扩展;配置通过不可变版本发布,组织可设默认版本、团队可设覆盖版本,每个团队同一类型同时只启用一个版本。每个类型包含:
- 可见范围:内部 / 外部 / 跨团队等(见 4.2.2)。
- 可见角色列表:声明该类型任务对哪些组织任务角色可见(角色 × 任务类型可见性矩阵),创建/编辑任务类型时填写。如
测试任务仅对tester可见,developer不可见(见 4.2.2)。 - 跨团队可见范围:
cross_team类型必须配置同组织的visible_team_ids,任务所属团队必须在其中;列表内团队的 active 内部成员按各自团队角色匹配visible_roles,外部任务不得使用该范围。 - 主状态机:该类型的状态节点 + 流转规则(见 6.1.2)。
- 资源/表单字段:该类型任务展示哪些资源与自定义字段,与状态机配置关联。示例:
- 开发任务:仓库 + PR + 分支
- 外部工单:客户联系方式 + 反馈截图
- 内部需求:PRD 文档链接 + 设计稿
- 资源型字段(仓库、PR、文档、链接)写入
TASK_RESOURCE;普通自定义字段写入TASK.form_data,字段 schema 必须显式声明存储目标,不能同一字段双写。
- 关联关系声明:该类型可声明与其他类型的关联及联动规则(如外部工单 → 内部任务,见 6.1.6);
cross_type在 MVP 中必须预先绑定目标内部任务类型和目标团队,不能等外部提交后再从未定义的输入中推断。 - 外部任务路由:
external类型必须配置一个组织内的默认处理团队或等价的受控路由规则,并配置至少一个该团队的内部处理方;外部提交人不能自行指定team_id。 - 节点实例参数表单(node_overrides_form_schemas):定义节点级实例参数的表单 schema(json 数组),一份 schema 通过
applies_to复用多个节点,驱动TASK.node_overrides渲染。MVP 的human_gate_approverschema 对需求类型的两个人工卡点要求approver_id,且服务端校验审批人属于同组织的 active 内部成员;新增节点级参数只需加 field,零代码改动。 - 新增任务类型 = 配置"可见范围 + 可见角色列表 + 状态机(含各节点 exit_mode)+ 表单字段 + 节点实例参数表单 + 关联声明",无需改动核心模型。
6.1.5 代码关联(PR 级)
- 任务可关联到一个或多个 PR(资源级,见 6.1.1 资源字段);PR 关联与合并状态作为后续迭代接入 GitHub Webhook 的资源契约,新增或更新 PR 资源时要重新评估已合并状态,覆盖“PR 先合并、后绑定任务”的场景。
- 后续自动流转:当某条流转边声明
trigger_mode = auto且auto_trigger = pr_merged时,关联 PR 合并后任务经 MQ 异步流转到下一个状态;多 PR 任务必须按该边的 guard 判断全部 active PR 是否已合并,发布走事务 outbox,消费条件未满足时保留并重试。
6.1.6 关联关系(逻辑层的主子任务 + 跨类型联动)
- 任务间通过有向关联关系连接,模型层不区分主/子,主子效果由关联关系推导。
- 挂载到主流程状态:一条关联关系可声明"子任务挂载在父任务主流程的某个状态节点之下"。
- 自动流转:当挂载在父任务某状态节点下至少有一个子任务且所有子任务均进入各自的终态节点(即完成)时,以父任务绑定版本的出边和 guard 为准,父任务自动流转到下一个主流程状态(对应痛点 3、6);没有子任务时不满足
children_done,不得直接流转。子任务只提供完成事件,不决定父任务的状态机;进入终态产生完成事件,不等待之后的status=closed生命周期写入。 - 关系变更后的重评估:建立、替换或解除关联时,必须在同一事务重新评估受影响的自动流转条件;按关联关系定义,真正产生完成事件的是
target任务(parent_child的子任务或cross_type的内部任务)。建立或替换关联时,若已完成的target已满足承载任务的children_done/related_task_done条件,立即写入或唤醒待处理事件;解除关联时同步撤销不再适用的待处理事件,不能只依赖目标任务完成时的事件。 - 关联授权:建立或修改关系支持双边授权申请。发起人先通过自己一端任务的
establish_relation权限,系统只向目标任务负责人/创建人或目标团队管理员展示最小元数据并生成待确认请求;目标方确认后,在同一事务重新校验双方当前权限并创建 active 关系及必要授权。组织管理员可直接创建,但任何建立关系的动作都不能通过关系本身反向获得目标任务可见性。 - 多级嵌套:支持多级子任务(子任务下还可再挂子任务)。
- 单父约束:一个任务最多只能有一个
parent_child父任务;整体形成有向无环森林。cross_type关联不参与root_task_id的计算。 - 跨团队/跨资源:内部
parent_child子任务可属于不同团队、挂载不同资源(仓库);这会触发关系驱动的任务级可见性授权。 - 跨类型关联(数据隔离):任务间可维护独立的关联关系,关联关系通过任务类型配置声明。
- 示例:创建外部工单时同步创建内部任务,二者相互关联,但数据完全隔离(各自可见性独立,见 4.2.2)。外部工单保留
submitter_id;同步创建的内部任务使用平台系统服务账号作为created_by,不得把外部提交人写入内部任务的创建人、负责人或相关人员。 - 联动:内部任务完成后,工单自动进入"确认完成"状态(联动规则在类型配置中声明);提交人驳回后,平台向固定目标团队的任务负责人/创建人和团队管理员生成 follow-up 待办,由目标团队内部执行者重新打开原内部任务或新建 follow-up 内部任务,完成后产生新的事件再次进入确认;外部工单处理方不因
cross_type关系获得内部任务可见性或操作权。cross_type的源端固定为外部工单(承载流转),目标端固定为内部处理任务(产生完成事件);同一外部工单同时只能有一个 active 目标,替换时先在同一事务将旧关系标记为replaced,只有新的 active 关系参与related_task_done判断。
- 示例:创建外部工单时同步创建内部任务,二者相互关联,但数据完全隔离(各自可见性独立,见 4.2.2)。外部工单保留
- 跨类型关联不自动授予对侧任务的完整内容可见性;外部工单仍只对提交人和配置的处理方返回客户内容,内部任务按自身类型和授权独立判定。
- 约束:所有
parent_child与cross_type关联关系共同构成有向无环图(DAG),禁止循环依赖,建立任一关联时都需做全图环检测。
6.1.7 归档策略
任务生命周期:活跃 → 已完成/关闭 →(gap 期 2 个月)→ 归档(离线表)。
- 延迟归档:任务关闭后保留 2 个月在线(gap 期),到期批量迁移至离线表。
- gap 期内可恢复:gap 期内任务仍在在线表,发现关错可重新打开(恢复关闭前记录的
reopen_state_id,不涉及表迁移);超过 gap 期任务已迁离线表,不允许恢复,只能新建任务。 - 重新打开目标:关闭任务时记录
reopen_state_id(默认取关闭前最后一个非终态节点);gap 期内重新打开时同时恢复status=active与该状态,清空closed_at。没有合法恢复节点时不得重新打开,只能新建任务。 - 归档门槛:无论组织管理员手动触发还是系统批处理,都必须校验
closed_at <= 当前时间 - 2 个月;gap 期内不得提前归档。 - 归档后不可关联:已归档任务不允许建立任何关联关系(主子/跨类型),仅可作为任务相关资源被引用(挂 ID 或链接)。任务处理方授权、评论及 @ 提及也随任务依赖数据一起迁移,归档后的读取仍必须经过原任务可见性、处理方 ACL 与字段投影规则。
- 离线表保留:不自动删除/冷存储,仅支持人工将离线表数据转为压缩包,人工周期以年为单位。
6.2 视图与查询
提供以下视图,覆盖不同角色与场景(对应痛点 1、2):
| 视图 | 说明 |
|---|---|
| 看板视图 | 按主流程状态分列,支持拖拽流转 |
| 列表视图 | 表格形式,支持多条件筛选 + 排序 |
| 我的视图 | 我负责的 / 我相关的(相关人员)/ 我提交的(外部人员) |
| 团队 / 组织视图 | 负责人看本团队全部任务,组织管理员看全组织 |
| 时间视图 | 按截止日期 / 迭代排期 |
6.2.1 筛选维度
- 通用筛选:负责人、团队、任务类型、主状态、时间范围等。
- 仅顶层任务:过滤出"无父任务"的任务(即在关联关系中不作为任何任务的子任务),用于只看主任务、隐藏子任务。
- 支持自定义视图 / 保存筛选条件:用户可保存常用筛选组合。
6.3 通知与协作
6.3.1 触发事件
以下事件触发通知(对应痛点 1,替代原群通知):
- 任务被分配给我 / 我成为相关人员
- 任务状态流转(尤其流转到"待我处理"的节点)
- 子任务全部完成、父任务自动流转
- 有人 @我 或评论
- 外部工单:我提交的工单有进展 / 待我确认完成
- 检查点(评审)被发起,且我是参与人
6.3.2 通知渠道
- 站内通知:平台内消息中心。
- IM 应用通知:集成团队自有 IM,发送应用通知(推送至群或私聊)。
- 新用户默认开启两个渠道;对用户已开启的每个渠道同时发送。
6.3.3 通知粒度(订阅机制)
- 用户订阅是发送渠道的最终开关:用户可配置接收哪些事件、走哪些渠道(站内 / IM);关闭某个渠道后,该事件不得再向该渠道发送,不受“两个渠道同时发送”的默认值影响。
- 支持免打扰 / 按事件类型订阅。
6.4 外部任务接入(后续迭代)
- 认证方式:复用公司认证中心 + OAuth2 体系,外部人员(客户/合作方)通过认证登录后访问平台。
- 提交工单:外部人员登录后在平台内提交工单/反馈,生成外部任务。
- 后续操作:外部人员登录后可对自己的工单补充信息、确认完成。
- 身份识别:基于 OAuth2 身份,"确认完成"操作仅工单提交人本人可执行。
- 可见性:外部任务仅提交人 + 被授权处理方可见(见 4.2.2)。
- 被授权处理方:通常为团队管理员,支持配置用户 ID 列表;外部人员不可读写处理方信息。
MVP 只落外部工单的任务类型、字段、状态机和关联声明配置,不交付 OAuth2 外部入口、工单提交页、补充信息和用户确认接口;这些端到端能力统一放入后续迭代。
7. 非功能需求
7.1 性能
- 任务量级:活跃任务千级(单库即可,无需分库分表;历史已关闭任务需归档策略)。
- 响应时间:列表 / 看板查询 P95 < 500ms。
7.2 可用性
- SLA:99%。
- 高可用部署:MVP 阶段单实例部署,暂不需要高可用;触发条件为 SLA 升级要求(升至 99.9%)时再立项。
- 架构预留约束(MVP 即需满足,保证后期上高可用低成本):
- 应用无状态:会话基于 OAuth2 token,不存本地内存/文件;任务状态全部存数据库(无内存/文件态)。
- 后台任务幂等:MQ 消费者、自动流转等后台任务需幂等,支持后期多副本水平扩展不重复处理;自动流转发布必须使用同库事务 outbox,条件未满足的消费事件要持久化延期并可再次评估。
7.3 安全与审计
- 认证:复用认证中心 + OAuth2。
- 审计日志:记录谁在何时对任务做了什么操作。
- 操作留痕:任务所有变更(状态流转、字段修改、关联变更)可追溯。
- 失败审计:任务创建前或已有任务操作被拒绝时,均写入独立的系统级审计;业务事务必须回滚,不能留下半条任务,且失败记录不能伪装成成功变更。只有已提交的任务变更才写入任务审计日志。
7.4 集成
- 后续迭代接入 GitHub Webhook(用于 PR 合并等外部事件回调),并通过事务 outbox + MQ 完成幂等自动流转;任务关系完成等平台内部事件可复用同一套事件管道。
- IM 应用通知、认证中心为既有集成。
7.5 国际化
- 暂不需要。
7.6 技术约束(关键设计决策)
root_task_id冗余字段:任务表冗余存储顶层任务 ID,直接提升数据库 IO 性能(避免 DAG 递归查询),结构化组装在用户端内存中完成。- 消息队列异步处理自动流转:子任务或关联任务完成等平台内部 MVP 事件,经 MQ 异步处理,解耦且保证可靠性;后续 GitHub Webhook 接收的 PR 合并事件也复用同一套可靠事件管道。产生内部完成事件的终态变更事务,以及后续的 Webhook 接收事务,必须同时写入
AUTO_FLOW_OUTBOX,由 outbox worker 在提交后发布并可补偿重试;消费者用AUTO_FLOW_EVENT做幂等接收,条件未满足时持久化延期并再次评估,不能只依赖消费侧落库。 - 查询策略(分库分表友好):
- 不依赖 SQL JOIN,应用层组装,保证后期分库分表无需改查询逻辑。
- 分片边界:MVP 单库;后续如需分片只按
org_id分片,保证同一组织内跨团队关系、授权、自动流转事件和归档迁移可以共置并在单库事务中完成;不得直接按team_id分片。 - 列表/看板页:一次请求内分步批量查询(① 查 TASK 列表 ② 收集
current_state_id集合批量查 STATE_NODE 取状态名),不依赖内存缓存,避免内存占用过高。 - 列表页不展示子任务信息,不冗余子任务计数。
- 详情页按需查询:只返回 TASK 主表数据,子任务/检查点/资源/相关人员点击对应行动点再查。
- 审计日志:字段级 diff(不存完整快照),普通字段和大 JSON 的变更路径均保留 before/after;敏感值以应用层信封加密保存,仅在合规回放服务中解密,普通投影一律脱敏。由此支持受控的逆序回放;审计记录跟随任务归档。
- 权限判定抽象(PermissionService):权限判定收敛在应用层,通过
PermissionService接口抽象,当前自实现(LocalPermissionService),后续可替换为统一权限平台实现(UnifiedPermissionService),业务代码零改动。接口:canViewTask(user, task):可见性判定(组织/团队/类型矩阵/单任务授权四层叠加)canPerformAction(user, task, action):操作权限判定canApproveGate(user, task, nodeId):人工卡点审批权限判定canViewComment(user, comment):评论可见性判定(任务权限 + 评论visibility)getTaskProjection(user, task):按字段可见性返回任务投影,禁止直接序列化原始form_datagetCommentProjection(user, comment):按评论权限返回评论投影,禁止越过visibility返回正文getAuditProjection(user, log):按审计权限返回脱敏投影,敏感值普通读取一律返回[REDACTED]- 权限模型为 RBAC + ABAC 复合:RBAC 处理角色→操作(组织/团队/角色矩阵);ABAC 基于主体/资源/操作/环境四类属性组合判定细粒度授权,其中资源属性含任务实例数据(如
task.participants、task.node_overrides[nodeId].approver_id),用于单任务参与者授权、卡点审批人判定。后续若自建权限平台,应采用支持 RBAC + ABAC 的策略引擎(如 Casbin/Oso/Cerbos),而非纯 RBAC。
8. 范围与优先级
8.1 MVP(第一期)
核心闭环,缺了平台无法运行:
- 任务模型:唯一负责人、相关人员、关联关系/主子任务、DAG 防环
- 任务类型模型:可见范围 + 状态机(含各节点 exit_mode)+ 表单字段 + 关联声明的数据模型必须先有;MVP 阶段写死 3 份配置:
需求/开发任务/外部工单(不实现可视化配置界面) - 权限模型:组织 / 团队 / 任务类型(角色矩阵)/ 单任务授权 四层可见性
- 基础视图:列表视图 + 我的视图
- 通知:站内 + IM 应用通知
- GitHub Issue 任务管理切换(硬目标):新任务全部在平台创建,存量 Issue 暂留 GitHub 并自然消亡,不迁移历史数据
其中,外部工单在 MVP 只提供模型与固定配置;外部人员 OAuth2 登录、提交工单、补充信息和确认完成均不属于 MVP 交付范围。 PR 关联与 GitHub Webhook 自动流转属于后续迭代;MVP 只保留任务资源和状态机版本对未来 pr_merged 事件的扩展位,不把该外部集成纳入一期验收。
8.2 后续迭代
按优先级排序:
| 优先级 | 功能 | 说明 |
|---|---|---|
| 高 | 检查点 / 评审节点 | 对应痛点 7,优先处理 |
| 高 | PR 关联 + 自动流转 | 对应痛点 3,接入 GitHub Webhook 与可靠事件管道 |
| 中 | 任务类型可视化配置 | MVP 写死配置 → 可视化配置界面 |
| 中 | 外部任务接入 | OAuth2 登录 + 提交工单 + 补充/确认 |
| 中 | 看板拖拽、时间视图 | 视图增强 |
| 低 | 自定义视图 / 保存筛选 | 视图增强 |
| 低 | 报表统计 | 数据洞察 |
9. 边界决策与开放问题
9.1 已决策的边界
| # | 边界 | 决策 |
|---|---|---|
| 1 | 任务删除 | 任务只能关闭/归档,不可删除;归档任务迁移至离线表(保留审计与关联完整性) |
| 2 | 跨团队子任务可见性 | 跨团队内部任务自动授予任务级可见性(见 4.2.2);外部工单仍只按提交人、处理方和受限管理投影授权 |
| 3 | 自动流转 vs 手动操作 | 节点声明默认 exit_mode(manual/auto/human_gate/terminal),每条 STATE_TRANSITION 明确实际 trigger_mode、auto_trigger、operator_policy 与 guard;事件发布走事务 outbox,条件未满足时持久化延期重试;无任务级 auto_host 开关(见 6.1.2) |
| 4 | 外部工单 ↔ 内部任务 | 通过关联关系联动,数据完全隔离;关联关系由任务类型配置声明,建立/更换关系时重新评估已完成 target 任务并补发自动流转事件(见 6.1.6) |
| 5 | MVP 任务类型 | 写死 3 份:需求 / 开发任务 / 外部工单 |
| 6 | 人工卡点审批权限 | 人工卡点(exit_mode = human_gate)作为特殊复核节点,可单独配置审批人(独立于任务负责人);普通卡点仅审批人/团队管理员/组织管理员可审批,外部工单的 submitter_only 卡点仅提交人可审批,且外部任务负责人/相关人员必须来自处理方白名单(见 6.1.2、4.2.3) |
| 7 | 归档离线表策略 | 关闭后 gap 期 2 个月在线,到期迁离线表;gap 期内可恢复,超期只能新建;归档后不可关联、仅作资源引用;离线表不自动删除,仅人工转压缩包(年为单位)(见 6.1.7) |
| 8 | 高可用部署 | MVP 单实例;触发条件为 SLA 升级;MVP 即满足"应用无状态 + 后台任务幂等"约束,保证后期低成本扩展(见 7.2) |
| 9 | GitHub Issue 迁移 | 不搬历史数据,只切增量:新任务全在平台创建,GitHub 不再新建 Issue;存量 Issue 暂留 GitHub 自然消亡(见 5 指标 5) |
| 10 | 团队内按类型隔离 | 同团队内按角色 × 任务类型可见性矩阵隔离(如开发不可见测试任务);任务类型为组织级,含可见角色列表;显式授权(相关人员/负责人)可突破类型隔离(见 4.2.2、6.1.4) |
9.2 待决策(开放问题)
(暂无,所有开放问题已决策)