adspecs 0.1.20 → 0.1.21
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/.adspecs/templates/04-/345/211/215/347/253/257/345/212/237/350/203/275/350/256/276/350/256/241/346/250/241/346/235/277.md +1 -1
- package/.adspecs/templates/05-/345/220/216/347/253/257/344/273/273/345/212/241/346/270/205/345/215/225/346/250/241/346/235/277.md +613 -724
- package/.adspecs/templates/05b-/345/211/215/347/253/257/344/273/273/345/212/241/346/270/205/345/215/225/346/250/241/346/235/277.md +51 -51
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.qoder-plugin/plugin.json +1 -1
- package/INSTALL.md +3 -3
- package/package.json +1 -1
- package/skills/adspecs-front-spec/SKILL.md +4 -4
- package/skills/adspecs-front-tasks/SKILL.md +213 -173
- package/skills/project-init/SKILL.md +93 -22
- package/src/commands/init.js +1 -1
- package/src/lib/dir-utils.js +28 -0
- package/src/lib/prompts.js +86 -5
- package/src/lib/report.js +20 -9
- package/src/lib/scaffolder.js +42 -9
|
@@ -1,724 +1,613 @@
|
|
|
1
|
-
---
|
|
2
|
-
|
|
3
|
-
description: "ECP
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
### 修订记录
|
|
7
|
-
|
|
8
|
-
| 版本号 | 修订日期 | 修订人 | 修订内容 |
|
|
9
|
-
| ------ | -------- | ------ | -------- |
|
|
10
|
-
|
|
|
11
|
-
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
| `
|
|
41
|
-
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
-
|
|
48
|
-
|
|
49
|
-
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
|
118
|
-
|
|
|
119
|
-
|
|
|
120
|
-
|
|
|
121
|
-
|
|
|
122
|
-
|
|
|
123
|
-
|
|
|
124
|
-
|
|
|
125
|
-
|
|
|
126
|
-
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
-
|
|
237
|
-
|
|
238
|
-
-
|
|
239
|
-
-
|
|
240
|
-
-
|
|
241
|
-
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
- [ ]
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
- [ ]
|
|
290
|
-
|
|
291
|
-
- [ ]
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
- [ ]
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
- [ ]
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
-
|
|
347
|
-
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
-
|
|
353
|
-
|
|
354
|
-
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
- [ ]
|
|
376
|
-
- [ ]
|
|
377
|
-
|
|
378
|
-
### 用户故事
|
|
379
|
-
|
|
380
|
-
- [ ]
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
- [ ]
|
|
406
|
-
- [ ]
|
|
407
|
-
- [ ]
|
|
408
|
-
|
|
409
|
-
###
|
|
410
|
-
|
|
411
|
-
- [ ]
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
-
|
|
534
|
-
-
|
|
535
|
-
-
|
|
536
|
-
-
|
|
537
|
-
-
|
|
538
|
-
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
[
|
|
544
|
-
|
|
545
|
-
[
|
|
546
|
-
|
|
547
|
-
[
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
#
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
## 实现策略
|
|
615
|
-
|
|
616
|
-
### MVP 优先(P1 用户故事:US-01 + US-02 + US-09 + US-04 + US-03 + US-05)
|
|
617
|
-
|
|
618
|
-
1. Phase 1:Maven 三模块环境搭建
|
|
619
|
-
2. Phase 2:基础设施(枚举 + Liquibase + 消息码 + 配置)**← 关键阻塞点**
|
|
620
|
-
3. Phase 3:US-01 创建并提报预测单 **← MVP 核心**
|
|
621
|
-
4. Phase 4:US-02 计划部门评审(并行追加)
|
|
622
|
-
5. Phase 5:US-09+US-08 撤回/取消/删除(并行追加)
|
|
623
|
-
6. Phase 6:US-04 转履约单(FO)(并行追加)
|
|
624
|
-
7. Phase 7:US-03 APS 排产反馈(并行追加)
|
|
625
|
-
8. Phase 8:US-05 变更单修改预测单(并行追加)
|
|
626
|
-
9. **STOP & VALIDATE**:全部 P1 故事端到端测试通过
|
|
627
|
-
10. P1 MVP 就绪 → 部署/演示
|
|
628
|
-
|
|
629
|
-
### 增量交付
|
|
630
|
-
|
|
631
|
-
1. Phase 1+2 → 基础就绪
|
|
632
|
-
2. Phase 3 → US-01 可独立测试 → 部署(MVP 最小可交付!)
|
|
633
|
-
3. Phase 4+5+6+7+8 → 逐个追加 P1 故事 → 每个故事独立测试 → 增量部署
|
|
634
|
-
4. Phase 9+10 → P2 故事追加
|
|
635
|
-
5. Final Phase → 集成收尾
|
|
636
|
-
|
|
637
|
-
### 团队并行策略
|
|
638
|
-
|
|
639
|
-
1. 团队共同完成 Phase 1+2(环境搭建 + 基础设施)
|
|
640
|
-
2. Phase 2 完成后:
|
|
641
|
-
- **开发者 A**:Phase 3(US-01 创建提报)**← 最高优先级,产出核心 Entity**
|
|
642
|
-
- **开发者 B**:Phase 2 的 Liquibase + 配置类
|
|
643
|
-
3. US-01 Entity 完成后:
|
|
644
|
-
- **开发者 A**:Phase 8(US-05 变更单,子表工作量大)
|
|
645
|
-
- **开发者 B**:Phase 4+5+6+7(US-02/09/04/03,同一主表 Service 的不同方法)
|
|
646
|
-
4. P1 全部完成 → 开发者 A+B 共同完成 Phase 9+10(P2 故事)+ Final Phase
|
|
647
|
-
|
|
648
|
-
---
|
|
649
|
-
|
|
650
|
-
## ECP 编码规范检查清单
|
|
651
|
-
|
|
652
|
-
> 生成 tasks.md 时必须逐条确认。此清单与 `adspecs-tasks` skill §ECP 平台编码规范完全对齐。
|
|
653
|
-
|
|
654
|
-
| # | 规范 | 检查项 | 通过 |
|
|
655
|
-
|---|------|--------|------|
|
|
656
|
-
| 1 | **Entity** | `extends BaseEntity<Entity>`, `@TableName(``table``)`, 所有字段 `@TableField` + `@Schema`, `IdType.ASSIGN_ID`,审计字段继承不重复 | ☐ |
|
|
657
|
-
| 2 | **DTO** | `extends ReqeustCommonDataBean`(注意拼写),校验分组内部接口(`save/update`),`@JSONField(format)`,消息码格式 `{port}_{table}_{三位序号}` | ☐ |
|
|
658
|
-
| 3 | **DAO** | `extends BaseCommonDAO_HI<Entity>`, `@Component("xxxDAO")`,XML 同包,`resultMap` 含全字段+审计,所有 SELECT 含 `WHERE delete_flag = 0` | ☐ |
|
|
659
|
-
| 4 | **禁止 QueryWrapper** | 所有 DB 操作通过 MyBatis XML,任务描述中无 QueryWrapper/LambdaQueryWrapper 字样 | ☐ |
|
|
660
|
-
| 5 | **Service** | 接口 `II{Entity}` extends `IBaseCommon<Entity>`,实现 `@Component("xxxService")` extends `BaseCommonServer<Entity>`, Save→FastJSON, Update→SpringBeanUtils | ☐ |
|
|
661
|
-
| 6 | **Controller** | `extends CommonAbstractService`,重写 `getBaseCommonServer()`,`@CheckToken`, `ResponseData<T>` 包装 | ☐ |
|
|
662
|
-
| 7 | **Ro** | `implements Serializable` + `serialVersionUID`,手动字段,`@DateTimeFormat @JsonFormat`,置于 `model/entity/readonly/` | ☐ |
|
|
663
|
-
| 8 | **异常** | 异常在 Service 层抛出,Controller 仅参数空校验,消息码枚举禁止硬编码 | ☐ |
|
|
664
|
-
| 9 | **i18n** | 7 个 `.properties`(default/zh_CN/zh_TW/en_US/vi_VN/th_TH/hu_HU),每个含该语言实际内容 | ☐ |
|
|
665
|
-
| 10 | **注入与工具** | `@Autowired` 注入,FastJSON 序列化,Hutool 优先,SLF4J 日志 | ☐ |
|
|
666
|
-
|
|
667
|
-
---
|
|
668
|
-
|
|
669
|
-
## TDD 执行指南
|
|
670
|
-
|
|
671
|
-
> 本模板任务顺序与 `test-driven-development` skill 的 RED→GREEN→REFACTOR 循环完全对齐。
|
|
672
|
-
|
|
673
|
-
### RED 阶段:编写测试并验证失败
|
|
674
|
-
|
|
675
|
-
```bash
|
|
676
|
-
# 1. 按 [TDD] 标记的任务编写测试代码
|
|
677
|
-
# 2. 运行并确认失败
|
|
678
|
-
mvn test -Dtest=ForecastOrderServiceTest
|
|
679
|
-
|
|
680
|
-
# 预期输出:Tests run: 5, Failures: 5(功能未实现,预期失败)
|
|
681
|
-
# 如果测试通过 → 测试缺陷,修测试
|
|
682
|
-
# 如果测试报错(非失败) → 编译错误/依赖缺失,修环境
|
|
683
|
-
```
|
|
684
|
-
|
|
685
|
-
### GREEN 阶段:最小代码使测试通过
|
|
686
|
-
|
|
687
|
-
```
|
|
688
|
-
按 TDD 任务之后的实现任务顺序:
|
|
689
|
-
Entity → DTO → Ro → DAO+XML → Service → Controller → Feign Client
|
|
690
|
-
|
|
691
|
-
每完成一个实现任务:
|
|
692
|
-
mvn test -Dtest=ForecastOrderServiceTest # 逐步变绿
|
|
693
|
-
|
|
694
|
-
Service 实现完成后 → 全部测试应变绿 ✅
|
|
695
|
-
```
|
|
696
|
-
|
|
697
|
-
### REFACTOR 阶段:清理与优化
|
|
698
|
-
|
|
699
|
-
```bash
|
|
700
|
-
# 所有测试通过后:
|
|
701
|
-
- 提取重复的校验逻辑到工具类
|
|
702
|
-
- 优化命名(方法名/变量名与业务一致)
|
|
703
|
-
- 添加日志注解(关键操作 @Slf4j)
|
|
704
|
-
- 运行全量测试确认不破坏
|
|
705
|
-
mvn test # 必须全绿
|
|
706
|
-
```
|
|
707
|
-
|
|
708
|
-
---
|
|
709
|
-
|
|
710
|
-
## 注意事项
|
|
711
|
-
|
|
712
|
-
- `[P]` 任务 = 操作不同文件,无未完成依赖,可并行执行
|
|
713
|
-
- `[TDD]` 任务 = 测试任务,**必须在同故事的实现任务之前编写并通过失败验证**
|
|
714
|
-
- `[Story]` 标签将任务映射到设计文档 §1.1.1 中的具体用户故事,支持全链路追溯
|
|
715
|
-
- **所有文件路径必须精确到三模块**(`{port}-{service}-api/model/application/`)
|
|
716
|
-
- **ECP 编码规范 10 条是硬性约束**,违反任一条 = 任务不合格
|
|
717
|
-
- **Save 用 FastJSON**:`JSONObject.parseObject(JSONObject.toJSONString(dto), Entity.class)`
|
|
718
|
-
- **Update 用 Spring BeanUtils**:`BeanUtils.copyProperties(dto, entity, "createdBy", "creationDate", "versionNum")`
|
|
719
|
-
- **WHERE delete_flag = 0**:所有 MyBatis XML SELECT 语句必须包含
|
|
720
|
-
- **消息码禁止硬编码**:所有异常和校验信息引用 `ResponseMsgCode` 枚举
|
|
721
|
-
- **异常在 Service 层抛出**:Controller 仅做参数空校验返回 `ResponseData.fail()`
|
|
722
|
-
- 每个任务或逻辑分组后建议 git commit
|
|
723
|
-
- 可在任何检查点停下验证故事的独立可用性
|
|
724
|
-
- 避免:模糊任务、同文件冲突、跨故事强耦合、违反 TDD 顺序(实现先于测试)
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
description: "后端功能实现的 TDD 任务列表模板。支持 ECP Java / Yudao Java / Python 技术栈自动检测"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
### 修订记录
|
|
7
|
+
|
|
8
|
+
| 版本号 | 修订日期 | 修订人 | 修订内容 |
|
|
9
|
+
| ------ | -------- | ------ | -------- |
|
|
10
|
+
| v3.0 | 2026-07-28 | AI | 技术栈解耦改造:去掉 M06-01 销售预测单具体类名,抽象为纯结构模板;新增三栈检测(ECP Java / Yudao Java / Python)+ 三栈映射表;编码规范检查清单拆分为栈无关项 + 栈专属项;Phase 任务示例全部使用 `{Entity}`/`{Service}`/`{Controller}` 等占位符 |
|
|
11
|
+
| v2.0 | 2026-06-13 | AI | ECP 平台专项改造:通用 Python 模板 → ECP Java Maven 三模块 TDD 模板 |
|
|
12
|
+
| v1.0 | 2026-06-12 | AI | 初始版本:通用 spec-kit 任务模板(Python 示例) |
|
|
13
|
+
|
|
14
|
+
# 任务清单:[功能名称]
|
|
15
|
+
|
|
16
|
+
**设计文档来源**:
|
|
17
|
+
- 系统设计文档:`docs/30-system-design/{module}/[功能名]_system-design.md`(必读,由 `adspecs-plan` 产出,包含 OOA+OOD 13 章节统一设计)
|
|
18
|
+
- PRD 文档:`docs/20-prd/{module}/[模块]/[需求规格说明书].md`(可选,用户故事验收场景参考)
|
|
19
|
+
- 建表 SQL:`docs/30-system-design/{module}/[功能名]_schema.sql`(可选,DDL 直接可用)
|
|
20
|
+
|
|
21
|
+
**前置条件**:
|
|
22
|
+
- 调用 `/adspecs-tasks` 前,必须已完成 `/adspecs-plan` 产出的 `_system-design.md`
|
|
23
|
+
- 系统设计文档必须包含:§1 需求映射、§2 实体+DTO/Ro、§3 数据模型、§4 Service 设计、§5 Controller 端点、§6 枚举+校验、§7 异常+消息码、§13 代码结构
|
|
24
|
+
|
|
25
|
+
**TDD 约定**:本模板遵循 `test-driven-development` skill 的"测试先行"原则——所有实现任务之前必须先有失败的测试任务。模板中的样本任务包含 `[TDD]` 标记的测试任务。
|
|
26
|
+
|
|
27
|
+
**组织方式**:任务按用户故事分组(设计文档 §1.1.1),以支持每个故事的独立 TDD 实现和独立测试。
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 技术栈检测(任务生成前置)
|
|
32
|
+
|
|
33
|
+
> **目的**:确定本项目的后端技术栈,后续所有术语、路径、示例均按检测到的栈展开。
|
|
34
|
+
> **输出变量**:`BACKEND_STACK`(`ecp-java` | `yudao-java` | `python`)和 `BACKEND_SERVICE_DIR`(后端服务根目录名,默认 `service/`)。
|
|
35
|
+
|
|
36
|
+
按以下优先级依次尝试,命中任意一级即停止:
|
|
37
|
+
|
|
38
|
+
| 优先级 | 检测源 | 判定规则 |
|
|
39
|
+
| ------ | ------ | -------- |
|
|
40
|
+
| 1 | `.adspecs/project.json` | 读取 `backend_stack` 字段(`ecp-java` / `yudao-java` / `python`)。`/project-init` 在初始化时写入 |
|
|
41
|
+
| 2 | 项目根 `CLAUDE.md` §Backend | 关键字命中:含 `ECP`/`com.sie.gushen`/`BaseCommonServer` → `ecp-java`;含 `Yudao`/`yudao-cloud`/`BaseMapperX` → `yudao-java`;含 `FastAPI`/`SQLAlchemy`/`Celery` → `python` |
|
|
42
|
+
| 3 | 系统设计文档 `_system-design.md` §技术栈 | 文档中声明的框架 |
|
|
43
|
+
| 4 | 项目目录结构启发式 | `pom.xml` + `com/sie/gushen` → `ecp-java`;`pom.xml` + `com/yudaocloud` 或 `com/sie/yudao` → `yudao-java`;`pyproject.toml` 或 `requirements.txt` → `python` |
|
|
44
|
+
| 5 | 回退:询问用户 | 使用 AskUserQuestion 让用户选择 `ECP Java` / `Yudao Java` / `Python` |
|
|
45
|
+
|
|
46
|
+
**`BACKEND_SERVICE_DIR` 检测**:
|
|
47
|
+
- 优先从 `.adspecs/project.json` 的 `backend_dir` 字段读取
|
|
48
|
+
- 其次从 `CLAUDE.md` §Backend 中提取后端服务根目录名
|
|
49
|
+
- 默认值:`service/`
|
|
50
|
+
|
|
51
|
+
检测完成后,在内部记录两个变量,后续章节按此展开:
|
|
52
|
+
```
|
|
53
|
+
BACKEND_STACK = ecp-java | yudao-java | python
|
|
54
|
+
BACKEND_SERVICE_DIR = {后端服务根目录名}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 任务格式:`- [ ] [TaskID] [P?] [TDD?] [Story?] 描述 + 精确文件路径`
|
|
60
|
+
|
|
61
|
+
**格式组成**:
|
|
62
|
+
|
|
63
|
+
| 元素 | 说明 |
|
|
64
|
+
|------|------|
|
|
65
|
+
| `- [ ]` | Markdown 复选框(始终存在) |
|
|
66
|
+
| `[TaskID]` | 全局递增序号:T001, T002, T003... |
|
|
67
|
+
| `[P]` | 可并行执行标记(操作不同文件,无未完成依赖) |
|
|
68
|
+
| `[TDD]` | 测试任务标记(Service 层单元测试 / Controller 层集成测试),**必须在同故事实现任务之前完成且验证失败** |
|
|
69
|
+
| `[Story]` | 用户故事标签:[US1], [US2]...(对应设计文档 §1.1.1)。Phase 1/2/Final 无此标签 |
|
|
70
|
+
| 描述 + 文件路径 | 明确操作描述 + 从服务根目录开始的完整文件路径。多文件任务可分行列出路径 |
|
|
71
|
+
|
|
72
|
+
**格式示例(按 `BACKEND_STACK` 展开)**:
|
|
73
|
+
|
|
74
|
+
*ECP Java 栈示例*:
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
- [ ] T012 [TDD] [US1] 编写 {Service} 提交{Entity} 单元测试(正常+拦截+边界),测试文件:
|
|
78
|
+
{BACKEND_SERVICE_DIR}/{port}-{service}-application/src/test/java/{PACKAGE_PATH}/model/service/impl/{Entity}ServiceTest.java
|
|
79
|
+
- [ ] T013 [US1] 创建 {Entity}(extends BaseEntity<{Entity}>, @TableName(`{table}`), @TableId(type=ASSIGN_ID), N+ 字段全带 @TableField+@Schema),文件:
|
|
80
|
+
{BACKEND_SERVICE_DIR}/{port}-{service}-model/src/main/java/{PACKAGE_PATH}/model/entity/{Entity}Entity.java
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
*Yudao Java 栈示例*:
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
- [ ] T012 [TDD] [US1] 编写 {Service} 单元测试(正常+异常+边界),测试文件:
|
|
87
|
+
{BACKEND_SERVICE_DIR}/{module}-service/src/test/java/{PACKAGE_PATH}/service/{Entity}ServiceTest.java
|
|
88
|
+
- [ ] T013 [US1] 创建 {Entity}(extends BaseDO, @TableName(`{table}`), N+ 字段全带 @TableField+@Schema),文件:
|
|
89
|
+
{BACKEND_SERVICE_DIR}/{module}-service/src/main/java/{PACKAGE_PATH}/dal/dataobject/{Entity}DO.java
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
*Python 栈示例*:
|
|
93
|
+
|
|
94
|
+
```text
|
|
95
|
+
- [ ] T012 [TDD] [US1] 编写 {service} 服务层单元测试(正常+异常+边界),测试文件:
|
|
96
|
+
{BACKEND_SERVICE_DIR}/tests/test_{service}.py
|
|
97
|
+
- [ ] T013 [US1] 创建 {Entity}Model(SQLAlchemy ORM,Column 定义 N+ 字段),文件:
|
|
98
|
+
{BACKEND_SERVICE_DIR}/app/models/{service}.py
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**错误示例**:
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
- ❌ 错误:`- [ ] 创建 {Entity} 实体`(缺少 TaskID + 文件路径 + Story 标签)
|
|
105
|
+
- ❌ 错误:`T001 [US1] 创建 Entity`(缺少复选框 + 精确文件路径)
|
|
106
|
+
- ❌ 错误:`- [ ] T001 [US1] 创建 Entity`(缺少文件路径)
|
|
107
|
+
- ❌ 错误:`- [ ] T010 [US1] 实现提交方法`(故事阶段内未先写 [TDD] 测试,违反 TDD 规则)
|
|
108
|
+
- ❌ 错误:`- [ ] T020 [TDD] [US1] 测试提交`(描述模糊,文件路径缺失)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 后端技术栈映射表
|
|
114
|
+
|
|
115
|
+
> 根据 §技术栈检测 得到的 `BACKEND_STACK` 选择对应列。所有 Phase 任务中的占位符均按此表展开。
|
|
116
|
+
|
|
117
|
+
| 概念 | ECP Java (`ecp-java`) | Yudao Java (`yudao-java`) | Python (`python`) |
|
|
118
|
+
| ---- | --------------------- | ------------------------- | ----------------- |
|
|
119
|
+
| 框架 | Spring Boot + ECP 平台扩展 | Spring Boot + Yudao Cloud | FastAPI + SQLAlchemy |
|
|
120
|
+
| 模块结构 | Maven 三模块(`-api`/`-model`/`-application`) | 单模块 / 多模块(`-service` 主模块) | 单包(`app/` + `tests/`) |
|
|
121
|
+
| 实体 | `extends BaseEntity<T>` + `@TableName` + `@TableField` + `@Schema`,`IdType.ASSIGN_ID` | `extends BaseDO` + `@TableName` + `@TableField` + `@Schema` | `class {Entity}Model(Base)` + SQLAlchemy Column |
|
|
122
|
+
| DTO | `extends ReqeustCommonDataBean`,校验分组内部接口,`@JSONField(format)` | `implements Serializable` + `@Schema` + JSR-303 注解 | Pydantic `BaseModel` + Field 校验 |
|
|
123
|
+
| Ro/VO | `implements Serializable` + `serialVersionUID`,手动字段,置于 `model/entity/readonly/` | `extends BaseConvert` 转 VO 对象 | Pydantic Response Schema |
|
|
124
|
+
| DAO/Repository | `extends BaseCommonDAO_HI<T>` + MyBatis XML 同包,`@Component("xxxDAO")` | `extends BaseMapperX<T>` + MyBatis-Plus `@Mapper` | SQLAlchemy `session.query` / async session |
|
|
125
|
+
| Service 接口 | `II{Entity}` extends `IBaseCommon<T>`(双 I 前缀) | 直接 Java 接口定义 | `Protocol` 或 `ABC` 抽象类 |
|
|
126
|
+
| Service 实现 | `extends BaseCommonServer<T>` + `@Component("xxxService")`,Save→FastJSON,Update→SpringBeanUtils | `@Service` + `BaseServiceImpl` 或 POJO | 函数 + `Depends` 或 class |
|
|
127
|
+
| Controller | `extends CommonAbstractService` + `@CheckToken` + `ResponseData<T>` 包装 | `@RestController` + `@Tag` + `@PreAuthorize` + `CommonResult<T>` | `@router` + `Depends` 权限 |
|
|
128
|
+
| Feign/RPC Client | `@FeignClient` 接口,放入 `-api/client/` | `@FeignClient` 接口 | `httpx.AsyncClient` 封装 |
|
|
129
|
+
| 枚举 | 普通 `enum`,存储值 `String` | `@Getter` + `@AllArgsConstructor` enum | Python `Enum` / `StrEnum` |
|
|
130
|
+
| 消息码/异常 | `enum ResponseMsgCode`,格式 `{port}_{table}_{三位序号}` | `ErrorCodeEnum` + `ServiceException` | 自定义 Exception + error_code |
|
|
131
|
+
| 消息消费 | Kafka `Consumer<String>` Bean,Bean name 匹配 YAML | RocketMQ `@RocketMQMessageListener` | Celery `@app.task` |
|
|
132
|
+
| i18n | 7 个 `.properties`(default/zh_CN/zh_TW/en_US/vi_VN/th_TH/hu_HU) | `messages_{locale}.properties` | `.po` / `.json` 文件 |
|
|
133
|
+
| DB 迁移 | Liquibase(master.xml → version.xml → DDL.sql) | Flyway(`V{version}__{name}.sql`) | Alembic(`env.py` + migration scripts) |
|
|
134
|
+
| 工具类 | Hutool + SLF4J | Hutool / Spring 工具类 | Python 标准库 + loguru |
|
|
135
|
+
| 配置类 | `@Configuration`(DataSource / MybatisPlus / SpringDoc) | `@Configuration` + `@ConfigurationProperties` | Pydantic Settings |
|
|
136
|
+
| 启动类 | `extends CommonApplication` + `@SpringBootApplication` + `@EnableDiscoveryClient` + `@EnableFeignClients` + `@MapperScan` | `@SpringBootApplication` + `@MapperScan` | `uvicorn` 入口 |
|
|
137
|
+
| 测试框架 | JUnit 5 + Mockito + `@SpringBootTest` | JUnit 5 + Mockito + `@SpringBootTest` | pytest + pytest-asyncio |
|
|
138
|
+
| 包路径 | `com.sie.gushen.{service}` | `com.yudaocloud.{module}` 或项目自定义 | Python 模块(`app.{module}`) |
|
|
139
|
+
| 参考规范 | `references/ecp-end-standard/` | `references/yudaocloud-end-standard/` | `references/python-end-standard/` |
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 后端项目路径约定
|
|
144
|
+
|
|
145
|
+
> 来源:CLAUDE.md §Backend + 系统设计文档 §13 代码结构。下方目录树按 `BACKEND_STACK` 展开。
|
|
146
|
+
|
|
147
|
+
### ECP Java 三模块路径
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
{BACKEND_SERVICE_DIR}/{port}-{service}/ # 服务根目录
|
|
151
|
+
├── {port}-{service}-api/ # 契约层
|
|
152
|
+
│ └── src/main/java/{PACKAGE_PATH}/api/
|
|
153
|
+
│ ├── client/ # @FeignClient 接口
|
|
154
|
+
│ └── dto/ # DTO
|
|
155
|
+
├── {port}-{service}-model/ # 数据层
|
|
156
|
+
│ ├── src/main/java/{PACKAGE_PATH}/model/
|
|
157
|
+
│ │ ├── entity/ # Entity
|
|
158
|
+
│ │ │ └── readonly/ # Ro
|
|
159
|
+
│ │ └── dao/ # DAO 接口 + MyBatis XML 同包
|
|
160
|
+
│ └── src/main/resources/liquibase/mysql/{service}/ # Liquibase
|
|
161
|
+
└── {port}-{service}-application/ # 实现层
|
|
162
|
+
├── src/main/java/{PACKAGE_PATH}/
|
|
163
|
+
│ ├── {Service}Application.java # 启动类
|
|
164
|
+
│ ├── api/controller/ # Controller
|
|
165
|
+
│ ├── model/service/ # Service 接口 + 实现
|
|
166
|
+
│ ├── app/consume/ # Kafka Consumer
|
|
167
|
+
│ └── infra/ # 配置/常量/枚举/工具
|
|
168
|
+
└── src/main/resources/config/ # i18n .properties
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Yudao Java 路径
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
{BACKEND_SERVICE_DIR}/{module}-{service}/ # 服务根目录
|
|
175
|
+
├── {module}-service/ # 主模块
|
|
176
|
+
│ └── src/main/java/{PACKAGE_PATH}/
|
|
177
|
+
│ ├── controller/admin/ # Controller
|
|
178
|
+
│ ├── controller/app/ # App 端 Controller
|
|
179
|
+
│ ├── dal/ # 数据层
|
|
180
|
+
│ │ ├── dataobject/ # DO(extends BaseDO)
|
|
181
|
+
│ │ ├── mysql/ # Mapper(extends BaseMapperX)
|
|
182
|
+
│ │ └── redis/ # Redis
|
|
183
|
+
│ ├── service/ # Service 层
|
|
184
|
+
│ ├── convert/ # VO ↔ DO 转换
|
|
185
|
+
│ ├── controller/admin/vo/ # VO 对象
|
|
186
|
+
│ ├── framework/ # 模块配置
|
|
187
|
+
│ └── enums/ # 枚举 + ErrorCode
|
|
188
|
+
└── {module}-api/ # API 模块(可选)
|
|
189
|
+
└── src/main/java/{PACKAGE_PATH}/api/
|
|
190
|
+
├── enums/ # API 枚举
|
|
191
|
+
└── dto/ # API DTO
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Python 路径
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
{BACKEND_SERVICE_DIR}/ # 服务根目录
|
|
198
|
+
├── app/ # 应用主包
|
|
199
|
+
│ ├── {module}/ # 业务模块
|
|
200
|
+
│ │ ├── router.py # FastAPI 路由
|
|
201
|
+
│ │ ├── service.py # 服务层
|
|
202
|
+
│ │ ├── schemas.py # Pydantic DTO/Schema
|
|
203
|
+
│ │ ├── dependencies.py # Depends 注入
|
|
204
|
+
│ │ └── crud.py # CRUD 封装
|
|
205
|
+
│ ├── models/ # SQLAlchemy Model
|
|
206
|
+
│ │ └── {module}.py
|
|
207
|
+
│ ├── core/ # 核心配置
|
|
208
|
+
│ │ ├── config.py # Pydantic Settings
|
|
209
|
+
│ │ ├── security.py # 权限/Token
|
|
210
|
+
│ │ └── exceptions.py # 自定义异常
|
|
211
|
+
│ ├── db/ # 数据库
|
|
212
|
+
│ │ ├── session.py # Session 工厂
|
|
213
|
+
│ │ └── migrations/ # Alembic 迁移
|
|
214
|
+
│ ├── tasks/ # Celery 异步任务
|
|
215
|
+
│ │ └── {module}.py
|
|
216
|
+
│ └── utils/ # 工具函数
|
|
217
|
+
├── tests/ # 测试
|
|
218
|
+
│ └── test_{module}.py
|
|
219
|
+
└── pyproject.toml # 依赖配置
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**变量替换**:
|
|
223
|
+
- `{port}`:微服务端口号(仅 Java 栈),如 `3103`
|
|
224
|
+
- `{service}`/`{module}`:服务/模块名(kebab-case),如 `sales-forecast`
|
|
225
|
+
- `{PACKAGE_PATH}`:Java 包路径(`.` 分隔),Python 栈无此项
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
<!--
|
|
230
|
+
============================================================================
|
|
231
|
+
重要提示:以下任务是**模板结构示例**,使用占位符 `{Entity}`/`{Service}`/`{Controller}` 等。
|
|
232
|
+
|
|
233
|
+
/adspecs-tasks 命令将根据系统设计文档替换为实际任务:
|
|
234
|
+
- 系统设计文档 §1.1.1 中的用户故事(及其优先级 P1、P2...)
|
|
235
|
+
- 系统设计文档 §2 中的实体/DTO/Ro 清单
|
|
236
|
+
- 系统设计文档 §3 中的数据模型
|
|
237
|
+
- 系统设计文档 §4 中的 Service 方法与业务行为
|
|
238
|
+
- 系统设计文档 §5 中的 Controller 端点
|
|
239
|
+
- 系统设计文档 §6 中的枚举定义
|
|
240
|
+
- 系统设计文档 §7 中的异常与消息码
|
|
241
|
+
- 系统设计文档 §13 中的完整目录树
|
|
242
|
+
|
|
243
|
+
每个生成的任务必须:
|
|
244
|
+
- 包含精确的后端文件路径(按 BACKEND_STACK 展开)
|
|
245
|
+
- 遵循 TDD 测试先行顺序([TDD] 标记的任务在实现任务之前)
|
|
246
|
+
- 包含正确的栈特定父类/接口(见 §后端技术栈映射表)
|
|
247
|
+
- 通过 §编码规范检查清单 的校验
|
|
248
|
+
============================================================================
|
|
249
|
+
-->
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Phase 1:环境搭建(共享基础设施)
|
|
254
|
+
|
|
255
|
+
**目的**:项目初始化与基础结构搭建
|
|
256
|
+
|
|
257
|
+
- [ ] T001 创建项目主配置文件(Maven `pom.xml` / Python `pyproject.toml`),定义模块结构,文件:
|
|
258
|
+
`{BACKEND_SERVICE_DIR}/{port|module}-{service}/{CONFIG_FILE}`
|
|
259
|
+
- [ ] T002 [P] 创建契约/API 模块目录结构(DTO、Client 接口目录),文件:
|
|
260
|
+
`{STACK_SPECIFIC_API_MODULE_PATH}`
|
|
261
|
+
- [ ] T003 [P] 创建数据层模块目录结构(Entity/DO、DAO/Mapper、迁移脚本),文件:
|
|
262
|
+
`{STACK_SPECIFIC_DATA_MODULE_PATH}`
|
|
263
|
+
- [ ] T004 [P] 创建实现层模块目录结构(Controller、Service、Config、Consumer、i18n),文件:
|
|
264
|
+
`{STACK_SPECIFIC_APP_MODULE_PATH}`
|
|
265
|
+
- [ ] T005 创建启动类/入口文件(按 §后端技术栈映射表 的"启动类"行),文件:
|
|
266
|
+
`{STACK_SPECIFIC_APPLICATION_PATH}`
|
|
267
|
+
- [ ] T006 [P] 创建应用配置文件(`application.yml` / `.env` / `settings.py`:server.port、数据源、ORM 配置、消息队列等),文件:
|
|
268
|
+
`{STACK_SPECIFIC_CONFIG_PATH}`
|
|
269
|
+
|
|
270
|
+
**检查点**:项目结构就绪,`mvn clean compile` 或 `python -c "import app"` 可通过
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Phase 2:基础设施(阻塞性前置依赖)
|
|
275
|
+
|
|
276
|
+
**目的**:枚举、消息码、数据库迁移、基础配置等被所有用户故事依赖的底层构件
|
|
277
|
+
|
|
278
|
+
**⚠️ 关键**:在此阶段完成之前,不得开始任何用户故事的工作
|
|
279
|
+
|
|
280
|
+
### 2.1 枚举类(所有枚举可并行创建)
|
|
281
|
+
|
|
282
|
+
- [ ] T007 [P] 创建 `{Enum1}`(N 状态枚举),文件:
|
|
283
|
+
`{STACK_SPECIFIC_ENUM_PATH}/{Enum1}.java|py`
|
|
284
|
+
- [ ] T008 [P] 创建 `{Enum2}`(N 状态枚举),文件:同上目录
|
|
285
|
+
- [ ] ...(按设计文档 §6 枚举清单扩展)
|
|
286
|
+
|
|
287
|
+
### 2.2 消息码与配置
|
|
288
|
+
|
|
289
|
+
- [ ] T0xx 创建消息码/错误码常量类/枚举(字段校验 001~005 + 业务异常 006+),文件:
|
|
290
|
+
`{STACK_SPECIFIC_MSGCODE_PATH}`
|
|
291
|
+
- [ ] T0xx [P] 创建 ORM 配置类(分页插件 + 乐观锁插件),文件:
|
|
292
|
+
`{STACK_SPECIFIC_ORM_CONFIG_PATH}`
|
|
293
|
+
- [ ] T0xx [P] 创建数据源配置类,文件:
|
|
294
|
+
`{STACK_SPECIFIC_DS_CONFIG_PATH}`
|
|
295
|
+
- [ ] T0xx [P] 创建 API 文档配置类,文件:
|
|
296
|
+
`{STACK_SPECIFIC_APIDOC_CONFIG_PATH}`
|
|
297
|
+
- [ ] T0xx 创建工具类 `{Utils}`(业务相关通用计算),文件:
|
|
298
|
+
`{STACK_SPECIFIC_UTILS_PATH}`
|
|
299
|
+
|
|
300
|
+
### 2.3 数据库迁移
|
|
301
|
+
|
|
302
|
+
- [ ] T0xx 创建数据库迁移入口文件(Liquibase `master.xml` / Flyway 配置 / Alembic `env.py`)
|
|
303
|
+
- [ ] T0xx 创建版本变更日志文件
|
|
304
|
+
- [ ] T0xx 创建 DDL SQL(`{table1}` N+ 字段 + 索引 + `{table2}` N+ 字段 + 索引,含审计字段)
|
|
305
|
+
|
|
306
|
+
**检查点**:基础设施就绪——所有枚举可编译,DDL 可执行建表,现在可以并行开始用户故事的 TDD 实现
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## Phase 3:US-01 — 创建并提报{业务对象}(优先级:P1)🎯 MVP 起点
|
|
311
|
+
|
|
312
|
+
**目标**:{用户角色}能针对{业务场景}创建{业务对象},填写{核心字段},保存草稿或提交至{下一环节}评审
|
|
313
|
+
|
|
314
|
+
**独立测试**:登录{用户角色}账号 → 输入{核心字段} → 点击提交 → 验证{业务对象}进入"{目标状态}"且生成单号
|
|
315
|
+
|
|
316
|
+
**来源**:设计文档 §1.1.1 US-01, §4.1 行为 1-2, §5.1 端点 1-N, §12.1 TC1
|
|
317
|
+
|
|
318
|
+
### 用户故事 1 的 TDD 测试(先写,确保失败后再实现)
|
|
319
|
+
|
|
320
|
+
> ⚠️ **TDD 铁律**:在编写任何实现代码之前,先编写以下测试并验证它们**因功能缺失而失败**。
|
|
321
|
+
|
|
322
|
+
- [ ] T0xx [TDD] [US1] 编写 `{Service}` 提交{业务对象}测试(正常场景),测试文件:
|
|
323
|
+
`{STACK_SPECIFIC_SERVICE_TEST_PATH}`
|
|
324
|
+
- [ ] T0xx [TDD] [P] [US1] 编写 `{Service}` 提交{业务对象}异常测试(业务规则拦截),测试文件:同上
|
|
325
|
+
- [ ] T0xx [TDD] [P] [US1] 编写 `{Service}` 提交{业务对象}边界测试(边界条件),测试文件:同上
|
|
326
|
+
- [ ] T0xx [TDD] [P] [US1] 编写 `{Service}` 保存草稿测试(部分字段可空),测试文件:同上
|
|
327
|
+
- [ ] T0xx [TDD] [US1] 编写 `{Controller}` 保存/提交端点集成测试,测试文件:
|
|
328
|
+
`{STACK_SPECIFIC_CONTROLLER_TEST_PATH}`
|
|
329
|
+
|
|
330
|
+
### 用户故事 1 的实现(测试验证失败后开始)
|
|
331
|
+
|
|
332
|
+
- [ ] T0xx [US1] 创建 `{Entity}`({STACK_SPECIFIC_ENTITY_DEF},N+ 字段全带 {STACK_SPECIFIC_FIELD_ANNOTATIONS}),文件:
|
|
333
|
+
`{STACK_SPECIFIC_ENTITY_PATH}`
|
|
334
|
+
- [ ] T0xx [P] [US1] 创建 `{DTO}`({STACK_SPECIFIC_DTO_DEF},含 `save`/`update` 校验分组),文件:
|
|
335
|
+
`{STACK_SPECIFIC_DTO_PATH}`
|
|
336
|
+
- [ ] T0xx [P] [US1] 创建 `{Ro}`({STACK_SPECIFIC_RO_DEF},含所有 Entity 字段 + 审计字段 + 子表列表),文件:
|
|
337
|
+
`{STACK_SPECIFIC_RO_PATH}`
|
|
338
|
+
- [ ] T0xx [US1] 创建 `{DAO}` 接口 + 映射文件({STACK_SPECIFIC_DAO_DEF},含全字段+审计,分页查询含 `WHERE delete_flag=0` 或等效逻辑),文件:
|
|
339
|
+
`{STACK_SPECIFIC_DAO_PATH}`
|
|
340
|
+
- [ ] T0xx [US1] 创建 `{Service}` 接口({STACK_SPECIFIC_SERVICE_IFACE_DEF},定义 N 个方法签名),文件:
|
|
341
|
+
`{STACK_SPECIFIC_SERVICE_IFACE_PATH}`
|
|
342
|
+
- [ ] T0xx [US1] 实现 `{Service}`({STACK_SPECIFIC_SERVICE_IMPL_DEF}):
|
|
343
|
+
- `save(dto)`:DTO→Entity 转换,设置初始状态
|
|
344
|
+
- `update(dto)`:状态校验 → 属性拷贝(排除审计字段)
|
|
345
|
+
- `submit(id)`:业务规则校验 → 生成单号 → 状态→目标状态
|
|
346
|
+
- `findById(id)`:含子表组装 Ro
|
|
347
|
+
- `findPagination(dto, pageIndex, pageRows, orderByBean)`:分页查询
|
|
348
|
+
文件:`{STACK_SPECIFIC_SERVICE_IMPL_PATH}`
|
|
349
|
+
- [ ] T0xx [US1] 创建 `{Controller}`({STACK_SPECIFIC_CONTROLLER_DEF},N 个端点):
|
|
350
|
+
- `GET /get-id` → `service.findById(id)`
|
|
351
|
+
- `POST /find-pagination` → `service.findPagination(...)`
|
|
352
|
+
- `POST /save` → `service.save(dto)`
|
|
353
|
+
- `POST /update` → `service.update(dto)`
|
|
354
|
+
- `POST /submit` → `service.submit(id)`
|
|
355
|
+
文件:`{STACK_SPECIFIC_CONTROLLER_PATH}`
|
|
356
|
+
- [ ] T0xx [US1] 创建 `{Client}` Feign/RPC 接口({STACK_SPECIFIC_CLIENT_DEF},调用外部服务),文件:
|
|
357
|
+
`{STACK_SPECIFIC_CLIENT_PATH}`
|
|
358
|
+
|
|
359
|
+
**检查点**:[TDD] 所有测试由红变绿,用户故事 1 可独立运行:创建草稿 → 填写完整 → 提交 → 生成单号 → 状态=目标状态
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## Phase 4~N:后续用户故事(按设计文档 §1.1.1 扩展)
|
|
364
|
+
|
|
365
|
+
**通用结构**(每个用户故事阶段):
|
|
366
|
+
|
|
367
|
+
```
|
|
368
|
+
## Phase N:US-{XX} — {故事标题}(优先级:P{X})
|
|
369
|
+
|
|
370
|
+
**目标**:{用户角色}能{业务动作}
|
|
371
|
+
**独立测试**:{端到端验收场景}
|
|
372
|
+
**来源**:设计文档 §1.1.1 US-{XX}, §4.1 行为 X-Y, §5.1 端点 X-N, §12 TC-N
|
|
373
|
+
|
|
374
|
+
### 用户故事 X 的 TDD 测试
|
|
375
|
+
- [ ] T0xx [TDD] [USX] 编写 {Service} {业务动作}测试(正常+异常+边界),测试文件:同上
|
|
376
|
+
- [ ] T0xx [TDD] [USX] 编写 {Controller} 端点集成测试,测试文件:同上
|
|
377
|
+
|
|
378
|
+
### 用户故事 X 的实现
|
|
379
|
+
- [ ] T0xx [USX] 扩展/创建 {Service}:{方法签名 + 业务规则}
|
|
380
|
+
- [ ] T0xx [USX] 扩展/创建 {Controller}:{端点定义}
|
|
381
|
+
- [ ] T0xx [P] [USX] 创建 {DTO}/{Client}/{Consumer}(按需)
|
|
382
|
+
|
|
383
|
+
**检查点**:用户故事 X 功能正常,TDD 测试红→绿
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## Final Phase:集成与收尾
|
|
389
|
+
|
|
390
|
+
**目的**:跨故事的质量保证、国际化、文档与合规验证
|
|
391
|
+
|
|
392
|
+
### 集成测试
|
|
393
|
+
|
|
394
|
+
- [ ] T0xx [TDD] 编写端到端集成测试({核心业务流程}全流程),文件:
|
|
395
|
+
`{STACK_SPECIFIC_E2E_TEST_PATH}`
|
|
396
|
+
- [ ] T0xx [TDD] [P] 编写{子对象}审批联动端到端测试,文件:同上
|
|
397
|
+
|
|
398
|
+
### i18n 国际化
|
|
399
|
+
|
|
400
|
+
- [ ] T0xx [P] 创建 i18n 文件(按 §后端技术栈映射表 的"i18n"行配置所需语言文件),含所有消息码(字段校验 001~005 + 业务异常 006+),文件:
|
|
401
|
+
`{STACK_SPECIFIC_I18N_PATH}`
|
|
402
|
+
|
|
403
|
+
### 代码评审与安全
|
|
404
|
+
|
|
405
|
+
- [ ] T0xx 执行编码规范合规检查(对照 §编码规范检查清单,按 `BACKEND_STACK` 逐条确认)
|
|
406
|
+
- [ ] T0xx 安全清单验证(所有端点权限校验、权限矩阵 §5.4 逐项检查、敏感操作二次确认、SQL 注入防范)
|
|
407
|
+
- [ ] T0xx 代码评审(按 `.adspecs/templates/06-代码评审报告模板.md` 执行)
|
|
408
|
+
|
|
409
|
+
### 文档与构建
|
|
410
|
+
|
|
411
|
+
- [ ] T0xx 构建验证(`mvn clean -U package` 或 `pytest`,全模块编译通过 + 单元测试全绿)
|
|
412
|
+
- [ ] T0xx API 文档完善(Swagger/OpenAPI 注解 → UI 可访问)
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## 依赖关系与执行顺序
|
|
417
|
+
|
|
418
|
+
### 阶段依赖
|
|
419
|
+
|
|
420
|
+
| 阶段 | 依赖 | 说明 |
|
|
421
|
+
|------|------|------|
|
|
422
|
+
| Phase 1(环境搭建) | 无 | 可立即开始 |
|
|
423
|
+
| Phase 2(基础设施) | Phase 1 完成 | **阻塞所有用户故事** |
|
|
424
|
+
| Phase 3(US-01 创建提报) | Phase 2 完成 | P1 MVP 起点,是其他故事的基础 |
|
|
425
|
+
| Phase 4+(后续故事) | Phase 2 + Phase 3 实体 | 可独立并行 |
|
|
426
|
+
| Final Phase | 所有目标用户故事完成 | 集成测试需全功能就绪 |
|
|
427
|
+
|
|
428
|
+
### 用户故事间依赖
|
|
429
|
+
|
|
430
|
+
- **US-01(P1)**:Phase 3,创建核心 Entity/Service/Controller,是其他故事的基础
|
|
431
|
+
- **后续 US(P1)**:仅新增 Service 方法,可与 US-01 并行(同 Service 类,不同方法)
|
|
432
|
+
- **P2 故事**:可在 P1 完成后开始
|
|
433
|
+
|
|
434
|
+
### 每个用户故事内部的 TDD 执行顺序
|
|
435
|
+
|
|
436
|
+
```
|
|
437
|
+
[STOP] 确认 Phase 2 基础设施已就绪
|
|
438
|
+
↓
|
|
439
|
+
[TDD] 编写 Service 层单元测试(正常 + 异常 + 边界)→ 运行测试 → 确认失败 ❌
|
|
440
|
+
↓
|
|
441
|
+
[TDD] 编写 Controller 层集成测试 → 运行测试 → 确认失败 ❌
|
|
442
|
+
↓
|
|
443
|
+
创建 Entity/DO/Model({STACK_SPECIFIC_ENTITY_DEF})
|
|
444
|
+
↓
|
|
445
|
+
创建 DTO/Schema({STACK_SPECIFIC_DTO_DEF})
|
|
446
|
+
↓
|
|
447
|
+
创建 Ro/VO/ResponseSchema({STACK_SPECIFIC_RO_DEF})
|
|
448
|
+
↓
|
|
449
|
+
创建 DAO/Mapper/Repository({STACK_SPECIFIC_DAO_DEF})
|
|
450
|
+
↓
|
|
451
|
+
创建 Service 接口 + 实现({STACK_SPECIFIC_SERVICE_IMPL_DEF})
|
|
452
|
+
↓
|
|
453
|
+
创建 Controller/Router({STACK_SPECIFIC_CONTROLLER_DEF})
|
|
454
|
+
↓
|
|
455
|
+
创建 Feign/RPC/HTTP Client({STACK_SPECIFIC_CLIENT_DEF})
|
|
456
|
+
↓
|
|
457
|
+
[TDD] 重新运行测试 → 全部通过 ✅
|
|
458
|
+
↓
|
|
459
|
+
[REFACTOR] 提取公共逻辑、优化命名、清理重复代码 → 保持测试绿
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
**并行加速**:标记 `[P]` 的 Entity/DTO/Ro/DAO 可同时创建(互不依赖),Service 实现必须在 DAO 完成后。
|
|
463
|
+
|
|
464
|
+
### 并行机会
|
|
465
|
+
|
|
466
|
+
- **Phase 2**:所有枚举类可并行创建;DB 迁移与配置类可并行
|
|
467
|
+
- **Phase 3**:Entity + DTO + Ro 可并行,Service 接口+DAO 可并行
|
|
468
|
+
- **跨故事并行**:US-01 Entity 完成后,其他 US 可并行推进(各自独立的 Controller 方法或独立子表)
|
|
469
|
+
- **Final Phase**:i18n 文件可完全并行
|
|
470
|
+
|
|
471
|
+
---
|
|
472
|
+
|
|
473
|
+
## 实现策略
|
|
474
|
+
|
|
475
|
+
### MVP 优先(P1 用户故事)
|
|
476
|
+
|
|
477
|
+
1. Phase 1:项目环境搭建
|
|
478
|
+
2. Phase 2:基础设施(枚举 + DB 迁移 + 消息码 + 配置)**← 关键阻塞点**
|
|
479
|
+
3. Phase 3:US-01 创建并提报 **← MVP 核心**
|
|
480
|
+
4. Phase 4+:逐个追加 P1 故事
|
|
481
|
+
5. **STOP & VALIDATE**:全部 P1 故事端到端测试通过
|
|
482
|
+
6. P1 MVP 就绪 → 部署/演示
|
|
483
|
+
|
|
484
|
+
### 增量交付
|
|
485
|
+
|
|
486
|
+
1. Phase 1+2 → 基础就绪
|
|
487
|
+
2. Phase 3 → US-01 可独立测试 → 部署(MVP 最小可交付!)
|
|
488
|
+
3. Phase 4+ → 逐个追加 P1 故事 → 每个故事独立测试 → 增量部署
|
|
489
|
+
4. P2 故事追加
|
|
490
|
+
5. Final Phase → 集成收尾
|
|
491
|
+
|
|
492
|
+
### 团队并行策略
|
|
493
|
+
|
|
494
|
+
1. 团队共同完成 Phase 1+2(环境搭建 + 基础设施)
|
|
495
|
+
2. Phase 2 完成后:
|
|
496
|
+
- **开发者 A**:Phase 3(US-01)**← 最高优先级,产出核心 Entity**
|
|
497
|
+
- **开发者 B**:Phase 2 的 DB 迁移 + 配置类
|
|
498
|
+
3. US-01 Entity 完成后:
|
|
499
|
+
- **开发者 A**:工作量最大的故事
|
|
500
|
+
- **开发者 B**:其他 P1 故事
|
|
501
|
+
4. P1 全部完成 → 共同完成 P2 + Final Phase
|
|
502
|
+
|
|
503
|
+
---
|
|
504
|
+
|
|
505
|
+
## 编码规范检查清单
|
|
506
|
+
|
|
507
|
+
> 生成 tasks.md 时必须逐条确认。按 `BACKEND_STACK` 执行对应列的检查项。
|
|
508
|
+
|
|
509
|
+
### 栈无关项(三栈共检)
|
|
510
|
+
|
|
511
|
+
- [ ] 实体/DO/Model 类型字段完整定义,含审计字段(created_by/creation_date/updated_by/update_date/version_num/delete_flag)
|
|
512
|
+
- [ ] DTO/Schema 含校验分组或校验规则
|
|
513
|
+
- [ ] 异常在 Service 层抛出,Controller 仅做参数空校验
|
|
514
|
+
- [ ] 消息码/错误码禁止硬编码,统一引用常量/枚举
|
|
515
|
+
- [ ] i18n 覆盖所需语言,每个文件含实际内容(非占位)
|
|
516
|
+
- [ ] 注入与工具使用项目约定(非自行实现)
|
|
517
|
+
- [ ] 日志规范(SLF4J / loguru / 标准 logging)
|
|
518
|
+
|
|
519
|
+
### ECP Java 专属项(`BACKEND_STACK=ecp-java` 时检查)
|
|
520
|
+
|
|
521
|
+
- [ ] Entity:`extends BaseEntity<Entity>` + `@TableName` + `@TableField` + `@Schema`,`IdType.ASSIGN_ID`
|
|
522
|
+
- [ ] DTO:`extends ReqeustCommonDataBean`(注意拼写),校验分组内部接口
|
|
523
|
+
- [ ] DAO:`extends BaseCommonDAO_HI<Entity>` + `@Component("xxxDAO")`,MyBatis XML 同包
|
|
524
|
+
- [ ] 禁止 QueryWrapper:所有 DB 操作通过 MyBatis XML,任务描述中无 QueryWrapper/LambdaQueryWrapper 字样
|
|
525
|
+
- [ ] Service:接口 `II{Entity}` extends `IBaseCommon<T>`,实现 extends `BaseCommonServer<T>`,Save→FastJSON,Update→SpringBeanUtils
|
|
526
|
+
- [ ] Controller:`extends CommonAbstractService`,重写 `getBaseCommonServer()`,`@CheckToken`,`ResponseData<T>` 包装
|
|
527
|
+
- [ ] Ro:`implements Serializable` + `serialVersionUID`,手动字段,置于 `model/entity/readonly/`
|
|
528
|
+
- [ ] 所有 MyBatis XML SELECT 含 `WHERE delete_flag = 0`
|
|
529
|
+
- [ ] i18n:7 个 `.properties` 文件
|
|
530
|
+
|
|
531
|
+
### Yudao Java 专属项(`BACKEND_STACK=yudao-java` 时检查)
|
|
532
|
+
|
|
533
|
+
- [ ] Entity:`extends BaseDO` + `@TableName` + `@TableField` + `@Schema`
|
|
534
|
+
- [ ] Mapper:`extends BaseMapperX<T>` + `@Mapper`,使用 MyBatis-Plus `LambdaQueryWrapperX`
|
|
535
|
+
- [ ] Service:`@Service` 注解,可直接实现或使用 `BaseServiceImpl`
|
|
536
|
+
- [ ] Controller:`@RestController` + `@Tag` + `@PreAuthorize`,返回 `CommonResult<T>`
|
|
537
|
+
- [ ] VO:使用 `BeanUtils.toBean` 或 `BaseConvert` 转换
|
|
538
|
+
- [ ] 错误码:`ErrorCodeEnum` + `ServiceException` 抛出
|
|
539
|
+
- [ ] DB 迁移:Flyway `V{version}__{name}.sql`
|
|
540
|
+
|
|
541
|
+
### Python 专属项(`BACKEND_STACK=python` 时检查)
|
|
542
|
+
|
|
543
|
+
- [ ] Model:SQLAlchemy `Base` 派生,`Column` 定义完整
|
|
544
|
+
- [ ] Schema:Pydantic `BaseModel`,Field 校验完整
|
|
545
|
+
- [ ] Router:FastAPI `@router` + `Depends` 权限注入
|
|
546
|
+
- [ ] Service:函数式或 class 式,`Depends` 注入 Session
|
|
547
|
+
- [ ] 异步任务:Celery `@app.task`,配置 broker/result_backend
|
|
548
|
+
- [ ] DB 迁移:Alembic `env.py` + 迁移脚本
|
|
549
|
+
- [ ] 错误处理:自定义 Exception + error_code,全局异常处理器
|
|
550
|
+
- [ ] 测试:pytest + pytest-asyncio,fixture 复用
|
|
551
|
+
|
|
552
|
+
---
|
|
553
|
+
|
|
554
|
+
## TDD 执行指南
|
|
555
|
+
|
|
556
|
+
> 本模板任务顺序与 `test-driven-development` skill 的 RED→GREEN→REFACTOR 循环完全对齐。
|
|
557
|
+
|
|
558
|
+
### RED 阶段:编写测试并验证失败
|
|
559
|
+
|
|
560
|
+
```bash
|
|
561
|
+
# ECP Java / Yudao Java
|
|
562
|
+
mvn test -Dtest={Entity}ServiceTest
|
|
563
|
+
|
|
564
|
+
# Python
|
|
565
|
+
pytest tests/test_{module}.py
|
|
566
|
+
|
|
567
|
+
# 预期输出:测试失败(功能未实现)
|
|
568
|
+
# 如果测试通过 → 测试缺陷,修测试
|
|
569
|
+
# 如果测试报错(非失败) → 编译错误/依赖缺失,修环境
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### GREEN 阶段:最小代码使测试通过
|
|
573
|
+
|
|
574
|
+
```
|
|
575
|
+
按 TDD 任务之后的实现任务顺序:
|
|
576
|
+
Entity → DTO → Ro/VO → DAO/Mapper → Service → Controller → Client
|
|
577
|
+
|
|
578
|
+
每完成一个实现任务:
|
|
579
|
+
运行测试 → 逐步变绿
|
|
580
|
+
|
|
581
|
+
Service 实现完成后 → 全部测试应变绿 ✅
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
### REFACTOR 阶段:清理与优化
|
|
585
|
+
|
|
586
|
+
```bash
|
|
587
|
+
# 所有测试通过后:
|
|
588
|
+
- 提取重复的校验逻辑到工具类
|
|
589
|
+
- 优化命名(方法名/变量名与业务一致)
|
|
590
|
+
- 添加日志(关键操作)
|
|
591
|
+
- 运行全量测试确认不破坏
|
|
592
|
+
|
|
593
|
+
# Java
|
|
594
|
+
mvn test # 必须全绿
|
|
595
|
+
|
|
596
|
+
# Python
|
|
597
|
+
pytest # 必须全绿
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
---
|
|
601
|
+
|
|
602
|
+
## 注意事项
|
|
603
|
+
|
|
604
|
+
- `[P]` 任务 = 操作不同文件,无未完成依赖,可并行执行
|
|
605
|
+
- `[TDD]` 任务 = 测试任务,**必须在同故事的实现任务之前编写并通过失败验证**
|
|
606
|
+
- `[Story]` 标签将任务映射到设计文档 §1.1.1 中的具体用户故事,支持全链路追溯
|
|
607
|
+
- **所有文件路径必须精确到模块**(按 §后端项目路径约定 的 `BACKEND_STACK` 展开)
|
|
608
|
+
- **编码规范检查清单是硬性约束**,违反任一条 = 任务不合格
|
|
609
|
+
- **消息码/错误码禁止硬编码**:所有异常和校验信息引用常量/枚举
|
|
610
|
+
- **异常在 Service 层抛出**:Controller 仅做参数空校验
|
|
611
|
+
- 每个任务或逻辑分组后建议 git commit
|
|
612
|
+
- 可在任何检查点停下验证故事的独立可用性
|
|
613
|
+
- 避免:模糊任务、同文件冲突、跨故事强耦合、违反 TDD 顺序(实现先于测试)
|