@educa-corp/sdd-framework 0.6.0 → 0.7.1
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/bin/gate-trace.js +25 -2
- package/bin/index.js +32 -5
- package/bin/lint-trace.js +41 -0
- package/bin/self-check.js +430 -3
- package/bin/trace-schema.json +418 -31
- package/core/FRAMEWORK_VERSION +1 -1
- package/{commands/extend-prd.md → core/commands/amend-prd.md} +206 -173
- package/core/commands/dev-run-test.md +48 -10
- package/core/commands/extend-prd.md +39 -12
- package/core/commands/generate-bdd.md +52 -10
- package/core/commands/generate-code.md +35 -2
- package/core/commands/generate-tech-docs.md +36 -4
- package/core/commands/map-testids.md +1 -1
- package/core/commands/qc-run-test.md +29 -3
- package/core/commands/refine-prd.md +13 -2
- package/core/commands/review-context.md +43 -8
- package/core/commands/sync.md +105 -1
- package/core/commands/validate-traces.md +289 -16
- package/core/rules/workflow.md +34 -0
- package/core/steps/context-loader.md +27 -6
- package/core/templates/feature.template +1 -1
- package/core/templates/project-context.yaml +3 -3
- package/core/templates/tech-design.template.md +2 -2
- package/docs/02-concepts/architecture.md +37 -1
- package/docs/02-concepts/overview.md +1 -1
- package/docs/02-concepts/pipeline-steps/02-specification.md +13 -7
- package/docs/02-concepts/pipeline-steps/07-dev-selftest.md +2 -0
- package/docs/02-concepts/pipeline-steps/08-qc-automation.md +1 -0
- package/docs/02-concepts/pipeline-steps/09-validate-traces.md +34 -3
- package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +10 -1
- package/docs/02-concepts/traceability.md +187 -183
- package/docs/03-guides/architect.md +13 -4
- package/docs/03-guides/developer.md +1 -0
- package/docs/03-guides/product-owner.md +89 -72
- package/docs/03-guides/tester-qa.md +81 -81
- package/docs/04-reference/commands.md +148 -134
- package/docs/04-reference/trace-schema.md +45 -1
- package/docs/explain/02b-extend-prd.md +1 -1
- package/docs/explain/02c-amend-prd.md +152 -0
- package/docs/explain/06-generate-bdd.md +1 -1
- package/docs/explain/13-dev-run-test.md +15 -1
- package/docs/explain/19-qc-run-test.md +91 -87
- package/docs/explain/21-validate-traces.md +79 -75
- package/docs/explain/28-sync.md +25 -0
- package/docs/explain/README.md +136 -135
- package/package.json +1 -8
- package/commands/debug.md +0 -529
- package/commands/debug.tmpl +0 -260
- package/commands/define-product.md +0 -438
- package/commands/define-product.tmpl +0 -225
- package/commands/dev-gen-test.md +0 -700
- package/commands/dev-gen-test.tmpl +0 -490
- package/commands/dev-run-test.md +0 -435
- package/commands/dev-run-test.tmpl +0 -225
- package/commands/dev-smoke-test.md +0 -374
- package/commands/dev-smoke-test.tmpl +0 -217
- package/commands/extend-prd.tmpl +0 -273
- package/commands/fix-bug.md +0 -519
- package/commands/fix-bug.tmpl +0 -197
- package/commands/generate-architecture.md +0 -354
- package/commands/generate-architecture.tmpl +0 -197
- package/commands/generate-bdd.md +0 -923
- package/commands/generate-bdd.tmpl +0 -590
- package/commands/generate-code.md +0 -859
- package/commands/generate-code.tmpl +0 -649
- package/commands/generate-design-spec.md +0 -737
- package/commands/generate-design-spec.tmpl +0 -524
- package/commands/generate-prd.md +0 -722
- package/commands/generate-prd.tmpl +0 -226
- package/commands/generate-spec-manifest.md +0 -321
- package/commands/generate-spec-manifest.tmpl +0 -164
- package/commands/generate-tech-docs.md +0 -920
- package/commands/generate-tech-docs.tmpl +0 -273
- package/commands/learn.md +0 -399
- package/commands/learn.tmpl +0 -130
- package/commands/map-testids.md +0 -238
- package/commands/map-testids.tmpl +0 -81
- package/commands/propose-scenario.md +0 -359
- package/commands/propose-scenario.tmpl +0 -202
- package/commands/qc-analyze.md +0 -269
- package/commands/qc-analyze.tmpl +0 -112
- package/commands/qc-design-test.md +0 -226
- package/commands/qc-design-test.tmpl +0 -69
- package/commands/qc-plan.md +0 -206
- package/commands/qc-plan.tmpl +0 -49
- package/commands/qc-report.md +0 -217
- package/commands/qc-report.tmpl +0 -60
- package/commands/qc-review.md +0 -210
- package/commands/qc-review.tmpl +0 -53
- package/commands/qc-run-test.md +0 -326
- package/commands/qc-run-test.tmpl +0 -116
- package/commands/refine-prd.md +0 -653
- package/commands/refine-prd.tmpl +0 -281
- package/commands/report-bug.md +0 -305
- package/commands/report-bug.tmpl +0 -148
- package/commands/review-code.md +0 -415
- package/commands/review-code.tmpl +0 -146
- package/commands/review-context.md +0 -902
- package/commands/review-context.tmpl +0 -530
- package/commands/review-tech-docs.md +0 -561
- package/commands/review-tech-docs.tmpl +0 -404
- package/commands/setup-ai-first.md +0 -602
- package/commands/setup-ai-first.tmpl +0 -450
- package/commands/sync.md +0 -430
- package/commands/sync.tmpl +0 -429
- package/commands/update-framework.md +0 -203
- package/commands/update-framework.tmpl +0 -202
- package/commands/validate-traces.md +0 -1077
- package/commands/validate-traces.tmpl +0 -920
- package/hooks/data-guard.js +0 -232
- package/hooks/settings.json +0 -19
- package/modules/android-compose/module.yaml +0 -13
- package/modules/android-compose/stack-profile.yaml +0 -57
- package/modules/angular/architecture-snippets/component-patterns.md +0 -187
- package/modules/angular/module.yaml +0 -6
- package/modules/angular/stack-profile.yaml +0 -38
- package/modules/context-engineering/architecture-snippets/context-design.md +0 -119
- package/modules/context-engineering/module.yaml +0 -9
- package/modules/context-engineering/stack-profile.yaml +0 -61
- package/modules/dotnet/architecture-snippets/clean-arch.md +0 -160
- package/modules/dotnet/module.yaml +0 -6
- package/modules/dotnet/stack-profile.yaml +0 -50
- package/modules/flutter/module.yaml +0 -14
- package/modules/flutter/stack-profile.yaml +0 -59
- package/modules/golang/architecture-snippets/domain-layout.md +0 -283
- package/modules/golang/module.yaml +0 -6
- package/modules/golang/stack-profile.yaml +0 -40
- package/modules/ios-swiftui/module.yaml +0 -13
- package/modules/ios-swiftui/stack-profile.yaml +0 -55
- package/modules/java-spring/architecture-snippets/layered-arch.md +0 -201
- package/modules/java-spring/module.yaml +0 -15
- package/modules/java-spring/stack-profile.yaml +0 -28
- package/modules/nextjs/architecture-snippets/app-router-patterns.md +0 -269
- package/modules/nextjs/module.yaml +0 -14
- package/modules/nextjs/stack-profile.yaml +0 -74
- package/modules/nuxt/module.yaml +0 -14
- package/modules/nuxt/stack-profile.yaml +0 -58
- package/modules/phaser-game/architecture-snippets/phaser-scene-patterns.md +0 -646
- package/modules/phaser-game/module.yaml +0 -15
- package/modules/phaser-game/stack-profile.yaml +0 -90
- package/modules/php-laravel/architecture-snippets/service-repository.md +0 -302
- package/modules/php-laravel/module.yaml +0 -15
- package/modules/php-laravel/stack-profile.yaml +0 -56
- package/modules/qc-playwright/stack-profile.yaml +0 -66
- package/modules/react/architecture-snippets/hooks-query-patterns.md +0 -254
- package/modules/react/module.yaml +0 -14
- package/modules/react/stack-profile.yaml +0 -63
- package/modules/react-native/module.yaml +0 -14
- package/modules/react-native/stack-profile.yaml +0 -56
- package/modules/vue/module.yaml +0 -14
- package/modules/vue/stack-profile.yaml +0 -65
- package/rules/data-protection.md +0 -80
- package/rules/workflow.md +0 -99
- package/skills/code/SKILL.md +0 -19
- package/skills/code/SKILL.tmpl +0 -19
- package/skills/debug/SKILL.md +0 -19
- package/skills/debug/SKILL.tmpl +0 -19
- package/skills/design-spec/SKILL.md +0 -11
- package/skills/design-spec/SKILL.tmpl +0 -11
- package/skills/discovery/SKILL.md +0 -14
- package/skills/discovery/SKILL.tmpl +0 -14
- package/skills/prd/SKILL.md +0 -19
- package/skills/prd/SKILL.tmpl +0 -19
- package/skills/qc/qa-analyst/DOC_GAPS.template.md +0 -63
- package/skills/qc/qa-analyst/acceptance-criteria.md +0 -60
- package/skills/qc/qa-analyst/business-rules.md +0 -59
- package/skills/qc/qa-analyst/data-flow.md +0 -64
- package/skills/qc/qa-analyst/spec-breakdown.md +0 -61
- package/skills/qc/qa-designer/e2e/journey.md +0 -41
- package/skills/qc/qa-designer/exploratory/charter.md +0 -68
- package/skills/qc/qa-designer/exploratory/explore-to-functional.md +0 -43
- package/skills/qc/qa-designer/functional/api.md +0 -45
- package/skills/qc/qa-designer/functional/gui-feature.md +0 -46
- package/skills/qc/qa-designer/functional/gui-screen.md +0 -52
- package/skills/qc/qa-designer/integration/api.md +0 -42
- package/skills/qc/qa-designer/integration/db.md +0 -39
- package/skills/qc/qa-designer/integration/gui.md +0 -40
- package/skills/qc/qa-designer/integration/kafka.md +0 -40
- package/skills/qc/qa-designer/non-functional.md +0 -40
- package/skills/qc/qa-planner/test-plan.md +0 -120
- package/skills/qc/qa-reviewer/script/e2e.md +0 -87
- package/skills/qc/qa-reviewer/script/exploratory.md +0 -45
- package/skills/qc/qa-reviewer/script/functional.md +0 -101
- package/skills/qc/qa-reviewer/script/integration.md +0 -91
- package/skills/qc/qa-reviewer/script/non-functional.md +0 -126
- package/skills/qc/qa-reviewer/test-case/e2e.md +0 -73
- package/skills/qc/qa-reviewer/test-case/exploratory.md +0 -43
- package/skills/qc/qa-reviewer/test-case/functional.md +0 -76
- package/skills/qc/qa-reviewer/test-case/integration.md +0 -69
- package/skills/qc/qa-reviewer/test-case/non-functional.md +0 -73
- package/skills/qc/qa-runner/e2e.md +0 -49
- package/skills/qc/qa-runner/exploratory/session.md +0 -36
- package/skills/qc/qa-runner/functional/api.md +0 -35
- package/skills/qc/qa-runner/functional/gui-feature.md +0 -51
- package/skills/qc/qa-runner/functional/gui-screen.md +0 -55
- package/skills/qc/qa-runner/integration.md +0 -47
- package/skills/qc/qa-runner/non-functional.md +0 -49
- package/skills/qc/qa-runner/report/report.md +0 -37
- package/skills/setup-ai-first/SKILL.md +0 -19
- package/skills/setup-ai-first/SKILL.tmpl +0 -19
- package/skills/spec/SKILL.md +0 -19
- package/skills/spec/SKILL.tmpl +0 -19
- package/skills/test/SKILL.md +0 -18
- package/skills/test/SKILL.tmpl +0 -18
- package/steps/business-language.md +0 -56
- package/steps/capture-lesson.md +0 -112
- package/steps/context-loader.md +0 -406
- package/steps/gate.md +0 -151
- package/steps/report-footer.md +0 -125
- package/steps/review-fanout.md +0 -159
- package/steps/spawn-agent.md +0 -129
- package/steps/trace-mirror.md +0 -53
- package/templates/README.md +0 -70
- package/templates/architecture.template.md +0 -394
- package/templates/ci/trace-gate.yml +0 -146
- package/templates/design-spec.template.md +0 -217
- package/templates/feature.template +0 -123
- package/templates/hooks/pre-push +0 -61
- package/templates/platform-guide.template.md +0 -145
- package/templates/prd.template.md +0 -283
- package/templates/product-definition.template.md +0 -188
- package/templates/project-context.yaml +0 -212
- package/templates/tech-design.template.md +0 -490
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
# {TICKET-ID} {Feature Name} — Design Spec [{Platform}]
|
|
2
|
-
|
|
3
|
-
<!--
|
|
4
|
-
Template này được sử dụng bởi /generate-design-spec.
|
|
5
|
-
Platform = web | app | app-ios | app-android
|
|
6
|
-
|
|
7
|
-
PLATFORM SECTIONS:
|
|
8
|
-
- Section 3A + 4A: chỉ dành cho web (react/nextjs/vue/angular). Xóa C khi dùng cho web.
|
|
9
|
-
- Section 3C + 4B: chỉ dành cho app (flutter/react-native/ios/android). Xóa A+B khi dùng cho app.
|
|
10
|
-
|
|
11
|
-
COMPONENT MAPPING (bắt buộc):
|
|
12
|
-
- Mọi component trong Component Inventory PHẢI được map với figma-components/{module}.md
|
|
13
|
-
- ✅ Matched → dùng Code Component và Import Path từ catalog
|
|
14
|
-
- ⚠️ TODO → đánh dấu [TODO — chưa implement]
|
|
15
|
-
- ❌ Chưa có → đánh dấu [NEW — cần confirm với designer]
|
|
16
|
-
|
|
17
|
-
FIGMA LINKS (bắt buộc mỗi màn):
|
|
18
|
-
- Mỗi screen PHẢI có link Figma node-level (URL chứa ?node-id=...) — lấy bằng
|
|
19
|
-
right-click frame → "Copy link to selection". Đây là link AI đọc được qua Figma MCP.
|
|
20
|
-
- Link file trần (không có node-id) KHÔNG hợp lệ — AI không định vị được frame.
|
|
21
|
-
- Screen chưa có design → đánh dấu ❌ Missing; spec giữ Status "draft", chặn sign-off
|
|
22
|
-
và /generate-bdd cho tới khi đủ link.
|
|
23
|
-
|
|
24
|
-
SCREEN STATES (bắt buộc mỗi màn):
|
|
25
|
-
- Tối thiểu: default, loading, error
|
|
26
|
-
- Thêm "empty" nếu màn có thể hiển thị trạng thái không có dữ liệu
|
|
27
|
-
- Thêm "success" nếu action tạo ra trạng thái xác nhận riêng biệt
|
|
28
|
-
-->
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
## Metadata
|
|
33
|
-
|
|
34
|
-
| Field | Value |
|
|
35
|
-
|--------------------|---------------------------------------------------------------|
|
|
36
|
-
| **Spec ID** | {TICKET-ID}-DS-{platform} |
|
|
37
|
-
| **Version** | 1.0 |
|
|
38
|
-
| **Status** | draft / approved |
|
|
39
|
-
| **Platform** | {web \| app \| app-ios \| app-android} |
|
|
40
|
-
| **Module** | {active_module} |
|
|
41
|
-
| **Service** | {active_service} |
|
|
42
|
-
| **Domain** | {domain} |
|
|
43
|
-
| **Business PRD** | [{TICKET-ID}](./{TICKET-ID}-slug.md) |
|
|
44
|
-
| **Figma** | {link file feature} ({linked}/{N} frame đã link) |
|
|
45
|
-
| **Author** | {tên PO hoặc "AI-assisted"} |
|
|
46
|
-
| **Created** | {YYYY-MM-DD} |
|
|
47
|
-
| **Updated** | {YYYY-MM-DD} |
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
# 1. Danh mục màn hình (Screen Inventory)
|
|
52
|
-
|
|
53
|
-
| # | Tên màn hình | Điểm vào | Figma Frame (link node-level) | Ghi chú |
|
|
54
|
-
|---|-------------|-------------|-------------------------------|-------|
|
|
55
|
-
| 1 | {Màn hình 1} | {người dùng đến từ đâu} | [Frame]({node-level url}) | |
|
|
56
|
-
| 2 | {Màn hình 2} | {điểm vào} | ❌ Missing — thêm link node-id | |
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
# 2. Đặc tả màn hình (Screen Specs)
|
|
61
|
-
|
|
62
|
-
## Màn hình 1: {Tên màn hình}
|
|
63
|
-
|
|
64
|
-
**Figma**: [{Tên frame}]({figma_frame_url})
|
|
65
|
-
|
|
66
|
-
### Layout
|
|
67
|
-
|
|
68
|
-
{Grid / max-width / padding / spacing — tham chiếu design token nếu áp dụng được}
|
|
69
|
-
|
|
70
|
-
### Component Inventory
|
|
71
|
-
|
|
72
|
-
| Component (Figma) | Code Component | Import Path | States | Ghi chú |
|
|
73
|
-
|------------------------|----------------|------------------------|---------------------------------|---------|
|
|
74
|
-
| {Figma/Button/Primary} | Button | @/components/ui/Button | default, loading, disabled | |
|
|
75
|
-
| {Figma/Input/Text} | TextInput | @/components/ui/Input | default, focus, error, disabled | |
|
|
76
|
-
|
|
77
|
-
### Screen States
|
|
78
|
-
|
|
79
|
-
| State | Trigger | Hành vi UI |
|
|
80
|
-
|-----------|----------------------------------|----------------------------------------------------------|
|
|
81
|
-
| default | Màn đã load, có dữ liệu | {Mô tả toàn bộ giao diện đã render} |
|
|
82
|
-
| loading | API đang gọi | {Vị trí và kiểu skeleton / spinner} |
|
|
83
|
-
| error | API thất bại / lỗi validation | {Toast / lỗi inline / màn lỗi + CTA khôi phục} |
|
|
84
|
-
| empty | Không có dữ liệu trả về | {Illustration + CTA — vd: "Chưa có mục nào. Thêm mới →"} |
|
|
85
|
-
| success | Action hoàn tất (nếu có) | {Toast xác nhận / điều hướng / thay đổi giao diện} |
|
|
86
|
-
|
|
87
|
-
### Actions & Navigation
|
|
88
|
-
|
|
89
|
-
| Action | Trigger | Kết quả |
|
|
90
|
-
|-----------------|---------------------------|---------------------------------------------------|
|
|
91
|
-
| {Tên action} | Tap/click {phần tử} | Điều hướng tới {Màn hình N} / Mở {Tên modal} |
|
|
92
|
-
| {Back/Cancel} | Cử chỉ back / nút | Quay lại {màn trước} mà không lưu |
|
|
93
|
-
|
|
94
|
-
---
|
|
95
|
-
|
|
96
|
-
<!-- Lặp lại ## Màn hình N cho mỗi màn bổ sung -->
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
# 3. Pattern tương tác (Interaction Patterns)
|
|
101
|
-
|
|
102
|
-
<!-- === CHỈ WEB — xóa section này cho app === -->
|
|
103
|
-
|
|
104
|
-
## A. Hành vi Responsive *(web)*
|
|
105
|
-
|
|
106
|
-
| Breakpoint | Width | Thay đổi layout |
|
|
107
|
-
|------------|------------|---------------------------------------------|
|
|
108
|
-
| Mobile | < 768px | {1 cột, bottom nav, CTA full-width} |
|
|
109
|
-
| Tablet | 768–1279px | {grid 2 cột, sidebar thu gọn} |
|
|
110
|
-
| Desktop | ≥ 1280px | {layout đầy đủ, max-width 1440px} |
|
|
111
|
-
|
|
112
|
-
## B. Hover / Focus / Keyboard *(web)*
|
|
113
|
-
|
|
114
|
-
| Phần tử | Hover | Focus | Keyboard |
|
|
115
|
-
|----------------|-------------------------------|---------------------------------|---------------|
|
|
116
|
-
| Primary button | Background → {color.hover} | Outline 2px {color.focus} | Enter / Space |
|
|
117
|
-
| Text input | Border → {color.border.hover} | Border → {color.primary} | Tab to focus |
|
|
118
|
-
|
|
119
|
-
<!-- === CHỈ APP — xóa section A+B cho app === -->
|
|
120
|
-
|
|
121
|
-
## C. Cử chỉ & Điều hướng *(app)*
|
|
122
|
-
|
|
123
|
-
| Cử chỉ | Màn / Phần tử | Hành vi |
|
|
124
|
-
|----------------------|---------------------|---------------------------------------------|
|
|
125
|
-
| Cử chỉ back | Mọi màn | {Quay lại / hiện dialog "Discard changes?"} |
|
|
126
|
-
| Pull-to-refresh | {Tên màn} | Refresh dữ liệu, spinner ở trên cùng |
|
|
127
|
-
| Swipe trái trên row | {List item} | Hiện action {Delete / Archive} |
|
|
128
|
-
|
|
129
|
-
### Navigation Stack *(app)*
|
|
130
|
-
|
|
131
|
-
```
|
|
132
|
-
{vd: BottomTab(Home) → ListPage → DetailPage → EditPage}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### Platform Conventions *(app)*
|
|
136
|
-
|
|
137
|
-
| Khía cạnh | iOS | Android |
|
|
138
|
-
|------------------|-------------------------------------------|-------------------------------------|
|
|
139
|
-
| Navigation bar | Nút back trên-trái, title canh giữa | Mũi tên Up, title canh trái |
|
|
140
|
-
| Bottom sheet | UISheetPresentation, hiện grabber | BottomSheet, drag handle |
|
|
141
|
-
| Dialog | Action canh phải | Action canh trái |
|
|
142
|
-
|
|
143
|
-
---
|
|
144
|
-
|
|
145
|
-
# 4. Cân nhắc theo Platform (Platform Considerations)
|
|
146
|
-
|
|
147
|
-
<!-- === CHỈ WEB === -->
|
|
148
|
-
|
|
149
|
-
## A. Accessibility *(web)*
|
|
150
|
-
|
|
151
|
-
- [ ] Mọi phần tử tương tác đều tới được bằng phím Tab — không có keyboard trap
|
|
152
|
-
- [ ] Focus trap bên trong modal
|
|
153
|
-
- [ ] Nút chỉ có icon phải có `aria-label`
|
|
154
|
-
- [ ] Nội dung động thông báo qua `aria-live`
|
|
155
|
-
- [ ] Tương phản WCAG AA: text ≥ 4.5:1, text lớn ≥ 3:1
|
|
156
|
-
- [ ] Input form có label hiển thị (không chỉ dùng placeholder)
|
|
157
|
-
|
|
158
|
-
<!-- === CHỈ APP === -->
|
|
159
|
-
|
|
160
|
-
## B. Thiết bị & OS *(app)*
|
|
161
|
-
|
|
162
|
-
- [ ] Áp dụng safe area insets (trên + dưới) ở mọi màn
|
|
163
|
-
- [ ] Touch target tối thiểu: 44×44pt (iOS) / 48×48dp (Android)
|
|
164
|
-
- [ ] Đã test trên 375pt (iPhone SE) và 360dp (Android nhỏ)
|
|
165
|
-
- [ ] Deep link: `{scheme}://{host}/{path}` → {tên màn}
|
|
166
|
-
- [ ] Permission: {Camera / Location / Notification} — nội dung lý do TBD
|
|
167
|
-
- [ ] Offline: {tên màn} hiện dữ liệu cache + banner; {action} bị disable kèm tooltip
|
|
168
|
-
- [ ] Đã test dark mode — không có màu hardcode
|
|
169
|
-
|
|
170
|
-
---
|
|
171
|
-
|
|
172
|
-
# 5. AC-UI — Tiêu chí chấp nhận về Design
|
|
173
|
-
|
|
174
|
-
> Được **PO + Designer** review và sign off trước khi sinh BDD.
|
|
175
|
-
> Bổ sung cho AC mức nghiệp vụ trong [Business PRD](./{TICKET-ID}-slug.md).
|
|
176
|
-
|
|
177
|
-
| ID | Tiêu chí chấp nhận | Verified by |
|
|
178
|
-
|--------|--------------------------------------------------------------------------|-----------------|
|
|
179
|
-
| AC-UI1 | Mọi màn khớp với frame Figma đã duyệt trong dung sai design-system | Designer |
|
|
180
|
-
| AC-UI2 | Trạng thái loading xuất hiện trong vòng 200ms kể từ khi gọi API | QA |
|
|
181
|
-
| AC-UI3 | Mọi thông báo lỗi đều hiển thị, rõ ràng, và kèm CTA khôi phục | PO |
|
|
182
|
-
| AC-UI4 | Empty state có illustration và call-to-action | PO + Designer |
|
|
183
|
-
| AC-UI5 | {Tiêu chí riêng theo platform} | QA |
|
|
184
|
-
|
|
185
|
-
---
|
|
186
|
-
|
|
187
|
-
# Appendix
|
|
188
|
-
|
|
189
|
-
## Tóm tắt Figma
|
|
190
|
-
|
|
191
|
-
| Màn hình | Figma Frame (node-level) | Trạng thái Link / Fetch |
|
|
192
|
-
|------------|--------------------------|--------------------------------|
|
|
193
|
-
| {Màn hình 1} | [Link]({node-level url}) | ✅ Đã link & fetch |
|
|
194
|
-
| {Màn hình 2} | — | ❌ Missing — không có link node-id |
|
|
195
|
-
|
|
196
|
-
## Design Token đã tham chiếu
|
|
197
|
-
|
|
198
|
-
| Token | Value | Dùng ở |
|
|
199
|
-
|-------------------|----------|----------------------------|
|
|
200
|
-
| `color.primary` | {#hex} | Button, link |
|
|
201
|
-
| `spacing.md` | {16px} | Khoảng cách dọc tiêu chuẩn |
|
|
202
|
-
|
|
203
|
-
## Tài liệu tham khảo
|
|
204
|
-
|
|
205
|
-
- [{TICKET-ID}](./{TICKET-ID}-slug.md) — Business PRD
|
|
206
|
-
|
|
207
|
-
## Giả định AI
|
|
208
|
-
|
|
209
|
-
- {Giả định — [AI DRAFT]}
|
|
210
|
-
|
|
211
|
-
---
|
|
212
|
-
|
|
213
|
-
## Changelog
|
|
214
|
-
|
|
215
|
-
| Version | Date | Changes |
|
|
216
|
-
|---------|--------------|-----------------|
|
|
217
|
-
| 1.0 | {YYYY-MM-DD} | Initial version |
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
# ============================================================
|
|
2
|
-
# @trace.id: {TICKET-ID}-UC{N}
|
|
3
|
-
# @trace.title: <Feature name>
|
|
4
|
-
# @trace.revision: 1 ← field tĩnh; version theo dõi bằng @trace.bdd_version
|
|
5
|
-
# @trace.domain: <domain>
|
|
6
|
-
# @trace.platform: {active_platform — web | app | system} ← BẮT BUỘC mọi mode; phải khớp segment bdd/{platform}/ của path
|
|
7
|
-
# @trace.service: {active_service — BẮT BUỘC mọi mode. "—" ở single-service/spec repo mode; "multi" nếu chưa chốt; "unresolved" nếu routing sai. Nguồn của cột TSV `service` — trace gộp không tách theo service nên đây là chỗ DUY NHẤT mang thông tin sở hữu}
|
|
8
|
-
# @trace.module: {active_module trong umbrella mode; "unknown" trong spec repo mode}
|
|
9
|
-
# @trace.status: draft
|
|
10
|
-
# @trace.author: AI-generated
|
|
11
|
-
# @trace.created_at: {YYYY-MM-DD}
|
|
12
|
-
# @trace.prd: {TICKET-ID}
|
|
13
|
-
# @trace.prd_version: {đọc từ metadata PRD "| **Version** |"}
|
|
14
|
-
# @trace.bdd_version: {cấp FILE — 1.0 nếu gen mới; tăng 0.1 khi gen lại. Khác @trace.sc_version (cấp từng SC) bên dưới}
|
|
15
|
-
# @trace.business_rules: {TICKET-ID}-UC{N}-BR{m}, {TICKET-ID}-UC{N}-BR{m+1} ← {m} lấy NGUYÊN từ PRD §3: BR đánh số LIÊN TỤC toàn PRD, KHÔNG reset theo UC
|
|
16
|
-
# @trace.dataset: {domain}.testdata.yaml
|
|
17
|
-
# ============================================================
|
|
18
|
-
|
|
19
|
-
# === CONTEXT ===
|
|
20
|
-
# Actor: <vai trò thực hiện hành động, vd: Consumer, Staff, System>
|
|
21
|
-
# Screens: <các màn liên quan, vd: Cart → Confirm Order → Order Detail>
|
|
22
|
-
# Entities: <business entity, vd: Order, OrderItem, Consumer>
|
|
23
|
-
# Pre-state: <state dùng chung trước khi vào các scenario>
|
|
24
|
-
|
|
25
|
-
# === SCOPE ===
|
|
26
|
-
# In: <UC này phủ gì>
|
|
27
|
-
# Out: <cái gì KHÔNG thuộc UC này — link tới UC/feature khác (R10)>
|
|
28
|
-
|
|
29
|
-
# === BUSINESS DEFINITION ===
|
|
30
|
-
# Tham chiếu nhanh các term dùng trong feature này. Chi tiết SoT: business-dictionary.md
|
|
31
|
-
# <Term 1>: <định nghĩa ngắn>
|
|
32
|
-
# <Term 2>: <định nghĩa ngắn>
|
|
33
|
-
#
|
|
34
|
-
# --- Popup/Modal Lifecycle (tùy chọn — BẮT BUỘC nếu feature là popup/modal; Pre-merge yêu cầu) ---
|
|
35
|
-
# - Open trigger: <khi nào popup hiển thị, vd: click menu sidebar>
|
|
36
|
-
# - Close trigger: <khi nào popup đóng, vd: F5 / click X / ESC / navigate away>
|
|
37
|
-
# - Refresh model: <data refresh khi nào, vd: mỗi lần open (NO CACHE) / persisted / polling>
|
|
38
|
-
# - State reset: <state nào reset khi đóng/mở lại, vd: pagination, expand, dropdown selection>
|
|
39
|
-
#
|
|
40
|
-
# --- Display Logic Matrix (tùy chọn — BẮT BUỘC nếu display logic phụ thuộc ≥2 chiều; Pre-merge yêu cầu) ---
|
|
41
|
-
# Liệt kê đủ ma trận N×M case + map mỗi case → SC. Tên SC theo pattern `<cấu trúc>: <outcome>` (KHÔNG dùng "(Case X)").
|
|
42
|
-
# | # | Dim1 | Dim2 | Format hiển thị | SC |
|
|
43
|
-
# |---|------|------|------------------------|------|
|
|
44
|
-
# | 1 | 0 | 0 | `Tên hàng` | SC{} |
|
|
45
|
-
# | 2 | 0 | 1 | `Tên hàng (đơn vị)` | SC{} |
|
|
46
|
-
# | ... | ... | ... | ... | ... |
|
|
47
|
-
|
|
48
|
-
Feature: <Feature name>
|
|
49
|
-
As a <role>
|
|
50
|
-
I want to <action>
|
|
51
|
-
So that <business value>
|
|
52
|
-
|
|
53
|
-
Background:
|
|
54
|
-
Given <precondition dùng chung — dùng alias từ dataset, không phải ID kỹ thuật>
|
|
55
|
-
|
|
56
|
-
# ==========================================================
|
|
57
|
-
# NHÓM 1: <Business theme> (<BR refs>)
|
|
58
|
-
# ==========================================================
|
|
59
|
-
|
|
60
|
-
# Side-effects: <liệt kê ngắn các Then side-effect cần verify>
|
|
61
|
-
# @trace.scenario: {TICKET-ID}-UC{N}-SC1
|
|
62
|
-
# @trace.sc_version: 1.0 ← cấp SCENARIO. Sửa thân SC này (tên/step/table/side-effect) thì +0.1, nếu không code cũ mãi hiện OK
|
|
63
|
-
# @trace.business_rules: {TICKET-ID}-UC{N}-BR{m}
|
|
64
|
-
@happy
|
|
65
|
-
Scenario: <mô tả business outcome — dùng động từ chính xác: create/receive/assign/block>
|
|
66
|
-
Given <input state — alias từ dataset>
|
|
67
|
-
When <single action>
|
|
68
|
-
Then <main observable outcome>
|
|
69
|
-
And <side-effect 1 khai báo trong header>
|
|
70
|
-
|
|
71
|
-
# Side-effects: <...>
|
|
72
|
-
# @trace.scenario: {TICKET-ID}-UC{N}-SC2
|
|
73
|
-
# @trace.sc_version: 1.0
|
|
74
|
-
# @trace.business_rules: {TICKET-ID}-UC{N}-BR{m}
|
|
75
|
-
@happy @alternative
|
|
76
|
-
Scenario: <cùng theme NHÓM 1 nhưng path khác — vd: giá trị enum khác>
|
|
77
|
-
Given <state>
|
|
78
|
-
When <action>
|
|
79
|
-
Then <outcome>
|
|
80
|
-
|
|
81
|
-
# ==========================================================
|
|
82
|
-
# NHÓM 2: <Business theme 2> (<BR refs>)
|
|
83
|
-
# ==========================================================
|
|
84
|
-
|
|
85
|
-
# Side-effects: <...>
|
|
86
|
-
# @trace.scenario: {TICKET-ID}-UC{N}-SC3
|
|
87
|
-
# @trace.sc_version: 1.0
|
|
88
|
-
# @trace.business_rules: {TICKET-ID}-UC{N}-BR{m+2}
|
|
89
|
-
@edge
|
|
90
|
-
Scenario: <scenario boundary / error>
|
|
91
|
-
Given <state>
|
|
92
|
-
When <action>
|
|
93
|
-
Then <expected error handling>
|
|
94
|
-
|
|
95
|
-
# === PRD COVERAGE (C.1 + C.2) ===
|
|
96
|
-
# AC mapping:
|
|
97
|
-
# AC1 (...) → SC1, SC2
|
|
98
|
-
# AC2 (...) → SC3
|
|
99
|
-
# BR mapping (mỗi bullet PHẢI có ≥1 SC — C.2):
|
|
100
|
-
# {TICKET-ID}-UC{N}-BR{m} (...) → SC1, SC2
|
|
101
|
-
# {TICKET-ID}-UC{N}-BR{m+2} (...) → SC3
|
|
102
|
-
# Wireframe mapping (mỗi component/action ≥1 SC — C.1):
|
|
103
|
-
# Screen "<screen name>":
|
|
104
|
-
# [x] <action 1> → SC1
|
|
105
|
-
# [x] <action 2> → SC2
|
|
106
|
-
# [ ] <action 3> → MISSING ← BLOCK MERGE
|
|
107
|
-
# Design Spec coverage (chỉ FE/App — C.1 mở rộng; bỏ khối này nếu không nạp design-spec):
|
|
108
|
-
# Screen "<screen>": loading → SC?, error → SC?, empty → SC?
|
|
109
|
-
# AC-UI behavioral: AC-UI3 (lỗi+khôi phục) → SC?, AC-UI4 (empty CTA) → SC?
|
|
110
|
-
# (bỏ AC-UI visual thuần: AC-UI1 khớp Figma, AC-UI5 WCAG — Designer/QA review riêng)
|
|
111
|
-
|
|
112
|
-
# === PRE-MERGE CHECKLIST ===
|
|
113
|
-
# - [ ] Mỗi SC có Side-effects + @trace.scenario + @trace.sc_version + @trace.business_rules
|
|
114
|
-
# - [ ] SỬA nội dung một SC (tên / step / data table / side-effect) → đã bump @trace.sc_version của
|
|
115
|
-
# CHÍNH SC đó (+0.1). Quên bump = code sinh từ SC cũ vẫn hiện OK, không ai biết phải regen.
|
|
116
|
-
# (Đổi @trace.business_rules / tag / comment → KHÔNG bump: không đổi hành vi cần implement.)
|
|
117
|
-
# - [ ] Coverage Matrix: 0 dòng MISSING (C.1)
|
|
118
|
-
# - [ ] FE/App: mỗi Screen State (≠default) + AC-UI behavioral của design-spec có ≥1 SC (C.1 mở rộng)
|
|
119
|
-
# - [ ] Mỗi AC/BR map tới ≥1 SC (C.2)
|
|
120
|
-
# - [ ] 0 banned term (C.4) — grep file trước khi merge
|
|
121
|
-
# - [ ] Feature ≥3 SC có NHÓM grouping theo business theme (C.5)
|
|
122
|
-
# - [ ] Nếu popup/modal: khai báo Popup/Modal Lifecycle trong BUSINESS DEFINITION
|
|
123
|
-
# - [ ] Nếu display logic ≥2 chiều: Display Logic Matrix trong BUSINESS DEFINITION
|
package/templates/hooks/pre-push
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env sh
|
|
2
|
-
# ─────────────────────────────────────────────────────────────────────────────
|
|
3
|
-
# SDD Framework — git pre-push hook
|
|
4
|
-
#
|
|
5
|
-
# CÀI (từ gốc project):
|
|
6
|
-
# cp .agent/templates/hooks/pre-push .git/hooks/pre-push
|
|
7
|
-
# chmod +x .git/hooks/pre-push
|
|
8
|
-
#
|
|
9
|
-
# Trên Windows: Git for Windows chạy hook bằng sh nên file này dùng được như vậy.
|
|
10
|
-
#
|
|
11
|
-
# VÌ SAO CÓ HOOK NÀY khi đã có CI (GAPS-v3 G39/G40): nó chặn ở chỗ RẺ NHẤT.
|
|
12
|
-
# Cụ thể là T7 — marker conflict git (`<<<<<<< HEAD`) lọt vào sổ trace. Một khi
|
|
13
|
-
# thứ đó vào nhánh chung thì mọi người kéo về đều có sổ hỏng, và sổ trace là dữ
|
|
14
|
-
# liệu KHÔNG dựng lại được. Bắt trước lúc push tốn 2 giây; bắt ở CI thì đã muộn
|
|
15
|
-
# một vòng, bắt bằng mắt thì thường là ba tuần sau.
|
|
16
|
-
#
|
|
17
|
-
# CỐ Ý CHỈ LINT, KHÔNG GATE:
|
|
18
|
-
# --lint-trace = cấu trúc sổ. Nhanh, offline được sau lần đầu, và một lỗi ở đây
|
|
19
|
-
# LUÔN là lỗi thật (tab lệch, marker conflict, enum sai).
|
|
20
|
-
# --gate-trace = cờ 🔴. Cần trace-report.json còn tươi, mà giữa lúc làm việc thì
|
|
21
|
-
# nó thường chưa tươi — đỏ liên tục ⇒ người ta gõ --no-verify ⇒
|
|
22
|
-
# mất luôn cả phần lint. Cờ 🔴 để CI chặn.
|
|
23
|
-
#
|
|
24
|
-
# Bỏ qua một lần (dùng có ý thức, đừng thành phản xạ): git push --no-verify
|
|
25
|
-
# ─────────────────────────────────────────────────────────────────────────────
|
|
26
|
-
|
|
27
|
-
# Không có node thì im lặng cho qua — hook không được làm người ta không push được
|
|
28
|
-
# vì lý do không liên quan tới việc họ đang làm.
|
|
29
|
-
command -v node >/dev/null 2>&1 || exit 0
|
|
30
|
-
|
|
31
|
-
# Không có sổ trace thì không có gì để kiểm (project chưa chạy /generate-bdd lần nào).
|
|
32
|
-
# Sửa đường dẫn nếu trace_dir của project khác (vd ../.trace, hay {spec_source}/.trace).
|
|
33
|
-
TRACE_DIR=".trace"
|
|
34
|
-
[ -d "$TRACE_DIR" ] || exit 0
|
|
35
|
-
|
|
36
|
-
echo "→ Lint sổ trace trước khi push ..."
|
|
37
|
-
|
|
38
|
-
if npx -y @educa-corp/sdd-framework@latest --lint-trace --trace "$TRACE_DIR"; then
|
|
39
|
-
exit 0
|
|
40
|
-
fi
|
|
41
|
-
|
|
42
|
-
cat <<'MSG'
|
|
43
|
-
|
|
44
|
-
──────────────────────────────────────────────────────────────────────
|
|
45
|
-
🔴 PUSH BỊ CHẶN — sổ trace hỏng cấu trúc.
|
|
46
|
-
|
|
47
|
-
Sổ trace là dữ liệu KHÔNG regenerate được. Đẩy một sổ hỏng lên nhánh
|
|
48
|
-
chung thì mọi người kéo về đều nhận bản hỏng.
|
|
49
|
-
|
|
50
|
-
Thường gặp nhất — marker conflict git chưa giải (T7):
|
|
51
|
-
1. Mở file lint vừa nêu, xoá 3 dòng <<<<<<< ======= >>>>>>>
|
|
52
|
-
2. GIỮ CẢ HAI BÊN, đừng chọn một bên (mất row là mất vĩnh viễn)
|
|
53
|
-
3. npx @educa-corp/sdd-framework --lint-trace # xác nhận sạch
|
|
54
|
-
4. /validate-traces trong Claude Code # reconcile row trùng
|
|
55
|
-
|
|
56
|
-
Playbook đầy đủ: docs/02-concepts/traceability.md
|
|
57
|
-
Bỏ qua một lần: git push --no-verify
|
|
58
|
-
──────────────────────────────────────────────────────────────────────
|
|
59
|
-
|
|
60
|
-
MSG
|
|
61
|
-
exit 1
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
# Platform Guide — {{SERVICE_NAME}}
|
|
2
|
-
|
|
3
|
-
> Guide này cung cấp context mà Claude dùng khi làm việc trong service/repository NÀY.
|
|
4
|
-
> Giữ ngắn gọn và đúng sự thật. Cập nhật khi kiến trúc hoặc domain model thay đổi.
|
|
5
|
-
> Tham chiếu: CLAUDE.md cho chuẩn toàn dự án. File này phủ context riêng của service.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# §1. Service Overview
|
|
10
|
-
|
|
11
|
-
**Tên service**: {{SERVICE_NAME}}
|
|
12
|
-
**Mục đích**: {{ONE_SENTENCE_PURPOSE}}
|
|
13
|
-
**Bounded context**: {{BOUNDED_CONTEXT}} # vd: "Sở hữu toàn bộ logic vòng đời order. KHÔNG sở hữu payment hay inventory."
|
|
14
|
-
**Team**: {{TEAM_NAME}}
|
|
15
|
-
**Repository**: {{REPO_URL}}
|
|
16
|
-
|
|
17
|
-
Trách nhiệm chính:
|
|
18
|
-
- {{RESPONSIBILITY_1}}
|
|
19
|
-
- {{RESPONSIBILITY_2}}
|
|
20
|
-
- {{RESPONSIBILITY_3}}
|
|
21
|
-
|
|
22
|
-
Service này KHÔNG xử lý:
|
|
23
|
-
- {{OUT_OF_SCOPE_1}} # vd: "Xử lý payment → xem payment-service"
|
|
24
|
-
- {{OUT_OF_SCOPE_2}}
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
# §2. Domain Model
|
|
29
|
-
|
|
30
|
-
Các entity chính và quan hệ của chúng:
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
{{ENTITY_1}} (aggregate root)
|
|
34
|
-
├── {{CHILD_ENTITY_1}} (value object / child entity)
|
|
35
|
-
└── {{CHILD_ENTITY_2}}
|
|
36
|
-
|
|
37
|
-
{{ENTITY_2}}
|
|
38
|
-
└── references {{ENTITY_1}} by ID
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
**{{ENTITY_1}}**:
|
|
42
|
-
- Field chính: {{KEY_FIELDS}}
|
|
43
|
-
- Vòng đời status: {{STATUS_1}} → {{STATUS_2}} → {{STATUS_3}}
|
|
44
|
-
- Business rule: {{KEY_RULE_1}}
|
|
45
|
-
|
|
46
|
-
**{{ENTITY_2}}**:
|
|
47
|
-
- Field chính: {{KEY_FIELDS}}
|
|
48
|
-
- Quan hệ: {{RELATIONSHIP_DESCRIPTION}}
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
# §3. Common Patterns
|
|
53
|
-
|
|
54
|
-
Các pattern riêng của service này (bổ sung cho chuẩn toàn dự án trong CLAUDE.md):
|
|
55
|
-
|
|
56
|
-
## {{PATTERN_NAME_1}}
|
|
57
|
-
```
|
|
58
|
-
// Khi nào dùng: {{USE_CASE}}
|
|
59
|
-
// Ví dụ:
|
|
60
|
-
{{CODE_EXAMPLE}}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## {{PATTERN_NAME_2}}
|
|
64
|
-
```
|
|
65
|
-
// Khi nào dùng: {{USE_CASE}}
|
|
66
|
-
// Ví dụ:
|
|
67
|
-
{{CODE_EXAMPLE}}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
---
|
|
71
|
-
|
|
72
|
-
# §4. Integration Points
|
|
73
|
-
|
|
74
|
-
## Upstream Dependencies (service này gọi các bên dưới)
|
|
75
|
-
|
|
76
|
-
| Service / System | Cái ta gọi | Protocol | Auth |
|
|
77
|
-
|------------------|--------------|----------|------|
|
|
78
|
-
| {{UPSTREAM_1}} | {{WHAT}} | REST/gRPC/Event | {{AUTH_METHOD}} |
|
|
79
|
-
| {{UPSTREAM_2}} | {{WHAT}} | REST/gRPC/Event | {{AUTH_METHOD}} |
|
|
80
|
-
|
|
81
|
-
## Downstream Consumers (các bên dưới gọi ta hoặc tiêu thụ event của ta)
|
|
82
|
-
|
|
83
|
-
| Consumer | Cái họ dùng | Protocol |
|
|
84
|
-
|----------|---------------|----------|
|
|
85
|
-
| {{DOWNSTREAM_1}} | {{WHAT}} | REST/Event |
|
|
86
|
-
| {{DOWNSTREAM_2}} | {{WHAT}} | REST/Event |
|
|
87
|
-
|
|
88
|
-
## Event phát ra (Produced)
|
|
89
|
-
|
|
90
|
-
| Tên event | Trigger | Tóm tắt payload |
|
|
91
|
-
|------------|---------|-----------------|
|
|
92
|
-
| {{EVENT_1}} | {{WHEN}} | {{PAYLOAD_FIELDS}} |
|
|
93
|
-
| {{EVENT_2}} | {{WHEN}} | {{PAYLOAD_FIELDS}} |
|
|
94
|
-
|
|
95
|
-
## Event tiêu thụ (Consumed)
|
|
96
|
-
|
|
97
|
-
| Tên event | Từ service | Ta làm gì với nó |
|
|
98
|
-
|------------|-------------|-------------------|
|
|
99
|
-
| {{EVENT_1}} | {{SOURCE}} | {{HANDLER_ACTION}} |
|
|
100
|
-
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
# §5. Known Constraints
|
|
104
|
-
|
|
105
|
-
## Ràng buộc hiệu năng (Performance)
|
|
106
|
-
- {{PERF_CONSTRAINT_1}} # vd: "Endpoint danh sách order phải phản hồi < 200ms cho tới 1000 order"
|
|
107
|
-
- {{PERF_CONSTRAINT_2}}
|
|
108
|
-
|
|
109
|
-
## Ràng buộc business rule
|
|
110
|
-
- {{BUSINESS_CONSTRAINT_1}} # vd: "Không thể huỷ order sau khi đã ship"
|
|
111
|
-
- {{BUSINESS_CONSTRAINT_2}}
|
|
112
|
-
|
|
113
|
-
## Phụ thuộc bên ngoài (External)
|
|
114
|
-
- {{EXTERNAL_DEP_1}} # vd: "Cần inventory-service sẵn sàng để tạo order"
|
|
115
|
-
- {{EXTERNAL_DEP_2}}
|
|
116
|
-
|
|
117
|
-
## Technical Debt đã biết
|
|
118
|
-
- {{TECH_DEBT_1}} # vd: "OrderItem.price bị nhân bản từ catalog — đồng bộ qua job hằng đêm"
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
# §6. Directory Structure
|
|
123
|
-
|
|
124
|
-
```
|
|
125
|
-
{{SERVICE_ROOT}}/
|
|
126
|
-
├── {{SOURCE_DIR}}/ # Code nguồn chính
|
|
127
|
-
│ ├── {{LAYER_1}}/ # vd: controller/ hoặc handler/
|
|
128
|
-
│ │ └── {{EXAMPLE_FILE}}
|
|
129
|
-
│ ├── {{LAYER_2}}/ # vd: service/ hoặc usecase/
|
|
130
|
-
│ │ └── {{EXAMPLE_FILE}}
|
|
131
|
-
│ ├── {{LAYER_3}}/ # vd: repository/ hoặc repo/
|
|
132
|
-
│ │ └── {{EXAMPLE_FILE}}
|
|
133
|
-
│ └── {{LAYER_4}}/ # vd: model/ hoặc domain/
|
|
134
|
-
│ └── {{EXAMPLE_FILE}}
|
|
135
|
-
├── {{TEST_DIR}}/ # Test phản chiếu cấu trúc src
|
|
136
|
-
├── specs/ # File BDD feature
|
|
137
|
-
│ └── bdd/
|
|
138
|
-
│ └── {{DOMAIN}}/
|
|
139
|
-
│ └── {{UC-ID}}-{{slug}}.feature
|
|
140
|
-
└── {{CONFIG_FILE}} # vd: application.yaml / appsettings.json
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
**Convention chính của repo này:**
|
|
144
|
-
- {{CONVENTION_1}} # vd: "Mọi DTO nằm trong package api/, không trộn với domain model"
|
|
145
|
-
- {{CONVENTION_2}} # vd: "Integration test nằm ở src/test/java/.../integration/ với @Tag(\"integration\")"
|