feat(slidev): update 3 4
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
# JeecgBoot 工单可复用资产包
|
||||
|
||||
这个目录里的文件不是大纲,而是课后可以直接复制到团队 `ai-dev-assets/` 的资产。
|
||||
|
||||
## 使用方式
|
||||
|
||||
@@ -9,7 +8,7 @@
|
||||
3. 需要把流程封装成团队能力时,复制 `skills/`。
|
||||
4. 需要课堂或项目交付表时,复制 `templates/` 和 `templates/jeecgboot/`。
|
||||
5. 需要验收和上线检查时,复制 `checklists/` 和 `checklists/jeecgboot/`。
|
||||
6. 需要反例教学时,复制 `examples/` 和 `examples/jeecgboot/`。
|
||||
|
||||
|
||||
## 资产清单
|
||||
|
||||
|
||||
Binary file not shown.
@@ -1,17 +1,18 @@
|
||||
# 安装说明
|
||||
|
||||
## 方式一:安装到 Codex Skills 目录
|
||||
## 方式一:安装到 TRAE Skills 目录
|
||||
|
||||
把 `skills/` 下的 4 个 Skill 文件夹复制到本机 Skills 目录:
|
||||
把 `skills/` 下的 5 个 Skill 文件夹复制到本机 Skills 目录:
|
||||
|
||||
```text
|
||||
~/.codex/skills/
|
||||
~/.trae/skills/
|
||||
```
|
||||
|
||||
安装后目录应类似:
|
||||
|
||||
```text
|
||||
~/.codex/skills/
|
||||
~/.trae/skills/
|
||||
├── project-knowledge-builder/
|
||||
├── generate-project-constraints/
|
||||
├── design-complex-business-module/
|
||||
├── review-business-delivery/
|
||||
@@ -34,6 +35,7 @@ skill-name/
|
||||
|
||||
```text
|
||||
Use $generate-project-constraints 为当前项目生成 AI 开发约束。
|
||||
Use $project-knowledge-builder 为当前项目生成 docs/project-knowledge 项目知识库。
|
||||
Use $design-complex-business-module 设计这个业务模块的权限、状态、审计、异常态和看板。
|
||||
Use $review-business-delivery Review 这批阶段交付物。
|
||||
Use $track-review-fix-loop 根据 Review 报告生成修复闭环记录。
|
||||
@@ -55,6 +57,8 @@ ai-engineering-assets/
|
||||
|
||||
此时 `SKILL.md` 作为标准工作流说明,`assets/` 作为可复制模板、Prompt、检查清单和反例库。
|
||||
|
||||
`examples/` 目录只用于学习参考,不要复制到通用 Skills 安装目录。换项目复用时,应先用 `project-knowledge-builder` 建立项目知识库,再用 `generate-project-constraints` 重新扫描目标项目,最后使用其他 Skill 生成该项目自己的权限、状态、审计、Review 和修复闭环资产。
|
||||
|
||||
## 维护建议
|
||||
|
||||
- 每次项目规则变化后,重新运行 `generate-project-constraints`。
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# AI Engineering Skills Delivery
|
||||
|
||||
本交付包提供 4 个可复用 AI 工程 Skill,覆盖真实项目中从项目约束生成、复杂业务设计、交付 Review 到修复闭环的完整流程。
|
||||
本交付包提供 5 个可复用 AI 工程 Skill,覆盖真实项目中从项目知识库、项目约束生成、复杂业务设计、交付 Review 到修复闭环的完整流程。
|
||||
|
||||
这些 Skill 不是单次 Prompt,而是可安装、可复制、可随项目持续维护的团队资产。
|
||||
|
||||
`skills/` 目录中的内容是通用资产,不能绑定某个训练项目或客户项目;具体案例只放在 `examples/` 目录,作为参考材料,不作为通用 Skill 安装项。
|
||||
|
||||
## 交付内容
|
||||
|
||||
```text
|
||||
@@ -11,6 +13,7 @@
|
||||
├── README.md
|
||||
├── INSTALL.md
|
||||
├── skills/
|
||||
│ ├── project-knowledge-builder/
|
||||
│ ├── generate-project-constraints/
|
||||
│ ├── design-complex-business-module/
|
||||
│ ├── review-business-delivery/
|
||||
@@ -23,17 +26,19 @@
|
||||
|
||||
| Skill | 用途 | 典型产物 |
|
||||
| --- | --- | --- |
|
||||
| `project-knowledge-builder` | 深度整理代码仓库,生成给人和 AI 复用的项目知识库 | 项目知识库 README、上下文图、架构/运行/前后端/数据/权限文档、RAG 索引建议、生成索引 |
|
||||
| `generate-project-constraints` | 从项目源码、配置、CI、文档中提取项目约束 | rules、约束提取表、验收清单 |
|
||||
| `design-complex-business-module` | 设计复杂业务模块的权限、状态、审计、异常态和看板 | RBAC 矩阵、状态流转表、审计 SOP、看板指标字典 |
|
||||
| `review-business-delivery` | 审查复杂业务交付物或 PR 的业务风险 | 阶段 Review 报告、风险清单、验收建议 |
|
||||
| `track-review-fix-loop` | 跟踪 Review 问题修复、验证和资产沉淀 | 修复记录、未闭环清单、资产更新建议 |
|
||||
| `design-complex-business-module` | 设计复杂业务模块的权限、状态、审计、异常态和看板 | RBAC 矩阵、权限控制方案、状态流转表、审计 SOP、异常态清单、看板指标字典、看板接口验收记录 |
|
||||
| `review-business-delivery` | 审查复杂业务交付物或 PR 的业务风险 | AI Review 报告、阶段 Review 报告、权限/状态/审计/异常态/看板检查清单、业务交付验收清单 |
|
||||
| `track-review-fix-loop` | 跟踪 Review 问题修复、验证和资产沉淀 | 修复记录、未闭环清单、资产更新建议、权限/状态/审计/指标反例库 |
|
||||
|
||||
## 推荐使用顺序
|
||||
|
||||
1. 使用 `generate-project-constraints` 为客户项目生成项目规则。
|
||||
2. 使用 `design-complex-business-module` 生成复杂业务设计资产。
|
||||
3. 使用 `review-business-delivery` 审查设计、代码或阶段交付物。
|
||||
4. 使用 `track-review-fix-loop` 跟踪修复、验证结果和资产沉淀。
|
||||
1. 使用 `project-knowledge-builder` 生成项目知识库,让团队和 AI 先理解项目。
|
||||
2. 使用 `generate-project-constraints` 为客户项目生成项目规则。
|
||||
3. 使用 `design-complex-business-module` 生成复杂业务设计资产。
|
||||
4. 使用 `review-business-delivery` 审查设计、代码或阶段交付物。
|
||||
5. 使用 `track-review-fix-loop` 跟踪修复、验证结果和资产沉淀。
|
||||
|
||||
## 适用项目
|
||||
|
||||
|
||||
+17
-14
@@ -1,16 +1,19 @@
|
||||
# 工单 RBAC 权限矩阵
|
||||
# <模块名称> RBAC 权限矩阵
|
||||
|
||||
| 功能点 | 管理员 | 工单负责人 | 研发处理人 | 测试验证人 | 只读观察者 | 权限字符建议 | 备注 |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| 查看列表 | 允许 | 条件允许 | 条件允许 | 条件允许 | 条件允许 | work:order:list | 按数据范围 |
|
||||
| 查看详情 | 允许 | 条件允许 | 条件允许 | 条件允许 | 条件允许 | work:order:query | 仅可见范围 |
|
||||
| 新建工单 | 允许 | 允许 | 允许 | 允许 | 拒绝 | work:order:add | |
|
||||
| 编辑工单 | 允许 | 条件允许 | 条件允许 | 拒绝 | 拒绝 | work:order:edit | 状态限制 |
|
||||
| 指派负责人 | 允许 | 条件允许 | 拒绝 | 拒绝 | 拒绝 | work:order:assign | |
|
||||
| 状态流转 | 允许 | 条件允许 | 条件允许 | 条件允许 | 拒绝 | work:order:transition | 按状态 |
|
||||
| 关闭工单 | 允许 | 条件允许 | 拒绝 | 条件允许 | 拒绝 | work:order:close | 测试验证后 |
|
||||
| 删除工单 | 允许 | 拒绝 | 拒绝 | 拒绝 | 拒绝 | work:order:delete | 高危操作 |
|
||||
| 查看审计日志 | 允许 | 条件允许 | 条件允许 | 条件允许 | 拒绝 | work:order:audit | |
|
||||
| 查看看板 | 允许 | 允许 | 条件允许 | 条件允许 | 条件允许 | work:order:dashboard | 按数据范围 |
|
||||
| 导出数据 | 允许 | 条件允许 | 拒绝 | 拒绝 | 拒绝 | work:order:export | |
|
||||
## 使用说明
|
||||
|
||||
将列名中的 `<角色A>`、`<角色B>`、`<角色C>` 替换为目标项目真实角色。权限字符只能写成建议,除非源码、菜单配置或后端注解已经证明。
|
||||
|
||||
| 功能点 | <管理员角色> | <业务负责人角色> | <处理人角色> | <审核人角色> | <只读角色> | 权限字符建议 | 数据范围 | 来源证据 | 备注 |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| 查看列表 | 允许 | 条件允许 | 条件允许 | 条件允许 | 条件允许 | `<module>:<entity>:list` | 按授权范围 | | |
|
||||
| 查看详情 | 允许 | 条件允许 | 条件允许 | 条件允许 | 条件允许 | `<module>:<entity>:query` | 仅可见数据 | | |
|
||||
| 新建记录 | 允许 | 允许 | 条件允许 | 条件允许 | 拒绝 | `<module>:<entity>:add` | 通常无数据范围 | | |
|
||||
| 编辑记录 | 允许 | 条件允许 | 条件允许 | 拒绝 | 拒绝 | `<module>:<entity>:edit` | 创建人/负责人/授权范围 | | 需结合状态 |
|
||||
| 分配/转交 | 允许 | 条件允许 | 拒绝 | 拒绝 | 拒绝 | `<module>:<entity>:assign` | 管理范围 | | 高风险操作 |
|
||||
| 状态流转 | 允许 | 条件允许 | 条件允许 | 条件允许 | 拒绝 | `<module>:<entity>:transition` | 当前数据范围 | | 需结合状态表 |
|
||||
| 关闭/归档 | 允许 | 条件允许 | 拒绝 | 条件允许 | 拒绝 | `<module>:<entity>:close` | 当前数据范围 | | 终态动作 |
|
||||
| 删除记录 | 条件允许 | 拒绝 | 拒绝 | 拒绝 | 拒绝 | `<module>:<entity>:delete` | 管理范围 | | 高危操作 |
|
||||
| 查看审计日志 | 允许 | 条件允许 | 条件允许 | 条件允许 | 拒绝 | `<module>:<entity>:audit` | 当前数据范围 | | |
|
||||
| 查看统计看板 | 允许 | 条件允许 | 条件允许 | 条件允许 | 条件允许 | `<module>:<entity>:dashboard` | 按角色过滤 | | |
|
||||
| 导出数据 | 条件允许 | 条件允许 | 拒绝 | 拒绝 | 拒绝 | `<module>:<entity>:export` | 管理范围或授权范围 | | 需脱敏 |
|
||||
|
||||
+10
-8
@@ -1,18 +1,20 @@
|
||||
# RBAC 权限矩阵生成 Prompt
|
||||
|
||||
```text
|
||||
请基于 JeecgBoot 工单模块设计 RBAC 权限矩阵。
|
||||
请基于目标业务模块设计 RBAC 权限矩阵。
|
||||
|
||||
输入材料:
|
||||
- 工单模块需求:<粘贴需求>
|
||||
- 角色列表:管理员、工单负责人、研发处理人、测试验证人、只读观察者
|
||||
- 功能点:查看列表、查看详情、新建、编辑、指派、状态流转、关闭、删除、查看审计、查看看板、导出
|
||||
- 项目依据:<粘贴权限、路由、菜单相关路径>
|
||||
- 模块名称:<填写>
|
||||
- 业务对象:<填写,例如订单、客户、申请、任务>
|
||||
- 需求说明或用户故事:<粘贴>
|
||||
- 角色列表:<粘贴目标项目真实角色>
|
||||
- 功能点:<粘贴页面、按钮、接口、数据动作>
|
||||
- 项目依据:<粘贴权限、路由、菜单、接口、后端校验相关路径>
|
||||
|
||||
输出要求:
|
||||
1. 先列事实依据:JeecgBoot 权限、菜单、动态路由相关路径。
|
||||
1. 先列事实依据:权限、菜单、动态路由、接口、后端校验相关路径。
|
||||
2. 输出 RBAC 权限矩阵:角色 x 功能点,允许、拒绝、条件允许。
|
||||
3. 输出权限字符建议,必须标注为建议。
|
||||
3. 输出权限字符建议,并标注哪些是事实、哪些是建议。
|
||||
4. 输出页面级、按钮级、接口级、数据范围四层控制。
|
||||
5. 输出不确定点:哪些权限必须业务方确认。
|
||||
6. 输出验收方式:如何证明权限确实生效。
|
||||
@@ -21,5 +23,5 @@
|
||||
- 不要直接改代码。
|
||||
- 不要把前端按钮隐藏当作安全边界。
|
||||
- 所有结论必须区分事实、推断、建议。
|
||||
- 不要把示例模块、示例角色或示例权限字符当成目标项目事实。
|
||||
```
|
||||
|
||||
|
||||
+11
-10
@@ -1,18 +1,19 @@
|
||||
# 工单审计日志 SOP
|
||||
# <模块名称> 审计日志 SOP
|
||||
|
||||
## 记录原则
|
||||
|
||||
所有会改变工单关键业务状态、负责人、可见性或结论的动作都必须记录审计日志。
|
||||
所有会改变目标业务对象关键状态、负责人/处理人、可见性、金额、结论或对外结果的动作都必须记录审计日志。
|
||||
|
||||
## 审计字段
|
||||
|
||||
| 字段 | 含义 | 示例 |
|
||||
| --- | --- | --- |
|
||||
| ticket_id | 工单 ID | WO-001 |
|
||||
| target_type | 业务对象类型 | order / customer / request |
|
||||
| target_id | 业务对象 ID | 100001 |
|
||||
| actor_id | 操作人 ID | 1001 |
|
||||
| actor_name | 操作人名称 | zhangsan |
|
||||
| action | 操作类型 | ASSIGN |
|
||||
| field_name | 变更字段 | assignee |
|
||||
| action | 操作类型 | ASSIGN / APPROVE / CLOSE |
|
||||
| field_name | 变更字段 | status / owner_id / amount |
|
||||
| old_value | 旧值 | lisi |
|
||||
| new_value | 新值 | wangwu |
|
||||
| source | 来源 | web |
|
||||
@@ -23,12 +24,13 @@
|
||||
|
||||
| 动作 | 写入时机 | oldValue | newValue | 验收 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 创建工单 | 创建成功后 | 空 | 工单摘要 | 审计列表可见 |
|
||||
| 创建记录 | 创建成功后 | 空 | 业务摘要 | 审计列表可见 |
|
||||
| 编辑字段 | 保存成功后 | 修改前字段 | 修改后字段 | 字段前后值正确 |
|
||||
| 指派负责人 | 指派成功后 | 原负责人 | 新负责人 | 审计记录负责人变化 |
|
||||
| 分配/转交 | 分配成功后 | 原处理人 | 新处理人 | 审计记录处理人变化 |
|
||||
| 状态流转 | 状态变更成功后 | 原状态 | 新状态 | 审计记录状态变化 |
|
||||
| 评论新增 | 评论保存后 | 空 | 评论摘要 | 审计记录评论动作 |
|
||||
| 关闭工单 | 关闭成功后 | 原状态 | 已关闭 | 审计记录关闭时间 |
|
||||
| 结论/审核 | 结论保存成功后 | 原结论 | 新结论 | 审计记录结论变化 |
|
||||
| 评论/备注新增 | 保存成功后 | 空 | 摘要或脱敏内容 | 审计记录评论动作 |
|
||||
| 关闭/归档 | 操作成功后 | 原状态 | 目标终态 | 审计记录关闭或归档时间 |
|
||||
|
||||
## 验收方式
|
||||
|
||||
@@ -37,4 +39,3 @@
|
||||
3. 敏感字段已脱敏。
|
||||
4. 操作失败不写成功审计。
|
||||
5. 多步写入失败时审计和业务数据保持一致。
|
||||
|
||||
|
||||
+2
-3
@@ -2,12 +2,11 @@
|
||||
|
||||
| 检查项 | 通过标准 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 创建记录 | 创建工单后能查询审计记录 | |
|
||||
| 创建记录 | 创建业务记录后能查询审计记录 | |
|
||||
| 字段变更 | 编辑关键字段记录 oldValue/newValue | |
|
||||
| 指派记录 | 指派负责人记录原负责人和新负责人 | |
|
||||
| 分配记录 | 分配或转交记录原处理人和新处理人 | |
|
||||
| 状态记录 | 状态流转记录原状态和新状态 | |
|
||||
| 操作人 | actor_id 和 actor_name 可追溯 | |
|
||||
| 来源 | source 或 request_id 可追溯 | |
|
||||
| 脱敏 | 敏感字段不明文进入审计 | |
|
||||
| 失败处理 | 操作失败不写成功审计 | |
|
||||
|
||||
|
||||
+1
-2
@@ -3,11 +3,10 @@
|
||||
| 异常态 | 必须验证 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 空列表 | 页面显示空状态,不报错 | |
|
||||
| 详情不存在 | 提示工单不存在,页面不崩溃 | |
|
||||
| 详情不存在 | 提示记录不存在,页面不崩溃 | |
|
||||
| 权限不足 | 前端提示或隐藏,后端拒绝 | |
|
||||
| 非法状态 | 返回非法流转,状态不变 | |
|
||||
| 重复提交 | 只成功一次,只写一条有效审计 | |
|
||||
| 参数缺失 | 返回参数错误,业务数据不变 | |
|
||||
| 并发修改 | 拒绝覆盖或提示刷新 | |
|
||||
| 看板无数据 | 图表显示空态,不显示假数据 | |
|
||||
|
||||
|
||||
+12
-12
@@ -1,13 +1,13 @@
|
||||
# 工单异常态清单
|
||||
|
||||
| 场景 | 触发条件 | 前端表现 | 后端响应 | 验收 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 权限不足 | 无权限操作 | 按钮不可见或提示无权限 | 403 或业务拒绝 | 不完成操作 |
|
||||
| 工单不存在 | 传入错误 ID | 显示不存在 | 404 或业务错误 | 页面不崩溃 |
|
||||
| 非法状态流转 | closed -> processing | 提示非法流转 | 状态不变 | 数据状态不变 |
|
||||
| 重复提交 | 连续点击提交 | 按钮 loading/禁用 | 只处理一次 | 只生成一条有效审计 |
|
||||
| 参数缺失 | 驳回缺少原因 | 表单校验提示 | 参数错误 | 不改变状态 |
|
||||
| 并发修改 | 数据版本过期 | 提示刷新 | 拒绝覆盖 | 旧数据不覆盖新数据 |
|
||||
| 看板无数据 | 无匹配记录 | 空状态 | 返回空集合 | 页面不报错 |
|
||||
| 审计日志为空 | 无审计记录 | 空状态 | 返回空集合 | 页面不报错 |
|
||||
# <模块名称> 异常态清单
|
||||
|
||||
| 场景 | 触发条件 | 前端表现 | 后端响应 | 验收 | 来源证据 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| 权限不足 | 无权限操作敏感功能 | 按钮不可见或提示无权限 | 403 或业务拒绝 | 不完成操作 | |
|
||||
| 记录不存在 | 传入错误 ID | 显示不存在 | 404 或业务错误 | 页面不崩溃 | |
|
||||
| 非法状态流转 | `<状态A> -> <状态C>` 不在状态表 | 提示非法流转 | 状态不变 | 数据状态不变 | |
|
||||
| 重复提交 | 连续点击提交或重复请求 | 按钮 loading/禁用 | 只处理一次 | 只生成一条有效审计 | |
|
||||
| 参数缺失 | 必填原因、金额、范围或结论缺失 | 表单校验提示 | 参数错误 | 不改变业务数据 | |
|
||||
| 并发修改 | 数据版本过期 | 提示刷新 | 拒绝覆盖或合并冲突 | 旧数据不覆盖新数据 | |
|
||||
| 统计无数据 | 无匹配记录 | 空状态 | 返回 0 或空集合 | 页面不显示假数据 | |
|
||||
| 审计日志为空 | 无审计记录 | 空状态 | 返回空集合 | 页面不报错 | |
|
||||
| 下游服务失败 | 外部接口超时或失败 | 错误提示且可重试 | 失败响应可追踪 | 不写成功审计 | |
|
||||
|
||||
+11
-4
@@ -1,24 +1,31 @@
|
||||
# 异常态补齐 Prompt
|
||||
|
||||
```text
|
||||
请基于 JeecgBoot 工单模块,列出状态流转、指派、删除、查询详情、审计日志、看板相关的异常态和防御性逻辑。
|
||||
请基于目标业务模块,列出状态流转、分配/转交、删除/作废、查询详情、审计日志、统计看板相关的异常态和防御性逻辑。
|
||||
|
||||
输入材料:
|
||||
- 模块名称:<填写>
|
||||
- 业务对象:<填写>
|
||||
- 角色与权限:<粘贴>
|
||||
- 状态流转表:<粘贴>
|
||||
- 接口契约或页面说明:<粘贴>
|
||||
|
||||
输出表格:
|
||||
场景 | 触发条件 | 前端表现 | 后端响应 | 用户提示 | 测试点 | 验收
|
||||
|
||||
必须覆盖:
|
||||
- 权限不足
|
||||
- 工单不存在
|
||||
- 记录不存在
|
||||
- 非法状态流转
|
||||
- 重复提交
|
||||
- 参数缺失
|
||||
- 并发修改
|
||||
- 看板无数据
|
||||
- 统计无数据
|
||||
- 审计日志为空
|
||||
- 下游服务失败
|
||||
|
||||
约束:
|
||||
- 先列异常态,不要直接改代码。
|
||||
- 给出每个异常态的验收步骤。
|
||||
- 标注事实、推断、建议和不确定点。
|
||||
```
|
||||
|
||||
|
||||
+4
-5
@@ -2,11 +2,10 @@
|
||||
|
||||
| 检查项 | 通过标准 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 菜单权限 | 工单菜单只对授权角色可见 | |
|
||||
| 按钮权限 | 新增、编辑、删除、指派、状态按钮按权限显示 | |
|
||||
| 菜单权限 | 目标模块菜单只对授权角色可见 | |
|
||||
| 按钮权限 | 新增、编辑、删除、分配、状态按钮按权限显示 | |
|
||||
| 接口权限 | 无权限账号直接请求敏感接口失败 | |
|
||||
| 数据权限 | 普通用户只能看到授权范围内工单 | |
|
||||
| 数据权限 | 普通用户只能看到授权范围内数据 | |
|
||||
| 权限字符 | 前端按钮、菜单配置、后端接口命名一致 | |
|
||||
| 审计 | 权限敏感操作成功后有审计记录 | |
|
||||
| 反例验证 | 无权限账号不能绕过前端执行删除/指派 | |
|
||||
|
||||
| 反例验证 | 无权限账号不能绕过前端执行删除/分配 | |
|
||||
|
||||
+8
-9
@@ -1,12 +1,11 @@
|
||||
# 工单权限控制方案
|
||||
# <模块名称> 权限控制方案
|
||||
|
||||
| 操作 | 前端入口 | 权限字符 | 后端接口 | 后端校验 | 数据权限 | 验收 |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| 新增工单 | 新增按钮 | work:order:add | /workOrder/add | 权限注解 | 无 | 无权限账号看不到按钮且直接请求失败 |
|
||||
| 编辑工单 | 编辑按钮 | work:order:edit | /workOrder/edit | 权限注解 + 状态校验 | 负责人/创建人范围 | 越权账号返回 403 或业务拒绝 |
|
||||
| 指派负责人 | 指派按钮 | work:order:assign | /workOrder/assign | 权限注解 | 管理员/负责人范围 | 普通研发无法指派他人 |
|
||||
| 状态流转 | 状态按钮 | work:order:transition | /workOrder/transition | 权限注解 + 状态机校验 | 相关工单范围 | 非法流转失败 |
|
||||
| 删除工单 | 删除按钮 | work:order:delete | /workOrder/delete | 权限注解 | 管理员范围 | 非管理员返回 403 |
|
||||
| 查看审计 | 审计页签 | work:order:audit | /workOrder/audit/list | 权限注解 | 相关工单范围 | 无权限不可见且接口拒绝 |
|
||||
| 看板 | 看板菜单 | work:order:dashboard | /workOrder/dashboard | 权限注解 | 数据范围过滤 | 不同角色数据范围不同 |
|
||||
|
||||
| 新增记录 | 新增按钮 | `<module>:<entity>:add` | `<POST /api/entity>` | 权限注解或统一鉴权 | 通常无数据范围 | 无权限账号看不到按钮且直接请求失败 |
|
||||
| 编辑记录 | 编辑按钮 | `<module>:<entity>:edit` | `<PUT /api/entity/{id}>` | 权限校验 + 状态校验 | 创建人/负责人/授权范围 | 越权账号返回 403 或业务拒绝 |
|
||||
| 分配/转交 | 分配按钮 | `<module>:<entity>:assign` | `<POST /api/entity/{id}/assign>` | 权限校验 | 管理范围或当前授权范围 | 未授权角色无法分配给他人 |
|
||||
| 状态流转 | 状态按钮 | `<module>:<entity>:transition` | `<POST /api/entity/{id}/transition>` | 权限校验 + 状态机校验 | 当前授权范围 | 非法流转失败且状态不变 |
|
||||
| 删除/作废 | 删除或作废按钮 | `<module>:<entity>:delete` | `<DELETE /api/entity/{id}>` | 权限校验 + 风险校验 | 管理范围 | 非授权角色返回 403 或业务拒绝 |
|
||||
| 查看审计 | 审计页签 | `<module>:<entity>:audit` | `<GET /api/entity/{id}/audit>` | 权限校验 | 当前授权范围 | 无权限不可见且接口拒绝 |
|
||||
| 统计看板 | 看板菜单 | `<module>:<entity>:dashboard` | `<GET /api/entity/dashboard>` | 权限校验 | 数据范围过滤 | 不同角色返回授权范围内统计 |
|
||||
|
||||
+4
-2
@@ -1,9 +1,11 @@
|
||||
# 权限控制方案生成 Prompt
|
||||
|
||||
```text
|
||||
请基于工单模块 RBAC 权限矩阵,生成 JeecgBoot 权限控制方案。
|
||||
请基于目标业务模块 RBAC 权限矩阵,生成权限控制方案。
|
||||
|
||||
输入材料:
|
||||
- 模块名称:<填写>
|
||||
- 业务对象:<填写>
|
||||
- RBAC 权限矩阵:<粘贴>
|
||||
- 接口契约表:<粘贴>
|
||||
- 当前项目权限相关路径:<粘贴>
|
||||
@@ -20,5 +22,5 @@
|
||||
- 不要直接改代码。
|
||||
- 后端接口权限必须单独说明。
|
||||
- 每个敏感操作必须有验收方式。
|
||||
- 权限字符、接口路径和角色名称必须来自输入材料;没有依据时标注为建议。
|
||||
```
|
||||
|
||||
|
||||
+1
-2
@@ -6,7 +6,6 @@
|
||||
| 合法流转 | 状态流转表中的合法路径可执行 | |
|
||||
| 非法流转 | 非法路径被拒绝且状态不变 | |
|
||||
| 角色限制 | 不同角色只能执行被授权动作 | |
|
||||
| 前置条件 | 驳回原因、关闭条件、负责人等校验完整 | |
|
||||
| 前置条件 | 驳回原因、关闭条件、处理人、审批意见等校验完整 | |
|
||||
| 审计日志 | 每次成功流转写审计 | |
|
||||
| 重复提交 | 重复点击不会产生重复有效流转 | |
|
||||
|
||||
|
||||
+15
-16
@@ -1,22 +1,21 @@
|
||||
# 工单状态流转表
|
||||
# <模块名称> 状态流转表
|
||||
|
||||
| 当前状态 | 动作 | 目标状态 | 允许角色 | 前置条件 | 后置动作 | 验收 |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| 新建 | 指派 | 新建 | 管理员/负责人 | 工单未关闭 | 写审计日志 | 指派人变化且状态不变 |
|
||||
| 新建 | 开始处理 | 处理中 | 研发处理人/负责人 | 已指派处理人 | 写审计日志 | 状态变为处理中 |
|
||||
| 处理中 | 提交验证 | 待验证 | 研发处理人/负责人 | 处理说明不为空 | 写审计日志 | 状态变为待验证 |
|
||||
| 待验证 | 验证通过 | 已关闭 | 测试验证人/负责人 | 验证结果通过 | 写审计日志和关闭时间 | 状态变为已关闭 |
|
||||
| 待验证 | 验证驳回 | 已驳回 | 测试验证人/负责人 | 驳回原因不为空 | 写审计日志 | 状态变为已驳回 |
|
||||
| 已驳回 | 重新处理 | 处理中 | 研发处理人/负责人 | 驳回原因已读 | 写审计日志 | 状态变为处理中 |
|
||||
| 已关闭 | 重新打开 | 新建 | 管理员 | 重开原因不为空 | 写审计日志 | 状态变为新建 |
|
||||
| 当前状态 | 动作 | 目标状态 | 允许角色 | 前置条件 | 后置动作 | 验收 | 来源证据 |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| 草稿/新建 | 提交 | 待处理/待审核 | 创建人/提交人 | 必填字段完整 | 写审计日志 | 状态变为目标状态 | |
|
||||
| 待处理/待审核 | 分配/领取 | 处理中 | 管理员/负责人/处理人 | 处理人存在且有权限 | 写审计日志 | 处理人变化且状态正确 | |
|
||||
| 处理中 | 提交结果 | 待确认/待复核 | 处理人/负责人 | 处理说明或结果不为空 | 写审计日志 | 状态变为待确认 | |
|
||||
| 待确认/待复核 | 通过 | 已完成/已关闭 | 审核人/负责人 | 审核结论通过 | 写审计日志和完成时间 | 状态进入终态 | |
|
||||
| 待确认/待复核 | 驳回 | 已驳回/待修改 | 审核人/负责人 | 驳回原因不为空 | 写审计日志 | 状态变为驳回态 | |
|
||||
| 已驳回/待修改 | 重新提交 | 待处理/待审核 | 创建人/处理人 | 修改说明不为空 | 写审计日志 | 回到处理链路 | |
|
||||
| 已完成/已关闭 | 重新打开 | 草稿/新建/处理中 | 管理员/负责人 | 重开原因不为空 | 写审计日志 | 状态按规则回退 | |
|
||||
|
||||
## 非法流转清单
|
||||
|
||||
| 当前状态 | 尝试动作 | 问题 | 系统响应 | 验收 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 已关闭 | 开始处理 | 关闭后不能直接处理 | 返回非法流转 | 状态不变 |
|
||||
| 新建 | 验证通过 | 未处理不能验证 | 返回非法流转 | 状态不变 |
|
||||
| 待验证 | 提交验证 | 重复提交验证 | 返回非法流转 | 只保留原状态 |
|
||||
| 处理中 | 验证通过 | 未进入待验证 | 返回非法流转 | 状态不变 |
|
||||
| 已驳回 | 关闭 | 驳回后不能直接关闭 | 返回非法流转 | 状态不变 |
|
||||
|
||||
| 已完成/已关闭 | 直接处理 | 终态不能直接进入处理中 | 返回非法流转 | 状态不变 |
|
||||
| 草稿/新建 | 直接通过 | 未提交或未处理不能通过 | 返回非法流转 | 状态不变 |
|
||||
| 待确认/待复核 | 重复提交结果 | 重复动作不应再次生效 | 返回非法流转或幂等结果 | 只保留原状态 |
|
||||
| 处理中 | 直接通过 | 未进入确认/复核节点 | 返回非法流转 | 状态不变 |
|
||||
| 已驳回/待修改 | 直接关闭 | 驳回后不能绕过修改或确认 | 返回非法流转 | 状态不变 |
|
||||
|
||||
+16
-17
@@ -1,23 +1,22 @@
|
||||
# 状态流转设计 Prompt
|
||||
|
||||
```text
|
||||
请为 JeecgBoot 工单模块设计状态流转规则。
|
||||
请为目标业务模块设计状态流转规则。
|
||||
|
||||
状态候选:
|
||||
- 新建
|
||||
输入材料:
|
||||
- 模块名称:<填写>
|
||||
- 业务对象:<填写>
|
||||
- 角色列表:<粘贴>
|
||||
- 当前需求或已有状态枚举:<粘贴>
|
||||
- 关键动作:<粘贴>
|
||||
|
||||
可参考但必须按项目替换的状态类型:
|
||||
- 草稿/新建
|
||||
- 待处理/待审核
|
||||
- 处理中
|
||||
- 待验证
|
||||
- 已关闭
|
||||
- 已驳回
|
||||
|
||||
动作候选:
|
||||
- 指派
|
||||
- 开始处理
|
||||
- 提交验证
|
||||
- 验证通过
|
||||
- 验证驳回
|
||||
- 关闭
|
||||
- 重新打开
|
||||
- 待确认/待复核
|
||||
- 已完成/已关闭
|
||||
- 已驳回/待修改
|
||||
|
||||
输出要求:
|
||||
1. 状态流转表:当前状态、动作、目标状态、允许角色、前置条件、后置动作、验收。
|
||||
@@ -28,7 +27,7 @@
|
||||
|
||||
约束:
|
||||
- 先出状态表,不要直接写 if else。
|
||||
- 已关闭、越权、缺少说明、重复提交必须覆盖。
|
||||
- 终态、越权、缺少说明、重复提交必须覆盖。
|
||||
- 每条规则必须有验收方式。
|
||||
- 没有需求依据的状态或动作必须标注为建议或待确认。
|
||||
```
|
||||
|
||||
|
||||
+9
-10
@@ -1,13 +1,12 @@
|
||||
# 工单看板指标字典
|
||||
# <模块名称> 看板指标字典
|
||||
|
||||
| 指标 | 含义 | 口径 | 数据来源 | 展示方式 | 权限 | 验收 |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| 工单总数 | 当前筛选范围内工单数量 | count(ticket_id) | 工单表 | 指标卡 | 看板权限 | 与列表同条件数量一致 |
|
||||
| 未关闭工单数 | 状态不是已关闭的数量 | status != closed | 工单表 | 指标卡 | 看板权限 | 过滤状态验证 |
|
||||
| 平均关闭周期 | 从创建到关闭平均耗时 | avg(close_time - create_time) | 工单表 | 指标卡/趋势 | 看板权限 | 抽样计算一致 |
|
||||
| 按优先级分布 | 高中低优先级数量 | group by priority | 工单表/字典 | 饼图/柱状图 | 看板权限 | 分组总和等于总数 |
|
||||
| 按类型分布 | 缺陷/需求/支持数量 | group by type | 工单表/字典 | 柱状图 | 看板权限 | 分组总和等于总数 |
|
||||
| 缺陷趋势 | 按日期统计缺陷工单 | type=bug group by date | 工单表 | 折线图 | 看板权限 | 日期范围正确 |
|
||||
| 逾期工单数 | 超过 SLA 未关闭数量 | due_time < now and status != closed | 工单表 | 指标卡 | 看板权限 | SLA 口径明确 |
|
||||
| 人员处理负载 | 按负责人统计未关闭数量 | group by assignee | 工单表 | 排行榜 | 管理员/负责人 | 数据范围正确 |
|
||||
|
||||
| 记录总数 | 当前筛选范围内业务记录数量 | count(target_id) | 主业务表 | 指标卡 | 看板权限 | 与列表同条件数量一致 |
|
||||
| 未完成数量 | 状态不在终态集合内的数量 | status not in `<terminal_statuses>` | 主业务表 | 指标卡 | 看板权限 | 过滤状态验证 |
|
||||
| 平均完成周期 | 从开始时间到完成时间的平均耗时 | avg(completed_at - started_at) | 主业务表 | 指标卡/趋势 | 看板权限 | 抽样计算一致 |
|
||||
| 按状态分布 | 各状态记录数量 | group by status | 主业务表/状态字典 | 饼图/柱状图 | 看板权限 | 分组总和等于总数 |
|
||||
| 按类型分布 | 各业务类型数量 | group by type | 主业务表/字典 | 柱状图 | 看板权限 | 分组总和等于总数 |
|
||||
| 趋势指标 | 按日期统计新增、完成或失败数量 | group by date_field | 主业务表 | 折线图 | 看板权限 | 日期范围正确 |
|
||||
| 逾期数量 | 超过 SLA 且未完成的数量 | due_at < now and status not in `<terminal_statuses>` | 主业务表 | 指标卡 | 看板权限 | SLA 口径明确 |
|
||||
| 人员处理负载 | 按负责人/处理人统计未完成数量 | group by owner_id / assignee_id | 主业务表 | 排行榜 | 管理员/负责人 | 数据范围正确 |
|
||||
|
||||
+16
-9
@@ -1,16 +1,23 @@
|
||||
# 看板指标设计 Prompt
|
||||
|
||||
```text
|
||||
请为 JeecgBoot 工单模块设计研发效能看板指标。
|
||||
请为目标业务模块设计业务看板指标。
|
||||
|
||||
指标方向:
|
||||
- 工单总数
|
||||
- 未关闭工单数
|
||||
- 平均关闭周期
|
||||
- 按优先级分布
|
||||
输入材料:
|
||||
- 模块名称:<填写>
|
||||
- 业务对象:<填写>
|
||||
- 角色与数据范围:<粘贴>
|
||||
- 状态枚举与时间字段:<粘贴>
|
||||
- 列表筛选条件:<粘贴>
|
||||
|
||||
指标方向可参考:
|
||||
- 记录总数
|
||||
- 未完成数量
|
||||
- 平均完成周期
|
||||
- 按状态分布
|
||||
- 按类型分布
|
||||
- 缺陷趋势
|
||||
- 逾期工单数
|
||||
- 趋势指标
|
||||
- 逾期数量
|
||||
- 人员处理负载
|
||||
|
||||
输出要求:
|
||||
@@ -24,5 +31,5 @@
|
||||
- 每个指标必须可计算。
|
||||
- 不要只写页面 UI。
|
||||
- 指标口径不清必须写入不确定点。
|
||||
- 不要把示例指标名直接当成目标项目事实。
|
||||
```
|
||||
|
||||
|
||||
+4
-2
@@ -1,9 +1,11 @@
|
||||
# 看板接口验收 Prompt
|
||||
|
||||
```text
|
||||
请为 JeecgBoot 工单看板统计接口生成验收记录。
|
||||
请为目标业务模块看板统计接口生成验收记录。
|
||||
|
||||
输入材料:
|
||||
- 模块名称:<填写>
|
||||
- 业务对象:<填写>
|
||||
- 看板指标字典:<粘贴>
|
||||
- 看板接口契约:<粘贴>
|
||||
- 权限矩阵:<粘贴>
|
||||
@@ -23,5 +25,5 @@
|
||||
约束:
|
||||
- 不要只说“接口正常”。
|
||||
- 每个指标至少有一个验收动作。
|
||||
- 每个验收动作都要说明账号/角色、请求参数、预期、实际和证据。
|
||||
```
|
||||
|
||||
|
||||
+2
-3
@@ -2,11 +2,10 @@
|
||||
|
||||
| 验收项 | 请求条件 | 通过标准 | 结果 |
|
||||
| --- | --- | --- | --- |
|
||||
| 默认查询 | 管理员默认条件 | 返回完整指标 | |
|
||||
| 默认查询 | 管理员或授权角色默认条件 | 返回完整指标 | |
|
||||
| 时间过滤 | 指定 start/end | 只统计时间范围内数据 | |
|
||||
| 类型过滤 | 指定工单类型 | 只统计对应类型 | |
|
||||
| 类型过滤 | 指定业务类型 | 只统计对应类型 | |
|
||||
| 空数据 | 无匹配条件 | 返回 0 或空集合 | |
|
||||
| 无权限 | 未授权账号 | 返回 403 或业务拒绝 | |
|
||||
| 数据范围 | 普通角色 | 只返回授权范围 | |
|
||||
| 指标一致性 | 固定样例数据 | 与手工计算一致 | |
|
||||
|
||||
|
||||
+7
-8
@@ -1,11 +1,10 @@
|
||||
# 工单看板接口验收记录
|
||||
# <模块名称> 看板接口验收记录
|
||||
|
||||
| 验收项 | 账号/条件 | 请求参数 | 预期 | 实际 | 证据 | 结论 |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| 工单总数 | 管理员 | 默认筛选 | 返回总数 | | | |
|
||||
| 空数据 | 管理员 + 无匹配条件 | 不存在的日期范围 | 返回空集合或 0 | | | |
|
||||
| 无权限 | 只读外角色 | 默认筛选 | 返回 403 或业务拒绝 | | | |
|
||||
| 时间过滤 | 管理员 | start/end | 只统计范围内数据 | | | |
|
||||
| 数据范围 | 普通研发 | 默认筛选 | 只返回本人相关数据 | | | |
|
||||
| 指标口径 | 管理员 | 固定样例数据 | 与手工计算一致 | | | |
|
||||
|
||||
| 记录总数 | 管理员或授权角色 | 默认筛选 | 返回总数 | | | |
|
||||
| 空数据 | 授权角色 + 无匹配条件 | 不存在的日期范围或筛选条件 | 返回空集合或 0 | | | |
|
||||
| 无权限 | 未授权角色 | 默认筛选 | 返回 403 或业务拒绝 | | | |
|
||||
| 时间过滤 | 授权角色 | start/end | 只统计范围内数据 | | | |
|
||||
| 数据范围 | 普通业务角色 | 默认筛选 | 只返回本人或授权范围内数据 | | | |
|
||||
| 指标口径 | 授权角色 | 固定样例数据 | 与手工计算一致 | | | |
|
||||
|
||||
+1
-12
@@ -95,17 +95,6 @@ Good wording:
|
||||
本项目未发现 `AGENTS.md`、`CLAUDE.md`、`.trae/rules` 或 `README.md` 中的明确 AI 协作规则。以下约束来自配置文件和源码模式;未能由仓库证明的内容已标记为待确认。
|
||||
```
|
||||
|
||||
## JeecgBoot Example
|
||||
|
||||
For the training case only, JeecgBoot evidence can generate rules such as:
|
||||
|
||||
- `硬约束`: backend uses `Result<T>` response wrapper, from backend `CLAUDE.md`.
|
||||
- `硬约束`: frontend uses `defHttp` and backend menu permission mode, from frontend `CLAUDE.md`.
|
||||
- `硬约束`: backend modification blocks require `update-begin` / `update-end`, from backend `CLAUDE.md`.
|
||||
- `观察性约束`: business features should follow existing controller/service/mapper layering after verifying representative modules.
|
||||
|
||||
Keep these examples out of generic outputs unless the target project is JeecgBoot or explicitly similar.
|
||||
|
||||
## Quality Gates
|
||||
|
||||
Before claiming completion:
|
||||
@@ -122,4 +111,4 @@ Before claiming completion:
|
||||
- Do not turn general best practices into project rules without evidence.
|
||||
- Do not merge business constraints, technical constraints, and delivery constraints into one vague list.
|
||||
- Do not omit verification steps; rules are useful only if a learner or team can check them.
|
||||
- Do not copy JeecgBoot-specific constraints into unrelated projects.
|
||||
- Do not copy one project's specific constraints into unrelated projects.
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@
|
||||
|
||||
## 可复用性
|
||||
|
||||
- [ ] JeecgBoot 等项目特有规则没有写进通用规则。
|
||||
- [ ] 某个项目特有规则没有写进通用规则。
|
||||
- [ ] 每条规则都标注了“可直接复用 / 需重新扫描 / 不可迁移”。
|
||||
- [ ] 换项目时必须重新扫描的内容已经列出。
|
||||
- [ ] 可以从本清单反推出生成步骤。
|
||||
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
---
|
||||
name: project-knowledge-builder
|
||||
description: Use when a user asks “项目知识库”, “看项目”, “整理项目”, or otherwise wants to inspect a software project deeply, build/refresh a project knowledge base, create onboarding docs, architecture maps, domain glossaries, ADRs, generated API/config/database indexes, or RAG-ready repository documentation.
|
||||
---
|
||||
|
||||
# Project Knowledge Builder
|
||||
|
||||
## Overview
|
||||
|
||||
Build a source-grounded project knowledge base that helps humans and AI agents understand, extend, troubleshoot, and index a codebase. Treat the knowledge base as a maintained system artifact, not a README rewrite.
|
||||
|
||||
## Quick Use
|
||||
|
||||
Users should not need to remember commands, script paths, or `$project-knowledge-builder`.
|
||||
|
||||
The shortest trigger is enough:
|
||||
|
||||
- `项目知识库`
|
||||
|
||||
Treat the current repository as the target and `docs/project-knowledge/` as the output path unless the user says otherwise. Run the bundled inventory script yourself and write the docs. Only show manual commands when the user explicitly asks for command-line usage.
|
||||
|
||||
## Language And Audience Defaults
|
||||
|
||||
If the user writes in Chinese or asks for Chinese, write human-facing narrative docs in Chinese by default: README, context, architecture, runtime, backend, frontend, data, auth/permissions, extension, troubleshooting, RAG guidance and ADRs. Keep source paths, class names, commands, API paths, config keys, table names, permission codes and metadata enum values unchanged.
|
||||
|
||||
Treat beginners as a primary audience. A useful knowledge base should let a new maintainer answer four questions without extra coaching:
|
||||
|
||||
1. What is this project and where are the main modules?
|
||||
2. How do I run it locally or identify the active runtime mode?
|
||||
3. How do I find the backend endpoint, frontend page, database table and permission code for a feature?
|
||||
4. What must change when adding a normal feature, especially menu/button permissions?
|
||||
|
||||
Do not make generated indexes overly friendly at the cost of precision. Keep generated files machine-refreshable; make narrative docs readable.
|
||||
|
||||
## Core Rule
|
||||
|
||||
Every claim must be traceable to the repository or to an explicitly marked inference. Prefer source paths, commands, generated inventories, and unresolved-question lists over confident prose.
|
||||
|
||||
## Workflow
|
||||
|
||||
1. **Set scope.** Confirm or assume the output location. Default to `docs/project-knowledge/`. If the user mentions RAG, Feishu/Lark, Dify, Notion, onboarding, architecture review, or API docs, tailor the output contract.
|
||||
2. **Read local instructions first.** Check root docs plus `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `.codex/`, `.agents/`, package manifests, build files, env examples, Docker files, and module READMEs.
|
||||
3. **Generate an inventory.** Run `scripts/project_inventory.py` from this skill against the repo. Use its output as a factual base, then inspect important files manually.
|
||||
4. **Map contexts.** Identify bounded contexts, runtime modes, major modules, owners implied by paths, external systems, and data stores. Use `CONTEXT.md` and `CONTEXT-MAP.md` style docs.
|
||||
5. **Extract generated indexes.** Produce machine-refreshable docs where possible: endpoints, frontend routes/views, config keys, env variables, database tables, permission codes, scheduled jobs, queues, and extension points.
|
||||
6. **Write human guides.** Produce onboarding, architecture, local run/deploy, data model, auth/permission, extension, troubleshooting, and glossary docs. Match the user's language for narrative docs; for Chinese users, use Chinese section titles such as `已观察来源`, `核心事实`, `操作影响`, and `未知与风险`.
|
||||
7. **Create ADRs for real decisions.** Record important architecture decisions already embodied in the code. Do not invent future decisions unless marked as proposed.
|
||||
8. **Add RAG metadata guidance.** Include chunking, source-path metadata, stale-data policy, and exclusion rules.
|
||||
9. **Verify.** Re-run the inventory, scan docs for placeholders, broken relative links, stale paths, and unsupported claims. Report what was verified and what remains uncertain.
|
||||
|
||||
## Output Contract
|
||||
|
||||
Read `references/output-contract.md` when creating or upgrading a full knowledge base.
|
||||
|
||||
Minimum useful set:
|
||||
|
||||
```text
|
||||
docs/project-knowledge/
|
||||
├── README.md
|
||||
├── CONTEXT.md
|
||||
├── CONTEXT-MAP.md
|
||||
├── 01-architecture.md
|
||||
├── 02-runtime.md
|
||||
├── 03-backend.md
|
||||
├── 04-frontend.md
|
||||
├── 05-data-and-migrations.md
|
||||
├── 06-auth-permissions.md
|
||||
├── 07-extension-guide.md
|
||||
├── 08-troubleshooting.md
|
||||
├── 09-rag-indexing.md
|
||||
├── adr/
|
||||
│ └── 0001-current-runtime-architecture.md
|
||||
└── generated/
|
||||
├── project-inventory.md
|
||||
├── backend-endpoints.md
|
||||
├── frontend-routes.md
|
||||
├── config-reference.md
|
||||
├── database-dictionary.md
|
||||
└── permission-codes.md
|
||||
```
|
||||
|
||||
Scale down only if the repo is small or the user requests a lighter artifact.
|
||||
|
||||
## Source-Grounding Standards
|
||||
|
||||
- Cite source paths inline for non-obvious claims.
|
||||
- Distinguish **Observed** from **Inferred** and **Unknown**.
|
||||
- Do not summarize generated code, dependencies, or configs from memory. Read them.
|
||||
- If external docs are needed for unstable facts, browse primary sources and link them.
|
||||
- Preserve project-specific conventions. If a repo requires trace comments, ADR format, or issue IDs, document and follow that.
|
||||
|
||||
## Cross-Platform Compatibility
|
||||
|
||||
Read `references/compatibility.md` when the user asks about macOS, Windows, Linux, CI, portability, or installing/running the skill across machines. The bundled inventory script is intended to run on Python 3.9+ with only the standard library.
|
||||
|
||||
## Inventory Script
|
||||
|
||||
Use this only for manual refreshes or when the user asks for the command. Run from the target repo:
|
||||
|
||||
macOS/Linux:
|
||||
|
||||
```sh
|
||||
python3 /path/to/skill/scripts/project_inventory.py --root . --out docs/project-knowledge/generated
|
||||
```
|
||||
|
||||
Windows PowerShell:
|
||||
|
||||
```powershell
|
||||
py -3 C:\path\to\skill\scripts\project_inventory.py --root . --out docs\project-knowledge\generated
|
||||
```
|
||||
|
||||
Useful options:
|
||||
|
||||
```sh
|
||||
python3 /path/to/skill/scripts/project_inventory.py --root . --out ./kb-inventory --json
|
||||
python3 /path/to/skill/scripts/project_inventory.py --root . --out docs/project-knowledge/generated --max-files 20000
|
||||
```
|
||||
|
||||
The script is a starting point, not a replacement for reading core files. Inspect representative files before writing narrative docs.
|
||||
|
||||
## Quality Gates
|
||||
|
||||
Before final response:
|
||||
|
||||
- List generated docs with a platform-appropriate command, such as `find docs/project-knowledge -type f | sort` on macOS/Linux or `Get-ChildItem docs/project-knowledge -Recurse -File` on PowerShell.
|
||||
- `rg -n "TODO|TBD|待补|unknown|your/path|foo|bar" docs/project-knowledge`
|
||||
- Re-run the inventory script after edits.
|
||||
- Check that top-level README links resolve.
|
||||
- If the user is Chinese, scan narrative docs for English-only structural headings such as `Observed Sources`, `Core Facts`, `Operational Implications`, `Unknowns/Risks`, `Architecture`, `Runtime`, `Backend`, `Frontend`, `Troubleshooting`, and translate them unless they are code, metadata, or generated output.
|
||||
- Check newcomer usefulness: README gives a reading order; runtime doc names local/Docker/cloud modes; auth doc explains menu/button permission flow; extension doc explains backend CRUD, frontend page and permission changes.
|
||||
- `git status --short` to report changed files.
|
||||
|
||||
If the user asked for “deep” or “落地”, do not stop at a single overview. Deliver generated indexes plus human guides.
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
interface:
|
||||
display_name: "项目知识库"
|
||||
short_description: "深度整理代码仓库知识库"
|
||||
default_prompt: "Use $project-knowledge-builder 为当前项目生成 docs/project-knowledge 项目知识库。"
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
# Cross-Platform Compatibility
|
||||
|
||||
Use this reference when running or installing the skill on macOS, Windows, Linux, or CI.
|
||||
|
||||
## Compatibility Summary
|
||||
|
||||
| Area | macOS | Linux | Windows |
|
||||
| --- | --- | --- | --- |
|
||||
| `SKILL.md` workflow | Supported | Supported | Supported |
|
||||
| `project_inventory.py` | Supported with Python 3.9+ | Supported with Python 3.9+ | Supported with Python 3.9+ |
|
||||
| Python dependencies | Standard library only | Standard library only | Standard library only |
|
||||
| Path handling | `pathlib` | `pathlib` | `pathlib` |
|
||||
| Shell dependency | None in script | None in script | None in script |
|
||||
| Generated Markdown paths | POSIX-style relative paths | POSIX-style relative paths | POSIX-style relative paths |
|
||||
|
||||
The script intentionally emits repository-relative paths with `/` separators so generated Markdown is stable across platforms and friendlier for URLs, GitHub, and RAG metadata.
|
||||
|
||||
## Python Invocation
|
||||
|
||||
macOS and Linux usually have one of these:
|
||||
|
||||
```sh
|
||||
python3 skills/project-knowledge-builder/scripts/project_inventory.py --root . --out docs/project-knowledge/generated
|
||||
python skills/project-knowledge-builder/scripts/project_inventory.py --root . --out docs/project-knowledge/generated
|
||||
```
|
||||
|
||||
Windows PowerShell usually uses:
|
||||
|
||||
```powershell
|
||||
py -3 skills\project-knowledge-builder\scripts\project_inventory.py --root . --out docs\project-knowledge\generated
|
||||
python skills\project-knowledge-builder\scripts\project_inventory.py --root . --out docs\project-knowledge\generated
|
||||
```
|
||||
|
||||
CI should prefer an explicit Python:
|
||||
|
||||
```sh
|
||||
python -m py_compile skills/project-knowledge-builder/scripts/project_inventory.py
|
||||
python skills/project-knowledge-builder/scripts/project_inventory.py --root . --out docs/project-knowledge/generated --json
|
||||
```
|
||||
|
||||
## Command Substitutions
|
||||
|
||||
| Task | macOS/Linux | Windows PowerShell |
|
||||
| --- | --- | --- |
|
||||
| List docs | `find docs/project-knowledge -type f \| sort` | `Get-ChildItem docs/project-knowledge -Recurse -File \| Sort-Object FullName` |
|
||||
| Search placeholders | `rg -n "TODO|TBD" docs/project-knowledge` | `rg -n "TODO|TBD" docs/project-knowledge` |
|
||||
| Show git status | `git status --short` | `git status --short` |
|
||||
| Remove temp output | `rm -rf ./kb-inventory` | `Remove-Item .\kb-inventory -Recurse -Force` |
|
||||
|
||||
`rg` is preferred where available. If `rg` is not installed, use the platform search available in the environment.
|
||||
|
||||
## Avoid In Skill Examples
|
||||
|
||||
- Hard-coded `/tmp` paths when the command should work on Windows.
|
||||
- POSIX-only command chains such as `cmd1 && cmd2` in user-facing instructions when a PowerShell equivalent is needed.
|
||||
- Shell glob assumptions that behave differently between zsh, bash, PowerShell, and cmd.
|
||||
- Python code that depends on executable shebang behavior; Windows users should call `py -3 script.py`.
|
||||
|
||||
## Known Limits
|
||||
|
||||
- Java endpoint extraction is regex-based and intentionally conservative. It does not fully resolve constants, composed annotations, or inherited controller mappings.
|
||||
- SQL table extraction looks for `CREATE TABLE`; tables created dynamically or through migrations in another DSL need manual documentation.
|
||||
- Frontend route extraction scans route-like literals and view files; runtime-generated route data from APIs still requires backend menu/permission data or database export.
|
||||
- Very large repositories may need `--max-files` tuning or additional ignore directories.
|
||||
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
# Project Knowledge Builder Output Contract
|
||||
|
||||
Use this reference when producing a full codebase knowledge base.
|
||||
|
||||
## Language Policy
|
||||
|
||||
Match the user's language for human-facing narrative docs. If the user writes in Chinese or asks for Chinese, write README, context, architecture, runtime, backend, frontend, data, auth/permissions, extension, troubleshooting, RAG guidance and ADRs in Chinese.
|
||||
|
||||
Keep technical anchors unchanged: source paths, commands, class names, method names, API paths, config keys, table names, permission codes, JSON keys and metadata enum values.
|
||||
|
||||
Generated indexes may remain technical and source-like. Do not hand-translate generated values if it reduces refreshability.
|
||||
|
||||
## Document Roles
|
||||
|
||||
| File | Purpose |
|
||||
| --- | --- |
|
||||
| `README.md` | Entry point, reading order, high-value links, freshness note. For Chinese output, title and usage guidance should be Chinese. |
|
||||
| `CONTEXT.md` | Domain language, business capabilities, user roles, core nouns, invariants. |
|
||||
| `CONTEXT-MAP.md` | Bounded contexts, module ownership, upstream/downstream dependencies, runtime boundaries. |
|
||||
| `01-architecture.md` | System shape, module graph, request/data/control flows, extension seams. |
|
||||
| `02-runtime.md` | Local run, build, env vars, Docker, deployment modes, process topology. Must identify local, Docker standalone and cloud modes when present. |
|
||||
| `03-backend.md` | Backend modules, entrypoints, API conventions, service/mapper/entity patterns. |
|
||||
| `04-frontend.md` | Frontend bootstrap, routing, state, API client, component/page conventions. |
|
||||
| `05-data-and-migrations.md` | Databases, migrations, schema sources, seed data, table families. |
|
||||
| `06-auth-permissions.md` | Authentication, authorization, token/session flow, permission-code lifecycle. Must explain menu/button permission flow when the repo has backend-driven menus. |
|
||||
| `07-extension-guide.md` | How to add a feature end-to-end, with source-grounded examples. Must cover backend CRUD, frontend page and permission/menu data changes when applicable. |
|
||||
| `08-troubleshooting.md` | Symptom-driven runbook with commands, files, and likely causes. |
|
||||
| `09-rag-indexing.md` | Chunking, metadata, exclusions, refresh cadence, stale-data policy. |
|
||||
| `adr/*.md` | Architecture decisions observed in the current code. |
|
||||
| `generated/*.md` | Data-derived indexes that can be regenerated. |
|
||||
|
||||
## Required Sections
|
||||
|
||||
Each narrative doc should include:
|
||||
|
||||
- **Observed Sources:** concrete files or commands used.
|
||||
- **Core Facts:** concise source-backed statements.
|
||||
- **Operational Implications:** what developers must do differently because of those facts.
|
||||
- **Unknowns/Risks:** gaps that need runtime access, DB export, product owner input, or external docs.
|
||||
|
||||
For Chinese output, use equivalent section labels:
|
||||
|
||||
- **已观察来源**
|
||||
- **核心事实**
|
||||
- **操作影响**
|
||||
- **未知与风险**
|
||||
|
||||
## Newcomer Usefulness Gate
|
||||
|
||||
Before considering the knowledge base useful for handoff, verify that a new maintainer can answer:
|
||||
|
||||
1. What is the product/project, and which directories matter first?
|
||||
2. How do I start or identify the active runtime mode?
|
||||
3. Where are backend endpoints, frontend routes/pages, config, tables and permission codes indexed?
|
||||
4. How do menu, button and backend permission checks connect?
|
||||
5. When adding a normal feature, which backend, frontend, database and permission artifacts usually change?
|
||||
|
||||
If the answer is not obvious from README plus the narrative docs, add or revise human-facing guidance before finishing. Do not solve this by making generated indexes longer.
|
||||
|
||||
## Generated Indexes
|
||||
|
||||
### `project-inventory.md`
|
||||
|
||||
Include:
|
||||
|
||||
- repository roots
|
||||
- build/package manifests
|
||||
- primary languages
|
||||
- major directories
|
||||
- scripts
|
||||
- Docker/compose files
|
||||
- env files
|
||||
- test files
|
||||
|
||||
### `backend-endpoints.md`
|
||||
|
||||
Include route method, path, class/file, approximate line, auth annotations, and notes. Do not invent full route paths when class-level and method-level mappings require Java expression resolution; show observed fragments and mark composition limitations.
|
||||
|
||||
### `frontend-routes.md`
|
||||
|
||||
Include static router files, dynamic route loaders, `src/views` index, route guard files, and external route package loaders.
|
||||
|
||||
### `config-reference.md`
|
||||
|
||||
Include env files, YAML/properties files, relevant keys, default values, and risk notes. Redact secrets.
|
||||
|
||||
### `database-dictionary.md`
|
||||
|
||||
Include SQL files, migration files, table names, table families, and whether the table is initialized, migrated, or inferred. Avoid loading huge SQL into prose; summarize and link.
|
||||
|
||||
### `permission-codes.md`
|
||||
|
||||
Include backend annotations, frontend permission helpers/usages, menu/permission SQL occurrences, and auth lifecycle notes.
|
||||
|
||||
## ADR Template
|
||||
|
||||
```markdown
|
||||
# ADR NNNN: Title
|
||||
|
||||
Date: YYYY-MM-DD
|
||||
Status: Observed
|
||||
|
||||
## Context
|
||||
|
||||
Source-backed facts that show the decision exists.
|
||||
|
||||
## Decision
|
||||
|
||||
The architecture decision embodied by the current code.
|
||||
|
||||
## Consequences
|
||||
|
||||
Benefits, tradeoffs, operational constraints, and migration risks.
|
||||
|
||||
## Sources
|
||||
|
||||
- `path/to/file`
|
||||
```
|
||||
|
||||
## RAG Metadata
|
||||
|
||||
Recommended metadata per chunk:
|
||||
|
||||
```json
|
||||
{
|
||||
"project": "name",
|
||||
"snapshot_date": "YYYY-MM-DD",
|
||||
"source_path": "path",
|
||||
"doc_type": "architecture|runtime|generated|adr|runbook",
|
||||
"domain": "backend|frontend|data|auth|deploy",
|
||||
"freshness": "manual|generated",
|
||||
"confidence": "observed|inferred|unknown"
|
||||
}
|
||||
```
|
||||
|
||||
## Anti-Patterns
|
||||
|
||||
- A long essay without generated indexes.
|
||||
- “Best practice” advice unrelated to the repo.
|
||||
- Copying README marketing text as architecture documentation.
|
||||
- Claiming an endpoint, table, permission, or runtime mode exists without a source path.
|
||||
- Hiding unknowns instead of listing them.
|
||||
+313
@@ -0,0 +1,313 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate a source-grounded project inventory for knowledge-base work."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
from collections import Counter, defaultdict
|
||||
from pathlib import Path
|
||||
from typing import Iterable
|
||||
|
||||
IGNORE_DIRS = {
|
||||
".git",
|
||||
".idea",
|
||||
".vscode",
|
||||
"node_modules",
|
||||
"dist",
|
||||
"build",
|
||||
"target",
|
||||
".gradle",
|
||||
".mvn/wrapper",
|
||||
"coverage",
|
||||
".next",
|
||||
".nuxt",
|
||||
"__pycache__",
|
||||
}
|
||||
|
||||
MANIFEST_NAMES = {
|
||||
"package.json",
|
||||
"pnpm-lock.yaml",
|
||||
"yarn.lock",
|
||||
"package-lock.json",
|
||||
"pom.xml",
|
||||
"build.gradle",
|
||||
"settings.gradle",
|
||||
"Cargo.toml",
|
||||
"pyproject.toml",
|
||||
"requirements.txt",
|
||||
"go.mod",
|
||||
"composer.json",
|
||||
"Gemfile",
|
||||
}
|
||||
|
||||
CONFIG_PATTERNS = (
|
||||
re.compile(r".*\.env(\..*)?$"),
|
||||
re.compile(r".*application[-\w]*\.(yml|yaml|properties)$"),
|
||||
re.compile(r".*\.(ya?ml|toml|ini|properties|conf)$"),
|
||||
)
|
||||
|
||||
HTTP_MAPPING_RE = re.compile(
|
||||
r"@(RequestMapping|GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping)\s*(?:\((.*?)\))?"
|
||||
)
|
||||
PERMISSION_RE = re.compile(r"@(?:RequiresPermissions|RequiresRoles)\s*\((.*?)\)")
|
||||
TABLE_NAME_RE = re.compile(
|
||||
r"\bCREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?`?([A-Za-z0-9_.$-]+)`?",
|
||||
re.IGNORECASE,
|
||||
)
|
||||
VUE_ROUTE_RE = re.compile(r"\b(path|name|component)\s*:\s*['\"]([^'\"]+)['\"]")
|
||||
|
||||
|
||||
def is_ignored(path: Path, root: Path) -> bool:
|
||||
rel_parts = path.relative_to(root).parts
|
||||
for i in range(len(rel_parts)):
|
||||
joined = "/".join(rel_parts[: i + 1])
|
||||
if joined in IGNORE_DIRS or rel_parts[i] in IGNORE_DIRS:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def iter_files(root: Path, max_files: int) -> Iterable[Path]:
|
||||
count = 0
|
||||
for dirpath, dirnames, filenames in os.walk(root):
|
||||
current = Path(dirpath)
|
||||
dirnames[:] = [d for d in dirnames if not is_ignored(current / d, root)]
|
||||
for name in filenames:
|
||||
path = current / name
|
||||
if is_ignored(path, root):
|
||||
continue
|
||||
count += 1
|
||||
if count > max_files:
|
||||
return
|
||||
yield path
|
||||
|
||||
|
||||
def rel(path: Path, root: Path) -> str:
|
||||
return path.relative_to(root).as_posix()
|
||||
|
||||
|
||||
def read_text(path: Path, limit: int = 400_000) -> str:
|
||||
try:
|
||||
data = path.read_bytes()
|
||||
except OSError:
|
||||
return ""
|
||||
if len(data) > limit:
|
||||
data = data[:limit]
|
||||
try:
|
||||
return data.decode("utf-8")
|
||||
except UnicodeDecodeError:
|
||||
try:
|
||||
return data.decode("utf-8", errors="ignore")
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
def detect_config(path: Path) -> bool:
|
||||
name = path.name
|
||||
return any(pattern.fullmatch(name) for pattern in CONFIG_PATTERNS)
|
||||
|
||||
|
||||
def extract_mapping_value(raw: str | None) -> str:
|
||||
if not raw:
|
||||
return ""
|
||||
value_match = re.search(r"['\"]([^'\"]+)['\"]", raw)
|
||||
if value_match:
|
||||
return value_match.group(1)
|
||||
return raw.strip().replace("\n", " ")[:120]
|
||||
|
||||
|
||||
def scan(root: Path, max_files: int) -> dict:
|
||||
files = list(iter_files(root, max_files))
|
||||
ext_counts = Counter(path.suffix.lower() or "[none]" for path in files)
|
||||
manifests = []
|
||||
configs = []
|
||||
docker = []
|
||||
tests = []
|
||||
java_endpoints = []
|
||||
permission_codes = []
|
||||
vue_routes = []
|
||||
views = []
|
||||
sql_tables = []
|
||||
major_dirs = defaultdict(int)
|
||||
|
||||
for path in files:
|
||||
r = rel(path, root)
|
||||
parts = Path(r).parts
|
||||
if parts:
|
||||
major_dirs[parts[0]] += 1
|
||||
if path.name in MANIFEST_NAMES:
|
||||
manifests.append(r)
|
||||
lower = path.name.lower()
|
||||
if lower.startswith("dockerfile") or "docker-compose" in lower:
|
||||
docker.append(r)
|
||||
if detect_config(path):
|
||||
configs.append(r)
|
||||
if re.search(r"(^|/)(test|tests|__tests__)(/|$)", r) or re.search(r"\.(test|spec)\.[A-Za-z0-9]+$", r):
|
||||
tests.append(r)
|
||||
if "/src/views/" in r and path.suffix.lower() in {".vue", ".tsx", ".ts"}:
|
||||
views.append(r)
|
||||
|
||||
suffix = path.suffix.lower()
|
||||
if suffix not in {".java", ".ts", ".tsx", ".vue", ".js", ".jsx", ".sql", ".yml", ".yaml", ".properties"}:
|
||||
continue
|
||||
text = read_text(path)
|
||||
if not text:
|
||||
continue
|
||||
|
||||
if suffix == ".java":
|
||||
lines = text.splitlines()
|
||||
class_mapping = ""
|
||||
class_name = ""
|
||||
pending_annotations: list[tuple[int, str, str]] = []
|
||||
for idx, line in enumerate(lines, start=1):
|
||||
class_match = re.search(r"\bclass\s+([A-Za-z0-9_]+)", line)
|
||||
if class_match:
|
||||
class_name = class_match.group(1)
|
||||
for match in HTTP_MAPPING_RE.finditer(line):
|
||||
value = extract_mapping_value(match.group(2))
|
||||
annotation = match.group(1)
|
||||
pending_annotations.append((idx, annotation, value))
|
||||
if annotation == "RequestMapping" and not class_mapping and ("class " not in line):
|
||||
class_mapping = value
|
||||
if re.search(r"\b(public|private|protected)\b.*\(", line) and pending_annotations:
|
||||
method = line.strip()[:160]
|
||||
for ann_line, annotation, value in pending_annotations:
|
||||
java_endpoints.append(
|
||||
{
|
||||
"file": r,
|
||||
"line": ann_line,
|
||||
"class": class_name,
|
||||
"annotation": annotation,
|
||||
"class_mapping": class_mapping,
|
||||
"mapping": value,
|
||||
"method_signature": method,
|
||||
}
|
||||
)
|
||||
pending_annotations = []
|
||||
for perm in PERMISSION_RE.finditer(line):
|
||||
permission_codes.append({"file": r, "line": idx, "value": perm.group(1).strip()})
|
||||
|
||||
if suffix in {".ts", ".tsx", ".vue", ".js", ".jsx"}:
|
||||
for idx, line in enumerate(text.splitlines(), start=1):
|
||||
if "path:" in line or "component:" in line or "name:" in line:
|
||||
for match in VUE_ROUTE_RE.finditer(line):
|
||||
vue_routes.append({"file": r, "line": idx, "key": match.group(1), "value": match.group(2)})
|
||||
|
||||
if suffix == ".sql":
|
||||
for match in TABLE_NAME_RE.finditer(text):
|
||||
sql_tables.append({"file": r, "table": match.group(1)})
|
||||
|
||||
return {
|
||||
"root": str(root),
|
||||
"file_count": len(files),
|
||||
"extensions": dict(ext_counts.most_common(40)),
|
||||
"major_dirs": dict(sorted(major_dirs.items(), key=lambda item: (-item[1], item[0]))),
|
||||
"manifests": sorted(manifests),
|
||||
"configs": sorted(configs),
|
||||
"docker": sorted(docker),
|
||||
"tests": sorted(tests),
|
||||
"views": sorted(views),
|
||||
"java_endpoints": java_endpoints,
|
||||
"permission_codes": permission_codes,
|
||||
"vue_routes": vue_routes,
|
||||
"sql_tables": sql_tables,
|
||||
}
|
||||
|
||||
|
||||
def write_md(data: dict, out_dir: Path) -> None:
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
def bullet(items: list[str], limit: int | None = None) -> str:
|
||||
selected = items if limit is None else items[:limit]
|
||||
if not selected:
|
||||
return "- None found\n"
|
||||
body = "".join(f"- `{item}`\n" for item in selected)
|
||||
if limit is not None and len(items) > limit:
|
||||
body += f"- ... {len(items) - limit} more\n"
|
||||
return body
|
||||
|
||||
inventory = [
|
||||
"# Project Inventory\n\n",
|
||||
f"Root: `{data['root']}`\n\n",
|
||||
f"Files scanned: {data['file_count']}\n\n",
|
||||
"## Major Directories\n\n",
|
||||
]
|
||||
inventory.extend(f"- `{name}`: {count} files\n" for name, count in data["major_dirs"].items())
|
||||
inventory.extend(["\n## Extensions\n\n"])
|
||||
inventory.extend(f"- `{name}`: {count}\n" for name, count in data["extensions"].items())
|
||||
inventory.extend(["\n## Manifests\n\n", bullet(data["manifests"])])
|
||||
inventory.extend(["\n## Config Files\n\n", bullet(data["configs"], 200)])
|
||||
inventory.extend(["\n## Docker Files\n\n", bullet(data["docker"])])
|
||||
inventory.extend(["\n## Test Files\n\n", bullet(data["tests"], 200)])
|
||||
(out_dir / "project-inventory.md").write_text("".join(inventory), encoding="utf-8")
|
||||
|
||||
endpoints = ["# Backend Endpoints\n\n"]
|
||||
if data["java_endpoints"]:
|
||||
endpoints.append("| File | Line | Class | Annotation | Class Mapping | Mapping | Method |\n")
|
||||
endpoints.append("| --- | ---: | --- | --- | --- | --- | --- |\n")
|
||||
for item in data["java_endpoints"]:
|
||||
method_signature = item["method_signature"].replace("|", "\\|")
|
||||
endpoints.append(
|
||||
f"| `{item['file']}` | {item['line']} | `{item['class']}` | `{item['annotation']}` | "
|
||||
f"`{item['class_mapping']}` | `{item['mapping']}` | `{method_signature}` |\n"
|
||||
)
|
||||
else:
|
||||
endpoints.append("No Java endpoint annotations found.\n")
|
||||
(out_dir / "backend-endpoints.md").write_text("".join(endpoints), encoding="utf-8")
|
||||
|
||||
routes = ["# Frontend Routes And Views\n\n", "## Views\n\n", bullet(data["views"], 400), "\n## Route-like Literals\n\n"]
|
||||
if data["vue_routes"]:
|
||||
routes.append("| File | Line | Key | Value |\n| --- | ---: | --- | --- |\n")
|
||||
for item in data["vue_routes"][:1000]:
|
||||
routes.append(f"| `{item['file']}` | {item['line']} | `{item['key']}` | `{item['value']}` |\n")
|
||||
if len(data["vue_routes"]) > 1000:
|
||||
routes.append(f"\nTruncated: {len(data['vue_routes']) - 1000} more route-like literals.\n")
|
||||
else:
|
||||
routes.append("No route-like literals found.\n")
|
||||
(out_dir / "frontend-routes.md").write_text("".join(routes), encoding="utf-8")
|
||||
|
||||
configs = ["# Config Reference\n\n", bullet(data["configs"], 500)]
|
||||
(out_dir / "config-reference.md").write_text("".join(configs), encoding="utf-8")
|
||||
|
||||
tables = ["# Database Dictionary\n\n"]
|
||||
if data["sql_tables"]:
|
||||
tables.append("| Table | Source |\n| --- | --- |\n")
|
||||
for item in sorted(data["sql_tables"], key=lambda x: (x["table"], x["file"])):
|
||||
tables.append(f"| `{item['table']}` | `{item['file']}` |\n")
|
||||
else:
|
||||
tables.append("No SQL CREATE TABLE statements found in scanned files.\n")
|
||||
(out_dir / "database-dictionary.md").write_text("".join(tables), encoding="utf-8")
|
||||
|
||||
perms = ["# Permission Codes\n\n"]
|
||||
if data["permission_codes"]:
|
||||
perms.append("| File | Line | Value |\n| --- | ---: | --- |\n")
|
||||
for item in data["permission_codes"]:
|
||||
permission_value = item["value"].replace("|", "\\|")
|
||||
perms.append(f"| `{item['file']}` | {item['line']} | `{permission_value}` |\n")
|
||||
else:
|
||||
perms.append("No permission annotations found.\n")
|
||||
(out_dir / "permission-codes.md").write_text("".join(perms), encoding="utf-8")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--root", default=".", help="Repository root to scan")
|
||||
parser.add_argument("--out", required=True, help="Output directory for generated Markdown")
|
||||
parser.add_argument("--json", action="store_true", help="Also write inventory.json")
|
||||
parser.add_argument("--max-files", type=int, default=30000, help="Maximum files to scan")
|
||||
args = parser.parse_args()
|
||||
|
||||
root = Path(args.root).resolve()
|
||||
out_dir = Path(args.out).resolve()
|
||||
data = scan(root, args.max_files)
|
||||
write_md(data, out_dir)
|
||||
if args.json:
|
||||
(out_dir / "inventory.json").write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
|
||||
print(f"Wrote project inventory to {out_dir}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
# 业务交付验收清单
|
||||
|
||||
本清单用于判断复杂业务模块是否达到可验收状态,适用于后台管理、审批流、运营系统、CRM、低代码二开和数据看板等项目。
|
||||
|
||||
## 项目理解
|
||||
|
||||
| 检查项 | 通过标准 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 能说明模块边界 | 说明模块负责什么、不负责什么 | |
|
||||
| 能定位关键目录 | 能指出前端页面、API 层、后端入口、服务层和数据层位置 | |
|
||||
| 能区分事实和推断 | 对没有源码依据的业务规则标注为推断或待确认 | |
|
||||
| 能记录不确定点 | 不确定内容没有被包装成确定事实 | |
|
||||
|
||||
## 需求与接口
|
||||
|
||||
| 检查项 | 通过标准 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 用户故事完整 | 覆盖主要角色、关键动作和限制条件 | |
|
||||
| 非目标范围明确 | 明确本次不做的能力、数据迁移、生产部署或外部集成 | |
|
||||
| 接口契约完整 | 覆盖列表、详情、新增、编辑、分配、状态、审计和看板 | |
|
||||
| 失败场景明确 | 每个关键接口至少有权限、参数、状态或数据不存在失败场景 | |
|
||||
| 验收方式明确 | 每个关键需求都有可执行检查方法 | |
|
||||
|
||||
## 权限与状态
|
||||
|
||||
| 检查项 | 通过标准 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 权限矩阵完整 | 覆盖页面级、按钮级、接口级和数据范围 | |
|
||||
| 权限字符合理 | 命名统一,并标注为建议或源码事实 | |
|
||||
| 后端权限未缺失 | 没有用前端按钮隐藏替代后端接口控制 | |
|
||||
| 状态流转表完整 | 覆盖初始态、处理中、确认/审核态、终态和驳回态 | |
|
||||
| 非法流转明确 | 列出关键非法流转、拒绝原因和验收方式 | |
|
||||
|
||||
## 审计、异常态与看板
|
||||
|
||||
| 检查项 | 通过标准 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 审计操作覆盖关键动作 | 创建、编辑、分配、状态流转、关闭/归档等关键动作被覆盖 | |
|
||||
| 审计字段可追溯 | 包含 actor、action、targetId、oldValue、newValue、source | |
|
||||
| 敏感信息处理 | oldValue/newValue 有脱敏说明 | |
|
||||
| 异常态可测试 | 权限不足、重复提交、非法状态、数据不存在、并发修改均覆盖 | |
|
||||
| 看板指标可计算 | 每个指标有口径、维度、过滤条件和数据来源建议 | |
|
||||
|
||||
## Review 与交付
|
||||
|
||||
| 检查项 | 通过标准 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| Review 有证据 | 问题能回到路径、表格、接口、角色或业务规则 | |
|
||||
| 风险按严重程度排序 | 高风险问题优先展示 | |
|
||||
| 建议可行动 | 每条建议有修复方向和验收方式 | |
|
||||
| 交付物齐全 | 设计表、Review 报告、验证记录和未闭环事项完整 | |
|
||||
| 能沉淀资产 | 高频问题能转成规则、检查清单、Prompt、反例或 Skill | |
|
||||
|
||||
## 判定原则
|
||||
|
||||
- 优先看证据,不优先看文字是否漂亮。
|
||||
- 优先看权限、状态、审计、异常态,不只看 CRUD。
|
||||
- 优先看不确定点是否被诚实标出。
|
||||
- 优先看结论能否被角色账号、接口请求、样例数据或浏览器操作验证。
|
||||
+2
-3
@@ -2,12 +2,11 @@
|
||||
|
||||
| 检查项 | 通过标准 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 创建记录 | 创建工单后能查询审计记录 | |
|
||||
| 创建记录 | 创建业务记录后能查询审计记录 | |
|
||||
| 字段变更 | 编辑关键字段记录 oldValue/newValue | |
|
||||
| 指派记录 | 指派负责人记录原负责人和新负责人 | |
|
||||
| 分配记录 | 分配或转交记录原处理人和新处理人 | |
|
||||
| 状态记录 | 状态流转记录原状态和新状态 | |
|
||||
| 操作人 | actor_id 和 actor_name 可追溯 | |
|
||||
| 来源 | source 或 request_id 可追溯 | |
|
||||
| 脱敏 | 敏感字段不明文进入审计 | |
|
||||
| 失败处理 | 操作失败不写成功审计 | |
|
||||
|
||||
|
||||
+1
-2
@@ -3,11 +3,10 @@
|
||||
| 异常态 | 必须验证 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 空列表 | 页面显示空状态,不报错 | |
|
||||
| 详情不存在 | 提示工单不存在,页面不崩溃 | |
|
||||
| 详情不存在 | 提示记录不存在,页面不崩溃 | |
|
||||
| 权限不足 | 前端提示或隐藏,后端拒绝 | |
|
||||
| 非法状态 | 返回非法流转,状态不变 | |
|
||||
| 重复提交 | 只成功一次,只写一条有效审计 | |
|
||||
| 参数缺失 | 返回参数错误,业务数据不变 | |
|
||||
| 并发修改 | 拒绝覆盖或提示刷新 | |
|
||||
| 看板无数据 | 图表显示空态,不显示假数据 | |
|
||||
|
||||
|
||||
+4
-5
@@ -2,11 +2,10 @@
|
||||
|
||||
| 检查项 | 通过标准 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 菜单权限 | 工单菜单只对授权角色可见 | |
|
||||
| 按钮权限 | 新增、编辑、删除、指派、状态按钮按权限显示 | |
|
||||
| 菜单权限 | 目标模块菜单只对授权角色可见 | |
|
||||
| 按钮权限 | 新增、编辑、删除、分配、状态按钮按权限显示 | |
|
||||
| 接口权限 | 无权限账号直接请求敏感接口失败 | |
|
||||
| 数据权限 | 普通用户只能看到授权范围内工单 | |
|
||||
| 数据权限 | 普通用户只能看到授权范围内数据 | |
|
||||
| 权限字符 | 前端按钮、菜单配置、后端接口命名一致 | |
|
||||
| 审计 | 权限敏感操作成功后有审计记录 | |
|
||||
| 反例验证 | 无权限账号不能绕过前端执行删除/指派 | |
|
||||
|
||||
| 反例验证 | 无权限账号不能绕过前端执行删除/分配 | |
|
||||
|
||||
+1
-2
@@ -6,7 +6,6 @@
|
||||
| 合法流转 | 状态流转表中的合法路径可执行 | |
|
||||
| 非法流转 | 非法路径被拒绝且状态不变 | |
|
||||
| 角色限制 | 不同角色只能执行被授权动作 | |
|
||||
| 前置条件 | 驳回原因、关闭条件、负责人等校验完整 | |
|
||||
| 前置条件 | 驳回原因、关闭条件、处理人、审批意见等校验完整 | |
|
||||
| 审计日志 | 每次成功流转写审计 | |
|
||||
| 重复提交 | 重复点击不会产生重复有效流转 | |
|
||||
|
||||
|
||||
+2
-3
@@ -2,11 +2,10 @@
|
||||
|
||||
| 验收项 | 请求条件 | 通过标准 | 结果 |
|
||||
| --- | --- | --- | --- |
|
||||
| 默认查询 | 管理员默认条件 | 返回完整指标 | |
|
||||
| 默认查询 | 管理员或授权角色默认条件 | 返回完整指标 | |
|
||||
| 时间过滤 | 指定 start/end | 只统计时间范围内数据 | |
|
||||
| 类型过滤 | 指定工单类型 | 只统计对应类型 | |
|
||||
| 类型过滤 | 指定业务类型 | 只统计对应类型 | |
|
||||
| 空数据 | 无匹配条件 | 返回 0 或空集合 | |
|
||||
| 无权限 | 未授权账号 | 返回 403 或业务拒绝 | |
|
||||
| 数据范围 | 普通角色 | 只返回授权范围 | |
|
||||
| 指标一致性 | 固定样例数据 | 与手工计算一致 | |
|
||||
|
||||
|
||||
+4
-2
@@ -1,9 +1,11 @@
|
||||
# 阶段 Review Prompt
|
||||
|
||||
```text
|
||||
请对 JeecgBoot 工单模块阶段交付物做 Review。
|
||||
请对目标业务模块阶段交付物做 Review。
|
||||
|
||||
输入材料:
|
||||
- 模块名称:<填写>
|
||||
- 业务对象:<填写>
|
||||
- RBAC 权限矩阵
|
||||
- 权限控制方案
|
||||
- 状态流转表
|
||||
@@ -26,5 +28,5 @@
|
||||
约束:
|
||||
- 不要只说整体不错。
|
||||
- 不要直接改代码。
|
||||
- 不要把示例模块、示例角色或示例接口当成目标项目事实。
|
||||
```
|
||||
|
||||
|
||||
+1
-2
@@ -15,7 +15,7 @@
|
||||
|
||||
| 等级 | 模块 | 问题 | 触发规则 | 风险 | 修复建议 | 验收 |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| P1 | 权限 | 删除接口只隐藏按钮,后端缺少权限校验 | 前端按钮不是安全边界 | 可绕过前端删除工单 | 后端补权限校验 | 无权限账号请求返回 403 |
|
||||
| P1 | 权限 | 敏感操作只做前端按钮隐藏,后端缺少权限校验 | 前端按钮不是安全边界 | 可绕过前端直接调用接口完成高风险操作 | 后端补权限校验和数据范围校验 | 无权限账号直接请求返回 403 或业务拒绝 |
|
||||
|
||||
## 不确定点
|
||||
|
||||
@@ -25,4 +25,3 @@
|
||||
## 结论
|
||||
|
||||
通过 / 有条件通过 / 不通过
|
||||
|
||||
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
# 验收清单
|
||||
|
||||
本清单用于判断学员是否真正掌握 JeecgBoot 工单案例,而不是只复制了 TRAE 输出。建议讲师在小组展示时逐项打分。
|
||||
|
||||
## 项目理解
|
||||
|
||||
| 检查项 | 通过标准 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 能说明 JeecgBoot 前后端目录 | 至少指出 `jeecg-boot`、`jeecgboot-vue3`、`docs/project-knowledge` 的用途 | |
|
||||
| 能定位后端入口 | 能指出 `JeecgSystemApplication.java` 和后端启动模块 | |
|
||||
| 能定位前端入口 | 能指出 `src/main.ts`、路由、Pinia 和 API 请求层 | |
|
||||
| 能区分事实和推断 | 对没有源码依据的业务规则标注为推断或待确认 | |
|
||||
| 能记录不确定点 | 不确定内容没有被包装成确定事实 | |
|
||||
|
||||
## 需求与接口
|
||||
|
||||
| 检查项 | 通过标准 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 用户故事完整 | 覆盖管理员、负责人、研发、测试、只读用户 | |
|
||||
| 非目标范围明确 | 明确课堂不做完整编码、生产部署、真实数据迁移 | |
|
||||
| 接口契约完整 | 覆盖列表、详情、新增、编辑、指派、状态、审计、看板 | |
|
||||
| 失败场景明确 | 每个关键接口至少有权限、参数、状态或数据不存在失败场景 | |
|
||||
| 验收方式明确 | 每个关键需求都有可执行检查方法 | |
|
||||
|
||||
## 权限与状态
|
||||
|
||||
| 检查项 | 通过标准 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 权限矩阵完整 | 覆盖页面级、按钮级、接口级和数据范围 | |
|
||||
| 权限字符合理 | 命名统一,并标注为建议而非源码事实 | |
|
||||
| 后端权限未缺失 | 没有用前端按钮隐藏替代后端接口控制 | |
|
||||
| 状态流转表完整 | 覆盖新建、处理中、待验证、已关闭、已驳回 | |
|
||||
| 非法流转明确 | 至少列出 5 条非法流转和拒绝原因 | |
|
||||
|
||||
## 审计、异常态与看板
|
||||
|
||||
| 检查项 | 通过标准 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 审计操作覆盖关键动作 | 创建、编辑、指派、状态流转、关闭、评论至少覆盖 5 类 | |
|
||||
| 审计字段可追溯 | 包含 actor、action、targetId、oldValue、newValue、source | |
|
||||
| 敏感信息处理 | oldValue/newValue 有脱敏说明 | |
|
||||
| 异常态可测试 | 权限不足、重复提交、非法状态、数据不存在、并发修改均覆盖 | |
|
||||
| 看板指标可计算 | 每个指标有口径、维度、过滤条件和数据来源建议 | |
|
||||
|
||||
## Review 与交付
|
||||
|
||||
| 检查项 | 通过标准 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| Review 有证据 | 问题能回到路径、表格或业务规则 | |
|
||||
| 风险按严重程度排序 | 高风险问题优先展示 | |
|
||||
| 建议可行动 | 每条建议有修复方向和验收方式 | |
|
||||
| 交付物齐全 | [worksheets.md](./worksheets.md) 中最终交付记录完整 | |
|
||||
| 能沉淀资产 | 能说明哪些内容进入 [assets-index.md](./assets-index.md) 的资产库 | |
|
||||
|
||||
## 评分建议
|
||||
|
||||
| 等级 | 分数 | 描述 |
|
||||
| --- | ---: | --- |
|
||||
| A | 90-100 | 依据充分,设计完整,风险清楚,验收可执行 |
|
||||
| B | 75-89 | 主链路完整,少量不确定点或验收细节不足 |
|
||||
| C | 60-74 | 有基本产出,但权限、状态、审计或异常态明显薄弱 |
|
||||
| D | 0-59 | 泛泛总结项目,缺少源码依据或无法验收 |
|
||||
|
||||
## 讲师判定原则
|
||||
|
||||
- 优先看证据,不优先看文字是否漂亮。
|
||||
- 优先看权限、状态、审计、异常态,不只看 CRUD。
|
||||
- 优先看不确定点是否被诚实标出。
|
||||
- 优先看能否复用到团队资产库。
|
||||
- 对没有依据的自信结论扣分。
|
||||
|
||||
+2
-3
@@ -2,7 +2,6 @@
|
||||
|
||||
| Review 编号 | 问题 | 是否成立 | 修改文件 | 修改说明 | 验证结果 | 资产沉淀 |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| R01 | 删除接口缺少后端权限校验 | 是 | WorkOrderController | 增加权限校验 | 无权限请求被拒绝 | 权限检查清单 |
|
||||
| R02 | closed 可重新处理 | 是 | WorkOrderService | 补非法流转校验 | closed -> processing 失败 | 状态流转检查清单 |
|
||||
| R01 | 敏感操作接口缺少后端权限校验 | 是 | `<Controller/API handler>` | 增加权限校验和数据范围校验 | 无权限请求被拒绝 | 权限检查清单 |
|
||||
| R02 | 终态记录可被直接改回处理中 | 是 | `<Service/Domain logic>` | 补非法流转校验 | terminal -> processing 失败 | 状态流转检查清单 |
|
||||
| R03 | 看板关闭周期口径不清 | 是 | 指标字典/看板接口 | 明确 create_time 到 close_time | 指标说明已更新 | 看板指标口径清单 |
|
||||
|
||||
|
||||
+10
-11
@@ -2,31 +2,30 @@
|
||||
|
||||
## 场景
|
||||
|
||||
工单指派负责人成功,但没有记录审计日志。
|
||||
业务记录分配处理人成功,但没有记录审计日志。
|
||||
|
||||
## 问题表现
|
||||
|
||||
| 操作 | 结果 |
|
||||
| --- | --- |
|
||||
| 张三将工单指派给李四 | 工单负责人变更成功 |
|
||||
| 查询审计日志 | 没有负责人变更记录 |
|
||||
| 张三将记录分配给李四 | 处理人变更成功 |
|
||||
| 查询审计日志 | 没有处理人变更记录 |
|
||||
|
||||
## 风险
|
||||
|
||||
无法追溯负责人变化,出现延误或争议时无法定位责任。
|
||||
无法追溯处理人变化,出现延误或争议时无法定位责任。
|
||||
|
||||
## 修复要求
|
||||
|
||||
1. 指派成功后写审计日志。
|
||||
2. 记录原负责人、新负责人、操作人、时间、来源。
|
||||
3. 指派失败不写成功审计。
|
||||
1. 分配成功后写审计日志。
|
||||
2. 记录原处理人、新处理人、操作人、时间、来源。
|
||||
3. 分配失败不写成功审计。
|
||||
4. 多步写入需要事务一致性。
|
||||
|
||||
## 验收
|
||||
|
||||
| 操作 | 预期 |
|
||||
| --- | --- |
|
||||
| 指派成功 | 审计列表出现 ASSIGN 记录 |
|
||||
| 指派失败 | 不出现成功审计 |
|
||||
| 查询详情 | 审计记录可在工单详情查看 |
|
||||
|
||||
| 分配成功 | 审计列表出现 ASSIGN 或同等业务动作记录 |
|
||||
| 分配失败 | 不出现成功审计 |
|
||||
| 查询详情 | 审计记录可在详情页查看 |
|
||||
|
||||
+7
-8
@@ -2,19 +2,19 @@
|
||||
|
||||
## 场景
|
||||
|
||||
工单删除按钮在前端按权限隐藏,但后端删除接口没有权限校验。
|
||||
敏感删除或作废按钮在前端按权限隐藏,但后端接口没有权限校验。
|
||||
|
||||
## 问题代码表现
|
||||
|
||||
| 层级 | 表现 |
|
||||
| --- | --- |
|
||||
| 前端 | 普通研发账号看不到删除按钮 |
|
||||
| 后端 | 直接请求 `/workOrder/delete` 仍可删除 |
|
||||
| 前端 | 普通业务账号看不到删除按钮 |
|
||||
| 后端 | 直接请求删除或作废接口仍可成功 |
|
||||
| 审计 | 删除记录可能缺失 |
|
||||
|
||||
## 风险
|
||||
|
||||
攻击者或误操作用户可以绕过前端直接调用接口删除工单。
|
||||
攻击者或误操作用户可以绕过前端直接调用接口删除或作废业务数据。
|
||||
|
||||
## 修复要求
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
|
||||
| 账号 | 操作 | 预期 |
|
||||
| --- | --- | --- |
|
||||
| 管理员 | 删除允许删除的工单 | 成功并写审计 |
|
||||
| 普通研发 | 直接请求删除接口 | 失败 |
|
||||
| 只读用户 | 前端访问删除按钮 | 不可见 |
|
||||
|
||||
| 管理员或授权角色 | 删除允许删除的数据 | 成功并写审计 |
|
||||
| 普通业务角色 | 直接请求删除接口 | 失败 |
|
||||
| 只读角色 | 前端访问删除按钮 | 不可见 |
|
||||
|
||||
+7
-8
@@ -2,22 +2,22 @@
|
||||
|
||||
## 场景
|
||||
|
||||
看板展示“平均关闭周期”,但没有说明从哪个时间到哪个时间。
|
||||
看板展示“平均完成周期”,但没有说明从哪个时间到哪个时间。
|
||||
|
||||
## 问题表现
|
||||
|
||||
| 指标 | 当前说明 |
|
||||
| --- | --- |
|
||||
| 平均关闭周期 | 最近工单平均处理时间 |
|
||||
| 平均完成周期 | 最近记录平均处理时间 |
|
||||
|
||||
## 风险
|
||||
|
||||
不同人理解不同:可能是创建到关闭,也可能是开始处理到关闭,导致管理判断失真。
|
||||
不同人理解不同:可能是创建到完成,也可能是开始处理到完成,导致管理判断失真。
|
||||
|
||||
## 修复要求
|
||||
|
||||
1. 明确定义为 `close_time - create_time` 或其他确定口径。
|
||||
2. 明确是否排除未关闭工单。
|
||||
1. 明确定义为 `completed_at - created_at`、`closed_at - created_at` 或其他确定口径。
|
||||
2. 明确是否排除未完成记录。
|
||||
3. 明确时间范围过滤字段。
|
||||
4. 用样例数据手工校验。
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
| 样例 | 预期 |
|
||||
| --- | --- |
|
||||
| 工单 A 创建 1 日、关闭 3 日 | 周期 2 天 |
|
||||
| 未关闭工单 | 不计入平均关闭周期 |
|
||||
| 记录 A 创建 1 日、完成 3 日 | 周期 2 天 |
|
||||
| 未完成记录 | 不计入平均完成周期 |
|
||||
| 过滤 7 月 | 只统计 7 月范围内符合口径的数据 |
|
||||
|
||||
|
||||
+3
-4
@@ -2,7 +2,7 @@
|
||||
|
||||
## 场景
|
||||
|
||||
已关闭工单可以直接被改回处理中。
|
||||
已完成或已关闭的业务记录可以直接被改回处理中。
|
||||
|
||||
## 问题表现
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
|
||||
## 风险
|
||||
|
||||
已关闭工单被重新打开但没有重开原因、没有审计、没有负责人确认,导致统计和责任链失真。
|
||||
终态记录被重新打开但没有重开原因、没有审计、没有负责人确认,导致统计和责任链失真。
|
||||
|
||||
## 修复要求
|
||||
|
||||
1. Service 层集中校验状态流转。
|
||||
2. 已关闭工单只能通过“重新打开”动作变为新建。
|
||||
2. 已完成或已关闭记录只能通过“重新打开”动作回到指定状态。
|
||||
3. 重新打开必须填写原因。
|
||||
4. 所有成功流转写审计日志。
|
||||
|
||||
@@ -28,4 +28,3 @@
|
||||
| closed -> processing | 失败,状态不变 |
|
||||
| closed -> reopen -> new | 成功,必须有原因 |
|
||||
| 重开成功 | 审计记录 oldValue=closed, newValue=new |
|
||||
|
||||
|
||||
@@ -21,16 +21,16 @@
|
||||
|
||||
## Skill 列表
|
||||
|
||||
| Skill | 用途 | 典型产物 |
|
||||
| --- | --- | --- |
|
||||
| `generate-project-constraints` | 从项目源码、配置、CI、文档中提取项目约束 | rules、约束提取表、验收清单 |
|
||||
| Skill | 用途 | 典型产物 |
|
||||
| -------------------------------- | ------------------------------------------------ | --------------------------------------------- |
|
||||
| `generate-project-constraints` | 从项目源码、配置、CI、文档中提取项目约束 | rules、约束提取表、验收清单 |
|
||||
| `design-complex-business-module` | 设计复杂业务模块的权限、状态、审计、异常态和看板 | RBAC 矩阵、状态流转表、审计 SOP、看板指标字典 |
|
||||
| `review-business-delivery` | 审查复杂业务交付物或 PR 的业务风险 | 阶段 Review 报告、风险清单、验收建议 |
|
||||
| `track-review-fix-loop` | 跟踪 Review 问题修复、验证和资产沉淀 | 修复记录、未闭环清单、资产更新建议 |
|
||||
| `review-business-delivery` | 审查复杂业务交付物或 PR 的业务风险 | 阶段 Review 报告、风险清单、验收建议 |
|
||||
| `track-review-fix-loop` | 跟踪 Review 问题修复、验证和资产沉淀 | 修复记录、未闭环清单、资产更新建议 |
|
||||
|
||||
## 推荐使用顺序
|
||||
|
||||
1. 使用 `generate-project-constraints` 为客户项目生成项目规则。
|
||||
1. 使用 `generate-project-constraints` 为项目生成项目规则。
|
||||
2. 使用 `design-complex-business-module` 生成复杂业务设计资产。
|
||||
3. 使用 `review-business-delivery` 审查设计、代码或阶段交付物。
|
||||
4. 使用 `track-review-fix-loop` 跟踪修复、验证结果和资产沉淀。
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
# 安装说明
|
||||
|
||||
## 方式一:安装到 Codex Skills 目录
|
||||
## 方式一:安装到 TRAE Skills 目录
|
||||
|
||||
把 `skills/` 下的 4 个 Skill 文件夹复制到本机 Skills 目录:
|
||||
|
||||
```text
|
||||
~/.codex/skills/
|
||||
~/.trae/skills/
|
||||
```
|
||||
|
||||
安装后目录应类似:
|
||||
|
||||
```text
|
||||
~/.codex/skills/
|
||||
~/.trae/skills/
|
||||
├── generate-project-constraints/
|
||||
├── design-complex-business-module/
|
||||
├── review-business-delivery/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<div class="mt-6 text-sm">
|
||||
|
||||
Commands 把常用话术封装成快捷入口,Skills 把完整能力封装成可复用资产。
|
||||
Commands 解决高频输入,Skills 解决可复用交付。两者都不是“把 Prompt 存起来”这么简单,而是把团队经验变成可触发、可验收、可维护的资产。
|
||||
|
||||
</div>
|
||||
|
||||
@@ -10,25 +10,26 @@ Commands 把常用话术封装成快捷入口,Skills 把完整能力封装成
|
||||
<div class="p-4 rounded-xl bg-blue-500/10 border border-blue-500/30">
|
||||
<div class="font-bold mb-2">Commands</div>
|
||||
|
||||
- `.trae/commands/`
|
||||
- Markdown 定义
|
||||
- 斜杠触发
|
||||
- 适合固定提示词
|
||||
- 固定入口
|
||||
- 固定输入
|
||||
- 固定输出
|
||||
- 低风险、短流程
|
||||
</div>
|
||||
<div class="p-4 rounded-xl bg-emerald-500/10 border border-emerald-500/30">
|
||||
<div class="font-bold mb-2">Skills</div>
|
||||
|
||||
- `.trae/skills/`
|
||||
- 描述按需加载
|
||||
- 可带脚本、模板、示例
|
||||
- 适合完整工作流
|
||||
- 多步流程
|
||||
- 可带模板和检查清单
|
||||
- 可沉淀项目经验
|
||||
- 适合交付给团队或客户
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
Commands 是第一代封装,核心是把常说的话存起来。
|
||||
Skills 是第二代封装,核心是把完成任务所需的说明、脚本、模板和示例放在一起。
|
||||
这页让学员建立两个概念的关系。
|
||||
这一页要先帮学员纠偏:Command 和 Skill 都不是“更长的 Prompt”。
|
||||
Command 的核心是减少重复输入,让同一类轻量任务有统一入口。
|
||||
Skill 的核心是把完成任务所需的判断流程、输入要求、输出标准、模板和检查清单放在一起。
|
||||
所以今天讲能力封装,不是为了多造几个文件,而是让团队经验以后可以被重复触发、重复验收、重复维护。
|
||||
-->
|
||||
|
||||
---
|
||||
@@ -37,23 +38,47 @@ Skills 是第二代封装,核心是把完成任务所需的说明、脚本、
|
||||
|
||||
<div class="mt-6 text-sm">
|
||||
|
||||
| 场景 | 示例 |
|
||||
|---|---|
|
||||
| 固定问法 | 总结当前 PR |
|
||||
| 固定格式 | 生成 commit message |
|
||||
| 固定检查 | 跑一次代码审查 |
|
||||
| 固定输出 | 生成日报、周报、变更说明 |
|
||||
| 判断标准 | 适合 Command 的特征 | 示例 |
|
||||
|---|---|---|
|
||||
| 问法固定 | 每次提问差异很小 | 生成 PR 说明 |
|
||||
| 输入固定 | 只需要 diff、日志或单个文件 | 总结当前变更 |
|
||||
| 输出固定 | 表格或固定段落即可 | commit message |
|
||||
| 风险较低 | 不直接改核心逻辑 | 生成日报 |
|
||||
| 不需要多步判断 | 不需要跨多个规则来决策 | 格式化说明 |
|
||||
|
||||
</div>
|
||||
|
||||
<div class="mt-4 p-3 rounded-xl bg-blue-500/10 border border-blue-500/30 text-sm">
|
||||
Command 的关键价值是降低重复输入成本。
|
||||
Command 的关键价值是降低重复输入成本,并让轻量任务输出稳定。
|
||||
</div>
|
||||
|
||||
<!--
|
||||
Commands 很适合固定流程。
|
||||
比如每次都要总结 PR、写 commit message、生成日报,就可以做成命令。
|
||||
它的边界也清楚:主要封装 prompt,适合轻量场景。
|
||||
这里要把 Command 的边界讲清楚。
|
||||
它适合“同一句话每天都要说”的场景,比如总结 PR、生成 commit message、提取 CI 日志摘要。
|
||||
但是如果一个任务需要先读项目规则、再判断风险、再套模板、最后给验收标准,Command 就不够了。
|
||||
不要把所有事情都做成斜杠命令,否则命令库会变成另一种噪声。
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Command 的坏味道
|
||||
|
||||
<div class="mt-6 text-sm">
|
||||
|
||||
| 坏 Command | 问题 | 更好的方向 |
|
||||
|---|---|---|
|
||||
| `/检查代码` | 范围太大,输出不可控 | `/代码生成Review` |
|
||||
| `/优化一下` | 没有目标和验收标准 | `/按性能规则检查列表页` |
|
||||
| `/生成文档` | 不知道文档对象和读者 | `/生成PR说明` |
|
||||
| `/帮我看看` | 没有输入边界 | 改成带输入材料的 Skill |
|
||||
|
||||
</div>
|
||||
|
||||
<!--
|
||||
这一页可以直接拿来点评学员写的命令。
|
||||
坏 Command 的共同特点是“看起来方便,实际上不可控”。
|
||||
AI 收到 `/检查代码` 以后,可能检查格式、可能检查 bug、可能检查权限,也可能给一段空泛评价。
|
||||
进入团队资产库的 Command 必须收敛:什么时候用、需要什么输入、输出什么格式、怎么验收。
|
||||
-->
|
||||
|
||||
---
|
||||
@@ -64,71 +89,115 @@ Commands 很适合固定流程。
|
||||
<div class="p-4 rounded-xl bg-emerald-500/10 border border-emerald-500/30">
|
||||
<div class="font-bold mb-2">按需加载</div>
|
||||
|
||||
Agent 先扫描 skill 描述,任务相关时再读取完整说明。
|
||||
Agent 先看 Skill 描述,任务相关时再读取完整说明。
|
||||
</div>
|
||||
<div class="p-4 rounded-xl bg-amber-500/10 border border-amber-500/30">
|
||||
<div class="font-bold mb-2">可携带资源</div>
|
||||
<div class="font-bold mb-2">携带资源</div>
|
||||
|
||||
Skill 可以包含脚本、模板、示例、参考文件和检查清单。
|
||||
Skill 可以带模板、Prompt、检查清单、反例和脚本。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 p-3 rounded-xl bg-gray-500/10 border border-gray-500/30 text-sm">
|
||||
Skill 不是单个 Markdown,而是一组能被复制、安装和维护的工作流资产。
|
||||
</div>
|
||||
|
||||
<!--
|
||||
Skills 的两个升级非常关键。
|
||||
按需加载能减少上下文干扰,可携带资源能把经验固化成工具包。
|
||||
所以 Skill 更适合企业培训后的标准化落地。
|
||||
Skills 的关键升级有两个。
|
||||
第一是按需加载,避免把所有团队知识一次性塞进上下文。
|
||||
第二是携带资源,避免每次都重新发模板、检查清单和示例。
|
||||
所以 Skill 更适合企业培训后的标准化落地:它把老师讲过的流程变成团队以后可以继续使用的能力包。
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Skill 的两种气质
|
||||
# 什么值得做成 Skill?
|
||||
|
||||
<div class="grid grid-cols-2 gap-6 mt-6 text-sm">
|
||||
<div class="p-4 rounded-xl bg-purple-500/10 border border-purple-500/30">
|
||||
<div class="font-bold mb-2">文科型 Skill</div>
|
||||
<div class="mt-5 text-sm">
|
||||
|
||||
- 品牌风格
|
||||
- 文档结构
|
||||
- 设计规范
|
||||
- 沟通口径
|
||||
</div>
|
||||
<div class="p-4 rounded-xl bg-cyan-500/10 border border-cyan-500/30">
|
||||
<div class="font-bold mb-2">理科型 Skill</div>
|
||||
| 判断问题 | 是,就更适合 Skill |
|
||||
|---|---|
|
||||
| 是否需要多步判断? | 权限、状态、审计、异常态、看板需要串起来 |
|
||||
| 是否需要项目证据? | 需要读源码、配置、规则和验收记录 |
|
||||
| 是否需要多个输出? | 矩阵、清单、Review 报告、修复记录 |
|
||||
| 是否需要资产复用? | 客户或团队下次还会做类似任务 |
|
||||
| 是否有质量门槛? | 必须能验收,不只是生成文字 |
|
||||
|
||||
- 自动化脚本
|
||||
- 构建命令
|
||||
- 测试流程
|
||||
- 数据处理工具链
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
这个分类方便学员理解。
|
||||
文科型 Skill 主要封装风格、结构和判断标准。
|
||||
理科型 Skill 主要封装工具、脚本和执行流程。
|
||||
企业团队通常两类都需要。
|
||||
这一页是判断标准。
|
||||
表格、清单、Prompt 本身不一定要做成 Skill。
|
||||
真正适合 Skill 的,是“怎么判断、怎么生成、怎么验收、怎么闭环”。
|
||||
例如 RBAC 权限矩阵只是一个模板;但“复杂业务模块设计”需要先定角色、再定权限、再定状态、再补审计和看板,这就是 Skill。
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# MCP 的价值
|
||||
# Skill 交付结构
|
||||
|
||||
<div class="mt-6 text-sm">
|
||||
<div class="mt-5 text-sm">
|
||||
|
||||
MCP 的历史价值是推动工具面向 AI 开放接口,让 Agent 能连接浏览器、数据库、文件系统、设计工具和内部平台。
|
||||
```text
|
||||
skill-name/
|
||||
├── SKILL.md
|
||||
├── agents/
|
||||
│ └── openai.yaml
|
||||
└── assets/
|
||||
├── templates/
|
||||
├── checklists/
|
||||
├── prompts/
|
||||
└── examples/
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-3 gap-4 mt-8 text-sm">
|
||||
<div class="p-3 rounded-xl bg-blue-500/10 border border-blue-500/30 text-center">打开连接可能性</div>
|
||||
<div class="p-3 rounded-xl bg-emerald-500/10 border border-emerald-500/30 text-center">统一工具描述方式</div>
|
||||
<div class="p-3 rounded-xl bg-amber-500/10 border border-amber-500/30 text-center">推动工具生态改造</div>
|
||||
<div class="mt-5 p-3 rounded-xl bg-emerald-500/10 border border-emerald-500/30 text-sm">
|
||||
给客户交付 Skill 时,交付的是完整文件夹,不是单个 `.md`。
|
||||
</div>
|
||||
|
||||
<!--
|
||||
MCP 要讲它的历史功绩。
|
||||
它让很多原本封闭的工具开始考虑给 AI 使用的接口。
|
||||
对企业来说,MCP 的意义是把内部工具、流程系统和 Agent 连接起来。
|
||||
这一页补一个非常落地的知识点。
|
||||
客户拿到 Skill 后,不应该只拿到一段 Prompt,而应该拿到完整目录。
|
||||
SKILL.md 说明什么时候触发、怎么执行、输出什么。
|
||||
agents/openai.yaml 是工具识别和展示用的元数据。
|
||||
assets 里放模板、检查清单、Prompt、反例和案例。
|
||||
这也是为什么培训产物最后可以打包给客户,而不是只发聊天记录。
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# Skill 的三种交付形态
|
||||
|
||||
<div class="grid grid-cols-3 gap-4 mt-6 text-sm">
|
||||
<div class="p-4 rounded-xl bg-blue-500/10 border border-blue-500/30">
|
||||
<div class="font-bold mb-2">知识型</div>
|
||||
|
||||
- 项目约束
|
||||
- 编码规范
|
||||
- 业务口径
|
||||
</div>
|
||||
<div class="p-4 rounded-xl bg-emerald-500/10 border border-emerald-500/30">
|
||||
<div class="font-bold mb-2">流程型</div>
|
||||
|
||||
- 复杂业务设计
|
||||
- 阶段 Review
|
||||
- 修复闭环
|
||||
</div>
|
||||
<div class="p-4 rounded-xl bg-amber-500/10 border border-amber-500/30">
|
||||
<div class="font-bold mb-2">工具型</div>
|
||||
|
||||
- 脚本
|
||||
- CLI
|
||||
- 测试和报告
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
原来的二分法课堂里容易理解,但交付给客户时不够工程化。
|
||||
这里改成三种交付形态:知识型、流程型、工具型。
|
||||
项目约束生成属于知识型,复杂业务模块设计和 Review 属于流程型,自动跑测试或生成报告属于工具型。
|
||||
企业团队通常三类都会有,但不要混在一个 Skill 里。
|
||||
-->
|
||||
|
||||
---
|
||||
@@ -139,16 +208,17 @@ MCP 要讲它的历史功绩。
|
||||
|
||||
| 接入方式 | 适合场景 | 课堂判断 |
|
||||
|---|---|---|
|
||||
| CLI | 命令稳定、脚本成熟、团队已有运维习惯 | 优先做轻量封装 |
|
||||
| MCP | 需要交互式工具、长连接、结构化能力描述 | 适合平台化接入 |
|
||||
| Skill | 需要把使用方法、模板、脚本一起交付 | 适合团队复用 |
|
||||
| Command | 固定话术、固定格式 | 降低重复输入 |
|
||||
| CLI | 命令稳定、脚本成熟 | 优先轻量封装 |
|
||||
| MCP | 交互式工具、结构化能力描述 | 适合平台化接入 |
|
||||
| Skill | 需要流程、模板、检查清单和示例 | 适合团队复用 |
|
||||
|
||||
</div>
|
||||
|
||||
<!--
|
||||
底层理念是:只要工具能被命令行或接口驱动,Agent 就能接入。
|
||||
MCP 是一种协议形态,CLI 是一种通用执行方式,Skill 是一种知识和流程封装方式。
|
||||
课堂里要帮助学员选接入方式。
|
||||
MCP 是一种协议形态,CLI 是一种执行方式,Command 是轻量入口,Skill 是知识和流程封装。
|
||||
课堂里要帮助学员判断,不是所有能力都上 MCP,也不是所有能力都做 Skill。
|
||||
-->
|
||||
|
||||
---
|
||||
@@ -160,13 +230,15 @@ MCP 是一种协议形态,CLI 是一种通用执行方式,Skill 是一种知
|
||||
| 需求 | 推荐封装 | 理由 |
|
||||
|---|---|---|
|
||||
| 每天生成日报 | Command | 固定话术、固定格式 |
|
||||
| 代码审查流程 | Skill | 需要规则、模板、示例 |
|
||||
| 项目约束生成 | Skill | 需要扫描源码、配置、规则并输出验收清单 |
|
||||
| 复杂业务模块设计 | Skill | 权限、状态、审计、看板需要串联判断 |
|
||||
| 内部平台查询 | CLI 或 MCP | 取决于现有接口形态 |
|
||||
| 设计规范落地 | Skill | 需要风格、样例、检查清单 |
|
||||
| 代码审查报告 | Skill | 需要规则、模板、反例和风险分级 |
|
||||
|
||||
</div>
|
||||
|
||||
<!--
|
||||
这个练习让学员判断同一个需求适合 command、skill、CLI 还是 MCP。
|
||||
判断标准是任务复杂度、资源依赖、团队复用和工具接入方式。
|
||||
这个练习让学员把封装方式和交付物对应起来。
|
||||
可以提醒大家:最后客户能复用的不是“今天课堂上写过的某一句 Prompt”,而是一组可安装、可复制、可维护的 Skill 包。
|
||||
判断标准是任务复杂度、资源依赖、团队复用、工具接入方式和验收成本。
|
||||
-->
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<div class="mt-6 text-sm">
|
||||
|
||||
工单模块不是普通 CRUD。不同角色看到的数据不同、能做的动作不同、承担的责任也不同。
|
||||
工单模块不是普通 CRUD。复杂度不在字段多少,而在谁能看、谁能改、什么条件下能改,以及出问题后能否追溯。
|
||||
|
||||
</div>
|
||||
|
||||
@@ -15,9 +15,42 @@
|
||||
</div>
|
||||
|
||||
<!--
|
||||
第四天从权限矩阵开始。
|
||||
工单模块看起来像 CRUD,但真实业务里管理员、负责人、研发、测试、只读用户的权限边界完全不同。
|
||||
如果不先设计矩阵,AI 很容易按默认 CRUD 生成所有按钮。
|
||||
第四天从权限矩阵开始,不是因为权限最容易写,而是因为权限最容易被 AI 简化成 CRUD 默认逻辑。
|
||||
工单模块看起来只是增删改查,但真实企业系统里,不同角色看到的数据、能执行的动作、承担的责任完全不同。
|
||||
如果不先设计矩阵,AI 很容易把新增、编辑、删除、指派、关闭这些按钮都生成出来,后面再补权限就会很被动。
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# 先矩阵,后代码
|
||||
|
||||
<div class="grid grid-cols-2 gap-6 mt-7 text-sm">
|
||||
<div class="p-4 rounded-xl bg-red-500/10 border border-red-500/30">
|
||||
<div class="font-bold mb-2">错误顺序</div>
|
||||
|
||||
1. 先生成页面和接口
|
||||
2. 再临时隐藏按钮
|
||||
3. 最后补权限说明
|
||||
</div>
|
||||
<div class="p-4 rounded-xl bg-emerald-500/10 border border-emerald-500/30">
|
||||
<div class="font-bold mb-2">推荐顺序</div>
|
||||
|
||||
1. 先定义角色和动作
|
||||
2. 再生成权限矩阵
|
||||
3. 最后落到菜单、按钮、接口、数据范围
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 p-3 rounded-xl bg-amber-500/10 border border-amber-500/30 text-sm">
|
||||
权限矩阵是后续代码生成、Review 和验收的依据,不是交付后的补充说明。
|
||||
</div>
|
||||
|
||||
<!--
|
||||
这里要强调开发顺序。
|
||||
AI 辅助开发最常见的问题,是先让它把 CRUD 做出来,再问“怎么加权限”。
|
||||
这样会导致权限变成页面装饰,而不是业务规则。
|
||||
正确做法是先用矩阵约束代码生成:哪些角色能看、能改、能流转、能删除、能看审计。
|
||||
后面所有页面按钮、后端接口、数据范围和测试账号,都要回到这张矩阵。
|
||||
-->
|
||||
|
||||
---
|
||||
@@ -28,23 +61,47 @@
|
||||
|
||||
| 功能 | 管理员 | 负责人 | 研发 | 测试 | 只读 |
|
||||
|---|---|---|---|---|---|
|
||||
| 查看列表 | Y | Y | Y | Y | Y |
|
||||
| 新增工单 | Y | Y | N | Y | N |
|
||||
| 编辑工单 | Y | Y | 条件允许 | 条件允许 | N |
|
||||
| 查看列表 | Y | 条件允许 | 条件允许 | 条件允许 | 条件允许 |
|
||||
| 查看详情 | Y | 条件允许 | 条件允许 | 条件允许 | 条件允许 |
|
||||
| 新增工单 | Y | Y | Y | Y | N |
|
||||
| 编辑工单 | Y | 条件允许 | 条件允许 | 条件允许 | N |
|
||||
| 删除工单 | Y | N | N | N | N |
|
||||
| 指派工单 | Y | Y | N | N | N |
|
||||
| 提交验证 | Y | Y | Y | N | N |
|
||||
| 关闭工单 | Y | Y | N | Y | N |
|
||||
| 驳回工单 | Y | Y | N | Y | N |
|
||||
| 查看审计 | Y | Y | 条件允许 | 条件允许 | N |
|
||||
| 查看看板 | Y | Y | N | N | N |
|
||||
| 指派工单 | Y | 条件允许 | N | N | N |
|
||||
| 提交验证 | Y | 条件允许 | Y | N | N |
|
||||
| 关闭工单 | Y | 条件允许 | N | Y | N |
|
||||
| 查看审计 | Y | 条件允许 | 条件允许 | 条件允许 | N |
|
||||
| 查看看板 | Y | Y | 条件允许 | 条件允许 | 条件允许 |
|
||||
|
||||
</div>
|
||||
|
||||
<!--
|
||||
这张矩阵是课堂产出,不是讲师单方面给答案。
|
||||
AI 可以生成初稿,但最终必须由业务和团队确认。
|
||||
条件允许要写清条件,比如只能编辑自己负责的工单。
|
||||
“条件允许”不能只写四个字,必须落到条件:只能看自己创建的工单、只能处理指派给自己的工单、只能关闭待验证状态的工单,还是只能查看所在团队的数据。
|
||||
如果条件写不清,后端数据权限和测试用例就没法落地。
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# 条件允许要展开
|
||||
|
||||
<div class="mt-5 text-sm">
|
||||
|
||||
| 条件类型 | 示例 | 验收方式 |
|
||||
|---|---|---|
|
||||
| 数据范围 | 只能看本人、本人团队、本人负责的工单 | 不同账号列表数量不同 |
|
||||
| 状态限制 | 只有待验证才能关闭 | 非目标状态接口返回拒绝 |
|
||||
| 角色叠加 | 负责人兼管理员时按更高权限 | 用双角色账号验证 |
|
||||
| 字段限制 | 研发只能改处理说明,不能改优先级 | 提交非法字段被拒绝 |
|
||||
| 时间限制 | 已关闭工单超过窗口不能重开 | 超时重开失败 |
|
||||
|
||||
</div>
|
||||
|
||||
<!--
|
||||
这是原来矩阵里容易被忽略的知识点。
|
||||
RBAC 不是只有允许和拒绝,真实业务里大量规则都是条件允许。
|
||||
条件允许一旦不展开,AI 生成代码时就会把它理解成允许,测试时也不知道怎么验证。
|
||||
所以矩阵之后必须补条件表,让权限从“角色判断”扩展到“角色 + 数据 + 状态 + 字段 + 时间”的组合判断。
|
||||
-->
|
||||
|
||||
---
|
||||
@@ -60,13 +117,15 @@ AI 可以生成初稿,但最终必须由业务和团队确认。
|
||||
管理员、负责人、研发、测试、只读用户。
|
||||
|
||||
功能点:
|
||||
查看列表、查看详情、新增、编辑、删除、指派、提交验证、关闭、驳回、查看审计记录、查看看板。
|
||||
查看列表、查看详情、新增、编辑、删除、指派、
|
||||
提交验证、关闭、驳回、查看审计记录、查看看板。
|
||||
|
||||
要求:
|
||||
1. 区分允许、禁止、条件允许。
|
||||
2. 条件允许必须说明条件。
|
||||
3. 每个敏感操作给出验收方式。
|
||||
4. 不要直接生成代码。
|
||||
1. 区分允许、拒绝、条件允许。
|
||||
2. 条件允许必须展开为数据、状态、字段或时间条件。
|
||||
3. 每个敏感操作给出后端接口验收方式。
|
||||
4. 标注哪些权限属于业务待确认。
|
||||
5. 不要直接生成代码。
|
||||
```
|
||||
|
||||
</div>
|
||||
@@ -74,4 +133,29 @@ AI 可以生成初稿,但最终必须由业务和团队确认。
|
||||
<!--
|
||||
这里训练学员不要直接让 AI 改代码。
|
||||
先生成矩阵,再确认业务边界,最后才进入权限控制方案。
|
||||
Prompt 里一定要写“不要直接生成代码”,因为这一页的目标是规则设计,不是实现。
|
||||
另外要让 AI 标注待确认项:谁能删除、谁能导出、谁能查看审计日志,这些不能让 AI 自己拍板。
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
# AI 容易漏掉的权限风险
|
||||
|
||||
<div class="mt-5 text-sm">
|
||||
|
||||
| 风险 | 表现 | Review 问法 |
|
||||
|---|---|---|
|
||||
| 前端按钮替代权限 | 按钮隐藏,但接口可直接调 | 无权限账号直接请求会怎样 |
|
||||
| 数据范围缺失 | 所有人看到同一批工单 | 普通用户能否看到他人数据 |
|
||||
| 条件允许泛化 | “条件允许”被实现成允许 | 条件在哪里校验 |
|
||||
| 审计权限遗漏 | 审计日志对不该看的人开放 | 谁能看 old/new value |
|
||||
| 删除权限过宽 | 负责人或研发能删除工单 | 删除是否只限管理员 |
|
||||
|
||||
</div>
|
||||
|
||||
<!--
|
||||
这一页是给后续 Review 铺垫。
|
||||
AI 很容易把权限理解成“有没有按钮”,但企业系统真正的风险在接口和数据范围。
|
||||
课堂里可以让学员拿这张表去追问 TRAE:这个权限风险在哪个文件、哪个接口、哪个测试账号可以验证。
|
||||
这样权限矩阵就不是一张漂亮表,而是 Review 和验收的入口。
|
||||
-->
|
||||
|
||||
Reference in New Issue
Block a user