@edupia-tutor/spec-driven-docs 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 (339) hide show
  1. package/bin/build.js +230 -0
  2. package/bin/index.js +598 -0
  3. package/commands/debug.md +830 -0
  4. package/commands/debug.tmpl +257 -0
  5. package/commands/define-product.md +652 -0
  6. package/commands/define-product.tmpl +158 -0
  7. package/commands/dev-gen-test.md +1010 -0
  8. package/commands/dev-gen-test.tmpl +490 -0
  9. package/commands/dev-run-test.md +744 -0
  10. package/commands/dev-run-test.tmpl +224 -0
  11. package/commands/dev-smoke-test.md +711 -0
  12. package/commands/dev-smoke-test.tmpl +217 -0
  13. package/commands/fix-bug.md +744 -0
  14. package/commands/fix-bug.tmpl +171 -0
  15. package/commands/generate-bdd.md +1054 -0
  16. package/commands/generate-bdd.tmpl +534 -0
  17. package/commands/generate-code.md +869 -0
  18. package/commands/generate-code.tmpl +349 -0
  19. package/commands/generate-design-spec.md +958 -0
  20. package/commands/generate-design-spec.tmpl +464 -0
  21. package/commands/generate-prd.md +748 -0
  22. package/commands/generate-prd.tmpl +254 -0
  23. package/commands/generate-spec-manifest.md +658 -0
  24. package/commands/generate-spec-manifest.tmpl +164 -0
  25. package/commands/generate-tech-docs.md +849 -0
  26. package/commands/generate-tech-docs.tmpl +355 -0
  27. package/commands/learn.md +636 -0
  28. package/commands/learn.tmpl +63 -0
  29. package/commands/map-testids.md +575 -0
  30. package/commands/map-testids.tmpl +81 -0
  31. package/commands/propose-scenario.md +623 -0
  32. package/commands/propose-scenario.tmpl +129 -0
  33. package/commands/qc-analyze.md +580 -0
  34. package/commands/qc-analyze.tmpl +86 -0
  35. package/commands/qc-design-test.md +562 -0
  36. package/commands/qc-design-test.tmpl +68 -0
  37. package/commands/qc-plan.md +543 -0
  38. package/commands/qc-plan.tmpl +49 -0
  39. package/commands/qc-report.md +554 -0
  40. package/commands/qc-report.tmpl +60 -0
  41. package/commands/qc-review.md +547 -0
  42. package/commands/qc-review.tmpl +53 -0
  43. package/commands/qc-run-test.md +604 -0
  44. package/commands/qc-run-test.tmpl +84 -0
  45. package/commands/refine-prd.md +772 -0
  46. package/commands/refine-prd.tmpl +140 -0
  47. package/commands/report-bug.md +639 -0
  48. package/commands/report-bug.tmpl +145 -0
  49. package/commands/review-code.md +677 -0
  50. package/commands/review-code.tmpl +104 -0
  51. package/commands/review-context.md +1047 -0
  52. package/commands/review-context.tmpl +415 -0
  53. package/commands/review-tech-docs.md +811 -0
  54. package/commands/review-tech-docs.tmpl +317 -0
  55. package/commands/setup-ai-first.md +545 -0
  56. package/commands/setup-ai-first.tmpl +358 -0
  57. package/commands/sync.md +451 -0
  58. package/commands/sync.tmpl +351 -0
  59. package/commands/update-framework.md +251 -0
  60. package/commands/update-framework.tmpl +151 -0
  61. package/commands/validate-traces.md +842 -0
  62. package/commands/validate-traces.tmpl +348 -0
  63. package/core/FRAMEWORK_VERSION +1 -0
  64. package/core/commands/debug.md +830 -0
  65. package/core/commands/define-product.md +652 -0
  66. package/core/commands/dev-gen-test.md +1010 -0
  67. package/core/commands/dev-run-test.md +744 -0
  68. package/core/commands/dev-smoke-test.md +711 -0
  69. package/core/commands/fix-bug.md +744 -0
  70. package/core/commands/generate-bdd.md +1054 -0
  71. package/core/commands/generate-code.md +869 -0
  72. package/core/commands/generate-design-spec.md +958 -0
  73. package/core/commands/generate-prd.md +748 -0
  74. package/core/commands/generate-spec-manifest.md +658 -0
  75. package/core/commands/generate-tech-docs.md +849 -0
  76. package/core/commands/learn.md +636 -0
  77. package/core/commands/map-testids.md +575 -0
  78. package/core/commands/propose-scenario.md +623 -0
  79. package/core/commands/qc-analyze.md +580 -0
  80. package/core/commands/qc-design-test.md +562 -0
  81. package/core/commands/qc-plan.md +543 -0
  82. package/core/commands/qc-report.md +554 -0
  83. package/core/commands/qc-review.md +547 -0
  84. package/core/commands/qc-run-test.md +604 -0
  85. package/core/commands/refine-prd.md +772 -0
  86. package/core/commands/report-bug.md +639 -0
  87. package/core/commands/review-code.md +677 -0
  88. package/core/commands/review-context.md +1047 -0
  89. package/core/commands/review-tech-docs.md +811 -0
  90. package/core/commands/setup-ai-first.md +545 -0
  91. package/core/commands/sync.md +451 -0
  92. package/core/commands/update-framework.md +251 -0
  93. package/core/commands/validate-traces.md +842 -0
  94. package/core/hooks/data-guard.js +141 -0
  95. package/core/hooks/settings.json +18 -0
  96. package/core/modules/android-compose/module.yaml +13 -0
  97. package/core/modules/android-compose/stack-profile.yaml +57 -0
  98. package/core/modules/angular/architecture-snippets/component-patterns.md +187 -0
  99. package/core/modules/angular/module.yaml +6 -0
  100. package/core/modules/angular/stack-profile.yaml +38 -0
  101. package/core/modules/context-engineering/architecture-snippets/context-design.md +119 -0
  102. package/core/modules/context-engineering/module.yaml +9 -0
  103. package/core/modules/context-engineering/stack-profile.yaml +61 -0
  104. package/core/modules/dotnet/architecture-snippets/clean-arch.md +160 -0
  105. package/core/modules/dotnet/module.yaml +6 -0
  106. package/core/modules/dotnet/stack-profile.yaml +50 -0
  107. package/core/modules/flutter/module.yaml +14 -0
  108. package/core/modules/flutter/stack-profile.yaml +59 -0
  109. package/core/modules/golang/architecture-snippets/domain-layout.md +283 -0
  110. package/core/modules/golang/module.yaml +6 -0
  111. package/core/modules/golang/stack-profile.yaml +40 -0
  112. package/core/modules/ios-swiftui/module.yaml +13 -0
  113. package/core/modules/ios-swiftui/stack-profile.yaml +55 -0
  114. package/core/modules/java-spring/architecture-snippets/layered-arch.md +201 -0
  115. package/core/modules/java-spring/module.yaml +15 -0
  116. package/core/modules/java-spring/stack-profile.yaml +28 -0
  117. package/core/modules/nextjs/architecture-snippets/app-router-patterns.md +269 -0
  118. package/core/modules/nextjs/module.yaml +14 -0
  119. package/core/modules/nextjs/stack-profile.yaml +74 -0
  120. package/core/modules/nuxt/module.yaml +14 -0
  121. package/core/modules/nuxt/stack-profile.yaml +58 -0
  122. package/core/modules/php-laravel/architecture-snippets/service-repository.md +302 -0
  123. package/core/modules/php-laravel/module.yaml +15 -0
  124. package/core/modules/php-laravel/stack-profile.yaml +56 -0
  125. package/core/modules/qc-playwright/stack-profile.yaml +66 -0
  126. package/core/modules/react/architecture-snippets/hooks-query-patterns.md +254 -0
  127. package/core/modules/react/module.yaml +14 -0
  128. package/core/modules/react/stack-profile.yaml +63 -0
  129. package/core/modules/react-native/module.yaml +14 -0
  130. package/core/modules/react-native/stack-profile.yaml +56 -0
  131. package/core/modules/vue/module.yaml +14 -0
  132. package/core/modules/vue/stack-profile.yaml +65 -0
  133. package/core/rules/data-protection.md +80 -0
  134. package/core/rules/workflow.md +44 -0
  135. package/core/skills/code/SKILL.md +770 -0
  136. package/core/skills/debug/SKILL.md +869 -0
  137. package/core/skills/design-spec/SKILL.md +589 -0
  138. package/core/skills/discovery/SKILL.md +554 -0
  139. package/core/skills/prd/SKILL.md +562 -0
  140. package/core/skills/qc/qa-analyst/DOC_GAPS.template.md +63 -0
  141. package/core/skills/qc/qa-analyst/acceptance-criteria.md +60 -0
  142. package/core/skills/qc/qa-analyst/business-rules.md +59 -0
  143. package/core/skills/qc/qa-analyst/data-flow.md +64 -0
  144. package/core/skills/qc/qa-analyst/spec-breakdown.md +61 -0
  145. package/core/skills/qc/qa-designer/e2e/journey.md +41 -0
  146. package/core/skills/qc/qa-designer/exploratory/charter.md +68 -0
  147. package/core/skills/qc/qa-designer/exploratory/explore-to-functional.md +43 -0
  148. package/core/skills/qc/qa-designer/functional/api.md +45 -0
  149. package/core/skills/qc/qa-designer/functional/gui-feature.md +46 -0
  150. package/core/skills/qc/qa-designer/functional/gui-screen.md +52 -0
  151. package/core/skills/qc/qa-designer/integration/api.md +42 -0
  152. package/core/skills/qc/qa-designer/integration/db.md +39 -0
  153. package/core/skills/qc/qa-designer/integration/gui.md +40 -0
  154. package/core/skills/qc/qa-designer/integration/kafka.md +40 -0
  155. package/core/skills/qc/qa-designer/non-functional.md +40 -0
  156. package/core/skills/qc/qa-planner/test-plan.md +120 -0
  157. package/core/skills/qc/qa-reviewer/script/e2e.md +87 -0
  158. package/core/skills/qc/qa-reviewer/script/exploratory.md +45 -0
  159. package/core/skills/qc/qa-reviewer/script/functional.md +101 -0
  160. package/core/skills/qc/qa-reviewer/script/integration.md +91 -0
  161. package/core/skills/qc/qa-reviewer/script/non-functional.md +126 -0
  162. package/core/skills/qc/qa-reviewer/test-case/e2e.md +73 -0
  163. package/core/skills/qc/qa-reviewer/test-case/exploratory.md +43 -0
  164. package/core/skills/qc/qa-reviewer/test-case/functional.md +76 -0
  165. package/core/skills/qc/qa-reviewer/test-case/integration.md +69 -0
  166. package/core/skills/qc/qa-reviewer/test-case/non-functional.md +73 -0
  167. package/core/skills/qc/qa-runner/e2e.md +49 -0
  168. package/core/skills/qc/qa-runner/exploratory/session.md +36 -0
  169. package/core/skills/qc/qa-runner/functional/api.md +35 -0
  170. package/core/skills/qc/qa-runner/functional/gui-feature.md +51 -0
  171. package/core/skills/qc/qa-runner/functional/gui-screen.md +55 -0
  172. package/core/skills/qc/qa-runner/integration.md +47 -0
  173. package/core/skills/qc/qa-runner/non-functional.md +49 -0
  174. package/core/skills/qc/qa-runner/report/report.md +37 -0
  175. package/core/skills/setup-ai-first/SKILL.md +216 -0
  176. package/core/skills/spec/SKILL.md +461 -0
  177. package/core/skills/test/SKILL.md +1297 -0
  178. package/core/steps/capture-lesson.md +79 -0
  179. package/core/steps/context-loader.md +307 -0
  180. package/core/steps/gate.md +87 -0
  181. package/core/steps/report-footer.md +100 -0
  182. package/core/steps/review-fanout.md +138 -0
  183. package/core/steps/spawn-agent.md +124 -0
  184. package/core/steps/trace-mirror.md +26 -0
  185. package/core/templates/architecture.template.md +113 -0
  186. package/core/templates/design-spec.template.md +217 -0
  187. package/core/templates/feature.template +259 -0
  188. package/core/templates/platform-guide.template.md +145 -0
  189. package/core/templates/prd.template.md +327 -0
  190. package/core/templates/product-definition.template.md +168 -0
  191. package/core/templates/project-context.yaml +161 -0
  192. package/docs/01-getting-started/README.md +19 -0
  193. package/docs/01-getting-started/core-concepts.md +102 -0
  194. package/docs/01-getting-started/installation.md +156 -0
  195. package/docs/01-getting-started/quickstart.md +85 -0
  196. package/docs/02-guides/README.md +26 -0
  197. package/docs/02-guides/developer/README.md +46 -0
  198. package/docs/02-guides/developer/bdd-and-trace.md +125 -0
  199. package/docs/02-guides/developer/commands.md +76 -0
  200. package/docs/02-guides/developer/pr-checklist.md +15 -0
  201. package/docs/02-guides/developer/scenarios.md +460 -0
  202. package/docs/02-guides/developer/workflow.md +121 -0
  203. package/docs/02-guides/product-owner/README.md +79 -0
  204. package/docs/02-guides/product-owner/commands.md +30 -0
  205. package/docs/02-guides/product-owner/handoff-checklist.md +42 -0
  206. package/docs/02-guides/product-owner/prd-writing-rules.md +45 -0
  207. package/docs/02-guides/product-owner/scenarios.md +436 -0
  208. package/docs/02-guides/tester/README.md +75 -0
  209. package/docs/02-guides/tester/bug-reporting.md +117 -0
  210. package/docs/02-guides/tester/qc-automation.md +165 -0
  211. package/docs/02-guides/tester/reading-specs.md +79 -0
  212. package/docs/02-guides/tester/scenarios.md +186 -0
  213. package/docs/02-guides/tester/spec-manifest.md +130 -0
  214. package/docs/02-guides/tester/test-checklist.md +31 -0
  215. package/docs/02-guides/tester/workflow.md +77 -0
  216. package/docs/03-concepts/README.md +19 -0
  217. package/docs/03-concepts/architecture.md +248 -0
  218. package/docs/03-concepts/pipeline.md +274 -0
  219. package/docs/03-concepts/traceability.md +149 -0
  220. package/docs/04-operations/README.md +33 -0
  221. package/docs/04-operations/bug-flow.md +362 -0
  222. package/docs/04-operations/publishing.md +137 -0
  223. package/docs/04-operations/sync-and-update.md +522 -0
  224. package/docs/05-reference/README.md +32 -0
  225. package/docs/05-reference/command-cheatsheet.md +147 -0
  226. package/docs/05-reference/commands.md +232 -0
  227. package/docs/05-reference/modules.md +110 -0
  228. package/docs/05-reference/trace-schema.md +153 -0
  229. package/docs/README.md +49 -0
  230. package/hooks/data-guard.js +141 -0
  231. package/hooks/settings.json +18 -0
  232. package/modules/android-compose/module.yaml +13 -0
  233. package/modules/android-compose/stack-profile.yaml +57 -0
  234. package/modules/angular/architecture-snippets/component-patterns.md +187 -0
  235. package/modules/angular/module.yaml +6 -0
  236. package/modules/angular/stack-profile.yaml +38 -0
  237. package/modules/context-engineering/architecture-snippets/context-design.md +119 -0
  238. package/modules/context-engineering/module.yaml +9 -0
  239. package/modules/context-engineering/stack-profile.yaml +61 -0
  240. package/modules/dotnet/architecture-snippets/clean-arch.md +160 -0
  241. package/modules/dotnet/module.yaml +6 -0
  242. package/modules/dotnet/stack-profile.yaml +50 -0
  243. package/modules/flutter/module.yaml +14 -0
  244. package/modules/flutter/stack-profile.yaml +59 -0
  245. package/modules/golang/architecture-snippets/domain-layout.md +283 -0
  246. package/modules/golang/module.yaml +6 -0
  247. package/modules/golang/stack-profile.yaml +40 -0
  248. package/modules/ios-swiftui/module.yaml +13 -0
  249. package/modules/ios-swiftui/stack-profile.yaml +55 -0
  250. package/modules/java-spring/architecture-snippets/layered-arch.md +201 -0
  251. package/modules/java-spring/module.yaml +15 -0
  252. package/modules/java-spring/stack-profile.yaml +28 -0
  253. package/modules/nextjs/architecture-snippets/app-router-patterns.md +269 -0
  254. package/modules/nextjs/module.yaml +14 -0
  255. package/modules/nextjs/stack-profile.yaml +74 -0
  256. package/modules/nuxt/module.yaml +14 -0
  257. package/modules/nuxt/stack-profile.yaml +58 -0
  258. package/modules/php-laravel/architecture-snippets/service-repository.md +302 -0
  259. package/modules/php-laravel/module.yaml +15 -0
  260. package/modules/php-laravel/stack-profile.yaml +56 -0
  261. package/modules/qc-playwright/stack-profile.yaml +66 -0
  262. package/modules/react/architecture-snippets/hooks-query-patterns.md +254 -0
  263. package/modules/react/module.yaml +14 -0
  264. package/modules/react/stack-profile.yaml +63 -0
  265. package/modules/react-native/module.yaml +14 -0
  266. package/modules/react-native/stack-profile.yaml +56 -0
  267. package/modules/vue/module.yaml +14 -0
  268. package/modules/vue/stack-profile.yaml +65 -0
  269. package/package.json +49 -0
  270. package/rules/data-protection.md +80 -0
  271. package/rules/workflow.md +44 -0
  272. package/scripts/init.sh +49 -0
  273. package/scripts/migrate-specs.js +256 -0
  274. package/scripts/upgrade.sh +94 -0
  275. package/skills/code/SKILL.md +770 -0
  276. package/skills/code/SKILL.tmpl +176 -0
  277. package/skills/debug/SKILL.md +869 -0
  278. package/skills/debug/SKILL.tmpl +262 -0
  279. package/skills/design-spec/SKILL.md +589 -0
  280. package/skills/design-spec/SKILL.tmpl +95 -0
  281. package/skills/discovery/SKILL.md +554 -0
  282. package/skills/discovery/SKILL.tmpl +147 -0
  283. package/skills/prd/SKILL.md +562 -0
  284. package/skills/prd/SKILL.tmpl +188 -0
  285. package/skills/qc/qa-analyst/DOC_GAPS.template.md +63 -0
  286. package/skills/qc/qa-analyst/acceptance-criteria.md +60 -0
  287. package/skills/qc/qa-analyst/business-rules.md +59 -0
  288. package/skills/qc/qa-analyst/data-flow.md +64 -0
  289. package/skills/qc/qa-analyst/spec-breakdown.md +61 -0
  290. package/skills/qc/qa-designer/e2e/journey.md +41 -0
  291. package/skills/qc/qa-designer/exploratory/charter.md +68 -0
  292. package/skills/qc/qa-designer/exploratory/explore-to-functional.md +43 -0
  293. package/skills/qc/qa-designer/functional/api.md +45 -0
  294. package/skills/qc/qa-designer/functional/gui-feature.md +46 -0
  295. package/skills/qc/qa-designer/functional/gui-screen.md +52 -0
  296. package/skills/qc/qa-designer/integration/api.md +42 -0
  297. package/skills/qc/qa-designer/integration/db.md +39 -0
  298. package/skills/qc/qa-designer/integration/gui.md +40 -0
  299. package/skills/qc/qa-designer/integration/kafka.md +40 -0
  300. package/skills/qc/qa-designer/non-functional.md +40 -0
  301. package/skills/qc/qa-planner/test-plan.md +120 -0
  302. package/skills/qc/qa-reviewer/script/e2e.md +87 -0
  303. package/skills/qc/qa-reviewer/script/exploratory.md +45 -0
  304. package/skills/qc/qa-reviewer/script/functional.md +101 -0
  305. package/skills/qc/qa-reviewer/script/integration.md +91 -0
  306. package/skills/qc/qa-reviewer/script/non-functional.md +126 -0
  307. package/skills/qc/qa-reviewer/test-case/e2e.md +73 -0
  308. package/skills/qc/qa-reviewer/test-case/exploratory.md +43 -0
  309. package/skills/qc/qa-reviewer/test-case/functional.md +76 -0
  310. package/skills/qc/qa-reviewer/test-case/integration.md +69 -0
  311. package/skills/qc/qa-reviewer/test-case/non-functional.md +73 -0
  312. package/skills/qc/qa-runner/e2e.md +49 -0
  313. package/skills/qc/qa-runner/exploratory/session.md +36 -0
  314. package/skills/qc/qa-runner/functional/api.md +35 -0
  315. package/skills/qc/qa-runner/functional/gui-feature.md +51 -0
  316. package/skills/qc/qa-runner/functional/gui-screen.md +55 -0
  317. package/skills/qc/qa-runner/integration.md +47 -0
  318. package/skills/qc/qa-runner/non-functional.md +49 -0
  319. package/skills/qc/qa-runner/report/report.md +37 -0
  320. package/skills/setup-ai-first/SKILL.md +216 -0
  321. package/skills/setup-ai-first/SKILL.tmpl +116 -0
  322. package/skills/spec/SKILL.md +461 -0
  323. package/skills/spec/SKILL.tmpl +174 -0
  324. package/skills/test/SKILL.md +1297 -0
  325. package/skills/test/SKILL.tmpl +296 -0
  326. package/steps/capture-lesson.md +79 -0
  327. package/steps/context-loader.md +307 -0
  328. package/steps/gate.md +87 -0
  329. package/steps/report-footer.md +100 -0
  330. package/steps/review-fanout.md +138 -0
  331. package/steps/spawn-agent.md +124 -0
  332. package/steps/trace-mirror.md +26 -0
  333. package/templates/architecture.template.md +113 -0
  334. package/templates/design-spec.template.md +217 -0
  335. package/templates/feature.template +259 -0
  336. package/templates/platform-guide.template.md +145 -0
  337. package/templates/prd.template.md +327 -0
  338. package/templates/product-definition.template.md +168 -0
  339. package/templates/project-context.yaml +161 -0
@@ -0,0 +1,153 @@
1
+ [📚 Docs](../README.md) › [Reference](README.md) › Trace TSV Schema
2
+
3
+ # Trace TSV Schema
4
+
5
+ > Schema chuẩn của `.trace/{UC-ID}.tsv` — file trace state per use-case. Mỗi UC một file: 1 header row + 1 data row mỗi scenario. Đây là nguồn dữ liệu cho `/validate-traces` và panel Living Docs.
6
+
7
+ ---
8
+
9
+ ## Mục lục
10
+
11
+ - [Canonical TSV header](#canonical-tsv-header)
12
+ - [Column reference](#column-reference)
13
+ - [Two independent signals: dev_selftest vs qc_status](#two-independent-signals-dev_selftest-vs-qc_status)
14
+ - [Status computation (validate-traces)](#status-computation-validate-traces)
15
+ - [@trace tags across artifacts](#trace-tags-across-artifacts)
16
+ - [trace-report.json](#trace-reportjson)
17
+
18
+ ---
19
+
20
+ ## Canonical TSV header
21
+
22
+ Tab-separated, một header row + một data row mỗi scenario. Header chính xác (từ `generate-bdd.tmpl`):
23
+
24
+ ```
25
+ sc_id sc_title spec_ver gen_ver implemented_by test_count test_classes dev_selftest dev_selftest_at qc_status qc_run_at qc_owner qc_blocked_by prd_version bdd_version tech_doc_revision fe_tech_doc_revision prd_status uc_status fe_phase status last_updated
26
+ ```
27
+
28
+ 22 cột, theo đúng thứ tự trên.
29
+
30
+ ---
31
+
32
+ ## Column reference
33
+
34
+ | # | Column | Ý nghĩa | Giá trị khởi tạo (`/generate-bdd`) | Ai ghi |
35
+ |---|--------|---------|------------------------------------|--------|
36
+ | 1 | `sc_id` | `{UC-ID}-SC{N}` — khóa chính của row | `{UC-ID}-SC{N}` | generate-bdd |
37
+ | 2 | `sc_title` | Scenario title text | từ `.feature` | generate-bdd |
38
+ | 3 | `spec_ver` | `@trace.sc_version` hiện tại của scenario | từ `.feature` | generate-bdd / validate-traces (reconcile) |
39
+ | 4 | `gen_ver` | Version tại thời điểm code được sinh | `—` | generate-code |
40
+ | 5 | `implemented_by` | `ClassName.method` cài đặt scenario | `—` | generate-code |
41
+ | 6 | `test_count` | Số test verify scenario | `—` | dev-gen-test |
42
+ | 7 | `test_classes` | Danh sách test class | `—` | dev-gen-test |
43
+ | 8 | `dev_selftest` | Kết quả dev self-check: `pass` / `fail` / `not_run` | `—` | **dev-run-test** |
44
+ | 9 | `dev_selftest_at` | Ngày chạy dev self-check (`YYYY-MM-DD`) | `—` | **dev-run-test** |
45
+ | 10 | `qc_status` | Kết quả QC chính thức: `pass` / `fail` / `skip` / `not_run` | `—` | **qc-run-test** |
46
+ | 11 | `qc_run_at` | Ngày chạy QC (`YYYY-MM-DD`) | `—` | **qc-run-test** |
47
+ | 12 | `qc_owner` | **Đang chờ ai** (PM view) khi SC chưa pass: `dev` / `po` / `—` | `—` | **qc-run-test** / **report-bug** |
48
+ | 13 | `qc_blocked_by` | Artifact liên quan: `BUG-{id}` / `GAP-{id}` / `—` | `—` | **qc-run-test** / **report-bug** |
49
+ | 14 | `prd_version` | `@trace.prd_version` từ `.feature` header | từ `.feature` | generate-bdd |
50
+ | 15 | `bdd_version` | `@trace.bdd_version` từ `.feature` header | từ `.feature` | generate-bdd |
51
+ | 16 | `tech_doc_revision` | **BE** API-contract revision tại thời điểm codegen | `—` | generate-code / review-tech-docs (BE doc) |
52
+ | 17 | `fe_tech_doc_revision` | **FE** client tech-design revision (`{UC-ID}-tech-design-{platform}.md`) tại thời điểm FE integration | `—` | generate-code `--phase=integration` / review-tech-docs (FE doc) |
53
+ | 18 | `prd_status` | `\| **Status** \|` từ PRD metadata | từ PRD | generate-bdd |
54
+ | 19 | `uc_status` | Trạng thái UC: `draft` / `approved` / … | `draft` (UC mới) | generate-bdd |
55
+ | 20 | `fe_phase` | FE phase khi implement (`ui` / `integration`) | `—` | generate-code `--phase` |
56
+ | 21 | `status` | Trạng thái tổng hợp: `OK` / `DRIFT` / `GAP` / `UNTRACKED` | `UNTRACKED` | validate-traces |
57
+ | 22 | `last_updated` | Ngày update gần nhất (`YYYY-MM-DD`) | today | mọi command ghi row |
58
+
59
+ > **`qc_owner` / `qc_blocked_by` (PM "waiting-on" view):** dành cho PO kiêm PM xem **case nào đang chờ ai**. `/qc-run-test` set khi ghi `qc_status`: product-gap FAIL → `qc_owner=dev`; `skip`/`not_run` do `DOC_GAPS` 🔴 Blocker mở → `qc_owner=po` + `qc_blocked_by=GAP-{id}`; `pass` → cả hai về `—`. `/report-bug` backfill `qc_blocked_by=BUG-{id}` (+ `qc_owner` theo layer) cho SC khớp. `/validate-traces` tổng hợp `waiting_dev` / `waiting_po` cho dashboard.
60
+
61
+ > **Re-generation rules (generate-bdd):** SC đã có trong TSV & `spec_ver` không đổi → chỉ update `sc_title`, `prd_version`, `bdd_version`, `prd_status`, `uc_status`, `last_updated`. Nếu `spec_ver` đổi → thêm `spec_ver` và set `status = DRIFT` ngay. SC mới → append với `gen_ver`/`implemented_by`/`test_count`/`test_classes`/`dev_selftest`/`dev_selftest_at`/`qc_status`/`qc_run_at`/`qc_owner`/`qc_blocked_by`/`tech_doc_revision`/`fe_tech_doc_revision` = `—`. SC bị xóa khỏi `.feature` → xóa row.
62
+
63
+ > **Backward-compat:** TSV cũ thiếu cột mới ở header → `/validate-traces` đọc thành giá trị rỗng, không lỗi: `qc_owner`/`qc_blocked_by` (trước 19 cột) → `null`; `fe_tech_doc_revision` (trước 22 cột) → `0`. Lần `/generate-bdd` re-gen kế tiếp tự nâng header lên 22 cột.
64
+
65
+ ---
66
+
67
+ ## Two independent signals: dev_selftest vs qc_status
68
+
69
+ Trace TSV mang **hai cột tín hiệu độc lập** — không bao giờ trộn:
70
+
71
+ | | `dev_selftest` (+ `dev_selftest_at`) | `qc_status` (+ `qc_run_at`) |
72
+ |---|--------------------------------------|------------------------------|
73
+ | Ghi bởi | `/dev-run-test` | `/qc-run-test` |
74
+ | Ý nghĩa | Dev tự smoke-check code mình vừa sinh | Kết quả QC automation **chính thức** |
75
+ | Giá trị | `pass` / `fail` / `not_run` | `pass` / `fail` / `skip` / `not_run` |
76
+ | Stack | Dev implementation module | `qc-playwright` module |
77
+ | Coverage chính thức? | **KHÔNG** — chỉ là dev self-check | **CÓ** — official QC result |
78
+ | Keyed by | `@trace.verifies={UC-ID}` | `@trace.verifies={UC-ID}-SC{N}` |
79
+
80
+ `/validate-traces` chỉ **đọc** hai cột này cho report — không bao giờ ghi đè (mỗi cột do command sở hữu nó quản lý). Living Docs hiển thị cả hai cạnh nhau.
81
+
82
+ ---
83
+
84
+ ## Status computation (validate-traces)
85
+
86
+ `/validate-traces` tính cột `status` theo thứ tự ưu tiên (rule đầu tiên khớp thì dừng):
87
+
88
+ | Rule | Status | Điều kiện |
89
+ |------|--------|-----------|
90
+ | 1 | `UNTRACKED` | `implemented_by == —` (chưa sinh code) |
91
+ | 2 | `GAP` | `implemented_by != —` AND (`test_count == —` OR `test_count == 0`) |
92
+ | 3 | `DRIFT` | `spec_ver != gen_ver` (scenario đổi sau lần codegen gần nhất) |
93
+ | 4 | `OK` | tất cả: `spec_ver == gen_ver`, `implemented_by != —`, `test_count > 0` |
94
+
95
+ Ngoài ra `/validate-traces` còn flag **`PRD_DRIFT`** (PRD version trong code/TSV trễ hơn PRD file hiện tại), **`TECHDOC_DRIFT`** (code BE sinh từ BE-contract revision cũ — so `tech_doc_revision`), và **`FE_TECHDOC_DRIFT`** (FE integration code sinh từ FE tech-design revision cũ — so `fe_tech_doc_revision`).
96
+
97
+ ---
98
+
99
+ ## @trace tags across artifacts
100
+
101
+ Mọi artifact link với nhau qua `@trace.*` tags.
102
+
103
+ **`.feature` files:**
104
+ ```gherkin
105
+ # @trace.id: FEAT-001-UC1
106
+ # @trace.service: web-admin
107
+ # @trace.module: react
108
+ # @trace.prd_version: 1.2
109
+ # @trace.bdd_version: 3
110
+ # @trace.api_source: existing # brownfield: API đã tồn tại, contract lấy từ PRD
111
+ ```
112
+ Per-scenario trong file: `# @trace.scenario: {UC-ID}-SC{N}`, `# @trace.sc_version: 1.0`, `# @trace.business_rules: ...`.
113
+
114
+ **Code:**
115
+ ```java
116
+ // @trace.implements=FEAT-001-UC1-SC2
117
+ // @trace.prd_version=1.2
118
+ // @trace.bdd_version=3
119
+ // @trace.tech_doc_revision=2
120
+ ```
121
+
122
+ **Dev self-check tests:**
123
+ ```java
124
+ // @trace.verifies=FEAT-001-UC1
125
+ // @trace.service=api-backend
126
+ // @trace.test_type=integration
127
+ ```
128
+
129
+ **QC tests** (`qc-playwright`, drive `qc_status`):
130
+ ```python
131
+ # @trace.verifies={UC-ID}-SC{N}
132
+ # @trace.source=<official .feature path>
133
+ # @trace.test_type=functional|integration|e2e|non-functional
134
+ ```
135
+
136
+ ---
137
+
138
+ ## trace-report.json
139
+
140
+ `/validate-traces` ghi `{paths.trace_dir}/trace-report.json` — single source of truth cho web dashboards. Cấu trúc rút gọn:
141
+
142
+ - `generated_at`, `domain`
143
+ - `summary` — aggregates: `total_prds`, `approved_prds`, `total_ucs`, `approved_ucs`, `draft_ucs`, `total_scs`, `coded_scs`, `tested_scs`, `code_coverage_pct`, `test_coverage_pct`, `drift_count`, `gap_count`, `untracked_count`, `dev_selftest_passing/failing/not_run`, `qc_passing/failing/skipped/not_run`, `waiting_dev`, `waiting_po`, `tech_docs_count`
144
+ - `prds[]` → `ucs[]` → `scenarios[]` — mỗi scenario có đầy đủ các trường của TSV row (gồm `dev_selftest`, `dev_selftest_at`, `qc_status`, `qc_run_at`)
145
+ - `issues` — phân loại: `drift`, `gap`, `untracked`, `prd_version_drift`, `techdoc_drift`, `fe_techdoc_drift` (kèm `platform`), mỗi entry kèm `fix` command gợi ý
146
+
147
+ **TSV `"—"` → JSON mapping:** `implemented_by: "—"` → `null` · `test_count: "—"` → `0` · `test_classes: "—"` → `[]` · `tech_doc_revision: "—"` → `0` · `fe_tech_doc_revision: "—"` → `0` · `dev_selftest: "—"` → `"not_run"` · `dev_selftest_at: "—"` → `null` · `qc_status: "—"` → `"not_run"` · `qc_run_at: "—"` → `null`.
148
+
149
+ > **Umbrella mode:** khi `spec_source` set, `.trace/*.tsv` authoritative nằm **một chỗ** ở `{spec_source}/.trace/` (committed — PM quản lý tập trung; mỗi scenario mang `@trace.service`). `/validate-traces` (hoặc `/sync`) sinh `trace-report.json` vào `{spec_source}/.living-docs/` + mirror `./.trace/trace-report.json` ở workspace hiện tại — cả hai generated, gitignore. (Không có `spec_source` → `.trace` per-service.)
150
+
151
+ ---
152
+
153
+ *Xem thêm:* [Command Reference](commands.md) (`/validate-traces`, `/qc-run-test`, `/dev-run-test`) · [03 · Concepts](../03-concepts/) (traceability system).
package/docs/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # 📚 Spec-Driven Docs — Documentation
2
+
3
+ > AI-First Spec-Driven Development for Claude Code: Discovery → PRD → Design-Spec → BDD →
4
+ > Code → Dev self-check → QC automation, with traceability and human review gates.
5
+
6
+ Tài liệu được chia theo **vai trò** và **chủ đề**. Bắt đầu ở mục phù hợp với bạn:
7
+
8
+ | Bạn là… | Bắt đầu ở |
9
+ |---------|-----------|
10
+ | Người mới / cài đặt lần đầu | [01 · Getting Started](01-getting-started/) |
11
+ | Product Owner | [Guide · Product Owner](02-guides/product-owner/README.md) |
12
+ | Developer | [Guide · Developer](02-guides/developer/README.md) |
13
+ | QC / Tester (QA) | [Guide · Tester / QA](02-guides/tester/README.md) — gồm cả pipeline QC tự động (`/qc-*`) |
14
+ | Muốn hiểu kiến trúc | [03 · Concepts](03-concepts/) |
15
+ | Vận hành / admin | [04 · Operations](04-operations/) |
16
+ | Tra cứu lệnh | [05 · Reference](05-reference/) |
17
+
18
+ ---
19
+
20
+ ## Mục lục
21
+
22
+ ### 01 · [Getting Started](01-getting-started/)
23
+ - [Installation](01-getting-started/installation.md) — cài framework, prerequisites
24
+ - [Quick Start](01-getting-started/quickstart.md) — chạy feature đầu tiên end-to-end
25
+ - [Core Concepts](01-getting-started/core-concepts.md) — khái niệm trong 5 phút
26
+
27
+ ### 02 · [Guides (theo vai trò)](02-guides/)
28
+ - [Product Owner](02-guides/product-owner/README.md) — define-product, PRD, design-spec, review
29
+ - [Developer](02-guides/developer/README.md) — BDD, tech-docs, code, dev self-check
30
+ - [Tester / QA](02-guides/tester/README.md) — spec-manifest, report-bug, propose-scenario, Living Docs, và **chương [QC Automation](02-guides/tester/qc-automation.md)** (pipeline `/qc-*`, `qc_status`)
31
+
32
+ ### 03 · [Concepts](03-concepts/)
33
+ - [Architecture](03-concepts/architecture.md) — layers, modules, plug-in system
34
+ - [Pipeline](03-concepts/pipeline.md) — các phase Discovery → QC
35
+ - [Traceability & Living Docs](03-concepts/traceability.md) — trace TSV, dev_selftest vs qc_status
36
+
37
+ ### 04 · [Operations](04-operations/)
38
+ - [Sync & Update](04-operations/sync-and-update.md) — `/sync`, `/update-framework`, umbrella
39
+ - [Bug Flow](04-operations/bug-flow.md) — report → fix → verify
40
+ - [Publishing](04-operations/publishing.md) — build + npm publish
41
+
42
+ ### 05 · [Reference](05-reference/)
43
+ - [Commands](05-reference/commands.md) — bảng đầy đủ mọi slash command
44
+ - [Trace Schema](05-reference/trace-schema.md) — cột TSV, trace tags
45
+ - [Modules](05-reference/modules.md) — stack modules (java-spring, react, …, qc-playwright)
46
+
47
+ ---
48
+
49
+ *Mỗi file có breadcrumb điều hướng ở đầu. Phiên bản framework mới nhất: xem trên [npm](https://www.npmjs.com/package/@edupia-tutor/spec-driven-docs).*
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * data-guard.js — Claude Code PreToolUse Hook
4
+ *
5
+ * Blocks AI from reading, writing, or executing commands involving
6
+ * sensitive files (credentials, secrets, private keys, .env, etc.)
7
+ *
8
+ * Install: copy to your project and register in .claude/settings.json
9
+ * (see hooks/settings.json for registration template)
10
+ *
11
+ * Exit codes:
12
+ * 0 = allow the tool call
13
+ * 2 = block the tool call (Claude Code interprets this as a hard block)
14
+ */
15
+
16
+ const readline = require('readline');
17
+
18
+ // ── Sensitive file patterns ────────────────────────────────────────────────
19
+
20
+ const SENSITIVE_PATH_PATTERNS = [
21
+ // Environment files
22
+ /^\.env$/i,
23
+ /^\.env\./i,
24
+ /\.env$/i,
25
+
26
+ // Secret/credential files
27
+ /secret/i,
28
+ /credential/i,
29
+ /password/i,
30
+ /passwd/i,
31
+ /private[_-]?key/i,
32
+ /api[_-]?key/i,
33
+ /access[_-]?token/i,
34
+ /auth[_-]?token/i,
35
+
36
+ // Crypto keys and certificates
37
+ /\.key$/i,
38
+ /\.pem$/i,
39
+ /\.p12$/i,
40
+ /\.pfx$/i,
41
+ /\.jks$/i,
42
+ /\.keystore$/i,
43
+
44
+ // Framework-specific prod configs
45
+ /application-(prod|production|staging)\.(yml|yaml|properties)$/i,
46
+ /appsettings\.(Production|Staging)\.json$/i,
47
+ /database\.yml$/i,
48
+ /config\/master\.key$/i,
49
+ /storage\/oauth-private\.key$/i,
50
+
51
+ // Secret directories
52
+ /^secrets\//i,
53
+ /\/secrets\//i,
54
+ /^\.secrets\//i,
55
+ ];
56
+
57
+ const SENSITIVE_BASH_PATTERNS = [
58
+ /\bprintenv\b/i,
59
+ /\benv\b.*\|\s*(grep|awk|sed).*secret/i,
60
+ /cat\s+\.env/i,
61
+ /docker\s+inspect/i,
62
+ /kubectl\s+get\s+secret.*-o\s+yaml/i,
63
+ ];
64
+
65
+ // ── Helpers ────────────────────────────────────────────────────────────────
66
+
67
+ function isSensitivePath(filePath) {
68
+ if (!filePath) return false;
69
+ const normalized = filePath.replace(/\\/g, '/');
70
+ return SENSITIVE_PATH_PATTERNS.some(pattern => pattern.test(normalized));
71
+ }
72
+
73
+ function isSensitiveCommand(command) {
74
+ if (!command) return false;
75
+ return SENSITIVE_BASH_PATTERNS.some(pattern => pattern.test(command));
76
+ }
77
+
78
+ function block(reason) {
79
+ console.error(`\n🔒 DATA GUARD — BLOCKED\n${reason}\n`);
80
+ console.error('If you need configuration values, describe what you need');
81
+ console.error('without sharing actual secrets. Use placeholder values in generated code.\n');
82
+ process.exit(2);
83
+ }
84
+
85
+ // ── Main ───────────────────────────────────────────────────────────────────
86
+
87
+ let rawInput = '';
88
+
89
+ process.stdin.setEncoding('utf8');
90
+ process.stdin.on('data', chunk => { rawInput += chunk; });
91
+ process.stdin.on('end', () => {
92
+ let input;
93
+ try {
94
+ input = JSON.parse(rawInput);
95
+ } catch {
96
+ // Cannot parse input — allow (fail open, not fail closed)
97
+ process.exit(0);
98
+ }
99
+
100
+ const toolName = input.tool_name || '';
101
+ const toolInput = input.tool_input || {};
102
+
103
+ // ── Read tool ─────────────────────────────────────────────────────────
104
+ if (toolName === 'Read') {
105
+ const filePath = toolInput.file_path || '';
106
+ if (isSensitivePath(filePath)) {
107
+ block(`Attempted to READ sensitive file: ${filePath}`);
108
+ }
109
+ }
110
+
111
+ // ── Write tool ────────────────────────────────────────────────────────
112
+ if (toolName === 'Write') {
113
+ const filePath = toolInput.file_path || '';
114
+ if (isSensitivePath(filePath)) {
115
+ block(`Attempted to WRITE to sensitive file: ${filePath}`);
116
+ }
117
+ }
118
+
119
+ // ── Edit tool ─────────────────────────────────────────────────────────
120
+ if (toolName === 'Edit') {
121
+ const filePath = toolInput.file_path || '';
122
+ if (isSensitivePath(filePath)) {
123
+ block(`Attempted to EDIT sensitive file: ${filePath}`);
124
+ }
125
+ }
126
+
127
+ // ── Bash tool ─────────────────────────────────────────────────────────
128
+ if (toolName === 'Bash') {
129
+ const command = toolInput.command || '';
130
+ if (isSensitiveCommand(command)) {
131
+ block(`Attempted to execute sensitive command: ${command}`);
132
+ }
133
+ // Also check if the command references a sensitive file path
134
+ if (isSensitivePath(command)) {
135
+ block(`Bash command references a sensitive file path: ${command}`);
136
+ }
137
+ }
138
+
139
+ // Allow all other tool calls
140
+ process.exit(0);
141
+ });
@@ -0,0 +1,18 @@
1
+ {
2
+ "_comment": "Claude Code hook registration template. Copy this content into your project's .claude/settings.json",
3
+ "_docs": "https://docs.anthropic.com/claude/claude-code/hooks",
4
+
5
+ "hooks": {
6
+ "PreToolUse": [
7
+ {
8
+ "matcher": "Read|Write|Edit|Bash",
9
+ "hooks": [
10
+ {
11
+ "type": "command",
12
+ "command": "node .claude/hooks/data-guard.js"
13
+ }
14
+ ]
15
+ }
16
+ ]
17
+ }
18
+ }
@@ -0,0 +1,13 @@
1
+ name: "Android (Jetpack Compose)"
2
+ version: "1.0.0"
3
+ description: "Native Android development with Jetpack Compose + Kotlin"
4
+ language: "Kotlin"
5
+ framework: "Jetpack Compose"
6
+ stack_type: "mobile"
7
+ default_layer_order:
8
+ - Domain models
9
+ - Repository (data layer)
10
+ - UseCase (domain logic)
11
+ - ViewModel (StateFlow<UiState>)
12
+ - Composable screens (presentation)
13
+ test_framework: "JUnit5 + MockK + Turbine"
@@ -0,0 +1,57 @@
1
+ build:
2
+ compile: "./gradlew assembleRelease"
3
+ test: "./gradlew test"
4
+ run: "./gradlew installDebug / Open in Android Studio → Run"
5
+ lint: "./gradlew lint"
6
+
7
+ architecture:
8
+ style: "MVVM + Clean Architecture (Composable → ViewModel → UseCase → Repository)"
9
+ key_rules:
10
+ - "Composables are pure UI functions — no business logic, no direct suspend calls"
11
+ - "ViewModels expose StateFlow<UiState>; Composables collect via collectAsStateWithLifecycle()"
12
+ - "UseCases are single-responsibility classes injected into ViewModels"
13
+ - "Repositories are interfaces; implementations live in the data layer"
14
+ - "Dependency injection via Hilt"
15
+ - "Never launch coroutines from a Composable directly — use LaunchedEffect or ViewModel"
16
+ folder_structure: |
17
+ src/main/java/{package}/
18
+ ├── core/
19
+ │ ├── network/ ← Retrofit instance, interceptors
20
+ │ ├── theme/ ← MaterialTheme, Color, Type, Shape
21
+ │ └── utils/
22
+ ├── shared/
23
+ │ └── components/ ← reusable Composables (AppButton, AppTextField...)
24
+ ├── features/
25
+ │ └── {domain}/
26
+ │ ├── ui/ ← Composable screens + components
27
+ │ ├── viewmodel/ ← ViewModel + UiState
28
+ │ ├── domain/ ← UseCases, domain models
29
+ │ └── data/ ← Repository impl, data sources
30
+
31
+ coding_standards:
32
+ naming:
33
+ composables: "PascalCase (e.g., OrderListScreen, CreateOrderForm)"
34
+ viewmodels: "PascalCase + ViewModel suffix (e.g., OrderListViewModel)"
35
+ usecases: "PascalCase + UseCase suffix (e.g., CreateOrderUseCase)"
36
+ files:
37
+ screen: "{Feature}Screen.kt"
38
+ viewmodel: "{Feature}ViewModel.kt"
39
+ usecase: "{Feature}UseCase.kt"
40
+ patterns:
41
+ state_management: "StateFlow<UiState> in ViewModel"
42
+ navigation: "Jetpack Navigation Compose"
43
+ networking: "Retrofit + OkHttp"
44
+ serialization: "Kotlinx Serialization or Gson"
45
+ di: "Hilt"
46
+ async: "Kotlin Coroutines + Flow"
47
+
48
+ testing:
49
+ unit: "JUnit5 + MockK + Turbine (Flow testing)"
50
+ ui: "Compose UI Test (composeTestRule)"
51
+ patterns:
52
+ - "Test ViewModel with fake repositories and TestCoroutineDispatcher"
53
+ - "UI tests use semantics matchers — set Modifier.testTag() on Composables"
54
+
55
+ trace_tags:
56
+ implements: "// @trace.implements={UC-ID}-SC{N}"
57
+ source: "// @trace.source=specs/{domain}/{prd-slug}/bdd/{UC-ID}.feature"
@@ -0,0 +1,187 @@
1
+ # Angular — Component Architecture Patterns
2
+
3
+ ## Smart / Container Component Pattern
4
+
5
+ ```typescript
6
+ // order-list.component.ts — Smart component: manages state, injects services
7
+ import { Component, OnInit, inject } from '@angular/core';
8
+ import { CommonModule } from '@angular/common';
9
+ import { OrderService } from '../services/order.service';
10
+ import { OrderListItemComponent } from './order-list-item.component';
11
+ import { Order } from '../models/order.model';
12
+
13
+ @Component({
14
+ selector: 'app-order-list',
15
+ standalone: true,
16
+ imports: [CommonModule, OrderListItemComponent],
17
+ template: `
18
+ <div class="order-list">
19
+ <app-order-list-item
20
+ *ngFor="let order of orders"
21
+ [order]="order"
22
+ (cancel)="onCancelOrder($event)"
23
+ />
24
+ </div>
25
+ `
26
+ })
27
+ export class OrderListComponent implements OnInit {
28
+ private orderService = inject(OrderService);
29
+ orders: Order[] = [];
30
+
31
+ ngOnInit(): void {
32
+ this.orderService.getOrders().subscribe(orders => this.orders = orders);
33
+ }
34
+
35
+ onCancelOrder(orderId: number): void {
36
+ this.orderService.cancelOrder(orderId).subscribe(() => {
37
+ this.orders = this.orders.filter(o => o.id !== orderId);
38
+ });
39
+ }
40
+ }
41
+ ```
42
+
43
+ ## Dumb / Presentational Component Pattern
44
+
45
+ ```typescript
46
+ // order-list-item.component.ts — Dumb component: pure I/O, OnPush, no service injection
47
+ import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
48
+ import { Order } from '../models/order.model';
49
+
50
+ @Component({
51
+ selector: 'app-order-list-item',
52
+ standalone: true,
53
+ changeDetection: ChangeDetectionStrategy.OnPush,
54
+ template: `
55
+ <div class="order-item">
56
+ <span>{{ order.id }}</span>
57
+ <span>{{ order.status }}</span>
58
+ <button (click)="cancel.emit(order.id)" [disabled]="order.status === 'CANCELLED'">
59
+ Cancel
60
+ </button>
61
+ </div>
62
+ `
63
+ })
64
+ export class OrderListItemComponent {
65
+ @Input({ required: true }) order!: Order;
66
+ @Output() cancel = new EventEmitter<number>();
67
+ }
68
+ ```
69
+
70
+ ## Service with HttpClient Pattern
71
+
72
+ ```typescript
73
+ // order.service.ts
74
+ import { Injectable, inject } from '@angular/core';
75
+ import { HttpClient, HttpParams } from '@angular/common/http';
76
+ import { Observable } from 'rxjs';
77
+ import { Order, CreateOrderRequest, OrderResponse } from '../models/order.model';
78
+ import { environment } from '@env/environment';
79
+
80
+ @Injectable({ providedIn: 'root' })
81
+ export class OrderService {
82
+ private http = inject(HttpClient);
83
+ private baseUrl = `${environment.apiUrl}/v1/orders`;
84
+
85
+ getOrders(customerId?: number): Observable<Order[]> {
86
+ let params = new HttpParams();
87
+ if (customerId) params = params.set('customerId', customerId.toString());
88
+ return this.http.get<Order[]>(this.baseUrl, { params });
89
+ }
90
+
91
+ getOrder(id: number): Observable<Order> {
92
+ return this.http.get<Order>(`${this.baseUrl}/${id}`);
93
+ }
94
+
95
+ createOrder(request: CreateOrderRequest): Observable<OrderResponse> {
96
+ return this.http.post<OrderResponse>(this.baseUrl, request);
97
+ }
98
+
99
+ cancelOrder(id: number): Observable<void> {
100
+ return this.http.patch<void>(`${this.baseUrl}/${id}/cancel`, {});
101
+ }
102
+ }
103
+ ```
104
+
105
+ ## Signal-Based State Pattern (Angular 17+)
106
+
107
+ ```typescript
108
+ // order.store.ts — using Angular Signals for state management
109
+ import { Injectable, signal, computed } from '@angular/core';
110
+ import { Order } from '../models/order.model';
111
+
112
+ @Injectable({ providedIn: 'root' })
113
+ export class OrderStore {
114
+ private _orders = signal<Order[]>([]);
115
+ private _loading = signal(false);
116
+ private _error = signal<string | null>(null);
117
+
118
+ // Public readable signals
119
+ readonly orders = this._orders.asReadonly();
120
+ readonly loading = this._loading.asReadonly();
121
+ readonly error = this._error.asReadonly();
122
+
123
+ // Computed signals
124
+ readonly pendingOrders = computed(() =>
125
+ this._orders().filter(o => o.status === 'PENDING')
126
+ );
127
+ readonly orderCount = computed(() => this._orders().length);
128
+
129
+ setOrders(orders: Order[]): void {
130
+ this._orders.set(orders);
131
+ }
132
+
133
+ setLoading(loading: boolean): void {
134
+ this._loading.set(loading);
135
+ }
136
+
137
+ setError(error: string | null): void {
138
+ this._error.set(error);
139
+ }
140
+
141
+ removeOrder(id: number): void {
142
+ this._orders.update(orders => orders.filter(o => o.id !== id));
143
+ }
144
+ }
145
+ ```
146
+
147
+ ## Route Guard Pattern
148
+
149
+ ```typescript
150
+ // auth.guard.ts
151
+ import { inject } from '@angular/core';
152
+ import { CanActivateFn, Router } from '@angular/router';
153
+ import { AuthService } from '../services/auth.service';
154
+
155
+ export const authGuard: CanActivateFn = (route, state) => {
156
+ const auth = inject(AuthService);
157
+ const router = inject(Router);
158
+
159
+ if (auth.isAuthenticated()) {
160
+ return true;
161
+ }
162
+ return router.createUrlTree(['/login'], { queryParams: { returnUrl: state.url } });
163
+ };
164
+ ```
165
+
166
+ ## Standalone Component with Lazy Loading
167
+
168
+ ```typescript
169
+ // app.routes.ts
170
+ import { Routes } from '@angular/router';
171
+ import { authGuard } from './guards/auth.guard';
172
+
173
+ export const APP_ROUTES: Routes = [
174
+ {
175
+ path: 'orders',
176
+ canActivate: [authGuard],
177
+ loadComponent: () =>
178
+ import('./features/orders/order-list.component').then(m => m.OrderListComponent)
179
+ },
180
+ {
181
+ path: 'orders/:id',
182
+ canActivate: [authGuard],
183
+ loadComponent: () =>
184
+ import('./features/orders/order-detail.component').then(m => m.OrderDetailComponent)
185
+ }
186
+ ];
187
+ ```
@@ -0,0 +1,6 @@
1
+ name: "Angular"
2
+ version: "1.0.0"
3
+ description: "Angular 17+ frontend with component-based architecture"
4
+ language: "TypeScript"
5
+ framework: "Angular"
6
+ stack_type: "frontend"
@@ -0,0 +1,38 @@
1
+ build:
2
+ compile: "ng build"
3
+ test: "ng test --watch=false"
4
+ run: "ng serve"
5
+
6
+ architecture:
7
+ style: "Component → Service → HTTP Client → Backend API"
8
+ key_rules:
9
+ - "Smart (container) components manage state and inject services"
10
+ - "Dumb (presentational) components receive data via @Input and emit via @Output"
11
+ - "Business logic lives in services, not in component classes"
12
+ - "Use OnPush change detection for all pure presentational components"
13
+ - "HTTP calls must be in services, never in component files"
14
+
15
+ coding_standards:
16
+ naming:
17
+ components: "PascalCase + Component suffix (e.g., OrderListComponent)"
18
+ services: "PascalCase + Service suffix (e.g., OrderService)"
19
+ pipes: "PascalCase + Pipe suffix (e.g., CurrencyFormatPipe)"
20
+ directives: "PascalCase + Directive suffix (e.g., HighlightDirective)"
21
+ guards: "PascalCase + Guard suffix (e.g., AuthGuard)"
22
+ files:
23
+ component: "{feature}.component.ts / .html / .scss"
24
+ service: "{feature}.service.ts"
25
+ model: "{feature}.model.ts"
26
+ store: "{feature}.store.ts"
27
+ patterns:
28
+ state_management: "NgRx (complex) or Angular Signals (simple/medium)"
29
+ http_error_handling: "HttpInterceptor catches 4xx/5xx globally"
30
+ lazy_loading: "All feature modules must be lazily loaded"
31
+
32
+ testing:
33
+ unit: "Jasmine + Karma or Jest"
34
+ e2e: "Cypress or Playwright"
35
+ patterns:
36
+ - "Use TestBed.configureTestingModule for component tests"
37
+ - "Mock services with jasmine.createSpyObj or jest.fn()"
38
+ - "Test component DOM via DebugElement and By.css selectors"