@educa-corp/sdd-framework 0.2.5 → 0.2.7
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/commands/debug.md +4 -1
- package/commands/define-product.md +4 -1
- package/commands/dev-gen-test.md +4 -1
- package/commands/dev-run-test.md +4 -1
- package/commands/dev-smoke-test.md +4 -1
- package/commands/fix-bug.md +4 -1
- package/commands/generate-architecture.md +4 -1
- package/commands/generate-bdd.md +4 -1
- package/commands/generate-code.md +97 -31
- package/commands/generate-code.tmpl +93 -30
- package/commands/generate-design-spec.md +4 -1
- package/commands/generate-prd.md +4 -1
- package/commands/generate-spec-manifest.md +4 -1
- package/commands/generate-tech-docs.md +244 -247
- package/commands/generate-tech-docs.tmpl +2 -0
- package/commands/learn.md +4 -1
- package/commands/map-testids.md +4 -1
- package/commands/propose-scenario.md +4 -1
- package/commands/qc-analyze.md +4 -1
- package/commands/qc-design-test.md +4 -1
- package/commands/qc-plan.md +4 -1
- package/commands/qc-report.md +4 -1
- package/commands/qc-review.md +4 -1
- package/commands/qc-run-test.md +4 -1
- package/commands/refine-prd.md +4 -1
- package/commands/report-bug.md +4 -1
- package/commands/review-code.md +4 -1
- package/commands/review-context.md +4 -1
- package/commands/review-tech-docs.md +4 -1
- package/commands/setup-ai-first.md +2 -1
- package/commands/validate-traces.md +4 -1
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/commands/debug.md +4 -1
- package/core/commands/define-product.md +4 -1
- package/core/commands/dev-gen-test.md +4 -1
- package/core/commands/dev-run-test.md +4 -1
- package/core/commands/dev-smoke-test.md +4 -1
- package/core/commands/fix-bug.md +4 -1
- package/core/commands/generate-architecture.md +4 -1
- package/core/commands/generate-bdd.md +4 -1
- package/core/commands/generate-code.md +97 -31
- package/core/commands/generate-design-spec.md +4 -1
- package/core/commands/generate-prd.md +4 -1
- package/core/commands/generate-spec-manifest.md +4 -1
- package/core/commands/generate-tech-docs.md +244 -247
- package/core/commands/learn.md +4 -1
- package/core/commands/map-testids.md +4 -1
- package/core/commands/propose-scenario.md +4 -1
- package/core/commands/qc-analyze.md +4 -1
- package/core/commands/qc-design-test.md +4 -1
- package/core/commands/qc-plan.md +4 -1
- package/core/commands/qc-report.md +4 -1
- package/core/commands/qc-review.md +4 -1
- package/core/commands/qc-run-test.md +4 -1
- package/core/commands/refine-prd.md +4 -1
- package/core/commands/report-bug.md +4 -1
- package/core/commands/review-code.md +4 -1
- package/core/commands/review-context.md +4 -1
- package/core/commands/review-tech-docs.md +4 -1
- package/core/commands/setup-ai-first.md +2 -1
- package/core/commands/validate-traces.md +4 -1
- package/core/steps/context-loader.md +2 -0
- package/core/steps/gate.md +2 -1
- package/core/templates/project-context.yaml +6 -0
- package/core/templates/tech-design.template.md +238 -246
- package/docs/02-concepts/pipeline-steps/06-code.md +7 -4
- package/docs/03-guides/developer.md +6 -3
- package/docs/explain/09-generate-code.md +41 -3
- package/package.json +1 -1
- package/steps/context-loader.md +2 -0
- package/steps/gate.md +2 -1
- package/templates/project-context.yaml +6 -0
- package/templates/tech-design.template.md +238 -246
|
@@ -58,7 +58,8 @@ Hiển thị và chờ phản hồi:
|
|
|
58
58
|
|
|
59
59
|
## Bước 1 — Xác định Target File
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
0. **Tách cờ trước khi resolve target.** `$ARGUMENTS` có thể lẫn các `--flag` (vd `--phase=integration`, `--comment`, `--fix`). **Loại bỏ mọi token bắt đầu bằng `--`** ra khỏi phần dùng để tìm target — chỉ giữ phần path/UC-ID/ticket. (Các flag đó do phần logic riêng của lệnh parse ở bước sau, KHÔNG phải tên file.)
|
|
62
|
+
1. Nếu `$ARGUMENTS` (đã tách cờ) được cung cấp và trỏ tới một file tồn tại → dùng trực tiếp làm target.
|
|
62
63
|
2. Nếu `$ARGUMENTS` là một **UC-ID / ticket ID / tên rút gọn** (không có path) → phân giải thành file bằng cách glob theo bố cục feature-package. `{prd-slug}` lúc này **chưa biết**, nên dùng wildcard `*` cho segment đó, và `**` đệ quy dưới `bdd/` để phủ hết các thư mục con theo platform (`bdd/web/`, `bdd/app/`, `bdd/system/`):
|
|
63
64
|
- **Lệnh BDD** (target là `.feature`): `{specs_dir}/{domain}/*/bdd/**/{UC-ID}*.feature` — hoặc `{specs_dir}/*/*/bdd/**/{UC-ID}*.feature` nếu domain cũng chưa biết. Nếu lệnh ngụ ý một platform/scope cụ thể (vd: system tech-doc cần BDD `system/`), ưu tiên kết quả trong thư mục con platform đó.
|
|
64
65
|
- **Lệnh PRD** (target là file PRD `{TICKET-ID}-{prd-slug}.md` — file `.md` duy nhất ở gốc feature folder, cạnh `bdd/`): `{specs_dir}/{domain}/*/{TICKET-ID}*.md` nếu biết TICKET-ID; nếu không, `{specs_dir}/{domain}/*/*.md` (khớp feature folder có id tương ứng), hoặc `{specs_dir}/*/*/*.md` nếu domain cũng chưa biết. *(Glob `*/*.md` ở cấp gốc folder chỉ khớp PRD — tech-docs/design-spec `.md` nằm sâu hơn trong thư mục con.)*
|
|
@@ -144,6 +145,7 @@ Thực hiện các bước theo đúng thứ tự. Lưu mọi thứ vào bộ nh
|
|
|
144
145
|
- `paths.business_dictionary` → path tới business-dictionary.md
|
|
145
146
|
- `paths.core_entities` → path tới core-entities.md
|
|
146
147
|
- `paths.tech_docs_dir` → gốc tài liệu kỹ thuật (gộp với specs_dir trong bố cục feature-package — tech-docs nằm dưới `{specs_dir}/{domain}/{prd-slug}/tech-docs/`)
|
|
148
|
+
- `paths.src_dir` → gốc mã nguồn (nơi generate-code đặt & quét code; nguồn chính cho FE + phạm vi reuse-scan của DS5)
|
|
147
149
|
- `paths.trace_dir` → thư mục trạng thái trace; cấu trúc: `.trace/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv` (mỗi UC × platform một sổ)
|
|
148
150
|
|
|
149
151
|
Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
@@ -156,6 +158,7 @@ Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
|
156
158
|
- `business_dictionary` = `specs/domain-knowledge/business-dictionary.md`
|
|
157
159
|
- `core_entities` = `specs/domain-knowledge/core-entities.md`
|
|
158
160
|
- `tech_docs_dir` = `specs`
|
|
161
|
+
- `src_dir` = `src`
|
|
159
162
|
- `trace_dir` = `.trace`
|
|
160
163
|
|
|
161
164
|
Lưu ý: Trong bố cục feature-package, `specs_dir` là gốc thống nhất. Mọi loại spec artifact (PRD, BDD, tech-docs, design-spec) đều nằm dưới `{specs_dir}/{domain}/{prd-slug}/`. `prd-slug` là tên folder feature-package, không phải một biến config riêng.
|
|
@@ -54,7 +54,8 @@ Hiển thị và chờ phản hồi:
|
|
|
54
54
|
|
|
55
55
|
## Bước 1 — Xác định Target File
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
0. **Tách cờ trước khi resolve target.** `$ARGUMENTS` có thể lẫn các `--flag` (vd `--phase=integration`, `--comment`, `--fix`). **Loại bỏ mọi token bắt đầu bằng `--`** ra khỏi phần dùng để tìm target — chỉ giữ phần path/UC-ID/ticket. (Các flag đó do phần logic riêng của lệnh parse ở bước sau, KHÔNG phải tên file.)
|
|
58
|
+
1. Nếu `$ARGUMENTS` (đã tách cờ) được cung cấp và trỏ tới một file tồn tại → dùng trực tiếp làm target.
|
|
58
59
|
2. Nếu `$ARGUMENTS` là một **UC-ID / ticket ID / tên rút gọn** (không có path) → phân giải thành file bằng cách glob theo bố cục feature-package. `{prd-slug}` lúc này **chưa biết**, nên dùng wildcard `*` cho segment đó, và `**` đệ quy dưới `bdd/` để phủ hết các thư mục con theo platform (`bdd/web/`, `bdd/app/`, `bdd/system/`):
|
|
59
60
|
- **Lệnh BDD** (target là `.feature`): `{specs_dir}/{domain}/*/bdd/**/{UC-ID}*.feature` — hoặc `{specs_dir}/*/*/bdd/**/{UC-ID}*.feature` nếu domain cũng chưa biết. Nếu lệnh ngụ ý một platform/scope cụ thể (vd: system tech-doc cần BDD `system/`), ưu tiên kết quả trong thư mục con platform đó.
|
|
60
61
|
- **Lệnh PRD** (target là file PRD `{TICKET-ID}-{prd-slug}.md` — file `.md` duy nhất ở gốc feature folder, cạnh `bdd/`): `{specs_dir}/{domain}/*/{TICKET-ID}*.md` nếu biết TICKET-ID; nếu không, `{specs_dir}/{domain}/*/*.md` (khớp feature folder có id tương ứng), hoặc `{specs_dir}/*/*/*.md` nếu domain cũng chưa biết. *(Glob `*/*.md` ở cấp gốc folder chỉ khớp PRD — tech-docs/design-spec `.md` nằm sâu hơn trong thư mục con.)*
|
|
@@ -140,6 +141,7 @@ Thực hiện các bước theo đúng thứ tự. Lưu mọi thứ vào bộ nh
|
|
|
140
141
|
- `paths.business_dictionary` → path tới business-dictionary.md
|
|
141
142
|
- `paths.core_entities` → path tới core-entities.md
|
|
142
143
|
- `paths.tech_docs_dir` → gốc tài liệu kỹ thuật (gộp với specs_dir trong bố cục feature-package — tech-docs nằm dưới `{specs_dir}/{domain}/{prd-slug}/tech-docs/`)
|
|
144
|
+
- `paths.src_dir` → gốc mã nguồn (nơi generate-code đặt & quét code; nguồn chính cho FE + phạm vi reuse-scan của DS5)
|
|
143
145
|
- `paths.trace_dir` → thư mục trạng thái trace; cấu trúc: `.trace/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv` (mỗi UC × platform một sổ)
|
|
144
146
|
|
|
145
147
|
Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
@@ -152,6 +154,7 @@ Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
|
152
154
|
- `business_dictionary` = `specs/domain-knowledge/business-dictionary.md`
|
|
153
155
|
- `core_entities` = `specs/domain-knowledge/core-entities.md`
|
|
154
156
|
- `tech_docs_dir` = `specs`
|
|
157
|
+
- `src_dir` = `src`
|
|
155
158
|
- `trace_dir` = `.trace`
|
|
156
159
|
|
|
157
160
|
Lưu ý: Trong bố cục feature-package, `specs_dir` là gốc thống nhất. Mọi loại spec artifact (PRD, BDD, tech-docs, design-spec) đều nằm dưới `{specs_dir}/{domain}/{prd-slug}/`. `prd-slug` là tên folder feature-package, không phải một biến config riêng.
|
package/core/commands/fix-bug.md
CHANGED
|
@@ -52,7 +52,8 @@ Hiển thị và chờ phản hồi:
|
|
|
52
52
|
|
|
53
53
|
## Bước 1 — Xác định Target File
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
0. **Tách cờ trước khi resolve target.** `$ARGUMENTS` có thể lẫn các `--flag` (vd `--phase=integration`, `--comment`, `--fix`). **Loại bỏ mọi token bắt đầu bằng `--`** ra khỏi phần dùng để tìm target — chỉ giữ phần path/UC-ID/ticket. (Các flag đó do phần logic riêng của lệnh parse ở bước sau, KHÔNG phải tên file.)
|
|
56
|
+
1. Nếu `$ARGUMENTS` (đã tách cờ) được cung cấp và trỏ tới một file tồn tại → dùng trực tiếp làm target.
|
|
56
57
|
2. Nếu `$ARGUMENTS` là một **UC-ID / ticket ID / tên rút gọn** (không có path) → phân giải thành file bằng cách glob theo bố cục feature-package. `{prd-slug}` lúc này **chưa biết**, nên dùng wildcard `*` cho segment đó, và `**` đệ quy dưới `bdd/` để phủ hết các thư mục con theo platform (`bdd/web/`, `bdd/app/`, `bdd/system/`):
|
|
57
58
|
- **Lệnh BDD** (target là `.feature`): `{specs_dir}/{domain}/*/bdd/**/{UC-ID}*.feature` — hoặc `{specs_dir}/*/*/bdd/**/{UC-ID}*.feature` nếu domain cũng chưa biết. Nếu lệnh ngụ ý một platform/scope cụ thể (vd: system tech-doc cần BDD `system/`), ưu tiên kết quả trong thư mục con platform đó.
|
|
58
59
|
- **Lệnh PRD** (target là file PRD `{TICKET-ID}-{prd-slug}.md` — file `.md` duy nhất ở gốc feature folder, cạnh `bdd/`): `{specs_dir}/{domain}/*/{TICKET-ID}*.md` nếu biết TICKET-ID; nếu không, `{specs_dir}/{domain}/*/*.md` (khớp feature folder có id tương ứng), hoặc `{specs_dir}/*/*/*.md` nếu domain cũng chưa biết. *(Glob `*/*.md` ở cấp gốc folder chỉ khớp PRD — tech-docs/design-spec `.md` nằm sâu hơn trong thư mục con.)*
|
|
@@ -138,6 +139,7 @@ Thực hiện các bước theo đúng thứ tự. Lưu mọi thứ vào bộ nh
|
|
|
138
139
|
- `paths.business_dictionary` → path tới business-dictionary.md
|
|
139
140
|
- `paths.core_entities` → path tới core-entities.md
|
|
140
141
|
- `paths.tech_docs_dir` → gốc tài liệu kỹ thuật (gộp với specs_dir trong bố cục feature-package — tech-docs nằm dưới `{specs_dir}/{domain}/{prd-slug}/tech-docs/`)
|
|
142
|
+
- `paths.src_dir` → gốc mã nguồn (nơi generate-code đặt & quét code; nguồn chính cho FE + phạm vi reuse-scan của DS5)
|
|
141
143
|
- `paths.trace_dir` → thư mục trạng thái trace; cấu trúc: `.trace/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv` (mỗi UC × platform một sổ)
|
|
142
144
|
|
|
143
145
|
Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
@@ -150,6 +152,7 @@ Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
|
150
152
|
- `business_dictionary` = `specs/domain-knowledge/business-dictionary.md`
|
|
151
153
|
- `core_entities` = `specs/domain-knowledge/core-entities.md`
|
|
152
154
|
- `tech_docs_dir` = `specs`
|
|
155
|
+
- `src_dir` = `src`
|
|
153
156
|
- `trace_dir` = `.trace`
|
|
154
157
|
|
|
155
158
|
Lưu ý: Trong bố cục feature-package, `specs_dir` là gốc thống nhất. Mọi loại spec artifact (PRD, BDD, tech-docs, design-spec) đều nằm dưới `{specs_dir}/{domain}/{prd-slug}/`. `prd-slug` là tên folder feature-package, không phải một biến config riêng.
|
|
@@ -65,7 +65,8 @@ Hiển thị và chờ phản hồi:
|
|
|
65
65
|
|
|
66
66
|
## Bước 1 — Xác định Target File
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
0. **Tách cờ trước khi resolve target.** `$ARGUMENTS` có thể lẫn các `--flag` (vd `--phase=integration`, `--comment`, `--fix`). **Loại bỏ mọi token bắt đầu bằng `--`** ra khỏi phần dùng để tìm target — chỉ giữ phần path/UC-ID/ticket. (Các flag đó do phần logic riêng của lệnh parse ở bước sau, KHÔNG phải tên file.)
|
|
69
|
+
1. Nếu `$ARGUMENTS` (đã tách cờ) được cung cấp và trỏ tới một file tồn tại → dùng trực tiếp làm target.
|
|
69
70
|
2. Nếu `$ARGUMENTS` là một **UC-ID / ticket ID / tên rút gọn** (không có path) → phân giải thành file bằng cách glob theo bố cục feature-package. `{prd-slug}` lúc này **chưa biết**, nên dùng wildcard `*` cho segment đó, và `**` đệ quy dưới `bdd/` để phủ hết các thư mục con theo platform (`bdd/web/`, `bdd/app/`, `bdd/system/`):
|
|
70
71
|
- **Lệnh BDD** (target là `.feature`): `{specs_dir}/{domain}/*/bdd/**/{UC-ID}*.feature` — hoặc `{specs_dir}/*/*/bdd/**/{UC-ID}*.feature` nếu domain cũng chưa biết. Nếu lệnh ngụ ý một platform/scope cụ thể (vd: system tech-doc cần BDD `system/`), ưu tiên kết quả trong thư mục con platform đó.
|
|
71
72
|
- **Lệnh PRD** (target là file PRD `{TICKET-ID}-{prd-slug}.md` — file `.md` duy nhất ở gốc feature folder, cạnh `bdd/`): `{specs_dir}/{domain}/*/{TICKET-ID}*.md` nếu biết TICKET-ID; nếu không, `{specs_dir}/{domain}/*/*.md` (khớp feature folder có id tương ứng), hoặc `{specs_dir}/*/*/*.md` nếu domain cũng chưa biết. *(Glob `*/*.md` ở cấp gốc folder chỉ khớp PRD — tech-docs/design-spec `.md` nằm sâu hơn trong thư mục con.)*
|
|
@@ -156,6 +157,7 @@ Thực hiện các bước theo đúng thứ tự. Lưu mọi thứ vào bộ nh
|
|
|
156
157
|
- `paths.business_dictionary` → path tới business-dictionary.md
|
|
157
158
|
- `paths.core_entities` → path tới core-entities.md
|
|
158
159
|
- `paths.tech_docs_dir` → gốc tài liệu kỹ thuật (gộp với specs_dir trong bố cục feature-package — tech-docs nằm dưới `{specs_dir}/{domain}/{prd-slug}/tech-docs/`)
|
|
160
|
+
- `paths.src_dir` → gốc mã nguồn (nơi generate-code đặt & quét code; nguồn chính cho FE + phạm vi reuse-scan của DS5)
|
|
159
161
|
- `paths.trace_dir` → thư mục trạng thái trace; cấu trúc: `.trace/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv` (mỗi UC × platform một sổ)
|
|
160
162
|
|
|
161
163
|
Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
@@ -168,6 +170,7 @@ Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
|
168
170
|
- `business_dictionary` = `specs/domain-knowledge/business-dictionary.md`
|
|
169
171
|
- `core_entities` = `specs/domain-knowledge/core-entities.md`
|
|
170
172
|
- `tech_docs_dir` = `specs`
|
|
173
|
+
- `src_dir` = `src`
|
|
171
174
|
- `trace_dir` = `.trace`
|
|
172
175
|
|
|
173
176
|
Lưu ý: Trong bố cục feature-package, `specs_dir` là gốc thống nhất. Mọi loại spec artifact (PRD, BDD, tech-docs, design-spec) đều nằm dưới `{specs_dir}/{domain}/{prd-slug}/`. `prd-slug` là tên folder feature-package, không phải một biến config riêng.
|
|
@@ -52,7 +52,8 @@ Hiển thị và chờ phản hồi:
|
|
|
52
52
|
|
|
53
53
|
## Bước 1 — Xác định Target File
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
0. **Tách cờ trước khi resolve target.** `$ARGUMENTS` có thể lẫn các `--flag` (vd `--phase=integration`, `--comment`, `--fix`). **Loại bỏ mọi token bắt đầu bằng `--`** ra khỏi phần dùng để tìm target — chỉ giữ phần path/UC-ID/ticket. (Các flag đó do phần logic riêng của lệnh parse ở bước sau, KHÔNG phải tên file.)
|
|
56
|
+
1. Nếu `$ARGUMENTS` (đã tách cờ) được cung cấp và trỏ tới một file tồn tại → dùng trực tiếp làm target.
|
|
56
57
|
2. Nếu `$ARGUMENTS` là một **UC-ID / ticket ID / tên rút gọn** (không có path) → phân giải thành file bằng cách glob theo bố cục feature-package. `{prd-slug}` lúc này **chưa biết**, nên dùng wildcard `*` cho segment đó, và `**` đệ quy dưới `bdd/` để phủ hết các thư mục con theo platform (`bdd/web/`, `bdd/app/`, `bdd/system/`):
|
|
57
58
|
- **Lệnh BDD** (target là `.feature`): `{specs_dir}/{domain}/*/bdd/**/{UC-ID}*.feature` — hoặc `{specs_dir}/*/*/bdd/**/{UC-ID}*.feature` nếu domain cũng chưa biết. Nếu lệnh ngụ ý một platform/scope cụ thể (vd: system tech-doc cần BDD `system/`), ưu tiên kết quả trong thư mục con platform đó.
|
|
58
59
|
- **Lệnh PRD** (target là file PRD `{TICKET-ID}-{prd-slug}.md` — file `.md` duy nhất ở gốc feature folder, cạnh `bdd/`): `{specs_dir}/{domain}/*/{TICKET-ID}*.md` nếu biết TICKET-ID; nếu không, `{specs_dir}/{domain}/*/*.md` (khớp feature folder có id tương ứng), hoặc `{specs_dir}/*/*/*.md` nếu domain cũng chưa biết. *(Glob `*/*.md` ở cấp gốc folder chỉ khớp PRD — tech-docs/design-spec `.md` nằm sâu hơn trong thư mục con.)*
|
|
@@ -136,6 +137,7 @@ Thực hiện các bước theo đúng thứ tự. Lưu mọi thứ vào bộ nh
|
|
|
136
137
|
- `paths.business_dictionary` → path tới business-dictionary.md
|
|
137
138
|
- `paths.core_entities` → path tới core-entities.md
|
|
138
139
|
- `paths.tech_docs_dir` → gốc tài liệu kỹ thuật (gộp với specs_dir trong bố cục feature-package — tech-docs nằm dưới `{specs_dir}/{domain}/{prd-slug}/tech-docs/`)
|
|
140
|
+
- `paths.src_dir` → gốc mã nguồn (nơi generate-code đặt & quét code; nguồn chính cho FE + phạm vi reuse-scan của DS5)
|
|
139
141
|
- `paths.trace_dir` → thư mục trạng thái trace; cấu trúc: `.trace/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv` (mỗi UC × platform một sổ)
|
|
140
142
|
|
|
141
143
|
Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
@@ -148,6 +150,7 @@ Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
|
148
150
|
- `business_dictionary` = `specs/domain-knowledge/business-dictionary.md`
|
|
149
151
|
- `core_entities` = `specs/domain-knowledge/core-entities.md`
|
|
150
152
|
- `tech_docs_dir` = `specs`
|
|
153
|
+
- `src_dir` = `src`
|
|
151
154
|
- `trace_dir` = `.trace`
|
|
152
155
|
|
|
153
156
|
Lưu ý: Trong bố cục feature-package, `specs_dir` là gốc thống nhất. Mọi loại spec artifact (PRD, BDD, tech-docs, design-spec) đều nằm dưới `{specs_dir}/{domain}/{prd-slug}/`. `prd-slug` là tên folder feature-package, không phải một biến config riêng.
|
|
@@ -52,7 +52,8 @@ Hiển thị và chờ phản hồi:
|
|
|
52
52
|
|
|
53
53
|
## Bước 1 — Xác định Target File
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
0. **Tách cờ trước khi resolve target.** `$ARGUMENTS` có thể lẫn các `--flag` (vd `--phase=integration`, `--comment`, `--fix`). **Loại bỏ mọi token bắt đầu bằng `--`** ra khỏi phần dùng để tìm target — chỉ giữ phần path/UC-ID/ticket. (Các flag đó do phần logic riêng của lệnh parse ở bước sau, KHÔNG phải tên file.)
|
|
56
|
+
1. Nếu `$ARGUMENTS` (đã tách cờ) được cung cấp và trỏ tới một file tồn tại → dùng trực tiếp làm target.
|
|
56
57
|
2. Nếu `$ARGUMENTS` là một **UC-ID / ticket ID / tên rút gọn** (không có path) → phân giải thành file bằng cách glob theo bố cục feature-package. `{prd-slug}` lúc này **chưa biết**, nên dùng wildcard `*` cho segment đó, và `**` đệ quy dưới `bdd/` để phủ hết các thư mục con theo platform (`bdd/web/`, `bdd/app/`, `bdd/system/`):
|
|
57
58
|
- **Lệnh BDD** (target là `.feature`): `{specs_dir}/{domain}/*/bdd/**/{UC-ID}*.feature` — hoặc `{specs_dir}/*/*/bdd/**/{UC-ID}*.feature` nếu domain cũng chưa biết. Nếu lệnh ngụ ý một platform/scope cụ thể (vd: system tech-doc cần BDD `system/`), ưu tiên kết quả trong thư mục con platform đó.
|
|
58
59
|
- **Lệnh PRD** (target là file PRD `{TICKET-ID}-{prd-slug}.md` — file `.md` duy nhất ở gốc feature folder, cạnh `bdd/`): `{specs_dir}/{domain}/*/{TICKET-ID}*.md` nếu biết TICKET-ID; nếu không, `{specs_dir}/{domain}/*/*.md` (khớp feature folder có id tương ứng), hoặc `{specs_dir}/*/*/*.md` nếu domain cũng chưa biết. *(Glob `*/*.md` ở cấp gốc folder chỉ khớp PRD — tech-docs/design-spec `.md` nằm sâu hơn trong thư mục con.)*
|
|
@@ -138,6 +139,7 @@ Thực hiện các bước theo đúng thứ tự. Lưu mọi thứ vào bộ nh
|
|
|
138
139
|
- `paths.business_dictionary` → path tới business-dictionary.md
|
|
139
140
|
- `paths.core_entities` → path tới core-entities.md
|
|
140
141
|
- `paths.tech_docs_dir` → gốc tài liệu kỹ thuật (gộp với specs_dir trong bố cục feature-package — tech-docs nằm dưới `{specs_dir}/{domain}/{prd-slug}/tech-docs/`)
|
|
142
|
+
- `paths.src_dir` → gốc mã nguồn (nơi generate-code đặt & quét code; nguồn chính cho FE + phạm vi reuse-scan của DS5)
|
|
141
143
|
- `paths.trace_dir` → thư mục trạng thái trace; cấu trúc: `.trace/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv` (mỗi UC × platform một sổ)
|
|
142
144
|
|
|
143
145
|
Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
@@ -150,6 +152,7 @@ Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
|
150
152
|
- `business_dictionary` = `specs/domain-knowledge/business-dictionary.md`
|
|
151
153
|
- `core_entities` = `specs/domain-knowledge/core-entities.md`
|
|
152
154
|
- `tech_docs_dir` = `specs`
|
|
155
|
+
- `src_dir` = `src`
|
|
153
156
|
- `trace_dir` = `.trace`
|
|
154
157
|
|
|
155
158
|
Lưu ý: Trong bố cục feature-package, `specs_dir` là gốc thống nhất. Mọi loại spec artifact (PRD, BDD, tech-docs, design-spec) đều nằm dưới `{specs_dir}/{domain}/{prd-slug}/`. `prd-slug` là tên folder feature-package, không phải một biến config riêng.
|
|
@@ -439,7 +442,7 @@ Lệnh này giới hạn nghiêm ngặt trong **một file feature** được tr
|
|
|
439
442
|
|
|
440
443
|
Đọc:
|
|
441
444
|
1. Chỉ file `.feature` đã giới hạn scope
|
|
442
|
-
2. Tech-doc gộp của PRD tại `{paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md` (nếu tồn tại) — **tra §10 UC Coverage làm mục lục** để định vị scenario/section của UC đang sinh; **endpoint liên quan = §4.1 entries mà §5 lane của UC này gọi tới** (đừng lấy endpoint/section của UC khác). Từ đó đọc §4 API, §4.5 client, §5 flow của đúng UC này
|
|
445
|
+
2. Tech-doc gộp của PRD tại `{paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md` (nếu tồn tại) — **tra §10 UC Coverage làm mục lục** để định vị scenario/section của UC đang sinh; **endpoint liên quan = §4.1 entries mà §5 lane của UC này gọi tới** (đừng lấy endpoint/section của UC khác). Từ đó đọc §4 API, §4.5 client, §5 flow của đúng UC này. **Đọc thêm §7 (Security & Authorization)** — luật phân quyền/enforce của UC → áp vào code; **và §8 (Error Handling & Edge Cases)** — mỗi row lỗi/biên phải có nhánh xử lý tương ứng trong code (khớp §4.3 error code), đừng chỉ code happy-path.
|
|
443
446
|
3. CLAUDE.md §architecture + §coding_standards
|
|
444
447
|
4. **(chỉ FE/App)** Design Spec — nạp qua **Guard** bên dưới (gate approved/độ-tươi + sanity), là nguồn của màn hình, component inventory, và link Figma frame từng-màn.
|
|
445
448
|
|
|
@@ -462,7 +465,7 @@ Lệnh này giới hạn nghiêm ngặt trong **một file feature** được tr
|
|
|
462
465
|
- **Sanity-scan** (như generate-bdd bước 2.5): màn thiếu state loading/error/empty, AC-UI không testable, component `[NEW]`/`[TODO]` chưa chốt, còn ❌ Missing frame → cảnh báo trong cùng CHECKPOINT.
|
|
463
466
|
- `Status: approved` VÀ `Built from PRD` khớp PRD hiện tại VÀ sạch cờ đỏ → dùng làm nguồn màn hình / component / Figma.
|
|
464
467
|
|
|
465
|
-
**Tech-doc contract (chỉ backend/system) — DS3:** *áp dụng khi lần sinh này tạo code **backend** — `@trace.platform = system
|
|
468
|
+
**Tech-doc contract (chỉ backend/system) — DS3:** *áp dụng khi lần sinh này tạo code **backend** — `@trace.platform = system` (nguồn chuẩn quyết BE/FE, xem Phase Detection). Bỏ qua FE (`@trace.platform` = `web`/`app`) — FE có nguồn shape riêng ở Phase Detection.*
|
|
466
469
|
|
|
467
470
|
Định vị tech-doc gộp `{paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md`, kiểm phần backend của UC này (§4.1 Endpoints / §4.2 Request-Response / §4.3 Error):
|
|
468
471
|
- **Brownfield** — nếu PRD Metadata `API Source: existing`: contract nằm ở Appendix "Existing API Contract" của PRD → nguồn hợp lệ, **bỏ qua DS3** (không cảnh báo).
|
|
@@ -481,13 +484,17 @@ Lệnh này giới hạn nghiêm ngặt trong **một file feature** được tr
|
|
|
481
484
|
|
|
482
485
|
## Phase Detection
|
|
483
486
|
|
|
487
|
+
> **Nguồn chuẩn quyết BE/FE = `@trace.platform` của FILE FEATURE** (`system` → BE · `web`/`app` → FE). KHÔNG dùng `platform_type` (suy từ module) để quyết BE/FE — nó chỉ dùng cho **idiom stack/module** (cú pháp, layer, thư viện). Lý do: repo fullstack một-module (vd Next.js có API route) có `platform_type` cố định một giá trị, nhưng vẫn có cả feature `system` (BE) lẫn `web` (FE) — chỉ tag của chính feature mới đúng.
|
|
488
|
+
|
|
484
489
|
Parse `$ARGUMENTS` tìm flag `--phase`:
|
|
485
490
|
|
|
486
491
|
| Flag | Ý nghĩa |
|
|
487
492
|
|---|---|
|
|
488
493
|
| `--phase=ui` | FE Phase 1 — sinh UI + layer mock API từ System BDD contract |
|
|
489
494
|
| `--phase=integration` | FE Phase 2 — thay mock adapter bằng lời gọi API thật từ tech docs |
|
|
490
|
-
| *(không có)* | Default — full
|
|
495
|
+
| *(không có)* | Default — full: **BE/`system`** → full backend; **FE (`web`/`app`)** → **FE full** (sinh UI + wire API thật trong một lần, không qua bước mock) |
|
|
496
|
+
|
|
497
|
+
**Xác định `fe_full`:** khi **KHÔNG** có `--phase` VÀ `@trace.platform` là `web`/`app` → đây là **FE full mode**. Sinh UI **và** wire API thật trong cùng một lần chạy, **bỏ qua** layer mock. Cụ thể: các section **sinh UI** chạy · **Mock API Layer** bị bỏ (chỉ dành `--phase=ui`) · **DS4** và **Integration Phase** VẪN chạy (xem điều kiện của từng section). BE/`system` ở default vẫn là full backend như trước.
|
|
491
498
|
|
|
492
499
|
**Nếu `--phase` được set — xác nhận platform:**
|
|
493
500
|
Đọc `@trace.platform` từ header file feature.
|
|
@@ -551,20 +558,55 @@ selection context, và code snippet — những thứ một URL web đơn không
|
|
|
551
558
|
qua Figma MCP và ground UI trên layout, variable, và mapping Code Connect trả về. Ưu tiên
|
|
552
559
|
component được map Code-Connect hơn là bịa markup; dùng tên token thật, không phải giá trị hardcode.
|
|
553
560
|
|
|
554
|
-
|
|
561
|
+
---
|
|
562
|
+
|
|
563
|
+
## Integration Gates — DS4 (contract) · DS5 (reuse)
|
|
564
|
+
|
|
565
|
+
*Áp dụng khi wire API thật: `--phase=integration` **HOẶC** `fe_full`. Bỏ qua `--phase=ui` và default BE.*
|
|
566
|
+
|
|
567
|
+
> **Sequencing ở `fe_full`:** hai cổng này chạy **trước** khi UI/adapter được sinh trong cùng lần chạy, nên chúng suy luận từ **BẢN THIẾT KẾ** (design-spec + tech-doc §4.5) — tức *kế hoạch*, KHÔNG phải code đã sinh. "Port do UI định nghĩa" và "mock adapter có sẵn" chỉ tồn tại ở luồng 2-pha (`--phase=integration` chạy sau `--phase=ui`); ở `fe_full` port thật được chốt tại bước Generate về sau.
|
|
568
|
+
|
|
555
569
|
Phân giải design điều khiển adapter từ **tech-doc gộp của PRD** `{paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md`:
|
|
556
570
|
- **Mapping port→endpoint→DTO→error** (ưu tiên): §4.5.4 (API Integration Layer của platform này) — mỗi client method → endpoint có thật.
|
|
557
571
|
- **Nguồn endpoint/shape**: §4.1 Endpoints + §4.2 Request-Response + §4.3 Error của cùng doc.
|
|
558
572
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
573
|
+
**Client contract gate — DS4** *(áp dụng khi `--phase=integration` **HOẶC** `fe_full`; KHÔNG áp dụng `--phase=ui` — UI vẫn degrade êm qua mock).* Đối xứng với DS3 của BE: soi §4.5.4 **đủ chưa** cho UC/platform này *trước khi* wire adapter thật.
|
|
574
|
+
|
|
575
|
+
1. **Xác định phạm vi cần:** các client method mà UC NÀY dùng — lấy từ §10 (định vị scenario của UC) → §4.5.4 rows. Nguồn interface port: `{UC-ID}ApiPort` của mock adapter (`--phase=integration`, đã có từ lần `--phase=ui` trước) HOẶC, ở `fe_full`, port do chính lần chạy này định nghĩa lúc sinh UI (§4.5.3 state + §4.5.4) — chưa có mock adapter.
|
|
576
|
+
2. **Kiểm tính đủ của §4.5.4 cho từng method:** có endpoint (resolve được ở §4.1) + map request + response→model + error→UI. *(Khác cảnh báo cũ: cái cũ chỉ bắt "thiếu HẲN §4.5.4"; DS4 bắt cả "thiếu MỘT PHẦN".)*
|
|
577
|
+
3. **Phân loại (giống DS3):**
|
|
578
|
+
- **Đủ + `@trace.status: approved` + 0 🔴 blocker-GAP (§12) chạm §4.5.4/UC này** → dùng làm nguồn, KHÔNG hỏi.
|
|
579
|
+
- **`@trace.status` = `draft`/`in-review`, HOẶC §12 còn 🔴 blocker `open` chạm UC này** → WARN (không chặn): "contract/mapping adapter chưa chốt / còn {n} blocker-GAP open — đảm bảo BE endpoint đã deploy hoặc confirm mapping thủ công; có thể rework khi §4.5.4 đổi."
|
|
580
|
+
- **Thiếu §4.5.4, HOẶC khuyết một phần cho method UC cần** →
|
|
581
|
+
a. Áp **SRC-CHAIN** (xem §Quy tắc nguồn giá trị) lấp phần thiếu từ nguồn khác (§4.1–4.3, PRD, BDD `Then`, core-entities, mock adapter đã sinh).
|
|
582
|
+
b. Phần SRC-CHAIN giải quyết được → tiếp tục.
|
|
583
|
+
c. Phần **thực sự còn trống** → **CHECKPOINT chặn mềm, GỘP mọi gap vào một lần** (mỗi gap ghi rõ "đã tìm ở: {nguồn}"):
|
|
584
|
+
```
|
|
585
|
+
⚠️ §4.5.4 chưa đủ cho {UC-ID}/{platform} — {n} mapping còn trống (đã vét SRC-CHAIN):
|
|
586
|
+
- {client method} → {thiếu gì: endpoint/field/error→UI}
|
|
587
|
+
Wire adapter thật với mapping chưa chốt sẽ phải rework.
|
|
588
|
+
Khuyến nghị (front-load): /generate-tech-docs {web|app .feature} → bổ sung §4.5.4 → /review-tech-docs.
|
|
589
|
+
Vẫn wire bây giờ? (Y = best-effort/giữ mock cho phần thiếu · N = dừng, đi hoàn thiện tech-docs)
|
|
590
|
+
```
|
|
591
|
+
Chỉ tiếp khi Y. *(Đây là "tư thế BE": trỏ ngược tech-docs thay vì hỏi live từng câu.)*
|
|
592
|
+
**FE component/service reuse gate — DS5** *(áp dụng khi `--phase=integration` **HOẶC** `fe_full`; KHÔNG áp dụng `--phase=ui`).* **Phát hiện & tái dùng** code FE đang tồn tại trước khi dựng mới — chống đẻ adapter/service **song song, mồ côi**, không nối vào app đang chạy.
|
|
593
|
+
|
|
594
|
+
1. **Định vị mock adapter framework:** tìm `{UC-ID}MockApiAdapter` trong `{paths.src_dir}/{domain}/` (output `--phase=ui`).
|
|
595
|
+
2. **Discovery code FE có sẵn:** quét `{paths.src_dir}` (phạm vi domain/feature) tìm **component / service / hook / api-client** mà các màn của UC này dùng — đối chiếu: component inventory của **design-spec**, path ở tech-doc **§4.5.2**, tên màn/UC. Lập danh sách "đã tồn tại" vs "chưa có".
|
|
596
|
+
3. **Quyết định reuse-or-new:**
|
|
597
|
+
- **CÓ mock adapter** (luồng 2-pha chuẩn) → tái dùng port/wiring của nó như cũ; **KHÔNG hỏi**.
|
|
598
|
+
- **KHÔNG có mock adapter NHƯNG discovery thấy component/service có sẵn** (brownfield / chạy integration một mình trên app đang chạy) → **CHECKPOINT hỏi, KHÔNG tự dựng mới:**
|
|
599
|
+
```
|
|
600
|
+
🔎 Thấy {N} phần FE đang tồn tại cho màn của {UC-ID}/{platform}:
|
|
601
|
+
- {path} ({component | service | hook | api-client})
|
|
602
|
+
Wire API thật vào code CÓ SẴN này, hay dựng mới?
|
|
603
|
+
R (reuse) — EXTEND/wire adapter vào component/service đang chạy (khuyến nghị)
|
|
604
|
+
N (new) — dựng adapter/service mới (chỉ khi code cũ không tái dùng được — ghi lý do)
|
|
605
|
+
```
|
|
606
|
+
- **R** → set `reuse_target` = các file có sẵn; Integration Phase **EXTEND/wire vào chúng** (áp Quy tắc EXTEND phi-phá-huỷ + Guard sau-ghi ở §File Scan), KHÔNG tạo file song song.
|
|
607
|
+
- **N** → dựng mới, ghi lý do vào report.
|
|
608
|
+
- **KHÔNG có mock adapter VÀ discovery KHÔNG thấy gì** → greenfield thật → sinh real adapter từ đầu dùng contract tech-doc (không cần hỏi).
|
|
609
|
+
4. Lưu `reuse_target` (hoặc `none`) cho Integration Phase dùng ở bước wire-up.
|
|
568
610
|
|
|
569
611
|
---
|
|
570
612
|
|
|
@@ -594,6 +636,11 @@ Trước khi định vị file, chốt **package đích** theo **Package Layout
|
|
|
594
636
|
|
|
595
637
|
**Quét module TÁI DÙNG trước khi tạo:** với mỗi layer, kiểm `{code_base_package}.{layer}` đã tồn tại trên disk chưa. Nếu đã có class phục vụ cùng entity/nghiệp vụ → **đặt member mới vào class đó (EXTEND)**, KHÔNG dựng cây layer / class song song. Chỉ tạo mới khi thực sự chưa có.
|
|
596
638
|
|
|
639
|
+
**Đặt code FE (`@trace.platform` = web/app):** quy tắc trên là cho BE (Java-style `{package}.{layer}`). FE đặt file theo thứ tự ưu tiên:
|
|
640
|
+
1. **Path ở tech-doc §4.5.2 (Component File Mapping)** — nếu có, dùng **nguyên văn** đường dẫn cột `Path` (đây là contract đặt file của FE).
|
|
641
|
+
2. **Else** → gốc `{paths.src_dir}` + quy ước thư mục của module/framework (vd `src/features/{domain}/…` React · `lib/{domain}/…` Flutter). Component/hook/service/adapter của cùng feature nằm gần nhau; **KHÔNG** rải mỗi file một nơi.
|
|
642
|
+
Adapter API mặc định tại `{paths.src_dir}/{domain}/` (khi §4.5.2 không chỉ định). Luôn **quét `{paths.src_dir}` tái dùng** như BE trước khi tạo mới (đồng bộ DS5).
|
|
643
|
+
|
|
597
644
|
---
|
|
598
645
|
|
|
599
646
|
## Seam & Stub Ledger — nối/lấp chỗ chưa implement *(chống mồ côi)*
|
|
@@ -725,9 +772,10 @@ Domain : {domain}
|
|
|
725
772
|
UC : chỉ {UC-ID} ← các file feature khác trong folder này KHÔNG được đọc
|
|
726
773
|
Tech : {language} / {framework}
|
|
727
774
|
Package : {code_base_package}.{layer} · {by-layer | by-feature} ← feature/UC ở TÊN CLASS, KHÔNG thành package (nếu by-layer)
|
|
728
|
-
Phase : {UI — mock layer | Integration — real API |
|
|
775
|
+
Phase : {UI — mock layer | Integration — real API | FE full — UI + real API | BE full} ← FE full = default trên web/app; bỏ dòng này với default BE
|
|
729
776
|
Scenarios: {N} total ({X} new, {Y} drifted, {Z} synced-skip)
|
|
730
777
|
Layer : {từ CLAUDE.md §2}
|
|
778
|
+
Client : {chỉ integration/fe_full — reuse: {reuse_target hoặc "dựng mới"} · gaps §4.5.4: {n còn trống hoặc "đủ"}} ← bỏ dòng này với BE / --phase=ui
|
|
731
779
|
|
|
732
780
|
Files:
|
|
733
781
|
CREATE {N} file mới
|
|
@@ -797,7 +845,7 @@ DTOs → Entity/Model → Repository → Service interface → Service impl →
|
|
|
797
845
|
Mỗi element **có action** (button, input, link, select, toggle, form-submit) PHẢI mang một **test-id ổn định** để QC định vị trực tiếp (không scan runtime):
|
|
798
846
|
|
|
799
847
|
1. **Nguồn id.** Nếu tech-doc gộp `{paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md` có **§4.5.6 Test Selectors** cho platform này, lấy id **nguyên văn** từ bảng đó (contract). Nếu chưa có (vd `--phase=ui` trước khi §4.5 được vẽ), **sinh id theo quy ước** `{uc-lower}-{screen}-{element}-{type}` (vd `ft001-login-submit-btn`) để QC vẫn có handle ổn định — chúng sẽ được đối chiếu với §4.5.6 của tech-design lúc integration.
|
|
800
|
-
2. **Emit qua attribute platform** (
|
|
848
|
+
2. **Emit qua attribute platform** — chọn attribute theo **`active_module`** (bảng dưới, mặc định). Chỉ override khi header `.feature` khai tường minh `@trace.testid_attr={attr}` (hiếm; dùng cho stack lai). Không có khai báo → theo module:
|
|
801
849
|
- web (`react`/`nextjs`/`vue`/`angular`) → `data-testid="..."`
|
|
802
850
|
- React Native → `testID="..."`
|
|
803
851
|
- Flutter → `Key('...')` (+ `Semantics(identifier: '...')` khi action cần)
|
|
@@ -837,24 +885,32 @@ Dựng mock từ `mock_source` đã phân giải ở Phase Detection — **shape
|
|
|
837
885
|
|
|
838
886
|
---
|
|
839
887
|
|
|
840
|
-
## Integration Phase (
|
|
888
|
+
## Integration Phase (`--phase=integration` HOẶC `fe_full`)
|
|
841
889
|
|
|
842
|
-
*Bỏ qua hoàn toàn section này nếu `--phase`
|
|
890
|
+
*Bỏ qua hoàn toàn section này nếu KHÔNG phải `--phase=integration` và KHÔNG phải `fe_full` (vd `--phase=ui`, hoặc default BE/`system`).*
|
|
891
|
+
|
|
892
|
+
*Hai chế độ vào section này:*
|
|
893
|
+
- **`--phase=integration`** — đã có mock adapter + UI từ lần `--phase=ui` trước → **thay** mock bằng real (có lật wire-up).
|
|
894
|
+
- **`fe_full`** — UI vừa được sinh trong CHÍNH lần chạy này, **không có bước mock** → wire real adapter **thẳng** (không có mock để thay/lật).
|
|
843
895
|
|
|
844
896
|
1. **Đọc integration design.** Trong tech-doc gộp `{paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md`: ưu tiên §4.5.4 (mapping port→endpoint→DTO→error của platform), dùng §4.1/§4.2/§4.3 làm nguồn endpoint / request-response / error-code. Nếu doc chưa có §4.5.4 cho platform này, trích endpoint + shape + error code trực tiếp từ §4.1–§4.3.
|
|
845
|
-
- **
|
|
846
|
-
2.
|
|
847
|
-
|
|
848
|
-
-
|
|
849
|
-
-
|
|
850
|
-
|
|
851
|
-
-
|
|
897
|
+
- **Tính đủ của §4.5.4 đã được cửa DS4 kiểm + vét SRC-CHAIN + gộp-hỏi TỪ TRƯỚC.** Ở bước này dùng thẳng kết quả đã phân giải của DS4 — **KHÔNG mở checkpoint/hỏi lại**. Nếu DS4 kết luận một mapping vẫn trống mà người đã chọn Y (best-effort) → ở `--phase=integration` giữ mock cho phần đó; ở `fe_full` để adapter trả stub, tag `@trace.stub`, ghi sổ seam; đừng bịa giá trị.
|
|
898
|
+
2. **Nguồn interface port `{UC-ID}ApiPort`:**
|
|
899
|
+
- `--phase=integration` (có mock) → đọc từ mock adapter có sẵn (output `--phase=ui`). Real adapter implements **cùng** interface → shape port/DTO đã cố định, **không hỏi lại shape**.
|
|
900
|
+
- `reuse_target` (DS5 chọn **R**) → dùng interface/kiểu mà **service/hook có sẵn** đang khai báo; adapter mới phải khớp chữ ký chúng đang gọi (không đổi hợp đồng của code đang chạy).
|
|
901
|
+
- `fe_full` greenfield → port do UI vừa sinh trong lần này định nghĩa (§4.5.3/§4.5.4). Không có mock adapter để đọc.
|
|
902
|
+
3. **Sinh / lắp real API adapter** — theo kết quả **DS5**:
|
|
903
|
+
- **`reuse_target` = none** (greenfield / DS5 chọn N) → sinh file mới `{paths.src_dir}/{domain}/{UC-ID}ApiAdapter.{ext}`, implements `{UC-ID}ApiPort`.
|
|
904
|
+
- **`reuse_target` có file** (DS5 chọn R) → **EXTEND vào service/api-client/hook đang chạy** (áp Quy tắc EXTEND phi-phá-huỷ + Guard sau-ghi ở §File Scan): thay lời gọi mock/placeholder bằng lời gọi HTTP thật **tại chỗ**, giữ nguyên mọi member cũ; **KHÔNG** tạo `{UC-ID}ApiAdapter` song song.
|
|
905
|
+
- Chung: gọi HTTP thật tới endpoint từ contract tech-doc; map field response sang shape port/service khai báo; tag:
|
|
852
906
|
```
|
|
853
907
|
@trace.implements={UC-ID}-SC{N}
|
|
854
908
|
@trace.tech_doc_revision={đọc từ header tech-doc}
|
|
855
909
|
```
|
|
856
|
-
4. **
|
|
857
|
-
|
|
910
|
+
4. **Wire-up:**
|
|
911
|
+
- `--phase=integration` (có mock) → **lật** DI binding / env flag để service/hook dùng adapter thật thay vì mock. **KHÔNG xoá mock adapter** — giữ cho unit test.
|
|
912
|
+
- `reuse_target` (DS5 chọn R) → wiring đã nằm trong chính component/service có sẵn (đã EXTEND ở bước 3) → **không thêm binding song song**; chỉ chỉnh cấu hình bật đường thật nếu code cũ có cờ mock.
|
|
913
|
+
- `fe_full` greenfield → wire service/hook thẳng vào `{UC-ID}ApiAdapter` (thật); không sinh mock adapter (unit test dùng stub/fake tại chỗ khi cần).
|
|
858
914
|
|
|
859
915
|
---
|
|
860
916
|
|
|
@@ -873,6 +929,16 @@ Dựng mock từ `mock_source` đã phân giải ở Phase Detection — **shape
|
|
|
873
929
|
{conventions.build_command} # từ project-context.yaml, tối đa 3 retry
|
|
874
930
|
```
|
|
875
931
|
|
|
932
|
+
> **GATE build (BẮT BUỘC):** chỉ khi build **SUCCESS** mới được đi tiếp sang **Write Trace State** và **Commit**.
|
|
933
|
+
> - Fail → sửa lỗi rồi retry (tối đa 3 lần).
|
|
934
|
+
> - **Vẫn fail sau 3 retry → DỪNG.** KHÔNG ghi trace, KHÔNG commit (trace/repo không được nói "đã xong" khi chưa build được). Xuất:
|
|
935
|
+
> ```
|
|
936
|
+
> ❌ Build FAIL sau 3 lần thử — không ghi trace, không commit.
|
|
937
|
+
> Lỗi cuối: {tóm tắt}
|
|
938
|
+
> File đã sinh giữ nguyên trên working tree để bạn sửa tay hoặc chạy /debug.
|
|
939
|
+
> ```
|
|
940
|
+
> Đặt Status badge = ❌ ở report cuối và dừng (bỏ qua Write Trace / Refresh Panel / Commit).
|
|
941
|
+
|
|
876
942
|
## Write Trace State
|
|
877
943
|
|
|
878
944
|
Cập nhật `{paths.trace_dir}/{domain}/{prd-slug}/{UC-ID}-{@trace.platform}.tsv` — với mỗi scenario đã implement, tìm row có sẵn theo `sc_id` và chỉ cập nhật các cột sau. *(Umbrella + `spec_source`: `trace_dir` phân giải về `{spec_source}/.trace` — lệnh này chạy từ `service_root` nhưng ghi trace row vào **spec repo** (liên-repo); commit/push spec submodule cho lần cập nhật trace, cùng với push code 2 tầng.)*
|
|
@@ -883,8 +949,8 @@ Cập nhật `{paths.trace_dir}/{domain}/{prd-slug}/{UC-ID}-{@trace.platform}.ts
|
|
|
883
949
|
| `implemented_by` | `{ControllerClass}.{methodName}` |
|
|
884
950
|
| `bdd_version` | `@trace.bdd_version` từ header `.feature` |
|
|
885
951
|
| `tech_doc_revision` | `@trace.revision` từ tech-doc gộp `{TICKET-ID}-tech-design.md` (§4 backend đã điều khiển codegen của UC này), hoặc `—` nếu chưa có doc |
|
|
886
|
-
| `fe_tech_doc_revision` | `@trace.revision` của cùng tech-doc gộp, ghi khi sinh FE
|
|
887
|
-
| `fe_phase` | `ui` nếu `--phase=ui` \| `integrated` nếu `--phase=integration`
|
|
952
|
+
| `fe_tech_doc_revision` | `@trace.revision` của cùng tech-doc gộp, ghi khi sinh FE có wire adapter theo §4.5.4 (`--phase=integration` **hoặc** `fe_full`); `—` cho BE, hoặc cho FE `--phase=ui` / chưa có §4.5.4 |
|
|
953
|
+
| `fe_phase` | `ui` nếu `--phase=ui` \| `integrated` nếu `--phase=integration` **hoặc** `fe_full` (đều đã wire real adapter) \| `—` cho BE |
|
|
888
954
|
| `last_updated` | hôm nay `YYYY-MM-DD` |
|
|
889
955
|
|
|
890
956
|
Giữ nguyên mọi cột khác (`sc_title`, `spec_ver`, `prd_version`, `prd_status`, `uc_status`, `test_count`, `test_classes`, `dev_selftest`, `dev_selftest_at`, `qc_status`, `qc_run_at`, `qc_owner`, `qc_blocked_by`).
|
|
@@ -1038,8 +1104,8 @@ Next : {lệnh gợi ý kèm ví dụ tham số}
|
|
|
1038
1104
|
/generate-code Hoàn tất — {UC-ID}
|
|
1039
1105
|
Files: created={N}, extended={M}, filled={F} stub, skipped={K} | Build: SUCCESS
|
|
1040
1106
|
Branch: feature/{TICKET_ID}-{slug}
|
|
1041
|
-
Phase : {UI (mock layer) | Integration (real API) |
|
|
1042
|
-
fe_phase : {ui | integrated | —}
|
|
1107
|
+
Phase : {UI (mock layer) | Integration (real API) | FE full (UI + real API) | BE full}
|
|
1108
|
+
fe_phase : {ui | integrated (—phase=integration | fe_full) | —}
|
|
1043
1109
|
Figma : {Dev Mode MCP local (grounded) | ⚠️ chỉ link web + text spec (không có MCP local) | n/a cho BE} ← chỉ UI FE/App
|
|
1044
1110
|
|
|
1045
1111
|
Next:
|
|
@@ -52,7 +52,8 @@ Hiển thị và chờ phản hồi:
|
|
|
52
52
|
|
|
53
53
|
## Bước 1 — Xác định Target File
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
0. **Tách cờ trước khi resolve target.** `$ARGUMENTS` có thể lẫn các `--flag` (vd `--phase=integration`, `--comment`, `--fix`). **Loại bỏ mọi token bắt đầu bằng `--`** ra khỏi phần dùng để tìm target — chỉ giữ phần path/UC-ID/ticket. (Các flag đó do phần logic riêng của lệnh parse ở bước sau, KHÔNG phải tên file.)
|
|
56
|
+
1. Nếu `$ARGUMENTS` (đã tách cờ) được cung cấp và trỏ tới một file tồn tại → dùng trực tiếp làm target.
|
|
56
57
|
2. Nếu `$ARGUMENTS` là một **UC-ID / ticket ID / tên rút gọn** (không có path) → phân giải thành file bằng cách glob theo bố cục feature-package. `{prd-slug}` lúc này **chưa biết**, nên dùng wildcard `*` cho segment đó, và `**` đệ quy dưới `bdd/` để phủ hết các thư mục con theo platform (`bdd/web/`, `bdd/app/`, `bdd/system/`):
|
|
57
58
|
- **Lệnh BDD** (target là `.feature`): `{specs_dir}/{domain}/*/bdd/**/{UC-ID}*.feature` — hoặc `{specs_dir}/*/*/bdd/**/{UC-ID}*.feature` nếu domain cũng chưa biết. Nếu lệnh ngụ ý một platform/scope cụ thể (vd: system tech-doc cần BDD `system/`), ưu tiên kết quả trong thư mục con platform đó.
|
|
58
59
|
- **Lệnh PRD** (target là file PRD `{TICKET-ID}-{prd-slug}.md` — file `.md` duy nhất ở gốc feature folder, cạnh `bdd/`): `{specs_dir}/{domain}/*/{TICKET-ID}*.md` nếu biết TICKET-ID; nếu không, `{specs_dir}/{domain}/*/*.md` (khớp feature folder có id tương ứng), hoặc `{specs_dir}/*/*/*.md` nếu domain cũng chưa biết. *(Glob `*/*.md` ở cấp gốc folder chỉ khớp PRD — tech-docs/design-spec `.md` nằm sâu hơn trong thư mục con.)*
|
|
@@ -138,6 +139,7 @@ Thực hiện các bước theo đúng thứ tự. Lưu mọi thứ vào bộ nh
|
|
|
138
139
|
- `paths.business_dictionary` → path tới business-dictionary.md
|
|
139
140
|
- `paths.core_entities` → path tới core-entities.md
|
|
140
141
|
- `paths.tech_docs_dir` → gốc tài liệu kỹ thuật (gộp với specs_dir trong bố cục feature-package — tech-docs nằm dưới `{specs_dir}/{domain}/{prd-slug}/tech-docs/`)
|
|
142
|
+
- `paths.src_dir` → gốc mã nguồn (nơi generate-code đặt & quét code; nguồn chính cho FE + phạm vi reuse-scan của DS5)
|
|
141
143
|
- `paths.trace_dir` → thư mục trạng thái trace; cấu trúc: `.trace/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv` (mỗi UC × platform một sổ)
|
|
142
144
|
|
|
143
145
|
Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
@@ -150,6 +152,7 @@ Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
|
150
152
|
- `business_dictionary` = `specs/domain-knowledge/business-dictionary.md`
|
|
151
153
|
- `core_entities` = `specs/domain-knowledge/core-entities.md`
|
|
152
154
|
- `tech_docs_dir` = `specs`
|
|
155
|
+
- `src_dir` = `src`
|
|
153
156
|
- `trace_dir` = `.trace`
|
|
154
157
|
|
|
155
158
|
Lưu ý: Trong bố cục feature-package, `specs_dir` là gốc thống nhất. Mọi loại spec artifact (PRD, BDD, tech-docs, design-spec) đều nằm dưới `{specs_dir}/{domain}/{prd-slug}/`. `prd-slug` là tên folder feature-package, không phải một biến config riêng.
|
|
@@ -52,7 +52,8 @@ Hiển thị và chờ phản hồi:
|
|
|
52
52
|
|
|
53
53
|
## Bước 1 — Xác định Target File
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
0. **Tách cờ trước khi resolve target.** `$ARGUMENTS` có thể lẫn các `--flag` (vd `--phase=integration`, `--comment`, `--fix`). **Loại bỏ mọi token bắt đầu bằng `--`** ra khỏi phần dùng để tìm target — chỉ giữ phần path/UC-ID/ticket. (Các flag đó do phần logic riêng của lệnh parse ở bước sau, KHÔNG phải tên file.)
|
|
56
|
+
1. Nếu `$ARGUMENTS` (đã tách cờ) được cung cấp và trỏ tới một file tồn tại → dùng trực tiếp làm target.
|
|
56
57
|
2. Nếu `$ARGUMENTS` là một **UC-ID / ticket ID / tên rút gọn** (không có path) → phân giải thành file bằng cách glob theo bố cục feature-package. `{prd-slug}` lúc này **chưa biết**, nên dùng wildcard `*` cho segment đó, và `**` đệ quy dưới `bdd/` để phủ hết các thư mục con theo platform (`bdd/web/`, `bdd/app/`, `bdd/system/`):
|
|
57
58
|
- **Lệnh BDD** (target là `.feature`): `{specs_dir}/{domain}/*/bdd/**/{UC-ID}*.feature` — hoặc `{specs_dir}/*/*/bdd/**/{UC-ID}*.feature` nếu domain cũng chưa biết. Nếu lệnh ngụ ý một platform/scope cụ thể (vd: system tech-doc cần BDD `system/`), ưu tiên kết quả trong thư mục con platform đó.
|
|
58
59
|
- **Lệnh PRD** (target là file PRD `{TICKET-ID}-{prd-slug}.md` — file `.md` duy nhất ở gốc feature folder, cạnh `bdd/`): `{specs_dir}/{domain}/*/{TICKET-ID}*.md` nếu biết TICKET-ID; nếu không, `{specs_dir}/{domain}/*/*.md` (khớp feature folder có id tương ứng), hoặc `{specs_dir}/*/*/*.md` nếu domain cũng chưa biết. *(Glob `*/*.md` ở cấp gốc folder chỉ khớp PRD — tech-docs/design-spec `.md` nằm sâu hơn trong thư mục con.)*
|
|
@@ -138,6 +139,7 @@ Thực hiện các bước theo đúng thứ tự. Lưu mọi thứ vào bộ nh
|
|
|
138
139
|
- `paths.business_dictionary` → path tới business-dictionary.md
|
|
139
140
|
- `paths.core_entities` → path tới core-entities.md
|
|
140
141
|
- `paths.tech_docs_dir` → gốc tài liệu kỹ thuật (gộp với specs_dir trong bố cục feature-package — tech-docs nằm dưới `{specs_dir}/{domain}/{prd-slug}/tech-docs/`)
|
|
142
|
+
- `paths.src_dir` → gốc mã nguồn (nơi generate-code đặt & quét code; nguồn chính cho FE + phạm vi reuse-scan của DS5)
|
|
141
143
|
- `paths.trace_dir` → thư mục trạng thái trace; cấu trúc: `.trace/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv` (mỗi UC × platform một sổ)
|
|
142
144
|
|
|
143
145
|
Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
@@ -150,6 +152,7 @@ Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
|
150
152
|
- `business_dictionary` = `specs/domain-knowledge/business-dictionary.md`
|
|
151
153
|
- `core_entities` = `specs/domain-knowledge/core-entities.md`
|
|
152
154
|
- `tech_docs_dir` = `specs`
|
|
155
|
+
- `src_dir` = `src`
|
|
153
156
|
- `trace_dir` = `.trace`
|
|
154
157
|
|
|
155
158
|
Lưu ý: Trong bố cục feature-package, `specs_dir` là gốc thống nhất. Mọi loại spec artifact (PRD, BDD, tech-docs, design-spec) đều nằm dưới `{specs_dir}/{domain}/{prd-slug}/`. `prd-slug` là tên folder feature-package, không phải một biến config riêng.
|
|
@@ -56,7 +56,8 @@ Hiển thị và chờ phản hồi:
|
|
|
56
56
|
|
|
57
57
|
## Bước 1 — Xác định Target File
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
0. **Tách cờ trước khi resolve target.** `$ARGUMENTS` có thể lẫn các `--flag` (vd `--phase=integration`, `--comment`, `--fix`). **Loại bỏ mọi token bắt đầu bằng `--`** ra khỏi phần dùng để tìm target — chỉ giữ phần path/UC-ID/ticket. (Các flag đó do phần logic riêng của lệnh parse ở bước sau, KHÔNG phải tên file.)
|
|
60
|
+
1. Nếu `$ARGUMENTS` (đã tách cờ) được cung cấp và trỏ tới một file tồn tại → dùng trực tiếp làm target.
|
|
60
61
|
2. Nếu `$ARGUMENTS` là một **UC-ID / ticket ID / tên rút gọn** (không có path) → phân giải thành file bằng cách glob theo bố cục feature-package. `{prd-slug}` lúc này **chưa biết**, nên dùng wildcard `*` cho segment đó, và `**` đệ quy dưới `bdd/` để phủ hết các thư mục con theo platform (`bdd/web/`, `bdd/app/`, `bdd/system/`):
|
|
61
62
|
- **Lệnh BDD** (target là `.feature`): `{specs_dir}/{domain}/*/bdd/**/{UC-ID}*.feature` — hoặc `{specs_dir}/*/*/bdd/**/{UC-ID}*.feature` nếu domain cũng chưa biết. Nếu lệnh ngụ ý một platform/scope cụ thể (vd: system tech-doc cần BDD `system/`), ưu tiên kết quả trong thư mục con platform đó.
|
|
62
63
|
- **Lệnh PRD** (target là file PRD `{TICKET-ID}-{prd-slug}.md` — file `.md` duy nhất ở gốc feature folder, cạnh `bdd/`): `{specs_dir}/{domain}/*/{TICKET-ID}*.md` nếu biết TICKET-ID; nếu không, `{specs_dir}/{domain}/*/*.md` (khớp feature folder có id tương ứng), hoặc `{specs_dir}/*/*/*.md` nếu domain cũng chưa biết. *(Glob `*/*.md` ở cấp gốc folder chỉ khớp PRD — tech-docs/design-spec `.md` nằm sâu hơn trong thư mục con.)*
|
|
@@ -143,6 +144,7 @@ Thực hiện các bước theo đúng thứ tự. Lưu mọi thứ vào bộ nh
|
|
|
143
144
|
- `paths.business_dictionary` → path tới business-dictionary.md
|
|
144
145
|
- `paths.core_entities` → path tới core-entities.md
|
|
145
146
|
- `paths.tech_docs_dir` → gốc tài liệu kỹ thuật (gộp với specs_dir trong bố cục feature-package — tech-docs nằm dưới `{specs_dir}/{domain}/{prd-slug}/tech-docs/`)
|
|
147
|
+
- `paths.src_dir` → gốc mã nguồn (nơi generate-code đặt & quét code; nguồn chính cho FE + phạm vi reuse-scan của DS5)
|
|
146
148
|
- `paths.trace_dir` → thư mục trạng thái trace; cấu trúc: `.trace/{domain}/{prd-slug}/{UC-ID}-{platform}.tsv` (mỗi UC × platform một sổ)
|
|
147
149
|
|
|
148
150
|
Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
@@ -155,6 +157,7 @@ Nếu không có section `paths`, dùng các giá trị mặc định:
|
|
|
155
157
|
- `business_dictionary` = `specs/domain-knowledge/business-dictionary.md`
|
|
156
158
|
- `core_entities` = `specs/domain-knowledge/core-entities.md`
|
|
157
159
|
- `tech_docs_dir` = `specs`
|
|
160
|
+
- `src_dir` = `src`
|
|
158
161
|
- `trace_dir` = `.trace`
|
|
159
162
|
|
|
160
163
|
Lưu ý: Trong bố cục feature-package, `specs_dir` là gốc thống nhất. Mọi loại spec artifact (PRD, BDD, tech-docs, design-spec) đều nằm dưới `{specs_dir}/{domain}/{prd-slug}/`. `prd-slug` là tên folder feature-package, không phải một biến config riêng.
|