refactor: 一次性佣金配置从套餐级别提升到系列级别
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m29s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m29s
主要变更: - 新增 tb_shop_series_allocation 表,存储系列级别的一次性佣金配置 - ShopPackageAllocation 移除 one_time_commission_amount 字段 - PackageSeries 新增 enable_one_time_commission 字段控制是否启用一次性佣金 - 新增 /api/admin/shop-series-allocations CRUD 接口 - 佣金计算逻辑改为从 ShopSeriesAllocation 获取一次性佣金金额 - 删除废弃的 ShopSeriesOneTimeCommissionTier 模型 - OpenAPI Tag '系列分配' 和 '单套餐分配' 合并为 '套餐分配' 迁移脚本: - 000042: 重构佣金套餐模型 - 000043: 简化佣金分配 - 000044: 一次性佣金分配重构 - 000045: PackageSeries 添加 enable_one_time_commission 字段 测试: - 新增验收测试 (shop_series_allocation, commission_calculation) - 新增流程测试 (one_time_commission_chain) - 删除过时的单元测试(已被验收测试覆盖)
This commit is contained in:
281
.opencode/skills/openspec-lock-consensus/SKILL.md
Normal file
281
.opencode/skills/openspec-lock-consensus/SKILL.md
Normal file
@@ -0,0 +1,281 @@
|
||||
---
|
||||
name: openspec-lock-consensus
|
||||
description: 锁定共识 - 在探索讨论后,将讨论结果锁定为正式共识文档。防止后续提案偏离讨论内容。
|
||||
license: MIT
|
||||
compatibility: Requires openspec CLI.
|
||||
metadata:
|
||||
author: junhong
|
||||
version: "1.1"
|
||||
---
|
||||
|
||||
# 共识锁定 Skill
|
||||
|
||||
在 `/opsx:explore` 讨论后,使用此 skill 将讨论结果锁定为正式共识。共识文档是后续所有 artifact 的基础约束。
|
||||
|
||||
## 触发方式
|
||||
|
||||
```
|
||||
/opsx:lock <change-name>
|
||||
```
|
||||
|
||||
或在探索结束后,AI 主动提议:
|
||||
> "讨论已经比较清晰了,要锁定共识吗?"
|
||||
|
||||
---
|
||||
|
||||
## 工作流程
|
||||
|
||||
### Step 1: 整理讨论要点
|
||||
|
||||
从对话中提取以下四个维度的共识:
|
||||
|
||||
| 维度 | 说明 | 示例 |
|
||||
|------|------|------|
|
||||
| **要做什么** | 明确的功能范围 | "支持批量导入 IoT 卡" |
|
||||
| **不做什么** | 明确排除的内容 | "不支持实时同步,仅定时批量" |
|
||||
| **关键约束** | 技术/业务限制 | "必须使用 Asynq 异步任务" |
|
||||
| **验收标准** | 如何判断完成 | "导入 1000 张卡 < 30s" |
|
||||
|
||||
### Step 2: 使用 Question_tool 逐维度确认
|
||||
|
||||
**必须使用 Question_tool 进行结构化确认**,每个维度一个问题:
|
||||
|
||||
```typescript
|
||||
// 示例:确认"要做什么"
|
||||
Question_tool({
|
||||
questions: [{
|
||||
header: "确认:要做什么",
|
||||
question: "以下是整理的功能范围,请确认:\n\n" +
|
||||
"1. 功能点 A\n" +
|
||||
"2. 功能点 B\n" +
|
||||
"3. 功能点 C\n\n" +
|
||||
"是否准确完整?",
|
||||
options: [
|
||||
{ label: "确认无误", description: "以上内容准确完整" },
|
||||
{ label: "需要补充", description: "有遗漏的功能点" },
|
||||
{ label: "需要删减", description: "有不应该包含的内容" }
|
||||
],
|
||||
multiple: false
|
||||
}]
|
||||
})
|
||||
```
|
||||
|
||||
**如果用户选择"需要补充"或"需要删减"**:
|
||||
- 用户会通过自定义输入提供修改意见
|
||||
- 根据反馈更新列表,再次使用 Question_tool 确认
|
||||
|
||||
**确认流程**:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ Question_tool: 确认"要做什么" │
|
||||
│ ├── 用户选择"确认无误" → 进入下一维度 │
|
||||
│ └── 用户选择其他/自定义 → 修改后重新确认 │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ Question_tool: 确认"不做什么" │
|
||||
│ ├── 用户选择"确认无误" → 进入下一维度 │
|
||||
│ └── 用户选择其他/自定义 → 修改后重新确认 │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ Question_tool: 确认"关键约束" │
|
||||
│ ├── 用户选择"确认无误" → 进入下一维度 │
|
||||
│ └── 用户选择其他/自定义 → 修改后重新确认 │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ Question_tool: 确认"验收标准" │
|
||||
│ ├── 用户选择"确认无误" → 生成 consensus.md │
|
||||
│ └── 用户选择其他/自定义 → 修改后重新确认 │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Step 3: 生成 consensus.md
|
||||
|
||||
所有维度确认后,创建文件:
|
||||
|
||||
```bash
|
||||
# 检查 change 是否存在
|
||||
openspec list --json
|
||||
|
||||
# 如果 change 不存在,先创建
|
||||
# openspec new <change-name>
|
||||
|
||||
# 写入 consensus.md
|
||||
```
|
||||
|
||||
**文件路径**: `openspec/changes/<change-name>/consensus.md`
|
||||
|
||||
---
|
||||
|
||||
## Question_tool 使用规范
|
||||
|
||||
### 每个维度的问题模板
|
||||
|
||||
**1. 要做什么**
|
||||
```typescript
|
||||
{
|
||||
header: "确认:要做什么",
|
||||
question: "以下是整理的【功能范围】:\n\n" +
|
||||
items.map((item, i) => `${i+1}. ${item}`).join('\n') +
|
||||
"\n\n请确认是否准确完整?",
|
||||
options: [
|
||||
{ label: "确认无误", description: "功能范围准确完整" },
|
||||
{ label: "需要补充", description: "有遗漏的功能点" },
|
||||
{ label: "需要删减", description: "有不应该包含的内容" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**2. 不做什么**
|
||||
```typescript
|
||||
{
|
||||
header: "确认:不做什么",
|
||||
question: "以下是明确【排除的内容】:\n\n" +
|
||||
items.map((item, i) => `${i+1}. ${item}`).join('\n') +
|
||||
"\n\n请确认是否正确?",
|
||||
options: [
|
||||
{ label: "确认无误", description: "排除范围正确" },
|
||||
{ label: "需要补充", description: "还有其他需要排除的" },
|
||||
{ label: "需要删减", description: "有些不应该排除" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**3. 关键约束**
|
||||
```typescript
|
||||
{
|
||||
header: "确认:关键约束",
|
||||
question: "以下是【关键约束】:\n\n" +
|
||||
items.map((item, i) => `${i+1}. ${item}`).join('\n') +
|
||||
"\n\n请确认是否正确?",
|
||||
options: [
|
||||
{ label: "确认无误", description: "约束条件正确" },
|
||||
{ label: "需要补充", description: "还有其他约束" },
|
||||
{ label: "需要修改", description: "约束描述不准确" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**4. 验收标准**
|
||||
```typescript
|
||||
{
|
||||
header: "确认:验收标准",
|
||||
question: "以下是【验收标准】(必须可测量):\n\n" +
|
||||
items.map((item, i) => `${i+1}. ${item}`).join('\n') +
|
||||
"\n\n请确认是否正确?",
|
||||
options: [
|
||||
{ label: "确认无误", description: "验收标准清晰可测量" },
|
||||
{ label: "需要补充", description: "还有其他验收标准" },
|
||||
{ label: "需要修改", description: "标准不够清晰或无法测量" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 处理用户反馈
|
||||
|
||||
当用户选择非"确认无误"选项或提供自定义输入时:
|
||||
|
||||
1. 解析用户的修改意见
|
||||
2. 更新对应维度的内容
|
||||
3. 再次使用 Question_tool 确认更新后的内容
|
||||
4. 重复直到用户选择"确认无误"
|
||||
|
||||
---
|
||||
|
||||
## consensus.md 模板
|
||||
|
||||
```markdown
|
||||
# 共识文档
|
||||
|
||||
**Change**: <change-name>
|
||||
**确认时间**: <timestamp>
|
||||
**确认人**: 用户
|
||||
|
||||
---
|
||||
|
||||
## 1. 要做什么
|
||||
|
||||
- [x] 功能点 A(已确认)
|
||||
- [x] 功能点 B(已确认)
|
||||
- [x] 功能点 C(已确认)
|
||||
|
||||
## 2. 不做什么
|
||||
|
||||
- [x] 排除项 A(已确认)
|
||||
- [x] 排除项 B(已确认)
|
||||
|
||||
## 3. 关键约束
|
||||
|
||||
- [x] 技术约束 A(已确认)
|
||||
- [x] 业务约束 B(已确认)
|
||||
|
||||
## 4. 验收标准
|
||||
|
||||
- [x] 验收标准 A(已确认)
|
||||
- [x] 验收标准 B(已确认)
|
||||
|
||||
---
|
||||
|
||||
## 讨论背景
|
||||
|
||||
<简要总结讨论的核心问题和解决方向>
|
||||
|
||||
## 关键决策记录
|
||||
|
||||
| 决策点 | 选择 | 原因 |
|
||||
|--------|------|------|
|
||||
| 决策 1 | 选项 A | 理由... |
|
||||
| 决策 2 | 选项 B | 理由... |
|
||||
|
||||
---
|
||||
|
||||
**签字确认**: 用户已通过 Question_tool 逐条确认以上内容
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 后续流程绑定
|
||||
|
||||
### Proposal 生成时
|
||||
|
||||
`/opsx:continue` 生成 proposal 时,**必须**:
|
||||
|
||||
1. 读取 `consensus.md`
|
||||
2. 确保 proposal 的 Capabilities 覆盖"要做什么"中的每一项
|
||||
3. 确保 proposal 不包含"不做什么"中的内容
|
||||
4. 确保 proposal 遵守"关键约束"
|
||||
|
||||
### 验证机制
|
||||
|
||||
如果 proposal 与 consensus 不一致,输出警告:
|
||||
|
||||
```
|
||||
⚠️ Proposal 验证警告:
|
||||
|
||||
共识中"要做什么"但 Proposal 未提及:
|
||||
- 功能点 C
|
||||
|
||||
共识中"不做什么"但 Proposal 包含:
|
||||
- 排除项 A
|
||||
|
||||
建议修正 Proposal 或更新共识。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Guardrails
|
||||
|
||||
- **必须使用 Question_tool** - 不要用纯文本确认
|
||||
- **逐维度确认** - 四个维度分开确认,不要合并
|
||||
- **不要跳过确认** - 每个维度都必须让用户明确确认
|
||||
- **不要自作主张** - 只整理讨论中明确提到的内容
|
||||
- **避免模糊表述** - "尽量"、"可能"、"考虑"等词汇需要明确化
|
||||
- **验收标准必须可测量** - 避免"性能要好"这类无法验证的标准
|
||||
|
||||
---
|
||||
|
||||
## 与其他 Skills 的关系
|
||||
|
||||
| Skill | 关系 |
|
||||
|-------|------|
|
||||
| `openspec-explore` | 探索结束后触发 lock |
|
||||
| `openspec-new-change` | lock 后触发 new(如果 change 不存在)|
|
||||
| `openspec-continue-change` | 生成 proposal 时读取 consensus 验证 |
|
||||
| `openspec-generate-acceptance-tests` | 从 consensus 的验收标准生成测试骨架 |
|
||||
Reference in New Issue
Block a user