sdd-full 1.0.0 → 1.2.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.
Files changed (36) hide show
  1. package/README.md +84 -39
  2. package/index.js +163 -29
  3. package/package.json +27 -11
  4. package/skills/README.md +75 -0
  5. package/skills/brainstorming/SKILL.md +164 -0
  6. package/skills/claudeception/SKILL.md +94 -0
  7. package/skills/competitive-brief/SKILL.md +119 -0
  8. package/skills/finishing-a-development-branch/SKILL.md +200 -0
  9. package/skills/market-research/SKILL.md +141 -0
  10. package/skills/mempalace-auto-saver/SKILL.md +300 -0
  11. package/skills/prd-write/SKILL.md +109 -0
  12. package/skills/quality-gate/SKILL.md +348 -0
  13. package/skills/receiving-code-review/SKILL.md +213 -0
  14. package/skills/release-flow/SKILL.md +402 -0
  15. package/skills/requesting-code-review/SKILL.md +105 -0
  16. package/skills/requirement-completion-officer/SKILL.md +122 -0
  17. package/skills/sdd/SKILL.md +1042 -0
  18. package/skills/sdd-add/SKILL.md +538 -0
  19. package/skills/sdd-code/SKILL.md +345 -0
  20. package/skills/sdd-deploy/SKILL.md +499 -0
  21. package/skills/sdd-full/SKILL.md +734 -0
  22. package/skills/sdd-ops/SKILL.md +304 -0
  23. package/skills/sdd-test/SKILL.md +381 -0
  24. package/skills/security-audit/SKILL.md +384 -0
  25. package/skills/systematic-debugging/SKILL.md +296 -0
  26. package/skills/test-driven-development/SKILL.md +371 -0
  27. package/skills/ui-sdd/SKILL.md +290 -0
  28. package/skills/unified-flow/SKILL.md +146 -0
  29. package/skills/using-superpowers/SKILL.md +115 -0
  30. package/skills/verification-before-completion/SKILL.md +139 -0
  31. package/skills/writing-plans/SKILL.md +142 -0
  32. package/skills//345/256/214/346/225/264/345/274/200/345/217/221/346/265/201/347/250/213/346/211/213/345/206/214.md +349 -0
  33. package/skills//346/212/200/350/203/275/344/275/223/347/263/273/345/256/214/345/226/204/345/273/272/350/256/256.md +244 -0
  34. package/skills//346/212/200/350/203/275/344/275/277/347/224/250/346/214/207/345/215/227.md +225 -0
  35. package/skills//346/212/200/350/203/275/345/206/263/347/255/226/346/240/221.md +235 -0
  36. package/skills-data.js +0 -107
@@ -0,0 +1,371 @@
1
+ ---
2
+ name: test-driven-development
3
+ description: 在编写实现代码之前,实现任何功能或错误修复时使用
4
+ ---
5
+
6
+ # 测试驱动开发 (TDD)
7
+
8
+ ## 概述
9
+
10
+ 先写测试。看着它失败。编写最小代码使其通过。
11
+
12
+ **核心原则:** 如果你没有看到测试失败,你就不知道它是否测试了正确的东西。
13
+
14
+ **违反规则的字面意思就是违反规则的精神。**
15
+
16
+ ## 何时使用
17
+
18
+ **始终:**
19
+ - 新功能
20
+ - 错误修复
21
+ - 重构
22
+ - 行为变更
23
+
24
+ **例外(询问你的人类伙伴):**
25
+ - 一次性原型
26
+ - 生成的代码
27
+ - 配置文件
28
+
29
+ 想“就这一次跳过 TDD”?停止。那是合理化。
30
+
31
+ ## 铁律
32
+
33
+ ```
34
+ 没有先失败的测试,就没有生产代码
35
+ ```
36
+
37
+ 在测试之前写代码?删除它。重新开始。
38
+
39
+ **没有例外:**
40
+ - 不要将其作为“参考”保留
41
+ - 不要在编写测试时“适应”它
42
+ - 不要看它
43
+ - 删除意味着删除
44
+
45
+ 从测试中重新实现。就这样。
46
+
47
+ ## 红-绿-重构
48
+
49
+ ```dot
50
+ digraph tdd_cycle {
51
+ rankdir=LR;
52
+ red [label="RED\n编写失败的测试", shape=box, style=filled, fillcolor="#ffcccc"];
53
+ verify_red [label="验证失败\n正确", shape=diamond];
54
+ green [label="GREEN\n最小代码", shape=box, style=filled, fillcolor="#ccffcc"];
55
+ verify_green [label="验证通过\n全部绿色", shape=diamond];
56
+ refactor [label="REFACTOR\n清理", shape=box, style=filled, fillcolor="#ccccff"];
57
+ next [label="下一个", shape=ellipse];
58
+
59
+ red -> verify_red;
60
+ verify_red -> green [label="是"];
61
+ verify_red -> red [label="错误\n失败"];
62
+ green -> verify_green;
63
+ verify_green -> refactor [label="是"];
64
+ verify_green -> green [label="否"];
65
+ refactor -> verify_green [label="保持\n绿色"];
66
+ verify_green -> next;
67
+ next -> red;
68
+ }
69
+ ```
70
+
71
+ ### 红 - 编写失败的测试
72
+
73
+ 编写一个最小测试,显示应该发生什么。
74
+
75
+ <Good>
76
+ ```typescript
77
+ test('重试失败操作 3 次', async () => {
78
+ let attempts = 0;
79
+ const operation = () => {
80
+ attempts++;
81
+ if (attempts < 3) throw new Error('fail');
82
+ return 'success';
83
+ };
84
+
85
+ const result = await retryOperation(operation);
86
+
87
+ expect(result).toBe('success');
88
+ expect(attempts).toBe(3);
89
+ });
90
+ ```
91
+ 名称清晰,测试真实行为,一个测试一个行为
92
+ </Good>
93
+
94
+ <Bad>
95
+ ```typescript
96
+ test('重试有效', async () => {
97
+ const mock = jest.fn()
98
+ .mockRejectedValueOnce(new Error())
99
+ .mockRejectedValueOnce(new Error())
100
+ .mockResolvedValueOnce('success');
101
+ await retryOperation(mock);
102
+ expect(mock).toHaveBeenCalledTimes(3);
103
+ });
104
+ ```
105
+ 名称模糊,测试模拟而非代码
106
+ </Bad>
107
+
108
+ **要求:**
109
+ - 一个行为
110
+ - 清晰的名称
111
+ - 真实代码(除非不可避免,否则不要使用模拟)
112
+
113
+ ### 验证红 - 看着它失败
114
+
115
+ **必须执行。永远不要跳过。**
116
+
117
+ ```bash
118
+ npm test path/to/test.test.ts
119
+ ```
120
+
121
+ 确认:
122
+ - 测试失败(不是错误)
123
+ - 失败消息符合预期
124
+ - 失败是因为功能缺失(不是拼写错误)
125
+
126
+ **测试通过?** 你在测试现有行为。修复测试。
127
+
128
+ **测试错误?** 修复错误,重新运行直到正确失败。
129
+
130
+ ### 绿 - 最小代码
131
+
132
+ 编写最简单的代码以通过测试。
133
+
134
+ <Good>
135
+ ```typescript
136
+ async function retryOperation<T>(fn: () => Promise<T>): Promise<T> {
137
+ for (let i = 0; i < 3; i++) {
138
+ try {
139
+ return await fn();
140
+ } catch (e) {
141
+ if (i === 2) throw e;
142
+ }
143
+ }
144
+ throw new Error('unreachable');
145
+ }
146
+ ```
147
+ 刚好足够通过
148
+ </Good>
149
+
150
+ <Bad>
151
+ ```typescript
152
+ async function retryOperation<T>(
153
+ fn: () => Promise<T>,
154
+ options?: {
155
+ maxRetries?: number;
156
+ backoff?: 'linear' | 'exponential';
157
+ onRetry?: (attempt: number) => void;
158
+ }
159
+ ): Promise<T> {
160
+ // YAGNI
161
+ }
162
+ ```
163
+ 过度设计
164
+ </Bad>
165
+
166
+ 不要添加功能、重构其他代码或超出测试范围的“改进”。
167
+
168
+ ### 验证绿 - 看着它通过
169
+
170
+ **必须执行。**
171
+
172
+ ```bash
173
+ npm test path/to/test.test.ts
174
+ ```
175
+
176
+ 确认:
177
+ - 测试通过
178
+ - 其他测试仍然通过
179
+ - 输出纯净(无错误、警告)
180
+
181
+ **测试失败?** 修复代码,不是测试。
182
+
183
+ **其他测试失败?** 立即修复。
184
+
185
+ ### 重构 - 清理
186
+
187
+ 仅在绿色之后:
188
+ - 移除重复
189
+ - 改进名称
190
+ - 提取辅助函数
191
+
192
+ 保持测试绿色。不要添加行为。
193
+
194
+ ### 重复
195
+
196
+ 下一个失败的测试用于下一个功能。
197
+
198
+ ## 好的测试
199
+
200
+ | 质量 | 好 | 坏 |
201
+ |------|----|----|
202
+ | **最小** | 一个行为。名称中有 "and"?拆分它。 | `test('validates email and domain and whitespace')` |
203
+ | **清晰** | 名称描述行为 | `test('test1')` |
204
+ | **展示意图** | 演示期望的 API | 掩盖代码应该做什么 |
205
+
206
+ ## 为什么顺序很重要
207
+
208
+ **"我会在之后写测试来验证它有效"**
209
+
210
+ 在代码之后写的测试立即通过。立即通过证明不了什么:
211
+ - 可能测试错误的东西
212
+ - 可能测试实现,而不是行为
213
+ - 可能遗漏你忘记的边缘情况
214
+ - 你从未看到它捕获错误
215
+
216
+ 测试优先迫使你看到测试失败,证明它实际上测试了某些东西。
217
+
218
+ **"我已经手动测试了所有边缘情况"**
219
+
220
+ 手动测试是临时的。你认为你测试了一切,但:
221
+ - 没有记录你测试了什么
222
+ - 代码更改时无法重新运行
223
+ - 在压力下容易忘记情况
224
+ - "我尝试时它有效" ≠ 全面
225
+
226
+ 自动化测试是系统的。它们每次都以相同的方式运行。
227
+
228
+ **"删除 X 小时的工作是浪费的"**
229
+
230
+ 沉没成本谬误。时间已经过去了。你现在的选择:
231
+ - 删除并重写 TDD(再 X 小时,高信心)
232
+ - 保留它并在之后添加测试(30 分钟,低信心,可能有错误)
233
+
234
+ "浪费"是保留你不能信任的代码。没有真实测试的工作代码是技术债务。
235
+
236
+ **"TDD 是教条的,务实意味着适应"**
237
+
238
+ TDD 就是务实:
239
+ - 在提交前发现错误(比之后调试更快)
240
+ - 防止回归(测试立即捕获中断)
241
+ - 记录行为(测试展示如何使用代码)
242
+ - 启用重构(自由更改,测试捕获中断)
243
+
244
+ "务实"的捷径 = 在生产中调试 = 更慢。
245
+
246
+ **"测试之后达到相同的目标 - 这是精神不是仪式"**
247
+
248
+ 不。测试之后回答"这做什么?"。测试之前回答"这应该做什么?"。
249
+
250
+ 测试之后被你的实现所偏见。你测试你构建的东西,而不是需要的东西。你验证记住的边缘情况,而不是发现的边缘情况。
251
+
252
+ 测试之前迫使在实现之前发现边缘情况。测试之后验证你记住了一切(你没有)。
253
+
254
+ 30 分钟的测试之后 ≠ TDD。你获得覆盖率,失去测试工作的证明。
255
+
256
+ ## 常见的合理化
257
+
258
+ | 借口 | 现实 |
259
+ |------|------|
260
+ | "太简单了,不需要测试" | 简单代码会中断。测试需要 30 秒。 |
261
+ | "我会之后测试" | 立即通过的测试证明不了什么。 |
262
+ | "测试之后达到相同的目标" | 测试之后 = "这做什么?" 测试之前 = "这应该做什么?" |
263
+ | "已经手动测试过了" | 临时 ≠ 系统。无记录,无法重新运行。 |
264
+ | "删除 X 小时是浪费的" | 沉没成本谬误。保留未验证的代码是技术债务。 |
265
+ | "保留作为参考,先写测试" | 你会适应它。那是测试之后。删除意味着删除。 |
266
+ | "需要先探索" | 很好。扔掉探索,从 TDD 开始。 |
267
+ | "测试难 = 设计不清" | 听测试的。难测试 = 难使用。 |
268
+ | "TDD 会减慢我" | TDD 比调试快。务实 = 测试优先。 |
269
+ | "手动测试更快" | 手动不能证明边缘情况。你会重新测试每个更改。 |
270
+ | "现有代码没有测试" | 你正在改进它。为现有代码添加测试。 |
271
+
272
+ ## 红旗 - 停止并重新开始
273
+
274
+ - 测试之前的代码
275
+ - 实现之后的测试
276
+ - 测试立即通过
277
+ - 无法解释测试为什么失败
278
+ - "稍后"添加的测试
279
+ - 合理化"就这一次"
280
+ - "我已经手动测试过了"
281
+ - "测试之后达到相同的目的"
282
+ - "这是精神不是仪式"
283
+ - "保留作为参考"或"适应现有代码"
284
+ - "已经花了 X 小时,删除是浪费的"
285
+ - "TDD 是教条的,我在务实"
286
+ - "这不同因为..."
287
+
288
+ **所有这些都意味着:删除代码。用 TDD 重新开始。**
289
+
290
+ ## 示例:错误修复
291
+
292
+ **错误:** 接受空电子邮件
293
+
294
+ **红**
295
+ ```typescript
296
+ test('拒绝空电子邮件', async () => {
297
+ const result = await submitForm({ email: '' });
298
+ expect(result.error).toBe('Email required');
299
+ });
300
+ ```
301
+
302
+ **验证红**
303
+ ```bash
304
+ $ npm test
305
+ 失败:期望 'Email required',得到 undefined
306
+ ```
307
+
308
+ **绿**
309
+ ```typescript
310
+ function submitForm(data: FormData) {
311
+ if (!data.email?.trim()) {
312
+ return { error: 'Email required' };
313
+ }
314
+ // ...
315
+ }
316
+ ```
317
+
318
+ **验证绿**
319
+ ```bash
320
+ $ npm test
321
+ 通过
322
+ ```
323
+
324
+ **重构**
325
+ 如果需要,提取多个字段的验证。
326
+
327
+ ## 验证清单
328
+
329
+ 在标记工作完成之前:
330
+
331
+ - [ ] 每个新函数/方法都有测试
332
+ - [ ] 每个测试在实现前都看到失败
333
+ - [ ] 每个测试因预期原因失败(功能缺失,不是拼写错误)
334
+ - [ ] 为每个测试编写最小代码以通过
335
+ - [ ] 所有测试通过
336
+ - [ ] 输出纯净(无错误、警告)
337
+ - [ ] 测试使用真实代码(仅在不可避免时使用模拟)
338
+ - [ ] 覆盖边缘情况和错误
339
+
340
+ 无法检查所有框?你跳过了 TDD。重新开始。
341
+
342
+ ## 卡住时
343
+
344
+ | 问题 | 解决方案 |
345
+ |------|----------|
346
+ | 不知道如何测试 | 编写期望的 API。先编写断言。询问你的人类伙伴。 |
347
+ | 测试太复杂 | 设计太复杂。简化接口。 |
348
+ | 必须模拟一切 | 代码耦合度太高。使用依赖注入。 |
349
+ | 测试设置庞大 | 提取辅助函数。仍然复杂?简化设计。 |
350
+
351
+ ## 调试集成
352
+
353
+ 发现错误?编写重现错误的失败测试。遵循 TDD 循环。测试证明修复并防止回归。
354
+
355
+ 永远不要没有测试就修复错误。
356
+
357
+ ## 测试反模式
358
+
359
+ 添加模拟或测试实用程序时,阅读 @testing-anti-patterns.md 以避免常见陷阱:
360
+ - 测试模拟行为而不是真实行为
361
+ - 向生产类添加仅测试方法
362
+ - 在不理解依赖关系的情况下模拟
363
+
364
+ ## 最终规则
365
+
366
+ ```
367
+ 生产代码 → 测试存在且首先失败
368
+ 否则 → 不是 TDD
369
+ ```
370
+
371
+ 未经你的人类伙伴许可,无例外。
@@ -0,0 +1,290 @@
1
+
2
+ # UI-SDD 完整整合版:App全域全景骨架 + 标准模板
3
+
4
+ ---
5
+
6
+ ## 第一部分:App全域全景骨架(项目启动第一步)
7
+
8
+ ### 核心定义
9
+ **App全域全景骨架**:在写任何SDD、写任何代码前,先把整个App所有页面、弹窗、公共组件、全局隐性规则,梳理成一棵完整结构树。作用:定结构、定拆分、防遗漏。
10
+
11
+ ---
12
+
13
+ ### 具体5步流程(照着做!)
14
+
15
+ #### 第1步:模拟用户完整走一遍App全流程
16
+ 从头到尾模拟真实用户操作,不思考设计、不写细节,只记录出现了哪些页面、哪些弹窗。
17
+
18
+ **示例(地图导航App)**:
19
+ ```
20
+ 打开App → 启动页 → 首页(Tab)→ 搜索页 → 详情页 → 设置 → 退出
21
+
22
+ 真实地图页
23
+
24
+ 语音测试页
25
+ ```
26
+
27
+ #### 第2步:逐一把看到的「页面、弹窗」全部罗列出来
28
+ 边走边记,看到什么写什么,不脑补、不省略。
29
+
30
+ **示例(地图导航App)**:
31
+ | 类型 | 名称 |
32
+ |------|------|
33
+ | 独立页面 | 启动页、首页、真实地图页、搜索页、语音测试页 |
34
+ | 弹窗 | 确认弹窗、权限申请弹窗、语音识别中浮层 |
35
+ | 反复出现组件 | 顶部导航栏、语音按钮、加载指示器、错误提示 |
36
+
37
+ #### 第3步:分类归为三大类(固定分类)
38
+ 把罗列好的内容,强制分成3类:
39
+
40
+ | 分类 | 说明 | 示例 |
41
+ |------|------|------|
42
+ | **业务页面(pages)** | 全屏独立页面,一页一个入口 | 启动页、首页、搜索页 |
43
+ | **弹窗/浮层(dialog)** | 非全屏、弹出覆盖式 | 确认弹窗、权限弹窗 |
44
+ | **全局公共组件(common)** | 多个页面复用的UI控件 | 导航栏、按钮、输入框 |
45
+
46
+ #### 第4步:梳理「全局隐性规则」(最容易漏!)
47
+ 单独拉出一类,不属于页面也不属于组件,但是整个App都要遵守:
48
+
49
+ | 规则分类 | 说明 | 示例 |
50
+ |----------|------|------|
51
+ | 全局配色/圆角/字体规范 | UI样式统一 | 主色调深海蓝、圆角统一8dp |
52
+ | 平台适配 | iOS/Android差异 | iOS刘海安全区、Android物理返回 |
53
+ | 页面路由/栈/返回逻辑 | 导航行为 | 返回保留页面栈、某些页面替换路由 |
54
+ | 未登录拦截/登录态管理 | 用户状态 | 首次使用请求权限 |
55
+ | 全局弱网/报错兜底 | 异常处理 | 网络不可用提示、加载失败重试 |
56
+ | 全局键盘适配/防抖/权限流程 | 交互细节 | 键盘弹出布局调整、点击防抖 |
57
+
58
+ #### 第5步:整理成「树形全景骨架结构」
59
+ 把上面三类,整理成树状层级:
60
+
61
+ ```
62
+ App全域全景骨架
63
+ ├─ 启动流程页面
64
+ │ ├─ 启动页(闪屏)
65
+ │ └─ 隐私协议页(可选)
66
+ ├─ 主业务页面
67
+ │ ├─ 首页
68
+ │ ├─ 真实地图页
69
+ │ ├─ 搜索页
70
+ │ └─ 语音测试页
71
+ ├─ 全局弹窗/浮层
72
+ │ ├─ 通用确认弹窗
73
+ │ ├─ 权限申请弹窗
74
+ │ └─ 语音识别浮层
75
+ ├─ 全局公共组件
76
+ │ ├─ 顶部导航栏
77
+ │ ├─ 语音按钮
78
+ │ ├─ 加载指示器
79
+ │ ├─ 错误提示
80
+ │ └─ 确认弹窗
81
+ └─ 全局隐性规则
82
+ ├─ 样式规范(颜色/字体/间距)
83
+ ├─ 平台适配(iOS/Android)
84
+ ├─ 路由逻辑(栈/返回)
85
+ ├─ 权限流程(定位/麦克风)
86
+ └─ 网络/键盘/防抖
87
+ ```
88
+
89
+ ---
90
+
91
+ ### 极简口诀(记住就会!)
92
+ 1. **模拟用户走全程**
93
+ 2. **所见全部罗列**
94
+ 3. **分成页面/弹窗/组件三类**
95
+ 4. **补上全局隐性规则**
96
+ 5. **整理成树形骨架**
97
+
98
+ ---
99
+
100
+ ### 画完骨架后马上能做什么?
101
+ 1. 直接按这个树,**建立SDD目录文件夹**
102
+ 2. 每个页面/弹窗/组件,对应新建SDD文档
103
+ 3. 对照骨架做「UI交互盘点清单」逐项打勾
104
+ 4. 保证后面所有SDD **100%全覆盖无遗漏**
105
+
106
+ ---
107
+
108
+ ## 第二部分:UI交互专用SDD标准模板
109
+
110
+ ### 何时使用
111
+ - 需要为新页面、弹窗、复杂组件编写设计文档
112
+ - 需要确保UI布局、交互、状态能1:1还原
113
+ - 适用于Web、原生iOS、原生Android、Flutter项目
114
+ - 需要替代原型设计,直接通过文档驱动开发
115
+
116
+ ---
117
+
118
+ ### 模板结构(完整11部分)
119
+
120
+ #### 1. 基础信息
121
+ | 字段 | 说明 |
122
+ |------|------|
123
+ | **归属平台** | Web / 原生iOS / 原生Android / Flutter |
124
+ | **页面名称** | 页面的正式名称 |
125
+ | **页面路由** | 路由地址(Web/Flutter)或页面标识 |
126
+ | **关联用户故事** | 对应的用户故事ID或描述 |
127
+ | **依赖接口/本地缓存** | 所需的数据接口或本地存储 |
128
+ | **适配机型/系统版本** | 适配范围 |
129
+
130
+ #### 2. 整体页面结构布局
131
+ - 整体布局方式:固定布局 / 流式 / 弹性 / 卡片式
132
+ - 页面整体分区(从上到下/从左到右)
133
+ - 全局样式基准(统一约束)
134
+
135
+ #### 3. 页面所有状态定义(必写!)
136
+ 必须逐条定义,不能只写正常状态:
137
+ 1. 默认初始态
138
+ 2. 加载中态(全局/局部)
139
+ 3. 空数据态
140
+ 4. 网络异常/接口报错态
141
+ 5. 表单禁用/按钮置灰态
142
+ 6. 操作成功反馈态
143
+ 7. 键盘弹出适配态(移动端必写)
144
+
145
+ #### 4. 组件清单 & 静态UI描述
146
+ 逐个列出页面所有控件,每项写清楚:
147
+ - 位置
148
+ - 文案/占位符
149
+ - 默认样式
150
+ - 显隐条件
151
+
152
+ #### 5. 逐组件交互逻辑(核心!)
153
+ | 组件类型 | 需定义内容 |
154
+ |----------|------------|
155
+ | 输入类 | 输入规则、实时校验、清空按钮、键盘类型 |
156
+ | 点击类 | 触发动作、防抖间隔、禁用条件、重复点击、点击反馈 |
157
+ | 手势类 | 滑动、下拉刷新、长按、iOS右滑返回、Android物理返回 |
158
+
159
+ #### 6. 弹窗、浮层、Toast交互规则
160
+ - 触发条件
161
+ - 弹出动画
162
+ - 遮罩是否可点击关闭
163
+ - 按钮确认/取消行为
164
+ - 自动消失时长
165
+ - 弹窗关闭后页面状态保留规则
166
+
167
+ #### 7. 页面跳转 & 返回逻辑
168
+ | 场景 | 路由 | 返回逻辑 | 保留页面栈 | 替换路由 |
169
+ |------|------|----------|------------|----------|
170
+ | 正向跳转 | | | | |
171
+ | 返回上一页 | | | | |
172
+
173
+ #### 8. 动画 & 过渡效果
174
+ - 页面进入/退出过渡动画
175
+ - 加载动画样式
176
+ - 按钮点击动效
177
+ - 列表加载骨架屏动效
178
+
179
+ #### 9. 边界&异常场景处理
180
+ 1. 弱网/无网络时表现
181
+ 2. 接口报错文案展示
182
+ 3. 输入超限、特殊字符拦截
183
+ 4. 无权限访问处理
184
+ 5. 首次进入/非首次进入差异化
185
+
186
+ #### 10. 平台差异化专属规则
187
+ 分别说明iOS、Android、Flutter、Web的差异。
188
+
189
+ #### 11. 验收标准(UI视觉 + 交互行为逐条可测!)
190
+ - 视觉验收
191
+ - 状态验收
192
+ - 交互验收
193
+ - 异常验收
194
+ - 平台适配验收
195
+
196
+ ---
197
+
198
+ ## 第三部分:完整工作流程
199
+
200
+ ### 项目从零启动(需求→UI→实现)
201
+ ```
202
+ 1. 用 sdd 技能:拆 Epic→Feature→Story,写验收标准,做估算
203
+ 2. 用 ui-sdd 的「App全域全景骨架」:梳理完整结构,建目录
204
+ 3. 用 ui-sdd 的「标准模板」:逐个页面写SDD
205
+ 4. 交付开发(或用 sdd-add 做快速实现)
206
+ ```
207
+
208
+ ### 正常迭代开发(日常新功能)
209
+ ```
210
+ 1. 用 sdd:把新功能拆成 Story,写验收标准
211
+ 2. 用 ui-sdd:回「全景骨架」补勾,补建/更新SDD
212
+ 3. 用 sdd-add:做快速实现,需求文档必须引用 sdd 的 Story 和 ui-sdd 的 SDD
213
+ ```
214
+
215
+ ### 临时需求/紧急修复
216
+ ```
217
+ 1. 直接用 sdd-add:快速澄清、优先级、实现
218
+ 2. 如果涉及UI/新增页面:必须同步回 ui-sdd 补勾、补建SDD
219
+ 3. 如果涉及Story拆分:必须同步回 sdd 补Story
220
+ ```
221
+
222
+ ---
223
+
224
+ ## 第四部分:文档关联引用规范
225
+
226
+ ### sdd Story 中引用 ui-sdd
227
+ 在 sdd 产出的 Story 文档中加入:
228
+ ```markdown
229
+ ## 关联文档
230
+ - 对应UI交互SDD:spec/ui/pages/xxx-page.sdd.md
231
+ - 复用组件SDD:spec/ui/common/ui-yyy.sdd.md
232
+ - 相关弹窗SDD:spec/ui/dialog/zzz-dialog.sdd.md
233
+ ```
234
+
235
+ ### ui-sdd SDD 中引用 sdd Story
236
+ 在 ui-sdd 产出的页面/组件SDD中加入:
237
+ ```markdown
238
+ ## 关联用户故事
239
+ - 主故事:US-001(在 docs/stories/user_stories.md)
240
+ - 相关故事:US-002、US-003
241
+ ```
242
+
243
+ ### sdd-add 临时需求中引用前两者
244
+ 在 sdd-add 产出的临时需求文档中加入:
245
+ ```markdown
246
+ ## 关联文档
247
+ - 关联Story:docs/stories/user_stories.md 中的 US-xxx
248
+ - 关联UI-SDD:spec/ui/pages/yyy-page.sdd.md
249
+ ```
250
+
251
+ ---
252
+
253
+ ## 第五部分:一句话原则
254
+
255
+ **「sdd 定方向(做什么),ui-sdd 定样子(怎么做),sdd-add 填细节(快速补);从上往下拆,从下往上补,互相引用不遗漏」**
256
+
257
+ ---
258
+
259
+ ## 附录:快速检查表
260
+
261
+ ### 「App全域全景骨架」完成检查
262
+ - [ ] 第1步:模拟用户走完全程
263
+ - [ ] 第2步:所见全部罗列(页面/弹窗/组件)
264
+ - [ ] 第3步:分成三大类(pages/dialog/common)
265
+ - [ ] 第4步:补上全局隐性规则
266
+ - [ ] 第5步:整理成树形结构
267
+
268
+ ### 单个UI-SDD文档完成检查
269
+ - [ ] 基础信息完整
270
+ - [ ] 页面结构清晰
271
+ - [ ] 所有状态定义(至少7种)
272
+ - [ ] 组件清单及静态UI
273
+ - [ ] 交互逻辑详细(包括防抖、点击反馈)
274
+ - [ ] 平台适配规则
275
+ - [ ] 验收标准明确(逐条可测)
276
+
277
+ ---
278
+
279
+ ## 最佳实践总结
280
+
281
+ 1. **骨架先行**:先画App全域全景骨架,再写单个SDD
282
+ 2. **状态优先**:定义所有状态,再写组件和交互
283
+ 3. **交互细化**:每个交互都要考虑边缘情况(防抖、反馈等)
284
+ 4. **平台适配**:明确列出各平台的差异
285
+ 5. **验收标准**:每条标准都要可测试
286
+ 6. **互相引用**:sdd、ui-sdd、sdd-add 三者文档互相关联
287
+
288
+ ---
289
+
290
+ *文档版本:v1.0 | 最后更新:2026-05-04*