项目管理

本页是一篇完整方案指南:以开源 project-management 模板插件(com.auraboot.template.project-management,命名空间 tpm)为例,从用户场景一路讲到开发实施和典型错误。它是 config 型插件——3 个 model、24 条命令、9 个页面全部是 DSL JSON 声明,没有任何后端 Java;下面每个标识符你都能在插件里 grep 到、对运行实例调得通。

源码:project-management on GitHub ↗

它的定位是「团队级简单项目跟踪」(catalogType: template),覆盖项目、任务、里程碑的完整生命周期。需要项目集汇总、RACI 分配、工时审批、燃尽看板的更复杂场景,本插件不内置,但都能用同样的 model + command + DSL 方式扩出来(见「6. 常见配置」)。


1. 用户场景

一个产品研发团队,平时同时推进几个项目(官网改版、移动端 App、内部工具),每个项目下拆若干任务,关键节点标里程碑。日常:

  • 立项 → 排期 → 启动项目 → 推进 → 完成或取消;
  • 任务从待办领取 → 进行中提交审核完成;
  • 给项目挂里程碑(如「MVP 发布」),到期标达成错过;
  • 项目经理看全局,成员只关心分到自己的任务,查看者只读。

项目编号、任务编号要自动生成,状态流转要可控、可审计,而不是谁都能随便把任务直接拖到「完成」。

2. 需求痛点

  • 没有受控状态机:Excel / 看板工具里任务状态随便改,跳过审核直接「完成」,没人拦得住。
  • 编号靠手填:PRJ-001 这种编号靠人维护,重复、断号、格式不统一。
  • 操作无授权无审计:谁在什么时候启动/取消了项目、把任务推进到哪一步,没有记录。
  • 集成困难:想让其他系统(CRM、自动化规则、AI agent)触发「新建任务」「完成项目」,却只能靠人工二次录入。

这些都不是「再加一张表」能解决的,而是受控状态变更的问题。

3. 产品方案

在 AuraBoot 里,每一个项目/任务/里程碑动作都是一条命令,走统一的 命令管道:

  • 任务详情页的「开始任务」按钮调用 tpm:start_task,而不是裸写状态字段;命令在管道里统一鉴权 → 校验 → 执行 → 审计 → 发事件
  • 状态流转命令(type: state_transition)带 fromStates / toState,平台据此挡住非法跳转——任务必须 in_review 才能 tpm:complete_task,跳步直接被拒。
  • 项目/任务/里程碑编号由命令的 autoSetFields 自动生成(PRJ-{yyyyMMdd}-{seq} / TSK-{yyyyMMdd}-{seq} / MS-{yyyyMMdd}-{seq}),不需要前端或人工填。
  • 同一条命令既是 UI 按钮的目标,也能被自动化规则、AI agent 调用——每条命令都带 cmd_risk_levelagent_hint(如删除类是 L4,新建是 L1,查询是 L0),CRM/自动化因此能安全地自动触发项目动作。

4. 功能设计

4.1 数据模型(3 个)

Model用途状态字典 / 关键状态值
tpm_project项目主实体,带起止日期、负责人、生命周期tpm_project_status:planning / active / on_hold / completed / cancelled
tpm_task项目下的任务,带负责人、优先级、截止日期tpm_task_status:todo / in_progress / in_review / done
tpm_milestone项目里程碑,标记关键交付节点tpm_milestone_status:pending / reached / missed

字段示例(均可在 config/fields/ grep 到):

  • tpm_project 字段:tpm_pj_code(编号,只读自动生成)、tpm_pj_nametpm_pj_descriptiontpm_pj_statustpm_pj_prioritytpm_pj_ownertpm_pj_start_datetpm_pj_end_date
  • tpm_task 字段:tpm_ts_codetpm_ts_titletpm_ts_project_id(dataType: reference,引用 tpm_project)、tpm_ts_descriptiontpm_ts_statustpm_ts_prioritytpm_ts_assigneetpm_ts_due_date
  • 优先级共用字典 tpm_priority:low / medium / high / urgent。

任务通过 tpm_ts_project_id 这个 reference 字段挂到项目上,这就是 model 之间的关联方式——不是裸外键,而是平台理解的引用关系。详见 Model 与 Field

4.2 命令与状态机

命令命名 tpm:<动词>_<名词>(冒号分隔,不是点号)。共 24 条:tpm_project 9 条、tpm_task 8 条、tpm_milestone 7 条。代表性命令:

命令类型模型权限
tpm:create_projectcreatetpm_projecttpm.project.manage
tpm:activate_projectstate_transitiontpm_projecttpm.project.manage
tpm:hold_project / tpm:complete_project / tpm:cancel_projectstate_transitiontpm_projecttpm.project.manage
tpm:create_taskcreatetpm_tasktpm.task.manage
tpm:start_task / tpm:review_task / tpm:complete_taskstate_transitiontpm_tasktpm.task.manage
tpm:delete_taskdeletetpm_tasktpm.task.manage
tpm:create_milestonecreatetpm_milestonetpm.milestone.manage
tpm:reach_milestone / tpm:miss_milestonestate_transitiontpm_milestonetpm.milestone.manage

任务状态机(来自 config/commands/tpm_task.jsonfromStates/toState):

todo ──tpm:start_task──> in_progress ──tpm:review_task──> in_review ──tpm:complete_task──> done

delete:仅 todo 可删(tpm:delete_task 带 precondition tpm_ts_status IN [todo])

项目状态机(来自 config/commands/tpm_project.json):

planning ──tpm:activate_project──> active ──tpm:complete_project──> completed
   │                                  │
   │                          tpm:hold_project ↕ tpm:activate_project
   │                                  │
   └────tpm:cancel_project────────> cancelled  (planning/active 都可取消)

每条命令都是一段声明。例如 tpm:start_task(config/commands/tpm_task.json 中的一条)的真实定义:

{
  "code": "tpm:start_task",
  "displayName:zh-CN": "开始任务",
  "type": "state_transition",
  "modelCode": "tpm_task",
  "stateField": "tpm_ts_status",
  "fromStates": ["todo"],
  "toState": "in_progress",
  "permissions": ["tpm.task.manage"],
  "agent_hint": "Start working on a task.",
  "cmd_risk_level": "L1",
  "precondition_description": "Task must be TODO.",
  "idempotent": false,
  "reversible": false
}

读出来的设计信息:这是一条 state_transition(todo → in_progress),只允许从 todo 出发(fromStates),要求 tpm.task.manage 权限,风险级 L1,并通过 agent_hint 告诉 agent 它能做什么。任务不在 todo 时调用它会被状态机直接拒绝。

create 类命令则靠 autoSetFields 自动落编号和初始状态。例如 tpm:create_task 里:

"autoSetFields": {
  "tpm_ts_code": { "strategy": "auto_generate", "pattern": "TSK-{yyyyMMdd}-{seq}" },
  "tpm_ts_status": { "strategy": "fixed_value", "value": "todo" }
}

新建任务时,前端只填 tpm_ts_titleinputFields,编号和初始状态由平台补齐。

4.3 权限与角色

config/permissions.json 定义 6 个权限码(<模块>.<资源>.<动作>,每资源 manage + read):

tpm.project.manage      tpm.project.read
tpm.task.manage         tpm.task.read
tpm.milestone.manage    tpm.milestone.read

manage(operation 型)管所有写动作(创建/编辑/状态流转/删除),read(data 型)管查看与列表。菜单项也绑了 read 权限——tpm_projects 菜单的 permissionCodetpm.project.read,没有该权限的用户连菜单都看不到。

这个模板插件不内置 roles.json——它只声明权限码,角色与授权由部署方按团队结构在权限治理里配(例如把 tpm.project.manage + tpm.task.manage 给项目经理,只给成员 tpm.task.manage + 三个 read,给查看者三个 read)。这正是 AuraBoot 的分层:插件声明能力(权限码),部署方决定谁有这些能力(角色)。详见 权限

4.4 页面

config/pages/9 个页面:每个 model 一套 list / form / detail(tpm_project_list/form/detailtpm_task_list/form/detailtpm_milestone_list/form/detail)。

  • list 页:列表 + 列头(状态/优先级走字典渲染成彩色标签)+ 搜索 + 行级操作(状态流转、编辑、删除)。
  • form 页:全字段录入,编号字段只读(tpm_ts_code / tpm_pj_code 由命令自动生成,不让填)。
  • detail 页:字段展示 + 生命周期操作工具栏(把 tpm:start_task 这类状态命令挂成按钮)。

菜单 config/menus.json 把三个 list 页挂到「项目管理」根菜单下,路径分别是 /p/tpm_project/p/tpm_task/p/tpm_milestone

配套 1 条命名查询 tpm_task_summary(config/named-queries.json):按项目分组统计各状态任务数,可用来给项目详情页做「任务分布」展示。本插件没有内置 dashboard 页面;要做管理驾驶舱,用这条命名查询 + 自己加图表块即可(见「6. 常见配置」)。

5. 具体开发与实施

先掌握基础。本插件没有任何后端 Java,全靠平台的几个核心契约。动手前请先读:Model 与 Field · Command · 命令管道 · Permission · 插件清单 · 纯配置 Plugin · Page Designer

落地一个像 project-management 这样的 config 插件,步骤是:

  1. 写插件清单 —— plugin.json 声明 pluginType: "config"namespace: "tpm"provides(三个 model)和 resourceDirs(把每类资源指到对应目录/文件)。详见 插件清单
  2. 定义 model 与字段 —— config/models.json(三个 model)+ config/fields/<model>.json,字段类型用平台 dataType(string / text / enum / date / reference…)。关联用 reference + referenceModelCode,不要写裸外键。详见 Model 与 Field
  3. 声明命令 —— 每个 model 一个 config/commands/<model>.json,状态流转用 type: state_transition + fromStates/toState,创建用 type: create + autoSetFields(编号、初始状态),并在每条命令的 permissions 绑权限码。详见 Command
  4. 配 model-field binding —— config/bindings/<model>.json 控制字段在列表/表单里的顺序、是否必填/可见/可编辑;并在 resourceDirs.modelFieldBindings 注册(见「典型错误」)。
  5. 设计页面 —— config/pages/,每个 model 的 list / form / detail 用 Page Designer 出 DSL,把状态命令挂成详情页工具栏按钮、行级操作。
  6. 权限、字典、菜单 —— config/permissions.json / dicts.json / menus.json。角色授权留给部署方在权限治理里配。
  7. 打包导入 —— 用 aura CLI 的 import-directory-sync(参数是目录 path)或平台导入接口;校验返回 success:true 才算导入成功。详见 纯配置 Plugin

6. 常见配置

  • 新增任务优先级 / 状态:在 tpm_prioritytpm_task_status 字典里追加一个 item,即可新增一档,无需改代码;若新状态要参与流转,补一条对应的 state_transition 命令。
  • 任务挂项目:tpm_ts_project_idreference 字段(referenceModelCode: tpm_project),表单里渲染成项目选择器;同理可加 reference 字段把任务关联到 CRM 客户、关联里程碑——跨插件接线自动继承同一套权限模型。
  • 管理驾驶舱:本插件不内置 dashboard,但可基于已有的命名查询 tpm_task_summary(按项目分组统计各状态任务数)新增图表块,或再写命名查询(逾期任务、负责人工时分布等),组成一个 dashboard 页面。
  • 里程碑预警:tpm_milestonetpm_ms_target_date,用自动化规则在到期未达成时发命令 tpm:miss_milestone 或通知。
  • AI / 自动化触发:每条命令带 agent_hintcmd_risk_level,可被自动化规则或 AI agent 调用——例如 CRM 成交后自动 tpm:create_project。注意删除类是 L4 高风险,按风险级决定是否需要人工确认。

7. 典型错误

  • 命令码用点号:写成 tpm.task.start 跑不通——真实是冒号 + 动词_名词:tpm:start_task。注意权限码反而用点号(tpm.task.manage),两者别混。
  • 绕过命令直接改状态字段:直接 UPDATE tpm_ts_status 会跳过状态机校验(fromStates/toState)、autoSetFields、鉴权和审计/事件。一切状态变更都走命令,这样跳步(如 todo 直接到 done)才会被拦住。
  • 跳步状态流转:任务必须 todo → in_progress → in_review → done 逐级走;在 in_progress 直接调 tpm:complete_task(它的 fromStates 只有 in_review)会被拒——这是设计,不是 bug。同理删除有 precondition:任务仅 todo 可删、项目仅 planning 可删、里程碑仅 pending 可删。
  • 手填自动编号:tpm_pj_code / tpm_ts_code / tpm_ms_codeautoSetFields 自动生成的只读字段(PRJ-/TSK-/MS-{yyyyMMdd}-{seq}),表单里不要让用户填,也别在 inputFields 里带它。
  • bindingRules 写进 commands.json 内联:不会被导入;必须独立放在 config/bindings/ 并在 resourceDirs 注册,否则报 [S-EXT-HANDLER] references unregistered handler。详见 纯配置 Plugin
  • 命令执行 payload 结构:字段放在 { "payload": { ... }, "operationType": ... },目标记录用 targetRecordId(不是 recordId)——放错位会出现「执行成功却字段为空」的迷惑性报错。

下一步

  • 系统总览 —— 插件、命令与运行时如何拼到一起
  • 命令管道 —— 上面每条命令都走的执行契约
  • 权限 —— tpm.*.manage/read 背后的五层模型
  • 插件清单 —— 如何声明依赖并将方案打包发布
  • 定价 —— 多租户治理、许可证权益、AI 辅助与可观测 Pro 等商业功能