prd-workflow-cli 1.4.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/workflows/prd-a1-scan.md +133 -0
- package/.agent/workflows/prd-a2ui-guide.md +6 -6
- package/.agent/workflows/prd-b-planning.md +135 -0
- package/.agent/workflows/prd-it-biz.md +56 -0
- package/.agent/workflows/prd-it-dev.md +163 -0
- package/.agent/workflows/prd-r2-review.md +104 -409
- package/.antigravity/rules.md +50 -265
- package/.cursorrules +57 -371
- package/GUIDE.md +147 -240
- package/README.md +170 -337
- package/bin/prd-cli.js +19 -12
- package/commands/baseline.js +174 -293
- package/commands/freeze-checks.js +424 -0
- package/commands/init.js +97 -162
- package/commands/it.js +286 -0
- package/commands/iteration.js +7 -91
- package/commands/planning.js +149 -517
- package/commands/review.js +78 -50
- package/commands/status.js +29 -38
- package/commands/upgrade.js +20 -0
- package/commands/version.js +222 -200
- package/package.json +2 -2
- package/rules/index.json +26 -27
- package/rules/schemas/rules.schema.json +1 -2
- package/templates/it-biz.md +141 -0
- package/templates/it-dev.md +237 -0
- package/templates//344/270/232/345/212/241/351/234/200/346/261/202.md +141 -0
- package/templates//346/212/200/346/234/257/350/247/204/346/240/274.md +237 -0
- package/.agent/workflows/prd-b1-planning-draft.md +0 -614
- package/.agent/workflows/prd-b2-planning-breakdown.md +0 -828
- package/.agent/workflows/prd-c1-requirement-list.md +0 -286
- package/.agent/workflows/prd-r1-review.md +0 -503
package/commands/baseline.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
const fs = require('fs-extra');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const chalk = require('chalk');
|
|
4
|
-
const confirm = require('./confirm');
|
|
5
4
|
|
|
5
|
+
/**
|
|
6
|
+
* 基线管理命令 (v2.0.0)
|
|
7
|
+
* 支持中文参数:产品定义、代码快照、用户反馈
|
|
8
|
+
*/
|
|
6
9
|
module.exports = async function (action, type, options = {}) {
|
|
7
10
|
const configPath = path.join(process.cwd(), '.prd-config.json');
|
|
8
11
|
|
|
@@ -12,7 +15,13 @@ module.exports = async function (action, type, options = {}) {
|
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
const config = await fs.readJSON(configPath);
|
|
15
|
-
|
|
18
|
+
|
|
19
|
+
// 支持新旧两种目录名
|
|
20
|
+
let baselineDir = path.join(process.cwd(), '01_基线');
|
|
21
|
+
if (!await fs.pathExists(baselineDir)) {
|
|
22
|
+
baselineDir = path.join(process.cwd(), '01_产品基线');
|
|
23
|
+
}
|
|
24
|
+
await fs.ensureDir(baselineDir);
|
|
16
25
|
|
|
17
26
|
if (action === 'create') {
|
|
18
27
|
await createBaselineDoc(type, baselineDir, config, configPath, options);
|
|
@@ -21,21 +30,35 @@ module.exports = async function (action, type, options = {}) {
|
|
|
21
30
|
}
|
|
22
31
|
};
|
|
23
32
|
|
|
33
|
+
// 中文名称到内部类型的映射
|
|
34
|
+
const typeMap = {
|
|
35
|
+
'产品定义': 'product',
|
|
36
|
+
'代码快照': 'codebase',
|
|
37
|
+
'用户反馈': 'feedback',
|
|
38
|
+
// 兼容旧版
|
|
39
|
+
'A0': 'product',
|
|
40
|
+
'A1': 'codebase',
|
|
41
|
+
'A2': 'feedback'
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// 类型到文件名的映射
|
|
45
|
+
const fileNameMap = {
|
|
46
|
+
'product': '产品定义.md',
|
|
47
|
+
'codebase': '代码快照.md',
|
|
48
|
+
'feedback': '用户反馈.md'
|
|
49
|
+
};
|
|
50
|
+
|
|
24
51
|
async function createBaselineDoc(type, baselineDir, config, configPath, options = {}) {
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
'A2': getA2Template(),
|
|
29
|
-
'R0': getR0Template()
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
if (!templates[type]) {
|
|
52
|
+
const internalType = typeMap[type];
|
|
53
|
+
|
|
54
|
+
if (!internalType) {
|
|
33
55
|
console.log(chalk.red(`✗ 未知的文档类型: ${type}`));
|
|
34
|
-
console.log('可用类型:
|
|
56
|
+
console.log('可用类型: 产品定义, 代码快照, 用户反馈');
|
|
57
|
+
console.log(chalk.gray('(兼容旧版: A0, A1, A2)'));
|
|
35
58
|
return;
|
|
36
59
|
}
|
|
37
60
|
|
|
38
|
-
const fileName =
|
|
61
|
+
const fileName = fileNameMap[internalType];
|
|
39
62
|
const filePath = path.join(baselineDir, fileName);
|
|
40
63
|
|
|
41
64
|
if (await fs.pathExists(filePath)) {
|
|
@@ -43,428 +66,286 @@ async function createBaselineDoc(type, baselineDir, config, configPath, options
|
|
|
43
66
|
return;
|
|
44
67
|
}
|
|
45
68
|
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const p0Exists = await fs.pathExists(p0Path);
|
|
60
|
-
const a0Exists = await fs.pathExists(a0Path);
|
|
61
|
-
const a1Exists = await fs.pathExists(a1Path);
|
|
62
|
-
const a2Exists = await fs.pathExists(a2Path);
|
|
63
|
-
|
|
64
|
-
console.log(` ${p0Exists ? '✅' : '❌'} P0_项目基本信息.md`);
|
|
65
|
-
console.log(` ${a0Exists ? '✅' : '❌'} A0_产品基础与范围说明.md`);
|
|
66
|
-
console.log(` ${a1Exists ? '✅' : '❌'} A1_已上线功能与流程清单.md`);
|
|
67
|
-
console.log(` ${a2Exists ? '✅' : '⚠️ (可选)'} A2_存量反馈与数据汇总.md`);
|
|
68
|
-
console.log('');
|
|
69
|
-
|
|
70
|
-
// P0、A0、A1 是必需的
|
|
71
|
-
if (!p0Exists || !a0Exists || !a1Exists) {
|
|
72
|
-
console.log(chalk.red('❌ 前置条件检查未通过!\n'));
|
|
73
|
-
console.log(chalk.yellow('R0 基线审视必须基于完整的 A 类基线文档。\n'));
|
|
74
|
-
console.log(chalk.bold('请先完成缺失的文档:'));
|
|
75
|
-
if (!p0Exists) console.log(' - 完善 P0(00_项目总览/P0_项目基本信息.md)');
|
|
76
|
-
if (!a0Exists) console.log(' - 创建 A0:prd baseline create A0');
|
|
77
|
-
if (!a1Exists) console.log(' - 创建 A1:prd baseline create A1');
|
|
78
|
-
console.log('');
|
|
79
|
-
console.log(chalk.gray('提示:A2 是可选的,但建议创建'));
|
|
80
|
-
|
|
81
|
-
// 在测试模式下抛出错误
|
|
82
|
-
if (process.env.PRD_TEST_MODE === 'true') {
|
|
83
|
-
throw new Error('R0 前置条件检查未通过');
|
|
84
|
-
}
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
console.log(chalk.green('✅ 前置条件检查通过!\n'));
|
|
89
|
-
|
|
90
|
-
// 2. PM 确认
|
|
91
|
-
if (options.pmConfirmed) {
|
|
92
|
-
console.log(chalk.green('✓ PM 已在对话中确认创建 R0 基线审视'));
|
|
93
|
-
} else if (process.env.PRD_TEST_MODE === 'true') {
|
|
94
|
-
// 测试模式:跳过交互式确认
|
|
95
|
-
console.log(chalk.yellow('⚠️ 测试模式:跳过交互式确认'));
|
|
96
|
-
} else {
|
|
97
|
-
// 交互式确认
|
|
98
|
-
console.log(chalk.yellow('⚠️ R0 基线审视将:'));
|
|
99
|
-
console.log(' 1. 系统性审视产品基线(基于 A0/A1/A2)');
|
|
100
|
-
console.log(' 2. 梳理用户路径和问题');
|
|
101
|
-
console.log(' 3. 识别关键成功因素');
|
|
102
|
-
console.log(' 4. 给出基线稳定性判定\n');
|
|
103
|
-
|
|
104
|
-
const confirmed = await confirm.confirmR0Creation();
|
|
105
|
-
if (!confirmed) {
|
|
106
|
-
console.log(chalk.yellow('\n已取消创建 R0'));
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
console.log(chalk.green('\n✓ PM 确认创建 R0\n'));
|
|
110
|
-
}
|
|
69
|
+
// 根据类型获取模板
|
|
70
|
+
let template;
|
|
71
|
+
switch (internalType) {
|
|
72
|
+
case 'product':
|
|
73
|
+
template = getProductTemplate();
|
|
74
|
+
break;
|
|
75
|
+
case 'codebase':
|
|
76
|
+
template = getCodebaseTemplate();
|
|
77
|
+
break;
|
|
78
|
+
case 'feedback':
|
|
79
|
+
template = getFeedbackTemplate();
|
|
80
|
+
break;
|
|
111
81
|
}
|
|
112
82
|
|
|
113
|
-
await fs.writeFile(filePath,
|
|
83
|
+
await fs.writeFile(filePath, template);
|
|
114
84
|
|
|
115
85
|
// 更新配置
|
|
116
|
-
config.stages.baseline.documents.push(
|
|
86
|
+
config.stages.baseline.documents.push(internalType);
|
|
117
87
|
await fs.writeJSON(configPath, config, { spaces: 2 });
|
|
118
88
|
|
|
119
89
|
console.log(chalk.green(`✓ 已创建: ${fileName}`));
|
|
120
90
|
console.log(chalk.cyan(`\n文件位置: ${filePath}\n`));
|
|
121
91
|
|
|
122
92
|
// 给出下一步提示
|
|
123
|
-
if (
|
|
124
|
-
console.log(chalk.bold('下一步建议:'));
|
|
125
|
-
console.log('1. 填写 A0 产品基础与范围说明');
|
|
126
|
-
console.log('2. 创建 A1: prd baseline create A1');
|
|
127
|
-
} else if (type === 'A1') {
|
|
128
|
-
console.log(chalk.bold('下一步建议:'));
|
|
129
|
-
console.log('1. 填写 A1 已上线功能与流程清单');
|
|
130
|
-
console.log('2. 创建 A2: prd baseline create A2');
|
|
131
|
-
} else if (type === 'A2') {
|
|
93
|
+
if (internalType === 'product') {
|
|
132
94
|
console.log(chalk.bold('下一步建议:'));
|
|
133
|
-
console.log('1.
|
|
134
|
-
console.log('2.
|
|
135
|
-
|
|
95
|
+
console.log('1. 填写产品定义(与 AI 对话完成)');
|
|
96
|
+
console.log('2. 创建代码快照: prd baseline create 代码快照');
|
|
97
|
+
console.log(chalk.yellow('\n💡 提示: 使用 /prd-代码快照 工作流让 AI 自动扫描代码生成'));
|
|
98
|
+
} else if (internalType === 'codebase') {
|
|
99
|
+
console.log(chalk.bold('⚠️ 重要提醒:'));
|
|
100
|
+
console.log(chalk.yellow('代码快照应由 AI 扫描代码自动生成,而非手动填写!'));
|
|
101
|
+
console.log('\n使用 /prd-代码快照 工作流让 AI 扫描代码。');
|
|
102
|
+
console.log('\n下一步建议:');
|
|
103
|
+
console.log('1. 创建用户反馈: prd baseline create 用户反馈');
|
|
104
|
+
} else if (internalType === 'feedback') {
|
|
136
105
|
console.log(chalk.bold('下一步建议:'));
|
|
137
|
-
console.log('1.
|
|
106
|
+
console.log('1. 整理用户反馈(可让 AI 协助)');
|
|
138
107
|
console.log('2. 开始第一轮迭代: prd iteration new');
|
|
139
|
-
console.log('');
|
|
140
|
-
console.log(chalk.yellow('⚠️ 重要提醒:'));
|
|
141
|
-
console.log(' R0 完成后,请勿自动创建后续文档!');
|
|
142
|
-
console.log(' 必须由 PM 明确指示才能进入下一阶段。');
|
|
143
108
|
}
|
|
144
109
|
console.log('');
|
|
145
110
|
}
|
|
146
111
|
|
|
147
|
-
function
|
|
148
|
-
|
|
149
|
-
'A0': 'A0_产品基础与范围说明.md',
|
|
150
|
-
'A1': 'A1_已上线功能与流程清单.md',
|
|
151
|
-
'A2': 'A2_存量反馈与数据汇总.md',
|
|
152
|
-
'R0': 'R0_基线审视报告.md'
|
|
153
|
-
};
|
|
154
|
-
return nameMap[type];
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function getA0Template() {
|
|
158
|
-
return `# A0_产品基础与范围说明
|
|
112
|
+
function getProductTemplate() {
|
|
113
|
+
return `# 产品定义
|
|
159
114
|
|
|
160
|
-
|
|
115
|
+
**创建时间**: ${new Date().toLocaleString('zh-CN')}
|
|
161
116
|
|
|
162
117
|
---
|
|
163
118
|
|
|
164
|
-
##
|
|
119
|
+
## 1. 产品是什么
|
|
165
120
|
|
|
166
|
-
### 产品是什么
|
|
167
121
|
<!-- 用一句话描述此产品 -->
|
|
168
122
|
|
|
169
|
-
|
|
123
|
+
|
|
124
|
+
## 2. 产品定位
|
|
125
|
+
|
|
170
126
|
<!-- 在整个业务体系中的角色 -->
|
|
171
127
|
|
|
128
|
+
|
|
172
129
|
---
|
|
173
130
|
|
|
174
|
-
##
|
|
131
|
+
## 3. 目标用户
|
|
175
132
|
|
|
176
133
|
### 主要用户群体
|
|
134
|
+
|
|
177
135
|
<!-- 列出主要用户类型 -->
|
|
178
136
|
|
|
179
|
-
### 用户画像
|
|
180
|
-
<!-- 描述典型用户特征 -->
|
|
181
137
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
## 三、核心使用场景
|
|
138
|
+
### 用户画像
|
|
185
139
|
|
|
186
|
-
|
|
187
|
-
<!-- 场景描述 -->
|
|
140
|
+
<!-- 描述典型用户特征 -->
|
|
188
141
|
|
|
189
|
-
### 场景二:
|
|
190
|
-
<!-- 场景描述 -->
|
|
191
142
|
|
|
192
143
|
---
|
|
193
144
|
|
|
194
|
-
##
|
|
145
|
+
## 4. 核心使用场景
|
|
195
146
|
|
|
196
|
-
###
|
|
197
|
-
<!-- 列出已有的核心功能 -->
|
|
147
|
+
### 场景一: [场景名称]
|
|
198
148
|
|
|
199
|
-
|
|
200
|
-
<!-- 简要说明技术实现方式 -->
|
|
149
|
+
<!-- 场景描述 -->
|
|
201
150
|
|
|
202
|
-
---
|
|
203
151
|
|
|
204
|
-
|
|
152
|
+
### 场景二: [场景名称]
|
|
205
153
|
|
|
206
|
-
|
|
207
|
-
<!-- 明确说明哪些场景不支持 -->
|
|
154
|
+
<!-- 场景描述 -->
|
|
208
155
|
|
|
209
|
-
### 已知限制
|
|
210
|
-
<!-- 列出当前的限制条件 -->
|
|
211
156
|
|
|
212
157
|
---
|
|
213
158
|
|
|
214
|
-
##
|
|
215
|
-
|
|
216
|
-
⚠️ **重要约束**:
|
|
217
|
-
- 不写规划、不写愿景
|
|
218
|
-
- 只描述"现在这个产品是什么样"
|
|
219
|
-
- 边界要写清楚(哪些能力没有、哪些不支持)
|
|
220
|
-
|
|
221
|
-
**目的**:
|
|
222
|
-
- 给 AI 和人一个统一的"现状语境"
|
|
223
|
-
- 防止后续规划"假设一个不存在的产品"
|
|
224
|
-
- 作为所有 B 规划的前置事实引用源
|
|
225
|
-
`;
|
|
226
|
-
}
|
|
159
|
+
## 5. 当前能力范围
|
|
227
160
|
|
|
228
|
-
|
|
229
|
-
return `# A1_已上线功能与流程清单
|
|
161
|
+
### 已有的核心功能
|
|
230
162
|
|
|
231
|
-
|
|
163
|
+
<!-- 列出已有的核心功能 -->
|
|
232
164
|
|
|
233
|
-
---
|
|
234
165
|
|
|
235
|
-
|
|
166
|
+
### 当前技术架构
|
|
236
167
|
|
|
237
|
-
|
|
238
|
-
- 功能 1.1:
|
|
239
|
-
- 功能 1.2:
|
|
168
|
+
<!-- 简要说明技术实现方式 -->
|
|
240
169
|
|
|
241
|
-
### 模块二: [模块名称]
|
|
242
|
-
- 功能 2.1:
|
|
243
|
-
- 功能 2.2:
|
|
244
170
|
|
|
245
171
|
---
|
|
246
172
|
|
|
247
|
-
##
|
|
173
|
+
## 6. 明确不做的事情
|
|
248
174
|
|
|
249
|
-
###
|
|
250
|
-
1. 步骤 1
|
|
251
|
-
2. 步骤 2
|
|
252
|
-
3. 步骤 3
|
|
253
|
-
|
|
254
|
-
### 路径二: [路径名称]
|
|
255
|
-
1. 步骤 1
|
|
256
|
-
2. 步骤 2
|
|
175
|
+
### 不支持的场景
|
|
257
176
|
|
|
258
|
-
|
|
177
|
+
<!-- 明确说明哪些场景不支持 -->
|
|
259
178
|
|
|
260
|
-
## 三、关键业务流程节点
|
|
261
179
|
|
|
262
|
-
###
|
|
263
|
-
<!-- 描述业务流程的关键节点 -->
|
|
180
|
+
### 已知限制
|
|
264
181
|
|
|
265
|
-
|
|
182
|
+
<!-- 列出当前的限制条件 -->
|
|
266
183
|
|
|
267
|
-
## 四、功能之间的依赖关系
|
|
268
|
-
|
|
269
|
-
### 依赖关系图
|
|
270
|
-
<!-- 描述功能间的依赖 -->
|
|
271
184
|
|
|
272
185
|
---
|
|
273
186
|
|
|
274
187
|
## 填写说明
|
|
275
188
|
|
|
276
189
|
⚠️ **重要约束**:
|
|
277
|
-
-
|
|
278
|
-
-
|
|
279
|
-
-
|
|
190
|
+
- 不写规划、不写愿景
|
|
191
|
+
- 只描述"现在这个产品是什么样"
|
|
192
|
+
- 边界要写清楚(哪些能力没有、哪些不支持)
|
|
280
193
|
|
|
281
194
|
**目的**:
|
|
282
|
-
-
|
|
283
|
-
-
|
|
284
|
-
-
|
|
195
|
+
- 给 AI 和人一个统一的"现状语境"
|
|
196
|
+
- 防止后续规划"假设一个不存在的产品"
|
|
197
|
+
- 作为所有规划的前置事实引用源
|
|
285
198
|
`;
|
|
286
199
|
}
|
|
287
200
|
|
|
288
|
-
function
|
|
289
|
-
return `#
|
|
201
|
+
function getCodebaseTemplate() {
|
|
202
|
+
return `# 代码快照
|
|
290
203
|
|
|
291
|
-
|
|
204
|
+
**创建时间**: ${new Date().toLocaleString('zh-CN')}
|
|
292
205
|
|
|
293
206
|
---
|
|
294
207
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
<!-- 摘要用户反馈内容 -->
|
|
299
|
-
- 来源:
|
|
300
|
-
- 时间:
|
|
301
|
-
|
|
302
|
-
### 反馈类型二:
|
|
303
|
-
<!-- 摘要用户反馈内容 -->
|
|
208
|
+
> ⚠️ **本文件应由 AI 扫描代码自动生成,请勿手动维护!**
|
|
209
|
+
>
|
|
210
|
+
> 使用 /prd-代码快照 工作流让 AI 扫描代码。
|
|
304
211
|
|
|
305
212
|
---
|
|
306
213
|
|
|
307
|
-
##
|
|
214
|
+
## 1. 项目概览
|
|
308
215
|
|
|
309
|
-
|
|
310
|
-
|
|
216
|
+
**项目类型**: [前端/后端/全栈/CLI]
|
|
217
|
+
**技术栈**: [React/Vue/Express/...]
|
|
218
|
+
**入口文件**: [...]
|
|
311
219
|
|
|
312
220
|
---
|
|
313
221
|
|
|
314
|
-
##
|
|
222
|
+
## 2. 功能清单
|
|
315
223
|
|
|
316
|
-
###
|
|
317
|
-
<!-- 描述问题 -->
|
|
318
|
-
- 来源:
|
|
319
|
-
- 影响范围:
|
|
224
|
+
### 2.1 [模块A]
|
|
320
225
|
|
|
321
|
-
|
|
226
|
+
| 功能 | 路径/入口 | 说明 |
|
|
227
|
+
|-----|----------|------|
|
|
228
|
+
| 功能1 | \`src/xxx\` | ... |
|
|
229
|
+
| 功能2 | \`src/yyy\` | ... |
|
|
322
230
|
|
|
323
|
-
|
|
231
|
+
### 2.2 [模块B]
|
|
324
232
|
|
|
325
|
-
|
|
326
|
-
<!-- 描述未解决的问题 -->
|
|
327
|
-
- 原因:
|
|
328
|
-
- 优先级:
|
|
233
|
+
...
|
|
329
234
|
|
|
330
235
|
---
|
|
331
236
|
|
|
332
|
-
##
|
|
333
|
-
|
|
334
|
-
**用途说明**:
|
|
335
|
-
当 C1/C2 讨论过程中产生了新需求,但超出当前版本(B3)的规划范围时,
|
|
336
|
-
应记录在此章节,等待下一轮迭代时纳入 B1 规划。
|
|
337
|
-
|
|
338
|
-
### 待下版事项 #1: [需求标题]
|
|
339
|
-
|
|
340
|
-
**来源**:C1/C2 讨论过程(第 XX 轮迭代,YYYY-MM-DD)
|
|
341
|
-
**原因**:超出 B3 首版范围,延后处理
|
|
237
|
+
## 3. API 清单(如有)
|
|
342
238
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
239
|
+
| 方法 | 路径 | 说明 |
|
|
240
|
+
|-----|------|------|
|
|
241
|
+
| GET | /api/xxx | ... |
|
|
242
|
+
| POST | /api/yyy | ... |
|
|
347
243
|
|
|
348
|
-
|
|
349
|
-
<!-- 需求的详细说明 -->
|
|
244
|
+
---
|
|
350
245
|
|
|
351
|
-
|
|
352
|
-
<!-- 保留 PM 原话 -->
|
|
246
|
+
## 4. 核心用户路径
|
|
353
247
|
|
|
354
|
-
|
|
355
|
-
<!-- 与现有需求的关联 -->
|
|
248
|
+
### 路径 1: [路径名称]
|
|
356
249
|
|
|
357
|
-
|
|
358
|
-
|
|
250
|
+
1. 步骤 1
|
|
251
|
+
2. 步骤 2
|
|
252
|
+
3. 步骤 3
|
|
359
253
|
|
|
360
254
|
---
|
|
361
255
|
|
|
362
|
-
##
|
|
256
|
+
## 5. 依赖关系
|
|
363
257
|
|
|
364
|
-
|
|
365
|
-
- 不做结论、不做方案
|
|
366
|
-
- 可以是原始反馈的整理
|
|
367
|
-
- 标注来源即可
|
|
258
|
+
### 模块间依赖
|
|
368
259
|
|
|
369
|
-
|
|
370
|
-
- 为 B 规划提供动因素材
|
|
371
|
-
- 防止规划"拍脑袋"
|
|
372
|
-
- 为 R 审视提供"现实校验"
|
|
373
|
-
- **暂存 C 阶段产生的超范围需求(待下版处理)**
|
|
260
|
+
<!-- 描述功能间的依赖 -->
|
|
374
261
|
|
|
375
262
|
---
|
|
376
263
|
|
|
377
|
-
##
|
|
378
|
-
|
|
379
|
-
### 何时写入本文档?
|
|
380
|
-
|
|
381
|
-
| 场景 | 写入章节 |
|
|
382
|
-
|------|----------|
|
|
383
|
-
| 收到用户反馈 | 一、用户反馈摘要 |
|
|
384
|
-
| 发现数据异常 | 二、数据异常或指标变化 |
|
|
385
|
-
| 内部发现问题 | 三、内部问题/投诉 |
|
|
386
|
-
| 已知但未解决的问题 | 四、已知未解决事项 |
|
|
387
|
-
| **C1/C2 讨论中产生的新需求** | **五、待下版事项** |
|
|
264
|
+
## 扫描日志
|
|
388
265
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
-
|
|
392
|
-
-
|
|
266
|
+
- 最后扫描时间: ___
|
|
267
|
+
- 扫描范围: ___
|
|
268
|
+
- 识别功能点: ___ 个
|
|
269
|
+
- 识别 API: ___ 个
|
|
393
270
|
`;
|
|
394
271
|
}
|
|
395
272
|
|
|
396
|
-
function
|
|
397
|
-
return `#
|
|
273
|
+
function getFeedbackTemplate() {
|
|
274
|
+
return `# 用户反馈
|
|
398
275
|
|
|
399
|
-
|
|
276
|
+
**创建时间**: ${new Date().toLocaleString('zh-CN')}
|
|
400
277
|
|
|
401
278
|
---
|
|
402
279
|
|
|
403
|
-
##
|
|
280
|
+
## 1. 用户反馈摘要
|
|
281
|
+
|
|
282
|
+
### 反馈 1: [标题]
|
|
283
|
+
|
|
284
|
+
- **来源**:
|
|
285
|
+
- **时间**:
|
|
286
|
+
- **内容**:
|
|
404
287
|
|
|
405
|
-
|
|
406
|
-
- A0_产品基础与范围说明.md
|
|
407
|
-
- A1_已上线功能与流程清单.md
|
|
408
|
-
- A2_存量反馈与数据汇总.md
|
|
288
|
+
### 反馈 2: [标题]
|
|
409
289
|
|
|
410
|
-
|
|
411
|
-
|
|
290
|
+
- **来源**:
|
|
291
|
+
- **时间**:
|
|
292
|
+
- **内容**:
|
|
412
293
|
|
|
413
294
|
---
|
|
414
295
|
|
|
415
|
-
##
|
|
296
|
+
## 2. 数据异常或指标变化
|
|
416
297
|
|
|
417
|
-
###
|
|
418
|
-
<!-- 从头到尾走一遍系统,描述实际使用情况 -->
|
|
298
|
+
### 异常 1: [标题]
|
|
419
299
|
|
|
420
|
-
|
|
421
|
-
|
|
300
|
+
- **发现时间**:
|
|
301
|
+
- **具体表现**:
|
|
302
|
+
- **影响范围**:
|
|
422
303
|
|
|
423
304
|
---
|
|
424
305
|
|
|
425
|
-
##
|
|
306
|
+
## 3. 内部问题/投诉
|
|
426
307
|
|
|
427
|
-
###
|
|
428
|
-
1.
|
|
429
|
-
2.
|
|
308
|
+
### 问题 1: [标题]
|
|
430
309
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
310
|
+
- **来源**:
|
|
311
|
+
- **描述**:
|
|
312
|
+
- **影响范围**:
|
|
434
313
|
|
|
435
314
|
---
|
|
436
315
|
|
|
437
|
-
##
|
|
316
|
+
## 4. 已知未解决事项
|
|
438
317
|
|
|
439
|
-
###
|
|
440
|
-
<!-- 列出技术层面的风险 -->
|
|
318
|
+
### 事项 1: [标题]
|
|
441
319
|
|
|
442
|
-
|
|
443
|
-
|
|
320
|
+
- **原因**:
|
|
321
|
+
- **优先级**: P0 / P1 / P2
|
|
444
322
|
|
|
445
323
|
---
|
|
446
324
|
|
|
447
|
-
##
|
|
325
|
+
## 5. 待下版事项
|
|
448
326
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
- [ ] 需要先解决关键问题
|
|
327
|
+
> 当规划/版本讨论过程中产生了新需求,但超出当前版本范围时,
|
|
328
|
+
> 记录在此章节,等待下一轮迭代时纳入规划。
|
|
452
329
|
|
|
453
|
-
|
|
454
|
-
|
|
330
|
+
### 待下版 #1: [需求标题]
|
|
331
|
+
|
|
332
|
+
**来源**: 第 XX 轮迭代讨论
|
|
333
|
+
**原因**: 超出首版范围,延后处理
|
|
334
|
+
**优先级**: P0 / P1 / P2
|
|
335
|
+
**详细描述**:
|
|
455
336
|
|
|
456
337
|
---
|
|
457
338
|
|
|
458
339
|
## 填写说明
|
|
459
340
|
|
|
460
341
|
⚠️ **重要约束**:
|
|
461
|
-
-
|
|
462
|
-
-
|
|
463
|
-
-
|
|
342
|
+
- 不做结论、不做方案
|
|
343
|
+
- 可以是原始反馈的整理
|
|
344
|
+
- 标注来源即可
|
|
464
345
|
|
|
465
346
|
**目的**:
|
|
466
|
-
-
|
|
467
|
-
-
|
|
468
|
-
-
|
|
347
|
+
- 为规划提供动因素材
|
|
348
|
+
- 防止规划"拍脑袋"
|
|
349
|
+
- 暂存超范围需求(待下版处理)
|
|
469
350
|
`;
|
|
470
351
|
}
|