@anhth2/spec-driven-dev-plugin 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/commands/debug.md +42 -7
  2. package/commands/define-product.md +42 -7
  3. package/commands/dev-gen-test.md +60 -17
  4. package/commands/dev-run-test.md +61 -18
  5. package/commands/dev-run-test.tmpl +1 -1
  6. package/commands/dev-smoke-test.md +42 -7
  7. package/commands/fix-bug.md +42 -7
  8. package/commands/generate-bdd.md +67 -21
  9. package/commands/generate-bdd.tmpl +7 -4
  10. package/commands/generate-code.md +113 -35
  11. package/commands/generate-code.tmpl +53 -18
  12. package/commands/generate-design-spec.md +42 -7
  13. package/commands/generate-prd.md +42 -7
  14. package/commands/generate-spec-manifest.md +42 -7
  15. package/commands/generate-tech-docs.md +229 -20
  16. package/commands/generate-tech-docs.tmpl +187 -13
  17. package/commands/learn.md +42 -7
  18. package/commands/map-testids.md +564 -0
  19. package/commands/map-testids.tmpl +81 -0
  20. package/commands/propose-scenario.md +42 -7
  21. package/commands/qc-analyze.md +42 -7
  22. package/commands/qc-design-test.md +44 -8
  23. package/commands/qc-design-test.tmpl +2 -1
  24. package/commands/qc-plan.md +42 -7
  25. package/commands/qc-report.md +42 -7
  26. package/commands/qc-review.md +42 -7
  27. package/commands/qc-run-test.md +62 -18
  28. package/commands/qc-run-test.tmpl +2 -1
  29. package/commands/refine-prd.md +42 -7
  30. package/commands/report-bug.md +42 -7
  31. package/commands/review-code.md +42 -7
  32. package/commands/review-context.md +42 -7
  33. package/commands/review-tech-docs.md +45 -9
  34. package/commands/review-tech-docs.tmpl +3 -2
  35. package/commands/setup-ai-first.md +37 -4
  36. package/commands/setup-ai-first.tmpl +2 -2
  37. package/commands/sync.md +35 -2
  38. package/commands/update-framework.md +35 -2
  39. package/commands/validate-traces.md +85 -40
  40. package/commands/validate-traces.tmpl +43 -33
  41. package/core/FRAMEWORK_VERSION +1 -1
  42. package/core/commands/debug.md +42 -7
  43. package/core/commands/define-product.md +42 -7
  44. package/core/commands/dev-gen-test.md +60 -17
  45. package/core/commands/dev-run-test.md +61 -18
  46. package/core/commands/dev-smoke-test.md +42 -7
  47. package/core/commands/fix-bug.md +42 -7
  48. package/core/commands/generate-bdd.md +67 -21
  49. package/core/commands/generate-code.md +113 -35
  50. package/core/commands/generate-design-spec.md +42 -7
  51. package/core/commands/generate-prd.md +42 -7
  52. package/core/commands/generate-spec-manifest.md +42 -7
  53. package/core/commands/generate-tech-docs.md +229 -20
  54. package/core/commands/learn.md +42 -7
  55. package/core/commands/map-testids.md +564 -0
  56. package/core/commands/propose-scenario.md +42 -7
  57. package/core/commands/qc-analyze.md +42 -7
  58. package/core/commands/qc-design-test.md +44 -8
  59. package/core/commands/qc-plan.md +42 -7
  60. package/core/commands/qc-report.md +42 -7
  61. package/core/commands/qc-review.md +42 -7
  62. package/core/commands/qc-run-test.md +62 -18
  63. package/core/commands/refine-prd.md +42 -7
  64. package/core/commands/report-bug.md +42 -7
  65. package/core/commands/review-code.md +42 -7
  66. package/core/commands/review-context.md +42 -7
  67. package/core/commands/review-tech-docs.md +45 -9
  68. package/core/commands/setup-ai-first.md +37 -4
  69. package/core/commands/sync.md +35 -2
  70. package/core/commands/update-framework.md +35 -2
  71. package/core/commands/validate-traces.md +85 -40
  72. package/core/modules/qc-playwright/stack-profile.yaml +1 -0
  73. package/core/skills/code/SKILL.md +77 -9
  74. package/core/skills/debug/SKILL.md +112 -11
  75. package/core/skills/design-spec/SKILL.md +42 -7
  76. package/core/skills/discovery/SKILL.md +42 -7
  77. package/core/skills/prd/SKILL.md +70 -4
  78. package/core/skills/setup-ai-first/SKILL.md +35 -2
  79. package/core/skills/spec/SKILL.md +70 -4
  80. package/core/skills/test/SKILL.md +119 -16
  81. package/core/steps/context-loader.md +7 -5
  82. package/core/steps/report-footer.md +35 -2
  83. package/core/steps/trace-mirror.md +18 -10
  84. package/core/templates/project-context.yaml +8 -5
  85. package/docs/01-getting-started/core-concepts.md +7 -7
  86. package/docs/01-getting-started/installation.md +2 -2
  87. package/docs/01-getting-started/quickstart.md +1 -1
  88. package/docs/02-guides/README.md +1 -2
  89. package/docs/02-guides/developer/README.md +1 -1
  90. package/docs/02-guides/developer/bdd-and-trace.md +10 -8
  91. package/docs/02-guides/developer/commands.md +3 -3
  92. package/docs/02-guides/developer/scenarios.md +26 -14
  93. package/docs/02-guides/developer/workflow.md +80 -20
  94. package/docs/02-guides/product-owner/README.md +6 -4
  95. package/docs/02-guides/product-owner/commands.md +1 -1
  96. package/docs/02-guides/product-owner/scenarios.md +80 -1
  97. package/docs/02-guides/tester/README.md +12 -11
  98. package/docs/02-guides/tester/bug-reporting.md +1 -1
  99. package/docs/02-guides/{qc-automation.md → tester/qc-automation.md} +14 -6
  100. package/docs/02-guides/tester/reading-specs.md +4 -4
  101. package/docs/02-guides/tester/scenarios.md +5 -5
  102. package/docs/02-guides/tester/spec-manifest.md +17 -12
  103. package/docs/02-guides/tester/test-checklist.md +3 -3
  104. package/docs/02-guides/tester/workflow.md +8 -11
  105. package/docs/03-concepts/architecture.md +5 -4
  106. package/docs/03-concepts/pipeline.md +18 -6
  107. package/docs/03-concepts/traceability.md +17 -17
  108. package/docs/04-operations/README.md +1 -1
  109. package/docs/04-operations/bug-flow.md +4 -4
  110. package/docs/04-operations/sync-and-update.md +163 -38
  111. package/docs/05-reference/README.md +3 -0
  112. package/docs/05-reference/command-cheatsheet.md +147 -0
  113. package/docs/05-reference/commands.md +72 -69
  114. package/docs/05-reference/modules.md +2 -2
  115. package/docs/05-reference/trace-schema.md +15 -14
  116. package/docs/README.md +3 -5
  117. package/modules/qc-playwright/stack-profile.yaml +1 -0
  118. package/package.json +1 -1
  119. package/skills/code/SKILL.md +77 -9
  120. package/skills/debug/SKILL.md +112 -11
  121. package/skills/design-spec/SKILL.md +42 -7
  122. package/skills/discovery/SKILL.md +42 -7
  123. package/skills/prd/SKILL.md +70 -4
  124. package/skills/setup-ai-first/SKILL.md +35 -2
  125. package/skills/spec/SKILL.md +70 -4
  126. package/skills/test/SKILL.md +119 -16
  127. package/steps/context-loader.md +7 -5
  128. package/steps/report-footer.md +35 -2
  129. package/steps/trace-mirror.md +18 -10
  130. package/templates/project-context.yaml +8 -5
@@ -187,7 +187,7 @@ If `services` section is present:
187
187
  - If `$ARGUMENTS` contains a path, extract the segment after `prd_dir`
188
188
 
189
189
  **2. Route to service** — if active domain matches a key in `services`:
190
- - Override `paths.specs_dir` → `services.{domain}.specs_dir`
190
+ - Override `paths.specs_dir` → `services.{domain}.specs_dir` — **only if `setup.spec_source` is NOT set.** When `spec_source` IS set, ALL BDD (web/app/**system**) is a shared cross-team artifact → leave `specs_dir` for step 4 to route to the spec repo; do NOT pin it per-service here.
191
191
  - Override `paths.tech_docs_dir` → `services.{domain}.tech_docs_dir` — **only if `setup.spec_source` is NOT set.** When `spec_source` IS set, the tech-design (API contract) is a cross-team artifact and must live in the shared spec repo (handled in step 4), so leave `tech_docs_dir` for step 4 to route — do NOT pin it per-service here.
192
192
  - Store `active_service` = `services.{domain}.path`
193
193
  - Store `active_service_module` = `services.{domain}.module`
@@ -198,6 +198,7 @@ If `services` section is present:
198
198
  - Set `active_service = unresolved`
199
199
 
200
200
  **4. Spec source auto-override** — if `setup.spec_source` is set AND the corresponding path was not already explicitly set in `paths:`:
201
+ - Override `paths.specs_dir` → `{spec_source}/specs/bdd` — **always when `spec_source` is set.** All BDD (web/app/**system**) lives in the shared spec repo so every umbrella (FE/App/BE) reads the same scenarios; the FE tech-design gate + `/generate-code --phase=ui`/`--phase=integration` resolve the `system/` BDD here. *(Per-service `specs/bdd` only when there is no `spec_source`.)*
201
202
  - Override `paths.prd_dir` → `{spec_source}/specs/prd`
202
203
  - Override `paths.design_spec_dir` → `{spec_source}/specs/design-spec`
203
204
  - Override `paths.tech_docs_dir` → `{spec_source}/specs/tech-docs` — **always when `spec_source` is set** (step 2 no longer pins tech-docs per-service in this case). The tech-design IS the cross-team API contract: BE authors it here, and FE/App read it from the same spec submodule at `/generate-code --phase=integration`. *(Per-service tech-docs only happen when there is no `spec_source` — a pure multi-service BE repo with no shared spec module.)*
@@ -207,8 +208,9 @@ If `services` section is present:
207
208
  - Override `paths.bug_reports_dir` → `{spec_source}/feedback/bug-reports`
208
209
  - Override `paths.bdd_proposals_dir` → `{spec_source}/feedback/bdd-proposals`
209
210
  - Override `paths.prd_change_requests_dir` → `{spec_source}/feedback/prd-change-requests`
211
+ - Override `paths.trace_dir` → `{spec_source}/.trace` — **always when `spec_source` is set.** Trace TSVs are consolidated in the spec repo (single authoritative location, no per-service split) so the PM/PO has one place to manage status. Code-side commands (`/generate-code`, `/dev-run-test`, `/qc-run-test`) run from `service_root` but **write their trace row into `{spec_source}/.trace`** — like they already push `feedback/` there. *(Per-service `.trace` only when there is no `spec_source`.)*
210
212
 
211
- > **Why under `spec_source`:** PRD, design-spec, domain knowledge, the **API contract (tech-docs)**, and tester feedback are all **cross-team artifacts** — they must live in the **shared spec repo** so every umbrella (FE/App/BE) reads the same source via `/sync`. Tech-docs specifically: BE authors the tech-design (API contract), commits + pushes it into the spec submodule (2-layer commit), and FE/App pull it on their next `/sync` to wire the real API in `/generate-code --phase=integration`. In single-service mode (no `spec_source`), these default under the repo root — still shared, same repo.
213
+ > **Why under `spec_source`:** PRD, design-spec, domain knowledge, **all BDD (web/app/system)**, the **API contract (tech-docs)**, tester feedback, **and the `.trace/` coverage state** are all **cross-team artifacts** — they live in the **shared spec repo** so every umbrella (FE/App/BE) and the PM read one source via `/sync`. The service submodule holds only **code** (+ build/test tooling). `.trace/` and `feedback/` are the dev/QC **write areas** in the spec repo (the PRD/BDD/design-spec/tech-docs there stay read-only for dev/QC only PO edits those). In single-service mode (no `spec_source`), everything defaults under the repo root — still one repo.
212
214
 
213
215
  ---
214
216
 
@@ -228,12 +230,12 @@ When `active_service` has been resolved to a real path in Step 1.5 (e.g., `user-
228
230
  |----------|--------|
229
231
  | `conventions.test_command` | service's `conventions.test_command` |
230
232
  | `conventions.build_command` | service's `conventions.build_command` |
231
- | `paths.trace_dir` | `{active_service}/{service paths.trace_dir}` default: `{active_service}/.trace` |
232
- | `paths.specs_dir` | `{active_service}/{service paths.specs_dir}` (if set in service config, else keep Step 1.5 override) |
233
+ | `paths.trace_dir` | **If `spec_source` is set → keep the Step 4 spec-repo route (`{spec_source}/.trace`); ignore any service-level `trace_dir`.** Only when there is no `spec_source`: `{active_service}/{service paths.trace_dir}` (default `{active_service}/.trace`). |
234
+ | `paths.specs_dir` | **If `spec_source` is set → keep the Step 4 spec-repo route (`{spec_source}/specs/bdd`); ignore any service-level `specs_dir`** (BDD is cross-team, never per-service in this mode). Only when there is no `spec_source`: `{active_service}/{service paths.specs_dir}` if set, else the Step 1.5 override. |
233
235
 
234
236
  **3. Store** `service_root = {active_service}` as the working directory anchor for all downstream commands:
235
237
  - Shell commands (`/dev-run-test`, `/dev-gen-test`) run **from within** `service_root`
236
- - File write operations (test files, trace TSVs) use paths **relative to** `service_root`
238
+ - **Source/test files** are written relative to `service_root`; **trace TSVs** are written to `{paths.trace_dir}` (the spec repo when `spec_source` is set — a cross-repo write, committed/pushed to the spec submodule like `feedback/`).
237
239
 
238
240
  **4. If service config not found** — keep umbrella defaults, still set `service_root = {active_service}` (path anchor is always needed even without a config override).
239
241
 
@@ -410,10 +412,57 @@ After completing all steps, you have loaded:
410
412
  Proceed to the next step of the calling command.
411
413
 
412
414
 
415
+ ---
416
+
417
+ ## Step 0 — Detect Platform & Route Output
418
+
419
+ Read `@trace.platform` from the feature file header (`web` | `app` | `system`). If absent, fall back to `platform_type` from context (`web-frontend`/`mobile` → FE; `backend` → BE).
420
+
421
+ | Platform | `active_tech_design` | Output file |
422
+ |----------|----------------------|-------------|
423
+ | `system` / backend | **`be`** — the cross-team **API contract** (authoritative) | `{paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design.md` |
424
+ | `web` / `app` (web-frontend / mobile) | **`fe`** — the **client technical design** (consumes the BE contract) | `{paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design-{platform}.md` |
425
+
426
+ Store `active_tech_design` and `tech_design_path`. The `-{platform}` suffix (mirroring design-spec) keeps the FE doc from colliding with the BE contract — both live in the shared spec repo when `spec_source` is set.
427
+
428
+ ---
429
+
430
+ ## Step 0.5 — FE/App Precondition Gate
431
+
432
+ *Skip this entire step for BE (`active_tech_design = be`).*
433
+
434
+ An FE/App technical design is a **derived** artifact: its API-integration layer maps onto the locked BE contract, and its state/error model comes from the system behavior. Both upstream inputs MUST exist first — **HALT** if either is missing:
435
+
436
+ 1. **System BDD** — locate `{paths.specs_dir}/{domain}/system/{TICKET-ID}*.feature`.
437
+ If not found → HALT:
438
+ ```
439
+ ❌ Cannot generate FE tech-design — System BDD not found for {TICKET-ID}.
440
+ The FE design needs the system-level (BE-facing) behavior first.
441
+ → PO/BE: /generate-bdd {prd-file} (produces the `system/` platform BDD)
442
+ ```
443
+ 2. **BE tech-docs (API contract)** — locate the BE doc `{paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design.md` and read its `@trace.status`.
444
+ - Not found → HALT:
445
+ ```
446
+ ❌ Cannot generate FE tech-design — BE API contract not found.
447
+ The FE integration layer maps to the BE contract; it must exist first.
448
+ → BE: /generate-tech-docs {system .feature} → /review-tech-docs (approve) → publish to spec repo
449
+ ```
450
+ - Found but `@trace.status` ≠ `approved` → WARN and ask:
451
+ ```
452
+ ⚠️ BE contract {UC-ID}-tech-design.md is status: {status} (not approved) — it may still change.
453
+ Designing the FE integration against a non-final contract risks rework.
454
+ Continue anyway? (Y/N)
455
+ ```
456
+ - Y → proceed (accept risk) · N → stop, wait for BE to approve.
457
+
458
+ Store `system_bdd_path` and `be_contract_path` — they are the primary inputs for the FE §3/§4 below.
459
+
413
460
  ---
414
461
 
415
462
  ## Brownfield Check
416
463
 
464
+ *BE (`active_tech_design = be`) only — for FE the "existing contract" is the BE doc loaded in Step 0.5.*
465
+
417
466
  Read the source `.feature` file header for `@trace.api_source`.
418
467
  Also check the source PRD Metadata table for `| **API Source** | existing |`.
419
468
 
@@ -430,10 +479,11 @@ If `active_mode = reverse-document` → load bảng "Existing API Contract" từ
430
479
 
431
480
  ## CHECKPOINT — Tech Design Plan
432
481
 
433
- Before generating, scan the feature file for scenario count, referenced BRs, and entities. Display and wait for Y:
482
+ Before generating, scan the feature file for scenario count, referenced BRs, and entities. Display the plan for the resolved `active_tech_design` and wait for Y:
434
483
 
484
+ **If `active_tech_design = be`:**
435
485
  ```
436
- Tech Design Plan — {UC-ID}
486
+ Tech Design Plan — {UC-ID} (BE · API contract)
437
487
  ──────────────────────────────────────────────────────
438
488
  UC : {UC-ID} — {feature title}
439
489
  Service : {trace.service}
@@ -457,12 +507,42 @@ Sections to generate:
457
507
  Proceed? (Y/N)
458
508
  ```
459
509
 
510
+ **If `active_tech_design = fe`:**
511
+ ```
512
+ Tech Design Plan — {UC-ID} (FE · {platform} · client design)
513
+ ──────────────────────────────────────────────────────
514
+ UC : {UC-ID} — {feature title}
515
+ Service : {trace.service} Module: {trace.module} ({platform})
516
+ Inputs : System BDD → {system_bdd_path}
517
+ BE contract → {be_contract_path} (status: {be status})
518
+ Scenarios : {N} FE scenarios | BDD ver: {trace.bdd_version}
519
+ Output : {paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design-{platform}.md
520
+
521
+ Sections to generate:
522
+ §1 Overview (FE scope of this UC)
523
+ §2 Component Architecture (tree + reuse from figma-components catalog)
524
+ §2b Test Selectors (stable test-id cho element có action — QC contract, attr theo platform)
525
+ §3 State Management (store/slices/state shape ← System BDD Then-clauses)
526
+ §4 API Integration Layer (port/adapter: each BE endpoint → FE service → DTO/model)
527
+ §5 Routing / Navigation
528
+ §6 Data Fetching & Client Caching (query keys, invalidation, optimistic updates)
529
+ §7 Error & Loading States (per scenario)
530
+ §8 Cross-Cutting (auth token, i18n, feature flags)
531
+ {§9 Offline / platform specifics — app only}
532
+ ──────────────────────────────────────────────────────
533
+ Proceed? (Y/N)
534
+ ```
535
+
460
536
  Wait for explicit "Y" before generating.
461
537
 
462
538
  ---
463
539
 
464
540
  ## Generate
465
541
 
542
+ Generate the document for the resolved `active_tech_design`.
543
+
544
+ ### Path A — BE API contract (`active_tech_design = be`)
545
+
466
546
  Write `{paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design.md`:
467
547
 
468
548
  ```markdown
@@ -533,17 +613,111 @@ External calls, events produced/consumed.
533
613
  | 1 | {YYYY-MM-DD} | Initial generation from {UC-ID}.feature (BDD v{bdd_version}) |
534
614
  ```
535
615
 
536
- ## Publishshare the contract (umbrella + shared spec repo)
616
+ ### Path B FE/App client technical design (`active_tech_design = fe`)
617
+
618
+ Write `{paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design-{platform}.md`. The §4 integration layer maps **directly onto the BE contract** loaded in Step 0.5 — every FE service method must trace to a real endpoint in `{be_contract_path}` (no invented endpoints). State and error models in §3/§7 derive from the **System BDD** `Then` clauses.
619
+
620
+ ```markdown
621
+ # FE Technical Design — {UC-ID} ({platform}): {Feature}
622
+
623
+ ---
624
+ @trace.id: {UC-ID}
625
+ @trace.domain: {domain}
626
+ @trace.platform: {web | app}
627
+ @trace.service: {read @trace.service from the .feature file header}
628
+ @trace.module: {read @trace.module — e.g. react / nextjs / vue / angular / flutter}
629
+ @trace.prd: {TICKET-ID}
630
+ @trace.bdd_version: {read @trace.bdd_version from the FE .feature header}
631
+ @trace.system_bdd: {system_bdd_path}
632
+ @trace.be_contract: {UC-ID}-tech-design.md # the BE API contract this design consumes
633
+ @trace.testid_attr: {data-testid (web) | testID (react-native) | Key/Semantics (flutter) | accessibilityIdentifier (native-ios)}
634
+ @trace.revision: 1
635
+ @trace.status: draft
636
+ @trace.generated_at: {YYYY-MM-DD}
637
+ ---
638
+
639
+ ## §1. Overview
640
+
641
+ {FE scope của UC: màn hình/luồng nào, render gì, tích hợp API nào. Nêu rõ design này map theo BE contract {UC-ID}-tech-design.md.}
642
+
643
+ ## §2. Component Architecture
644
+
645
+ Component tree (container vs presentational). Ưu tiên tái dùng từ figma-components catalog (Step 6-B context); chỉ tạo mới khi không có sẵn.
646
+
647
+ | Component | Type | Reuse (catalog) / New | Responsibility |
648
+ |-----------|------|-----------------------|----------------|
649
+ | {Name} | container/presentational | {catalog name \| NEW} | {what it renders / handles} |
650
+
651
+ ## §2b. Test Selectors — Element IDs cho element CÓ ACTION (QC contract)
652
+
653
+ Mỗi element tương tác (button, input, link, select, toggle, form-submit…) được gán **test-id ổn định** để QC locate **trực tiếp** — không scan/giả lập runtime. Đây là contract giữa FE code (emit id) và QC Page Object (đọc id).
654
+
655
+ - **Quy ước (semantic-stable):** `{uc-lower}-{screen}-{element}-{type}` — vd `ft001-login-submit-btn`, `ft001-login-email-input`. **KHÔNG** nhúng số scenario (đổi khi renumber).
656
+ - **Attribute theo platform** (`@trace.testid_attr`): web `data-testid` · React Native `testID` · Flutter `Key('id')` + `Semantics(identifier:)` · native iOS `accessibilityIdentifier`.
657
+ - **Cross-platform (web ↔ app):** cùng một element logic dùng **CÙNG test-id value** trên cả web và app — chỉ *attribute* khác theo platform. Mỗi platform có file tech-design riêng (`-web.md` / `-app.md`) với §2b riêng, nhưng id value phải khớp để QC tái dùng logic test và 2 doc không lệch. Khi gen platform thứ hai, **đọc §2b của file platform kia** và tái dùng id đã có; chỉ thêm id cho element mà platform này có riêng.
658
+ - Chỉ gán cho element **có action**; element tĩnh (label, text thuần) không cần.
659
+
660
+ | Test-ID | Element | Component (§2) | Action | Serves SC |
661
+ |---------|---------|----------------|--------|-----------|
662
+ | `{uc}-{screen}-{element}-{type}` | {Submit button} | {LoginForm} | {submit login} | SC1, SC3 |
663
+
664
+ > QC: Page Object locator lấy test-id từ bảng này (ưu tiên `data-testid`/attribute tương ứng). Element có action mà **chưa** có test-id ở đây → QC fallback role/text (chậm hơn) và nên bổ sung vào bảng này.
665
+ >
666
+ > **Element từ component reuse / code có sẵn (brownfield):** id sống ở **usage site**, component dùng chung phải *forward* được test-id. Đừng tự bịa ở đây — chạy `/map-testids {UC-ID}` để reverse-document id đang có, gán id còn thiếu, patch forwarding + ghi catalog, rồi điền §2b này. Lệnh này chỉ tự gán id cho component **mới**.
667
+
668
+ ## §3. State Management
669
+
670
+ State shape suy ra từ System BDD `Then` clauses + response shapes trong BE contract. Nêu store/slices, server-state vs UI-state.
671
+
672
+ | Slice / Key | Shape | Nguồn (BE field / local) | Updated by |
673
+ |-------------|-------|--------------------------|------------|
674
+
675
+ ## §4. API Integration Layer (port/adapter)
676
+
677
+ **Mỗi method phải map tới một endpoint CÓ THẬT trong BE contract `{UC-ID}-tech-design.md`.** Đây là hợp đồng thay thế mock adapter của `/generate-code --phase=ui`.
678
+
679
+ | FE service method | BE endpoint (từ contract) | Request map | Response → model | Error → UI |
680
+ |-------------------|---------------------------|-------------|------------------|-----------|
681
+ | {svc.getX()} | {GET /api/v1/...} | {params} | {DTO → ViewModel} | {4xx/5xx → state/toast} |
682
+
683
+ ## §5. Routing / Navigation
684
+
685
+ Routes / màn hình, params, guards (auth/role), lazy-load.
686
+
687
+ ## §6. Data Fetching & Client Caching
688
+
689
+ Query keys, cache invalidation triggers, optimistic updates, refetch policy (client-side — KHÔNG phải server cache).
690
+
691
+ ## §7. Error & Loading States
692
+
693
+ | Scenario (BDD) | Loading UI | Error UI | Empty state |
694
+ |----------------|-----------|----------|-------------|
695
+
696
+ ## §8. Cross-Cutting
697
+
698
+ Auth token injection/refresh, i18n keys, feature flags, analytics events.
699
+
700
+ {## §9. Offline / Platform Specifics — app only}
701
+ {Cached-data behavior, offline banner, background sync, platform permissions.}
702
+
703
+ ## Changelog
704
+
705
+ | Revision | Date | Changes |
706
+ |----------|------|---------|
707
+ | 1 | {YYYY-MM-DD} | Initial FE design from {UC-ID} ({platform}) BDD v{bdd_version}, mapping BE contract {UC-ID}-tech-design.md |
708
+ ```
709
+
710
+ ## Publish — share the doc (umbrella + shared spec repo)
537
711
 
538
- If `paths.tech_docs_dir` resolved **under `setup.spec_source`** (e.g. `{spec_source}/specs/tech-docs`), the tech-doc was just written **inside the spec submodule**. It is the cross-team **API contract** FE/App read it via their own `/sync`. Publish it so they can (2-layer commit):
712
+ If `paths.tech_docs_dir` resolved **under `setup.spec_source`** (e.g. `{spec_source}/specs/tech-docs`), the doc was just written **inside the spec submodule**. Publish it (2-layer commit) so the rest of the team reads it via `/sync` — the BE doc is the cross-team **API contract**; the FE doc is the **client design** other FE/App devs (and reviewers) consume:
539
713
 
540
714
  ```bash
541
715
  cd {spec_source}
542
- git add specs/tech-docs/{domain}/{UC-ID}-tech-design.md
543
- git commit -m "docs({UC-ID}): tech design / API contract"
544
- git push origin {spec_branch} # the branch FE/App track in .gitmodules
716
+ git add {tech_design_path} # be: {UC-ID}-tech-design.md · fe: {UC-ID}-tech-design-{platform}.md
717
+ git commit -m "docs({UC-ID}): {be: tech design / API contract | fe: FE tech design ({platform})}"
718
+ git push origin {spec_branch} # the branch teammates track in .gitmodules
545
719
  cd -
546
- git add {spec_source} && git commit -m "chore: bump spec pointer ({UC-ID} tech design)"
720
+ git add {spec_source} && git commit -m "chore: bump spec pointer ({UC-ID} {be|fe} tech design)"
547
721
  ```
548
722
 
549
723
  If `tech_docs_dir` is **local** — i.e. no `setup.spec_source` (single-repo, or a pure multi-service BE repo with no shared spec module) — skip this; no cross-repo publish needed. Whenever `spec_source` is set, tech-docs route to the spec submodule and this publish step applies.
@@ -572,6 +746,36 @@ Output Artifacts:
572
746
 
573
747
  If no files were written (e.g., review or analysis commands) → write `Output Artifacts: none (read-only)`.
574
748
 
749
+ ## Pipeline Position
750
+
751
+ Print a one-line map of the pipeline with the CURRENT command's phase marked `◀ bạn ở đây`,
752
+ so the user always sees where this command sits in the end-to-end flow:
753
+
754
+ ```
755
+ Discovery → PRD → [Design Spec] → BDD → Tech Design → Code → Dev Self-Check → QC → Trace Audit
756
+ ```
757
+
758
+ Find the current command in this phase legend and mark **its** phase in the map above:
759
+
760
+ | Phase | Commands |
761
+ |-------|----------|
762
+ | Discovery | `/define-product` |
763
+ | PRD | `/generate-prd` · `/refine-prd` · `/review-context` (PRD) |
764
+ | Design Spec | `/generate-design-spec` |
765
+ | BDD | `/generate-bdd` · `/review-context` (BDD) |
766
+ | Tech Design | `/generate-tech-docs` · `/map-testids` · `/review-tech-docs` |
767
+ | Code | `/generate-code` · `/review-code` |
768
+ | Dev Self-Check | `/dev-gen-test` · `/dev-run-test` · `/dev-smoke-test` |
769
+ | QC | `/qc-analyze` · `/qc-plan` · `/qc-design-test` · `/qc-review` · `/qc-run-test` · `/qc-report` |
770
+ | Trace Audit | `/validate-traces` |
771
+
772
+ For a **review command**, also append the 3-step review loop with the current step marked, e.g.:
773
+ `Vòng review: [① phân tích ◀] → ② Review Board → ③ --resume`.
774
+
775
+ **Cross-cutting commands** (`/sync`, `/update-framework`, `/fix-bug`, `/debug`, `/learn`,
776
+ `/report-bug`, `/propose-scenario`, `/generate-spec-manifest`) sit outside the linear pipeline —
777
+ **omit the Pipeline line entirely** for these (do not force-fit them onto the map).
778
+
575
779
  ## Next Command Suggestion
576
780
 
577
781
  Suggest the logical next command based on workflow phase:
@@ -613,17 +817,22 @@ Suggest the logical next command based on workflow phase:
613
817
  Format the footer as:
614
818
  ```
615
819
  ---
616
- Status : {badge}
820
+ Status : {badge}
617
821
  {Output Artifacts block}
618
- Next : {suggested command with example arguments}
822
+ Pipeline : Discovery PRD [BDD ◀ bạn ở đây] → Tech Design → Code → Dev Self-Check → QC → Trace Audit
823
+ (review cmd) Vòng review: [① phân tích ◀] → ② Review Board → ③ --resume
824
+ Next : {suggested command with example arguments}
619
825
  ```
826
+ *(Omit the `Pipeline` line for cross-cutting commands listed above.)*
620
827
 
621
828
 
622
829
  ```
623
- /generate-tech-docs Complete — {UC-ID}
624
- File: {paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design.md
625
- Next: /review-tech-docs {paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design.md
830
+ /generate-tech-docs Complete — {UC-ID} ({active_tech_design: BE API contract | FE {platform} client design})
831
+ File: {tech_design_path}
832
+ Next: /review-tech-docs {tech_design_path}
626
833
  ← SA/Lead review required before code generation
627
- → if tech-docs live in the shared spec repo: commit + push to the spec submodule (see Publish above) so FE/App `/sync` can read the contract
628
- → after approved: /generate-code {paths.specs_dir}/{domain}/{UC-ID}-{slug}.feature
834
+ → if it lives in the shared spec repo: commit + push to the spec submodule (see Publish above) so teammates `/sync` can read it
835
+ → after approved:
836
+ BE → /generate-code {system .feature}
837
+ FE → /generate-code {web|app .feature} --phase=integration (wires real API per §4 of this doc)
629
838
  ```
@@ -31,8 +31,55 @@
31
31
 
32
32
  ---
33
33
 
34
+ ## Step 0 — Detect Platform & Route Output
35
+
36
+ Read `@trace.platform` from the feature file header (`web` | `app` | `system`). If absent, fall back to `platform_type` from context (`web-frontend`/`mobile` → FE; `backend` → BE).
37
+
38
+ | Platform | `active_tech_design` | Output file |
39
+ |----------|----------------------|-------------|
40
+ | `system` / backend | **`be`** — the cross-team **API contract** (authoritative) | `{paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design.md` |
41
+ | `web` / `app` (web-frontend / mobile) | **`fe`** — the **client technical design** (consumes the BE contract) | `{paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design-{platform}.md` |
42
+
43
+ Store `active_tech_design` and `tech_design_path`. The `-{platform}` suffix (mirroring design-spec) keeps the FE doc from colliding with the BE contract — both live in the shared spec repo when `spec_source` is set.
44
+
45
+ ---
46
+
47
+ ## Step 0.5 — FE/App Precondition Gate
48
+
49
+ *Skip this entire step for BE (`active_tech_design = be`).*
50
+
51
+ An FE/App technical design is a **derived** artifact: its API-integration layer maps onto the locked BE contract, and its state/error model comes from the system behavior. Both upstream inputs MUST exist first — **HALT** if either is missing:
52
+
53
+ 1. **System BDD** — locate `{paths.specs_dir}/{domain}/system/{TICKET-ID}*.feature`.
54
+ If not found → HALT:
55
+ ```
56
+ ❌ Cannot generate FE tech-design — System BDD not found for {TICKET-ID}.
57
+ The FE design needs the system-level (BE-facing) behavior first.
58
+ → PO/BE: /generate-bdd {prd-file} (produces the `system/` platform BDD)
59
+ ```
60
+ 2. **BE tech-docs (API contract)** — locate the BE doc `{paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design.md` and read its `@trace.status`.
61
+ - Not found → HALT:
62
+ ```
63
+ ❌ Cannot generate FE tech-design — BE API contract not found.
64
+ The FE integration layer maps to the BE contract; it must exist first.
65
+ → BE: /generate-tech-docs {system .feature} → /review-tech-docs (approve) → publish to spec repo
66
+ ```
67
+ - Found but `@trace.status` ≠ `approved` → WARN and ask:
68
+ ```
69
+ ⚠️ BE contract {UC-ID}-tech-design.md is status: {status} (not approved) — it may still change.
70
+ Designing the FE integration against a non-final contract risks rework.
71
+ Continue anyway? (Y/N)
72
+ ```
73
+ - Y → proceed (accept risk) · N → stop, wait for BE to approve.
74
+
75
+ Store `system_bdd_path` and `be_contract_path` — they are the primary inputs for the FE §3/§4 below.
76
+
77
+ ---
78
+
34
79
  ## Brownfield Check
35
80
 
81
+ *BE (`active_tech_design = be`) only — for FE the "existing contract" is the BE doc loaded in Step 0.5.*
82
+
36
83
  Read the source `.feature` file header for `@trace.api_source`.
37
84
  Also check the source PRD Metadata table for `| **API Source** | existing |`.
38
85
 
@@ -49,10 +96,11 @@ If `active_mode = reverse-document` → load bảng "Existing API Contract" từ
49
96
 
50
97
  ## CHECKPOINT — Tech Design Plan
51
98
 
52
- Before generating, scan the feature file for scenario count, referenced BRs, and entities. Display and wait for Y:
99
+ Before generating, scan the feature file for scenario count, referenced BRs, and entities. Display the plan for the resolved `active_tech_design` and wait for Y:
53
100
 
101
+ **If `active_tech_design = be`:**
54
102
  ```
55
- Tech Design Plan — {UC-ID}
103
+ Tech Design Plan — {UC-ID} (BE · API contract)
56
104
  ──────────────────────────────────────────────────────
57
105
  UC : {UC-ID} — {feature title}
58
106
  Service : {trace.service}
@@ -76,12 +124,42 @@ Sections to generate:
76
124
  Proceed? (Y/N)
77
125
  ```
78
126
 
127
+ **If `active_tech_design = fe`:**
128
+ ```
129
+ Tech Design Plan — {UC-ID} (FE · {platform} · client design)
130
+ ──────────────────────────────────────────────────────
131
+ UC : {UC-ID} — {feature title}
132
+ Service : {trace.service} Module: {trace.module} ({platform})
133
+ Inputs : System BDD → {system_bdd_path}
134
+ BE contract → {be_contract_path} (status: {be status})
135
+ Scenarios : {N} FE scenarios | BDD ver: {trace.bdd_version}
136
+ Output : {paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design-{platform}.md
137
+
138
+ Sections to generate:
139
+ §1 Overview (FE scope of this UC)
140
+ §2 Component Architecture (tree + reuse from figma-components catalog)
141
+ §2b Test Selectors (stable test-id cho element có action — QC contract, attr theo platform)
142
+ §3 State Management (store/slices/state shape ← System BDD Then-clauses)
143
+ §4 API Integration Layer (port/adapter: each BE endpoint → FE service → DTO/model)
144
+ §5 Routing / Navigation
145
+ §6 Data Fetching & Client Caching (query keys, invalidation, optimistic updates)
146
+ §7 Error & Loading States (per scenario)
147
+ §8 Cross-Cutting (auth token, i18n, feature flags)
148
+ {§9 Offline / platform specifics — app only}
149
+ ──────────────────────────────────────────────────────
150
+ Proceed? (Y/N)
151
+ ```
152
+
79
153
  Wait for explicit "Y" before generating.
80
154
 
81
155
  ---
82
156
 
83
157
  ## Generate
84
158
 
159
+ Generate the document for the resolved `active_tech_design`.
160
+
161
+ ### Path A — BE API contract (`active_tech_design = be`)
162
+
85
163
  Write `{paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design.md`:
86
164
 
87
165
  ```markdown
@@ -152,17 +230,111 @@ External calls, events produced/consumed.
152
230
  | 1 | {YYYY-MM-DD} | Initial generation from {UC-ID}.feature (BDD v{bdd_version}) |
153
231
  ```
154
232
 
155
- ## Publishshare the contract (umbrella + shared spec repo)
233
+ ### Path B FE/App client technical design (`active_tech_design = fe`)
234
+
235
+ Write `{paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design-{platform}.md`. The §4 integration layer maps **directly onto the BE contract** loaded in Step 0.5 — every FE service method must trace to a real endpoint in `{be_contract_path}` (no invented endpoints). State and error models in §3/§7 derive from the **System BDD** `Then` clauses.
236
+
237
+ ```markdown
238
+ # FE Technical Design — {UC-ID} ({platform}): {Feature}
239
+
240
+ ---
241
+ @trace.id: {UC-ID}
242
+ @trace.domain: {domain}
243
+ @trace.platform: {web | app}
244
+ @trace.service: {read @trace.service from the .feature file header}
245
+ @trace.module: {read @trace.module — e.g. react / nextjs / vue / angular / flutter}
246
+ @trace.prd: {TICKET-ID}
247
+ @trace.bdd_version: {read @trace.bdd_version from the FE .feature header}
248
+ @trace.system_bdd: {system_bdd_path}
249
+ @trace.be_contract: {UC-ID}-tech-design.md # the BE API contract this design consumes
250
+ @trace.testid_attr: {data-testid (web) | testID (react-native) | Key/Semantics (flutter) | accessibilityIdentifier (native-ios)}
251
+ @trace.revision: 1
252
+ @trace.status: draft
253
+ @trace.generated_at: {YYYY-MM-DD}
254
+ ---
255
+
256
+ ## §1. Overview
257
+
258
+ {FE scope của UC: màn hình/luồng nào, render gì, tích hợp API nào. Nêu rõ design này map theo BE contract {UC-ID}-tech-design.md.}
259
+
260
+ ## §2. Component Architecture
261
+
262
+ Component tree (container vs presentational). Ưu tiên tái dùng từ figma-components catalog (Step 6-B context); chỉ tạo mới khi không có sẵn.
263
+
264
+ | Component | Type | Reuse (catalog) / New | Responsibility |
265
+ |-----------|------|-----------------------|----------------|
266
+ | {Name} | container/presentational | {catalog name \| NEW} | {what it renders / handles} |
267
+
268
+ ## §2b. Test Selectors — Element IDs cho element CÓ ACTION (QC contract)
269
+
270
+ Mỗi element tương tác (button, input, link, select, toggle, form-submit…) được gán **test-id ổn định** để QC locate **trực tiếp** — không scan/giả lập runtime. Đây là contract giữa FE code (emit id) và QC Page Object (đọc id).
271
+
272
+ - **Quy ước (semantic-stable):** `{uc-lower}-{screen}-{element}-{type}` — vd `ft001-login-submit-btn`, `ft001-login-email-input`. **KHÔNG** nhúng số scenario (đổi khi renumber).
273
+ - **Attribute theo platform** (`@trace.testid_attr`): web `data-testid` · React Native `testID` · Flutter `Key('id')` + `Semantics(identifier:)` · native iOS `accessibilityIdentifier`.
274
+ - **Cross-platform (web ↔ app):** cùng một element logic dùng **CÙNG test-id value** trên cả web và app — chỉ *attribute* khác theo platform. Mỗi platform có file tech-design riêng (`-web.md` / `-app.md`) với §2b riêng, nhưng id value phải khớp để QC tái dùng logic test và 2 doc không lệch. Khi gen platform thứ hai, **đọc §2b của file platform kia** và tái dùng id đã có; chỉ thêm id cho element mà platform này có riêng.
275
+ - Chỉ gán cho element **có action**; element tĩnh (label, text thuần) không cần.
276
+
277
+ | Test-ID | Element | Component (§2) | Action | Serves SC |
278
+ |---------|---------|----------------|--------|-----------|
279
+ | `{uc}-{screen}-{element}-{type}` | {Submit button} | {LoginForm} | {submit login} | SC1, SC3 |
280
+
281
+ > QC: Page Object locator lấy test-id từ bảng này (ưu tiên `data-testid`/attribute tương ứng). Element có action mà **chưa** có test-id ở đây → QC fallback role/text (chậm hơn) và nên bổ sung vào bảng này.
282
+ >
283
+ > **Element từ component reuse / code có sẵn (brownfield):** id sống ở **usage site**, component dùng chung phải *forward* được test-id. Đừng tự bịa ở đây — chạy `/map-testids {UC-ID}` để reverse-document id đang có, gán id còn thiếu, patch forwarding + ghi catalog, rồi điền §2b này. Lệnh này chỉ tự gán id cho component **mới**.
284
+
285
+ ## §3. State Management
286
+
287
+ State shape suy ra từ System BDD `Then` clauses + response shapes trong BE contract. Nêu store/slices, server-state vs UI-state.
288
+
289
+ | Slice / Key | Shape | Nguồn (BE field / local) | Updated by |
290
+ |-------------|-------|--------------------------|------------|
291
+
292
+ ## §4. API Integration Layer (port/adapter)
293
+
294
+ **Mỗi method phải map tới một endpoint CÓ THẬT trong BE contract `{UC-ID}-tech-design.md`.** Đây là hợp đồng thay thế mock adapter của `/generate-code --phase=ui`.
295
+
296
+ | FE service method | BE endpoint (từ contract) | Request map | Response → model | Error → UI |
297
+ |-------------------|---------------------------|-------------|------------------|-----------|
298
+ | {svc.getX()} | {GET /api/v1/...} | {params} | {DTO → ViewModel} | {4xx/5xx → state/toast} |
299
+
300
+ ## §5. Routing / Navigation
301
+
302
+ Routes / màn hình, params, guards (auth/role), lazy-load.
303
+
304
+ ## §6. Data Fetching & Client Caching
305
+
306
+ Query keys, cache invalidation triggers, optimistic updates, refetch policy (client-side — KHÔNG phải server cache).
307
+
308
+ ## §7. Error & Loading States
309
+
310
+ | Scenario (BDD) | Loading UI | Error UI | Empty state |
311
+ |----------------|-----------|----------|-------------|
312
+
313
+ ## §8. Cross-Cutting
314
+
315
+ Auth token injection/refresh, i18n keys, feature flags, analytics events.
316
+
317
+ {## §9. Offline / Platform Specifics — app only}
318
+ {Cached-data behavior, offline banner, background sync, platform permissions.}
319
+
320
+ ## Changelog
321
+
322
+ | Revision | Date | Changes |
323
+ |----------|------|---------|
324
+ | 1 | {YYYY-MM-DD} | Initial FE design from {UC-ID} ({platform}) BDD v{bdd_version}, mapping BE contract {UC-ID}-tech-design.md |
325
+ ```
326
+
327
+ ## Publish — share the doc (umbrella + shared spec repo)
156
328
 
157
- If `paths.tech_docs_dir` resolved **under `setup.spec_source`** (e.g. `{spec_source}/specs/tech-docs`), the tech-doc was just written **inside the spec submodule**. It is the cross-team **API contract** FE/App read it via their own `/sync`. Publish it so they can (2-layer commit):
329
+ If `paths.tech_docs_dir` resolved **under `setup.spec_source`** (e.g. `{spec_source}/specs/tech-docs`), the doc was just written **inside the spec submodule**. Publish it (2-layer commit) so the rest of the team reads it via `/sync` — the BE doc is the cross-team **API contract**; the FE doc is the **client design** other FE/App devs (and reviewers) consume:
158
330
 
159
331
  ```bash
160
332
  cd {spec_source}
161
- git add specs/tech-docs/{domain}/{UC-ID}-tech-design.md
162
- git commit -m "docs({UC-ID}): tech design / API contract"
163
- git push origin {spec_branch} # the branch FE/App track in .gitmodules
333
+ git add {tech_design_path} # be: {UC-ID}-tech-design.md · fe: {UC-ID}-tech-design-{platform}.md
334
+ git commit -m "docs({UC-ID}): {be: tech design / API contract | fe: FE tech design ({platform})}"
335
+ git push origin {spec_branch} # the branch teammates track in .gitmodules
164
336
  cd -
165
- git add {spec_source} && git commit -m "chore: bump spec pointer ({UC-ID} tech design)"
337
+ git add {spec_source} && git commit -m "chore: bump spec pointer ({UC-ID} {be|fe} tech design)"
166
338
  ```
167
339
 
168
340
  If `tech_docs_dir` is **local** — i.e. no `setup.spec_source` (single-repo, or a pure multi-service BE repo with no shared spec module) — skip this; no cross-repo publish needed. Whenever `spec_source` is set, tech-docs route to the spec submodule and this publish step applies.
@@ -172,10 +344,12 @@ If `tech_docs_dir` is **local** — i.e. no `setup.spec_source` (single-repo, or
172
344
  {{include:steps/report-footer.md}}
173
345
 
174
346
  ```
175
- /generate-tech-docs Complete — {UC-ID}
176
- File: {paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design.md
177
- Next: /review-tech-docs {paths.tech_docs_dir}/{domain}/{UC-ID}-tech-design.md
347
+ /generate-tech-docs Complete — {UC-ID} ({active_tech_design: BE API contract | FE {platform} client design})
348
+ File: {tech_design_path}
349
+ Next: /review-tech-docs {tech_design_path}
178
350
  ← SA/Lead review required before code generation
179
- → if tech-docs live in the shared spec repo: commit + push to the spec submodule (see Publish above) so FE/App `/sync` can read the contract
180
- → after approved: /generate-code {paths.specs_dir}/{domain}/{UC-ID}-{slug}.feature
351
+ → if it lives in the shared spec repo: commit + push to the spec submodule (see Publish above) so teammates `/sync` can read it
352
+ → after approved:
353
+ BE → /generate-code {system .feature}
354
+ FE → /generate-code {web|app .feature} --phase=integration (wires real API per §4 of this doc)
181
355
  ```