You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

4.3 KiB

status
accepted

项目双轴状态机模型(crm-project:stage 非线性骨架 + status 横切 + filing 独立轴)

Context

A5 项目管理(crm-project)需要一套生命周期模型,管理项目从冲突处理到结项的全过程。建模时存在两条路线:

  • 商机域旧模型:项目寄居 crm_opportunity 表、opp_status=5 切域(票 07 共表定案)——已被 ADR-0041 / spec §2.1 路线甲推翻(项目落独立 crm_project 表);
  • 商机域的双轴形态:opp_status(归属流转)+ current_stage_id(模板驱动阶段节点)——不能照搬:项目阶段骨架固定(原型 7 阶段全画、无可配模板),且报备/赢输是商机没有的正交语义。

约束(grilling 20260821 拍板,spec §0 会话表 #8/#9/#12):

  • stage5 是赢/输分叉点:赢单 stage5 闭环锁死不进结项;仅输单进 stage6——阶段轴非线性
  • 回退 = 弹窗多步选前序节点、下限 stage1、仅管理员+销售总监;三终态锁死(结项/已关闭/赢单);
  • 报备独立于双轴:建项目即触发(filing_status=1),审核通过=冲突解除(一次动作双写 stage 0→1)。

Considered Options

  • A(选中):三轴分离——轴1 project_stage(tinyint 0~6,固定骨架枚举 ProjectStage,非线性迁移图收敛于 ProjectStageMachine)+ 轴2 project_status(1/2/3,横切:进行中/已关闭/已结项)+ 独立轴 filing_status(0~3,报备)。赢输之别由 bid_result(0/1/2)在 stage5 表达,不新增 status 值。
  • B:照搬商机模板驱动阶段(current_stage_id + stage_template)——项目阶段骨架产品定案固定 7 节点,模板机制是纯开销;且商机阶段节点 id 化后回退/连跳判定要查模板表,项目的回退「已经过节点」由动态留痕即可投影,否。
  • C:赢/输各占一个 status 值——status 轴语义是「归属处境」(进行中/已关闭/已结项),赢输是 stage5 上的业务结果,塞进 status 会让「赢单+已关闭」「输单+已关闭」组合爆炸,否。

Decision

  1. 双轴 + 独立报备轴落在 crm_project 主表三列:project_stage(0~6)/project_status(1/2/3)/filing_status(0~3,0 本期不可达);bid_result(0/1/2)住 stage5 分叉点。
  2. 迁移判定收敛单点 ProjectStageMachine:常规推进(1→2→3→4→5)、唯一连跳 3→5(无需招投标)、回退守卫(多步选前序节点、下限 stage1、三终态锁 + 赢单锁)、关闭守卫(任意 stage、已关闭/已结项不可再关)、赢输守卫(仅 stage5 未标记)、冲突解除守卫(仅 stage0)。
  3. 「已经过节点」投影:项目动态 project_oplog 阶段类动作带结构化 from_stage/to_stage,回退可选节点 = 动态投影 ∪ {stage1}——3→5 连跳跳过的 stage4 不在可选列表(spec §3 已回写)。
  4. 写侧授权双层:状态动作(推进/关闭/赢输/冲突解除)= 负责人 ∨ 管理员/销售总监(ProjectActionAuthorizer,68010);阶段回退 = 管理员/销售总监(ProjectRollbackAuthorizer,68005)。系统无「报备专员→用户」绑定,报备审核动作暂按同一 owner∨管理口径强制(16R/D-02 拍板,细分角色随权限系统接线收紧)。
  5. 动态留痕单写入口 ProjectOplogWriter(append-only,全事件落 project_oplog);状态落库走实体 @Version CAS(并发变化 68003)。

Consequences

  • 主流程(建档→冲突解除双写→推进→连跳→多步回退→赢单闭环/输单结项→关闭记因→三终态锁)e2e 全通(票 14/15 冒烟 35 步 + 票 17 复测主链 11 步);赢单态可被主动关闭为「已关闭」系 spec §3「任意 stage 可主动关闭」的既有口径(复测观察项,供产品复核)。
  • 回退口径与 spec §3 双向回写定稿(连跳后可选节点、权限承载);报备/赢输语义不再有 schema 层歧义。
  • 将来若产品要求「赢单不可关闭」「报备专员细分权限」,只需改 ProjectStageMachine.ensureCloseable / ProjectActionAuthorizer 实现各一处。
  • 决策来源:crm-project-wayfinding 票 03(阶段状态机)+ grilling 补拍(spec §0 会话表 #8/#9/#12);本 ADR 即 spec §8 留痕清单的「项目双轴模型」项。