siesa-agents 2.1.40 → 2.1.41

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 (552) hide show
  1. package/README.md +147 -147
  2. package/bin/install.js +534 -534
  3. package/bin/prepare-publish.js +26 -26
  4. package/bin/restore-folders.js +26 -26
  5. package/bmad/_config/agent-manifest.csv +20 -20
  6. package/bmad/_config/agents/bmb-agent-builder.customize.yaml +41 -41
  7. package/bmad/_config/agents/bmb-module-builder.customize.yaml +41 -41
  8. package/bmad/_config/agents/bmb-workflow-builder.customize.yaml +41 -41
  9. package/bmad/_config/files-manifest.csv +469 -469
  10. package/bmad/_config/ides/claude-code.yaml +6 -6
  11. package/bmad/_config/manifest.yaml +14 -14
  12. package/bmad/_config/task-manifest.csv +6 -6
  13. package/bmad/_config/tool-manifest.csv +1 -1
  14. package/bmad/_config/workflow-manifest.csv +45 -45
  15. package/bmad/_memory/config.yaml +11 -11
  16. package/bmad/bmb/README.md +25 -25
  17. package/bmad/bmb/agents/agent-builder.md +57 -57
  18. package/bmad/bmb/agents/module-builder.md +60 -60
  19. package/bmad/bmb/agents/workflow-builder.md +56 -56
  20. package/bmad/bmb/config.yaml +12 -12
  21. package/bmad/bmb/docs/workflows/architecture.md +220 -220
  22. package/bmad/bmb/docs/workflows/common-workflow-tools.csv +18 -18
  23. package/bmad/bmb/docs/workflows/csv-data-file-standards.md +206 -206
  24. package/bmad/bmb/docs/workflows/intent-vs-prescriptive-spectrum.md +220 -220
  25. package/bmad/bmb/docs/workflows/step-file-rules.md +469 -469
  26. package/bmad/bmb/docs/workflows/templates/step-01-init-continuable-template.md +241 -241
  27. package/bmad/bmb/docs/workflows/templates/step-1b-template.md +223 -223
  28. package/bmad/bmb/docs/workflows/templates/step-file.md +139 -139
  29. package/bmad/bmb/docs/workflows/templates/step-template.md +290 -290
  30. package/bmad/bmb/docs/workflows/templates/workflow-template.md +104 -104
  31. package/bmad/bmb/docs/workflows/templates/workflow.md +58 -58
  32. package/bmad/bmb/docs/workflows/terms.md +97 -97
  33. package/bmad/bmb/reference/agents/simple-examples/README.md +223 -223
  34. package/bmad/bmb/reference/readme.md +3 -3
  35. package/bmad/bmb/reference/workflows/meal-prep-nutrition/data/dietary-restrictions.csv +17 -17
  36. package/bmad/bmb/reference/workflows/meal-prep-nutrition/data/macro-calculator.csv +15 -15
  37. package/bmad/bmb/reference/workflows/meal-prep-nutrition/data/recipe-database.csv +27 -27
  38. package/bmad/bmb/reference/workflows/meal-prep-nutrition/steps/step-01-init.md +177 -177
  39. package/bmad/bmb/reference/workflows/meal-prep-nutrition/steps/step-01b-continue.md +121 -121
  40. package/bmad/bmb/reference/workflows/meal-prep-nutrition/steps/step-02-profile.md +165 -165
  41. package/bmad/bmb/reference/workflows/meal-prep-nutrition/steps/step-03-assessment.md +154 -154
  42. package/bmad/bmb/reference/workflows/meal-prep-nutrition/steps/step-04-strategy.md +183 -183
  43. package/bmad/bmb/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md +168 -168
  44. package/bmad/bmb/reference/workflows/meal-prep-nutrition/steps/step-06-prep-schedule.md +195 -195
  45. package/bmad/bmb/reference/workflows/meal-prep-nutrition/templates/assessment-section.md +25 -25
  46. package/bmad/bmb/reference/workflows/meal-prep-nutrition/templates/nutrition-plan.md +68 -68
  47. package/bmad/bmb/reference/workflows/meal-prep-nutrition/templates/prep-schedule-section.md +29 -29
  48. package/bmad/bmb/reference/workflows/meal-prep-nutrition/templates/profile-section.md +47 -47
  49. package/bmad/bmb/reference/workflows/meal-prep-nutrition/templates/shopping-section.md +37 -37
  50. package/bmad/bmb/reference/workflows/meal-prep-nutrition/templates/strategy-section.md +18 -18
  51. package/bmad/bmb/reference/workflows/meal-prep-nutrition/workflow.md +59 -59
  52. package/bmad/bmb/workflows/agent/data/agent-compilation.md +273 -273
  53. package/bmad/bmb/workflows/agent/data/agent-menu-patterns.md +233 -233
  54. package/bmad/bmb/workflows/agent/data/agent-metadata.md +208 -208
  55. package/bmad/bmb/workflows/agent/data/brainstorm-context.md +146 -146
  56. package/bmad/bmb/workflows/agent/data/communication-presets.csv +61 -61
  57. package/bmad/bmb/workflows/agent/data/critical-actions.md +120 -120
  58. package/bmad/bmb/workflows/agent/data/expert-agent-architecture.md +236 -236
  59. package/bmad/bmb/workflows/agent/data/expert-agent-validation.md +173 -173
  60. package/bmad/bmb/workflows/agent/data/module-agent-validation.md +124 -124
  61. package/bmad/bmb/workflows/agent/data/persona-properties.md +266 -266
  62. package/bmad/bmb/workflows/agent/data/principles-crafting.md +292 -292
  63. package/bmad/bmb/workflows/agent/data/reference/expert-examples/journal-keeper/journal-keeper-sidecar/entries/yy-mm-dd-entry-template.md +16 -16
  64. package/bmad/bmb/workflows/agent/data/reference/module-examples/architect.md +68 -68
  65. package/bmad/bmb/workflows/agent/data/simple-agent-architecture.md +204 -204
  66. package/bmad/bmb/workflows/agent/data/simple-agent-validation.md +132 -132
  67. package/bmad/bmb/workflows/agent/data/understanding-agent-types.md +222 -222
  68. package/bmad/bmb/workflows/agent/steps-c/step-01-brainstorm.md +126 -126
  69. package/bmad/bmb/workflows/agent/steps-c/step-02-discovery.md +168 -168
  70. package/bmad/bmb/workflows/agent/steps-c/step-03-type-metadata.md +294 -294
  71. package/bmad/bmb/workflows/agent/steps-c/step-04-persona.md +210 -210
  72. package/bmad/bmb/workflows/agent/steps-c/step-05-commands-menu.md +176 -176
  73. package/bmad/bmb/workflows/agent/steps-c/step-06-activation.md +275 -275
  74. package/bmad/bmb/workflows/agent/steps-c/step-07a-build-simple.md +185 -185
  75. package/bmad/bmb/workflows/agent/steps-c/step-07b-build-expert.md +201 -201
  76. package/bmad/bmb/workflows/agent/steps-c/step-07c-build-module.md +258 -258
  77. package/bmad/bmb/workflows/agent/steps-c/step-08a-plan-traceability.md +203 -203
  78. package/bmad/bmb/workflows/agent/steps-c/step-08b-metadata-validation.md +135 -135
  79. package/bmad/bmb/workflows/agent/steps-c/step-08c-persona-validation.md +161 -161
  80. package/bmad/bmb/workflows/agent/steps-c/step-08d-menu-validation.md +158 -158
  81. package/bmad/bmb/workflows/agent/steps-c/step-08e-structure-validation.md +306 -306
  82. package/bmad/bmb/workflows/agent/steps-c/step-08f-sidecar-validation.md +462 -462
  83. package/bmad/bmb/workflows/agent/steps-c/step-09-celebrate.md +244 -244
  84. package/bmad/bmb/workflows/agent/steps-e/e-01-load-existing.md +214 -214
  85. package/bmad/bmb/workflows/agent/steps-e/e-02-discover-edits.md +191 -191
  86. package/bmad/bmb/workflows/agent/steps-e/e-03a-validate-metadata.md +78 -78
  87. package/bmad/bmb/workflows/agent/steps-e/e-03b-validate-persona.md +76 -76
  88. package/bmad/bmb/workflows/agent/steps-e/e-03c-validate-menu.md +75 -75
  89. package/bmad/bmb/workflows/agent/steps-e/e-03d-validate-structure.md +75 -75
  90. package/bmad/bmb/workflows/agent/steps-e/e-03e-validate-sidecar.md +78 -78
  91. package/bmad/bmb/workflows/agent/steps-e/e-03f-validation-summary.md +119 -119
  92. package/bmad/bmb/workflows/agent/steps-e/e-04-type-metadata.md +122 -122
  93. package/bmad/bmb/workflows/agent/steps-e/e-05-persona.md +132 -132
  94. package/bmad/bmb/workflows/agent/steps-e/e-06-commands-menu.md +120 -120
  95. package/bmad/bmb/workflows/agent/steps-e/e-07-activation.md +122 -122
  96. package/bmad/bmb/workflows/agent/steps-e/e-08a-edit-simple.md +134 -134
  97. package/bmad/bmb/workflows/agent/steps-e/e-08b-edit-expert.md +117 -117
  98. package/bmad/bmb/workflows/agent/steps-e/e-08c-edit-module.md +120 -120
  99. package/bmad/bmb/workflows/agent/steps-e/e-09a-validate-metadata.md +70 -70
  100. package/bmad/bmb/workflows/agent/steps-e/e-09b-validate-persona.md +70 -70
  101. package/bmad/bmb/workflows/agent/steps-e/e-09c-validate-menu.md +69 -69
  102. package/bmad/bmb/workflows/agent/steps-e/e-09d-validate-structure.md +69 -69
  103. package/bmad/bmb/workflows/agent/steps-e/e-09e-validate-sidecar.md +70 -70
  104. package/bmad/bmb/workflows/agent/steps-e/e-09f-validation-summary.md +111 -111
  105. package/bmad/bmb/workflows/agent/steps-e/e-10-celebrate.md +150 -150
  106. package/bmad/bmb/workflows/agent/steps-v/v-01-load-review.md +128 -128
  107. package/bmad/bmb/workflows/agent/steps-v/v-02a-validate-metadata.md +73 -73
  108. package/bmad/bmb/workflows/agent/steps-v/v-02b-validate-persona.md +72 -72
  109. package/bmad/bmb/workflows/agent/steps-v/v-02c-validate-menu.md +71 -71
  110. package/bmad/bmb/workflows/agent/steps-v/v-02d-validate-structure.md +71 -71
  111. package/bmad/bmb/workflows/agent/steps-v/v-02e-validate-sidecar.md +76 -76
  112. package/bmad/bmb/workflows/agent/steps-v/v-03-summary.md +100 -100
  113. package/bmad/bmb/workflows/agent/templates/agent-plan.template.md +5 -5
  114. package/bmad/bmb/workflows/agent/templates/expert-agent-template/expert-agent.template.md +76 -76
  115. package/bmad/bmb/workflows/agent/templates/simple-agent.template.md +71 -71
  116. package/bmad/bmb/workflows/agent/workflow.md +123 -123
  117. package/bmad/bmb/workflows/create-module/steps/step-01-init.md +156 -156
  118. package/bmad/bmb/workflows/create-module/steps/step-01b-continue.md +170 -170
  119. package/bmad/bmb/workflows/create-module/steps/step-02-concept.md +218 -218
  120. package/bmad/bmb/workflows/create-module/steps/step-03-components.md +268 -268
  121. package/bmad/bmb/workflows/create-module/steps/step-04-structure.md +229 -229
  122. package/bmad/bmb/workflows/create-module/steps/step-05-config.md +234 -234
  123. package/bmad/bmb/workflows/create-module/steps/step-06-agents.md +297 -297
  124. package/bmad/bmb/workflows/create-module/steps/step-07-workflows.md +229 -229
  125. package/bmad/bmb/workflows/create-module/steps/step-08-installer.md +187 -187
  126. package/bmad/bmb/workflows/create-module/steps/step-09-documentation.md +310 -310
  127. package/bmad/bmb/workflows/create-module/steps/step-10-roadmap.md +338 -338
  128. package/bmad/bmb/workflows/create-module/steps/step-11-validate.md +336 -336
  129. package/bmad/bmb/workflows/create-module/templates/agent.template.md +313 -313
  130. package/bmad/bmb/workflows/create-module/templates/installer.template.js +47 -47
  131. package/bmad/bmb/workflows/create-module/templates/module-plan.template.md +5 -5
  132. package/bmad/bmb/workflows/create-module/templates/module.template.yaml +53 -53
  133. package/bmad/bmb/workflows/create-module/templates/workflow-plan-template.md +23 -23
  134. package/bmad/bmb/workflows/create-module/validation.md +126 -126
  135. package/bmad/bmb/workflows/create-module/workflow.md +56 -56
  136. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/data/dietary-restrictions.csv +17 -17
  137. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/data/macro-calculator.csv +15 -15
  138. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/data/recipe-database.csv +27 -27
  139. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/steps/step-01-init.md +177 -177
  140. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/steps/step-01b-continue.md +150 -150
  141. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/steps/step-02-profile.md +164 -164
  142. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/steps/step-03-assessment.md +152 -152
  143. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/steps/step-04-strategy.md +182 -182
  144. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/steps/step-05-shopping.md +167 -167
  145. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/steps/step-06-prep-schedule.md +194 -194
  146. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/templates/assessment-section.md +25 -25
  147. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/templates/nutrition-plan.md +68 -68
  148. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/templates/prep-schedule-section.md +29 -29
  149. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/templates/profile-section.md +47 -47
  150. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/templates/shopping-section.md +37 -37
  151. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/templates/strategy-section.md +18 -18
  152. package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/workflow.md +58 -58
  153. package/bmad/bmb/workflows/create-workflow/steps/step-01-init.md +158 -158
  154. package/bmad/bmb/workflows/create-workflow/steps/step-02-gather.md +212 -212
  155. package/bmad/bmb/workflows/create-workflow/steps/step-03-tools-configuration.md +251 -251
  156. package/bmad/bmb/workflows/create-workflow/steps/step-04-plan-review.md +217 -217
  157. package/bmad/bmb/workflows/create-workflow/steps/step-05-output-format-design.md +290 -290
  158. package/bmad/bmb/workflows/create-workflow/steps/step-06-design.md +272 -272
  159. package/bmad/bmb/workflows/create-workflow/steps/step-07-build.md +323 -323
  160. package/bmad/bmb/workflows/create-workflow/steps/step-08-review.md +285 -285
  161. package/bmad/bmb/workflows/create-workflow/steps/step-09-complete.md +188 -188
  162. package/bmad/bmb/workflows/create-workflow/workflow.md +59 -59
  163. package/bmad/bmb/workflows/edit-workflow/steps/step-01-analyze.md +217 -217
  164. package/bmad/bmb/workflows/edit-workflow/steps/step-02-discover.md +254 -254
  165. package/bmad/bmb/workflows/edit-workflow/steps/step-03-improve.md +218 -218
  166. package/bmad/bmb/workflows/edit-workflow/steps/step-04-validate.md +194 -194
  167. package/bmad/bmb/workflows/edit-workflow/steps/step-05-compliance-check.md +246 -246
  168. package/bmad/bmb/workflows/edit-workflow/templates/completion-summary.md +75 -75
  169. package/bmad/bmb/workflows/edit-workflow/templates/improvement-goals.md +68 -68
  170. package/bmad/bmb/workflows/edit-workflow/templates/improvement-log.md +40 -40
  171. package/bmad/bmb/workflows/edit-workflow/templates/validation-results.md +51 -51
  172. package/bmad/bmb/workflows/edit-workflow/templates/workflow-analysis.md +56 -56
  173. package/bmad/bmb/workflows/edit-workflow/workflow.md +59 -59
  174. package/bmad/bmb/workflows/workflow-compliance-check/steps/step-01-validate-goal.md +153 -153
  175. package/bmad/bmb/workflows/workflow-compliance-check/steps/step-02-workflow-validation.md +244 -244
  176. package/bmad/bmb/workflows/workflow-compliance-check/steps/step-03-step-validation.md +275 -275
  177. package/bmad/bmb/workflows/workflow-compliance-check/steps/step-04-file-validation.md +296 -296
  178. package/bmad/bmb/workflows/workflow-compliance-check/steps/step-05-intent-spectrum-validation.md +265 -265
  179. package/bmad/bmb/workflows/workflow-compliance-check/steps/step-06-web-subprocess-validation.md +361 -361
  180. package/bmad/bmb/workflows/workflow-compliance-check/steps/step-07-holistic-analysis.md +259 -259
  181. package/bmad/bmb/workflows/workflow-compliance-check/steps/step-08-generate-report.md +302 -302
  182. package/bmad/bmb/workflows/workflow-compliance-check/templates/compliance-report.md +140 -140
  183. package/bmad/bmb/workflows/workflow-compliance-check/workflow.md +59 -59
  184. package/bmad/bmb/workflows-legacy/edit-module/README.md +171 -171
  185. package/bmad/bmb/workflows-legacy/edit-module/checklist.md +163 -163
  186. package/bmad/bmb/workflows-legacy/edit-module/instructions.md +340 -340
  187. package/bmad/bmb/workflows-legacy/edit-module/workflow.yaml +32 -32
  188. package/bmad/bmb/workflows-legacy/module-brief/README.md +264 -264
  189. package/bmad/bmb/workflows-legacy/module-brief/checklist.md +116 -116
  190. package/bmad/bmb/workflows-legacy/module-brief/instructions.md +268 -268
  191. package/bmad/bmb/workflows-legacy/module-brief/template.md +275 -275
  192. package/bmad/bmb/workflows-legacy/module-brief/workflow.yaml +34 -34
  193. package/bmad/bmm/agents/analyst.md +76 -76
  194. package/bmad/bmm/agents/architect.md +68 -68
  195. package/bmad/bmm/agents/dev.md +70 -70
  196. package/bmad/bmm/agents/pm.md +70 -70
  197. package/bmad/bmm/agents/quick-flow-solo-dev.md +68 -68
  198. package/bmad/bmm/agents/sm.md +71 -71
  199. package/bmad/bmm/agents/tea.md +71 -71
  200. package/bmad/bmm/agents/tech-writer.md +72 -72
  201. package/bmad/bmm/agents/ux-designer.md +68 -68
  202. package/bmad/bmm/config.yaml +18 -18
  203. package/bmad/bmm/data/README.md +29 -29
  204. package/bmad/bmm/data/documentation-standards.md +262 -262
  205. package/bmad/bmm/data/project-context-template.md +40 -40
  206. package/bmad/bmm/teams/default-party.csv +21 -21
  207. package/bmad/bmm/teams/team-fullstack.yaml +12 -12
  208. package/bmad/bmm/testarch/knowledge/api-request.md +303 -303
  209. package/bmad/bmm/testarch/knowledge/auth-session.md +356 -356
  210. package/bmad/bmm/testarch/knowledge/burn-in.md +273 -273
  211. package/bmad/bmm/testarch/knowledge/ci-burn-in.md +675 -675
  212. package/bmad/bmm/testarch/knowledge/component-tdd.md +486 -486
  213. package/bmad/bmm/testarch/knowledge/contract-testing.md +957 -957
  214. package/bmad/bmm/testarch/knowledge/data-factories.md +500 -500
  215. package/bmad/bmm/testarch/knowledge/email-auth.md +721 -721
  216. package/bmad/bmm/testarch/knowledge/error-handling.md +725 -725
  217. package/bmad/bmm/testarch/knowledge/feature-flags.md +750 -750
  218. package/bmad/bmm/testarch/knowledge/file-utils.md +260 -260
  219. package/bmad/bmm/testarch/knowledge/fixture-architecture.md +401 -401
  220. package/bmad/bmm/testarch/knowledge/fixtures-composition.md +382 -382
  221. package/bmad/bmm/testarch/knowledge/intercept-network-call.md +280 -280
  222. package/bmad/bmm/testarch/knowledge/log.md +294 -294
  223. package/bmad/bmm/testarch/knowledge/network-error-monitor.md +272 -272
  224. package/bmad/bmm/testarch/knowledge/network-first.md +486 -486
  225. package/bmad/bmm/testarch/knowledge/network-recorder.md +265 -265
  226. package/bmad/bmm/testarch/knowledge/nfr-criteria.md +670 -670
  227. package/bmad/bmm/testarch/knowledge/overview.md +283 -283
  228. package/bmad/bmm/testarch/knowledge/playwright-config.md +730 -730
  229. package/bmad/bmm/testarch/knowledge/probability-impact.md +601 -601
  230. package/bmad/bmm/testarch/knowledge/recurse.md +296 -296
  231. package/bmad/bmm/testarch/knowledge/risk-governance.md +615 -615
  232. package/bmad/bmm/testarch/knowledge/selective-testing.md +732 -732
  233. package/bmad/bmm/testarch/knowledge/selector-resilience.md +527 -527
  234. package/bmad/bmm/testarch/knowledge/test-healing-patterns.md +644 -644
  235. package/bmad/bmm/testarch/knowledge/test-levels-framework.md +473 -473
  236. package/bmad/bmm/testarch/knowledge/test-priorities-matrix.md +373 -373
  237. package/bmad/bmm/testarch/knowledge/test-quality.md +664 -664
  238. package/bmad/bmm/testarch/knowledge/timing-debugging.md +372 -372
  239. package/bmad/bmm/testarch/knowledge/visual-debugging.md +524 -524
  240. package/bmad/bmm/testarch/tea-index.csv +33 -33
  241. package/bmad/bmm/workflows/1-analysis/create-product-brief/product-brief.template.md +10 -10
  242. package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +182 -182
  243. package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +166 -166
  244. package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +204 -204
  245. package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +207 -207
  246. package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +210 -210
  247. package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +224 -224
  248. package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +199 -199
  249. package/bmad/bmm/workflows/1-analysis/create-product-brief/workflow.md +58 -58
  250. package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +137 -137
  251. package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +229 -229
  252. package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +238 -238
  253. package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +206 -206
  254. package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +234 -234
  255. package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +443 -443
  256. package/bmad/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +182 -182
  257. package/bmad/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +237 -237
  258. package/bmad/bmm/workflows/1-analysis/research/market-steps/step-02-customer-insights.md +200 -200
  259. package/bmad/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +249 -249
  260. package/bmad/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +259 -259
  261. package/bmad/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +177 -177
  262. package/bmad/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +475 -475
  263. package/bmad/bmm/workflows/1-analysis/research/research.template.md +29 -29
  264. package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +137 -137
  265. package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +239 -239
  266. package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +248 -248
  267. package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +202 -202
  268. package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +239 -239
  269. package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +486 -486
  270. package/bmad/bmm/workflows/1-analysis/research/workflow.md +173 -173
  271. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01-init.md +135 -135
  272. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +127 -127
  273. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +190 -190
  274. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +216 -216
  275. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +219 -219
  276. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +234 -234
  277. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +252 -252
  278. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +254 -254
  279. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +224 -224
  280. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +224 -224
  281. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +241 -241
  282. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +248 -248
  283. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +237 -237
  284. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +264 -264
  285. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +228 -228
  286. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +13 -13
  287. package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +43 -43
  288. package/bmad/bmm/workflows/2-plan-workflows/prd/domain-complexity.csv +12 -12
  289. package/bmad/bmm/workflows/2-plan-workflows/prd/prd-template.md +11 -11
  290. package/bmad/bmm/workflows/2-plan-workflows/prd/project-types.csv +10 -10
  291. package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-01-init.md +197 -197
  292. package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-01b-continue.md +166 -166
  293. package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-02-discovery.md +421 -421
  294. package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-03-success.md +290 -290
  295. package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-04-journeys.md +291 -291
  296. package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-05-domain.md +271 -271
  297. package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-06-innovation.md +262 -262
  298. package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-07-project-type.md +258 -258
  299. package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-08-scoping.md +299 -299
  300. package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-09-functional.md +270 -270
  301. package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-10-nonfunctional.md +294 -294
  302. package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-11-complete.md +186 -186
  303. package/bmad/bmm/workflows/2-plan-workflows/prd/workflow.md +63 -63
  304. package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +190 -190
  305. package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +178 -178
  306. package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +179 -179
  307. package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +139 -139
  308. package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +252 -252
  309. package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +133 -133
  310. package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/templates/readiness-report-template.md +4 -4
  311. package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +55 -55
  312. package/bmad/bmm/workflows/3-solutioning/create-architecture/architecture-decision-template.md +12 -12
  313. package/bmad/bmm/workflows/3-solutioning/create-architecture/data/company-standards/architecture-patterns.md +415 -415
  314. package/bmad/bmm/workflows/3-solutioning/create-architecture/data/company-standards/backend-standards.md +811 -811
  315. package/bmad/bmm/workflows/3-solutioning/create-architecture/data/company-standards/frontend-standards.md +375 -375
  316. package/bmad/bmm/workflows/3-solutioning/create-architecture/data/company-standards/technical-preferences-ux.md +422 -422
  317. package/bmad/bmm/workflows/3-solutioning/create-architecture/data/company-standards/technology-stack.md +235 -235
  318. package/bmad/bmm/workflows/3-solutioning/create-architecture/data/domain-complexity.csv +10 -10
  319. package/bmad/bmm/workflows/3-solutioning/create-architecture/data/project-types.csv +6 -6
  320. package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-01-init.md +166 -166
  321. package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +164 -164
  322. package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +224 -224
  323. package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +342 -342
  324. package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +328 -328
  325. package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +368 -368
  326. package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +379 -379
  327. package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +366 -366
  328. package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +352 -352
  329. package/bmad/bmm/workflows/3-solutioning/create-architecture/workflow.md +51 -51
  330. package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +259 -259
  331. package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +233 -233
  332. package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +272 -272
  333. package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +145 -145
  334. package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -57
  335. package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +59 -59
  336. package/bmad/bmm/workflows/4-implementation/code-review/checklist.md +23 -23
  337. package/bmad/bmm/workflows/4-implementation/code-review/instructions.xml +224 -224
  338. package/bmad/bmm/workflows/4-implementation/code-review/workflow.yaml +49 -49
  339. package/bmad/bmm/workflows/4-implementation/correct-course/checklist.md +279 -279
  340. package/bmad/bmm/workflows/4-implementation/correct-course/instructions.md +206 -206
  341. package/bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml +58 -58
  342. package/bmad/bmm/workflows/4-implementation/create-story/checklist.md +358 -358
  343. package/bmad/bmm/workflows/4-implementation/create-story/steps/step-01-determine-story.md +85 -85
  344. package/bmad/bmm/workflows/4-implementation/create-story/steps/step-02-analyze.md +67 -67
  345. package/bmad/bmm/workflows/4-implementation/create-story/steps/step-03-architecture.md +71 -71
  346. package/bmad/bmm/workflows/4-implementation/create-story/steps/step-04-web-research.md +58 -58
  347. package/bmad/bmm/workflows/4-implementation/create-story/steps/step-05-create-file.md +76 -76
  348. package/bmad/bmm/workflows/4-implementation/create-story/steps/step-06-finalize.md +66 -66
  349. package/bmad/bmm/workflows/4-implementation/create-story/template.md +49 -49
  350. package/bmad/bmm/workflows/4-implementation/create-story/workflow.md +58 -58
  351. package/bmad/bmm/workflows/4-implementation/create-story/workflow.yaml.bak +63 -63
  352. package/bmad/bmm/workflows/4-implementation/dev-story/checklist.md +85 -85
  353. package/bmad/bmm/workflows/4-implementation/dev-story/instructions.xml +470 -470
  354. package/bmad/bmm/workflows/4-implementation/dev-story/workflow.yaml +25 -25
  355. package/bmad/bmm/workflows/4-implementation/retrospective/instructions.md +1443 -1443
  356. package/bmad/bmm/workflows/4-implementation/retrospective/workflow.yaml +56 -56
  357. package/bmad/bmm/workflows/4-implementation/sprint-planning/checklist.md +33 -33
  358. package/bmad/bmm/workflows/4-implementation/sprint-planning/instructions.md +225 -225
  359. package/bmad/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +55 -55
  360. package/bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +52 -52
  361. package/bmad/bmm/workflows/4-implementation/sprint-status/instructions.md +229 -229
  362. package/bmad/bmm/workflows/4-implementation/sprint-status/workflow.yaml +34 -34
  363. package/bmad/bmm/workflows/bmad-quick-flow/create-tech-spec/steps/step-01-understand.md +189 -189
  364. package/bmad/bmm/workflows/bmad-quick-flow/create-tech-spec/steps/step-02-investigate.md +144 -144
  365. package/bmad/bmm/workflows/bmad-quick-flow/create-tech-spec/steps/step-03-generate.md +128 -128
  366. package/bmad/bmm/workflows/bmad-quick-flow/create-tech-spec/steps/step-04-review.md +173 -173
  367. package/bmad/bmm/workflows/bmad-quick-flow/create-tech-spec/tech-spec-template.md +74 -74
  368. package/bmad/bmm/workflows/bmad-quick-flow/create-tech-spec/workflow.md +79 -79
  369. package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +156 -156
  370. package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +120 -120
  371. package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +113 -113
  372. package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +113 -113
  373. package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +106 -106
  374. package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-06-resolve-findings.md +140 -140
  375. package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +52 -52
  376. package/bmad/bmm/workflows/document-project/checklist.md +245 -245
  377. package/bmad/bmm/workflows/document-project/documentation-requirements.csv +12 -12
  378. package/bmad/bmm/workflows/document-project/instructions.md +221 -221
  379. package/bmad/bmm/workflows/document-project/templates/deep-dive-template.md +345 -345
  380. package/bmad/bmm/workflows/document-project/templates/index-template.md +169 -169
  381. package/bmad/bmm/workflows/document-project/templates/project-overview-template.md +103 -103
  382. package/bmad/bmm/workflows/document-project/templates/project-scan-report-schema.json +160 -160
  383. package/bmad/bmm/workflows/document-project/templates/source-tree-template.md +135 -135
  384. package/bmad/bmm/workflows/document-project/workflow.yaml +28 -28
  385. package/bmad/bmm/workflows/document-project/workflows/deep-dive-instructions.md +298 -298
  386. package/bmad/bmm/workflows/document-project/workflows/deep-dive.yaml +31 -31
  387. package/bmad/bmm/workflows/document-project/workflows/full-scan-instructions.md +1106 -1106
  388. package/bmad/bmm/workflows/document-project/workflows/full-scan.yaml +31 -31
  389. package/bmad/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-library.json +90 -90
  390. package/bmad/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-templates.yaml +127 -127
  391. package/bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/checklist.md +39 -39
  392. package/bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/instructions.md +130 -130
  393. package/bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/workflow.yaml +25 -25
  394. package/bmad/bmm/workflows/excalidraw-diagrams/create-diagram/checklist.md +43 -43
  395. package/bmad/bmm/workflows/excalidraw-diagrams/create-diagram/instructions.md +141 -141
  396. package/bmad/bmm/workflows/excalidraw-diagrams/create-diagram/workflow.yaml +25 -25
  397. package/bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/checklist.md +49 -49
  398. package/bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/instructions.md +241 -241
  399. package/bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/workflow.yaml +25 -25
  400. package/bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/checklist.md +38 -38
  401. package/bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/instructions.md +133 -133
  402. package/bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/workflow.yaml +25 -25
  403. package/bmad/bmm/workflows/generate-project-context/project-context-template.md +21 -21
  404. package/bmad/bmm/workflows/generate-project-context/steps/step-01-discover.md +218 -218
  405. package/bmad/bmm/workflows/generate-project-context/steps/step-02-generate.md +318 -318
  406. package/bmad/bmm/workflows/generate-project-context/steps/step-03-complete.md +278 -278
  407. package/bmad/bmm/workflows/generate-project-context/workflow.md +50 -50
  408. package/bmad/bmm/workflows/testarch/atdd/atdd-checklist-template.md +364 -364
  409. package/bmad/bmm/workflows/testarch/atdd/checklist.md +374 -374
  410. package/bmad/bmm/workflows/testarch/atdd/instructions.md +806 -806
  411. package/bmad/bmm/workflows/testarch/atdd/workflow.yaml +45 -45
  412. package/bmad/bmm/workflows/testarch/automate/checklist.md +582 -582
  413. package/bmad/bmm/workflows/testarch/automate/instructions.md +1324 -1324
  414. package/bmad/bmm/workflows/testarch/automate/workflow.yaml +52 -52
  415. package/bmad/bmm/workflows/testarch/ci/checklist.md +248 -248
  416. package/bmad/bmm/workflows/testarch/ci/github-actions-template.yaml +198 -198
  417. package/bmad/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +149 -149
  418. package/bmad/bmm/workflows/testarch/ci/instructions.md +536 -536
  419. package/bmad/bmm/workflows/testarch/ci/workflow.yaml +45 -45
  420. package/bmad/bmm/workflows/testarch/framework/checklist.md +321 -321
  421. package/bmad/bmm/workflows/testarch/framework/instructions.md +481 -481
  422. package/bmad/bmm/workflows/testarch/framework/workflow.yaml +47 -47
  423. package/bmad/bmm/workflows/testarch/nfr-assess/checklist.md +407 -407
  424. package/bmad/bmm/workflows/testarch/nfr-assess/instructions.md +722 -722
  425. package/bmad/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +445 -445
  426. package/bmad/bmm/workflows/testarch/nfr-assess/workflow.yaml +47 -47
  427. package/bmad/bmm/workflows/testarch/test-design/checklist.md +235 -235
  428. package/bmad/bmm/workflows/testarch/test-design/instructions.md +788 -788
  429. package/bmad/bmm/workflows/testarch/test-design/test-design-template.md +294 -294
  430. package/bmad/bmm/workflows/testarch/test-design/workflow.yaml +54 -54
  431. package/bmad/bmm/workflows/testarch/test-review/checklist.md +472 -472
  432. package/bmad/bmm/workflows/testarch/test-review/instructions.md +628 -628
  433. package/bmad/bmm/workflows/testarch/test-review/test-review-template.md +390 -390
  434. package/bmad/bmm/workflows/testarch/test-review/workflow.yaml +46 -46
  435. package/bmad/bmm/workflows/testarch/trace/checklist.md +655 -655
  436. package/bmad/bmm/workflows/testarch/trace/instructions.md +1047 -1047
  437. package/bmad/bmm/workflows/testarch/trace/trace-template.md +675 -675
  438. package/bmad/bmm/workflows/testarch/trace/workflow.yaml +55 -55
  439. package/bmad/bmm/workflows/workflow-status/init/instructions.md +346 -346
  440. package/bmad/bmm/workflows/workflow-status/init/workflow.yaml +28 -28
  441. package/bmad/bmm/workflows/workflow-status/instructions.md +395 -395
  442. package/bmad/bmm/workflows/workflow-status/paths/enterprise-brownfield.yaml +103 -103
  443. package/bmad/bmm/workflows/workflow-status/paths/enterprise-greenfield.yaml +100 -100
  444. package/bmad/bmm/workflows/workflow-status/paths/method-brownfield.yaml +103 -103
  445. package/bmad/bmm/workflows/workflow-status/paths/method-greenfield.yaml +100 -100
  446. package/bmad/bmm/workflows/workflow-status/project-levels.yaml +59 -59
  447. package/bmad/bmm/workflows/workflow-status/workflow-status-template.yaml +24 -24
  448. package/bmad/bmm/workflows/workflow-status/workflow.yaml +30 -30
  449. package/bmad/cis/agents/brainstorming-coach.md +60 -60
  450. package/bmad/cis/agents/creative-problem-solver.md +60 -60
  451. package/bmad/cis/agents/design-thinking-coach.md +60 -60
  452. package/bmad/cis/agents/innovation-strategist.md +60 -60
  453. package/bmad/cis/agents/presentation-master.md +66 -66
  454. package/bmad/cis/agents/storyteller/storyteller.md +57 -57
  455. package/bmad/cis/config.yaml +11 -11
  456. package/bmad/cis/teams/creative-squad.yaml +7 -7
  457. package/bmad/cis/teams/default-party.csv +12 -12
  458. package/bmad/cis/workflows/README.md +139 -139
  459. package/bmad/cis/workflows/design-thinking/README.md +56 -56
  460. package/bmad/cis/workflows/design-thinking/design-methods.csv +30 -30
  461. package/bmad/cis/workflows/design-thinking/instructions.md +202 -202
  462. package/bmad/cis/workflows/design-thinking/template.md +111 -111
  463. package/bmad/cis/workflows/design-thinking/workflow.yaml +27 -27
  464. package/bmad/cis/workflows/innovation-strategy/README.md +56 -56
  465. package/bmad/cis/workflows/innovation-strategy/innovation-frameworks.csv +30 -30
  466. package/bmad/cis/workflows/innovation-strategy/instructions.md +276 -276
  467. package/bmad/cis/workflows/innovation-strategy/template.md +189 -189
  468. package/bmad/cis/workflows/innovation-strategy/workflow.yaml +27 -27
  469. package/bmad/cis/workflows/problem-solving/README.md +56 -56
  470. package/bmad/cis/workflows/problem-solving/instructions.md +252 -252
  471. package/bmad/cis/workflows/problem-solving/solving-methods.csv +30 -30
  472. package/bmad/cis/workflows/problem-solving/template.md +165 -165
  473. package/bmad/cis/workflows/problem-solving/workflow.yaml +27 -27
  474. package/bmad/cis/workflows/storytelling/README.md +58 -58
  475. package/bmad/cis/workflows/storytelling/instructions.md +293 -293
  476. package/bmad/cis/workflows/storytelling/story-types.csv +25 -25
  477. package/bmad/cis/workflows/storytelling/template.md +113 -113
  478. package/bmad/cis/workflows/storytelling/workflow.yaml +27 -27
  479. package/bmad/core/agents/bmad-master.md +57 -57
  480. package/bmad/core/config.yaml +9 -9
  481. package/bmad/core/resources/excalidraw/README.md +160 -160
  482. package/bmad/core/resources/excalidraw/excalidraw-helpers.md +127 -127
  483. package/bmad/core/resources/excalidraw/library-loader.md +50 -50
  484. package/bmad/core/resources/excalidraw/validate-json-instructions.md +79 -79
  485. package/bmad/core/tasks/index-docs.xml +64 -64
  486. package/bmad/core/tasks/review-adversarial-general.xml +41 -41
  487. package/bmad/core/tasks/shard-doc.xml +108 -108
  488. package/bmad/core/tasks/validate-workflow.xml +88 -88
  489. package/bmad/core/tasks/workflow.xml +234 -234
  490. package/bmad/core/workflows/advanced-elicitation/methods.csv +51 -51
  491. package/bmad/core/workflows/advanced-elicitation/workflow.xml +116 -116
  492. package/bmad/core/workflows/brainstorming/brain-methods.csv +61 -61
  493. package/bmad/core/workflows/brainstorming/steps/step-01-session-setup.md +197 -197
  494. package/bmad/core/workflows/brainstorming/steps/step-01b-continue.md +122 -122
  495. package/bmad/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -225
  496. package/bmad/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -237
  497. package/bmad/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -209
  498. package/bmad/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -264
  499. package/bmad/core/workflows/brainstorming/steps/step-03-technique-execution.md +340 -340
  500. package/bmad/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -303
  501. package/bmad/core/workflows/brainstorming/template.md +15 -15
  502. package/bmad/core/workflows/brainstorming/workflow.md +51 -51
  503. package/bmad/core/workflows/party-mode/steps/step-01-agent-loading.md +139 -139
  504. package/bmad/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +204 -204
  505. package/bmad/core/workflows/party-mode/steps/step-03-graceful-exit.md +159 -159
  506. package/bmad/core/workflows/party-mode/workflow.md +206 -206
  507. package/claude/hooks/file-restriction-hook.py +51 -51
  508. package/claude/hooks/track-agent.py +67 -67
  509. package/claude/settings.local.json +76 -76
  510. package/gemini/commands/BMad/agents/analyst.toml +6 -0
  511. package/gemini/commands/BMad/agents/architect.toml +6 -0
  512. package/gemini/commands/BMad/agents/bmad-master.toml +6 -0
  513. package/gemini/commands/BMad/agents/bmad-orchestrator.toml +6 -0
  514. package/gemini/commands/BMad/agents/dev.toml +6 -0
  515. package/gemini/commands/BMad/agents/pm.toml +6 -0
  516. package/gemini/commands/BMad/agents/po.toml +6 -0
  517. package/gemini/commands/BMad/agents/qa.toml +6 -0
  518. package/gemini/commands/BMad/agents/sm.toml +6 -0
  519. package/gemini/commands/BMad/agents/ux-expert.toml +6 -0
  520. package/gemini/commands/BMad/tasks/advanced-elicitation.toml +6 -0
  521. package/gemini/commands/BMad/tasks/apply-qa-fixes.toml +6 -0
  522. package/gemini/commands/BMad/tasks/brownfield-create-epic.toml +6 -0
  523. package/gemini/commands/BMad/tasks/brownfield-create-story.toml +6 -0
  524. package/gemini/commands/BMad/tasks/correct-course.toml +6 -0
  525. package/gemini/commands/BMad/tasks/create-brownfield-story.toml +6 -0
  526. package/gemini/commands/BMad/tasks/create-deep-research-prompt.toml +6 -0
  527. package/gemini/commands/BMad/tasks/create-doc.toml +6 -0
  528. package/gemini/commands/BMad/tasks/create-next-story.toml +6 -0
  529. package/gemini/commands/BMad/tasks/document-project.toml +6 -0
  530. package/gemini/commands/BMad/tasks/execute-checklist.toml +6 -0
  531. package/gemini/commands/BMad/tasks/facilitate-brainstorming-session.toml +6 -0
  532. package/gemini/commands/BMad/tasks/generate-ai-frontend-prompt.toml +6 -0
  533. package/gemini/commands/BMad/tasks/index-docs.toml +6 -0
  534. package/gemini/commands/BMad/tasks/kb-mode-interaction.toml +6 -0
  535. package/gemini/commands/BMad/tasks/nfr-assess.toml +6 -0
  536. package/gemini/commands/BMad/tasks/qa-gate.toml +6 -0
  537. package/gemini/commands/BMad/tasks/review-story.toml +6 -0
  538. package/gemini/commands/BMad/tasks/risk-profile.toml +6 -0
  539. package/gemini/commands/BMad/tasks/shard-doc.toml +6 -0
  540. package/gemini/commands/BMad/tasks/test-design.toml +6 -0
  541. package/gemini/commands/BMad/tasks/trace-requirements.toml +6 -0
  542. package/gemini/commands/BMad/tasks/validate-next-story.toml +6 -0
  543. package/github/workflows/publish.yml +150 -150
  544. package/index.js +9 -9
  545. package/mcp.json +14 -14
  546. package/package.json +41 -40
  547. package/resources/images/Siesa_Logosimbolo_Azul.svg +24 -24
  548. package/resources/images/Siesa_Logosimbolo_Blanco.svg +24 -24
  549. package/resources/images/Siesa_Simbolo_Azul.svg +14 -14
  550. package/resources/images/Siesa_Simbolo_Blanco.svg +14 -14
  551. package/vscode/mcp.json +15 -15
  552. package/vscode/settings.json +12 -12
@@ -1,812 +1,812 @@
1
- # Backend Development Standards
2
-
3
- > **Note**: For architecture patterns and principles (Clean Architecture, DDD, folder structure), see [architecture-patterns.md](./architecture-patterns.md)
4
-
5
- ## Technology Stack Standards
6
-
7
- ### Core Technologies
8
- - **.NET 10**: Main framework with C#
9
- - **C# Minimal API**: Lightweight and modern approach for APIs
10
- - **Entity Framework Core 10**: ORM for database operations
11
- - **xUnit**: Unit and integration testing framework
12
- - **FluentValidation**: Validation for DTOs and models
13
-
14
- ### Framework Standards
15
- - **Default Framework**: .NET 10 with C# Minimal API
16
- - **Database**: PostgreSQL with Entity Framework Core 10 (mandatory)
17
- - **ORM Extensions**:
18
- - **linq2db**: For highly optimized complex queries requiring maximum performance
19
- - **DynamicLinq**: For runtime dynamic filters from user input or configurable scenarios
20
- - **LinqKit**: For composable type-safe predicates in DDD repositories with complex business rules
21
- - **Testing**: TDD approach with xUnit and high test coverage
22
- - **Documentation**: Scalar (NO Swagger) auto-generated
23
- - **Primary Keys**: UUID (Guid) for all entities
24
-
25
- ## CRITICAL: DateTime Type Standards
26
-
27
- ### ⚠️ Mandatory Rule: Use DateTimeOffset for Timestamps
28
-
29
- **ALWAYS use `DateTimeOffset` instead of `DateTime`** for all timestamp fields in entities, DTOs, and database models.
30
-
31
- #### Why DateTimeOffset?
32
-
33
- - **PostgreSQL Compatibility**: PostgreSQL uses `TIMESTAMP WITH TIME ZONE` which maps correctly to `DateTimeOffset` but NOT to `DateTime`
34
- - **Timezone Awareness**: `DateTimeOffset` preserves timezone information, preventing timezone conversion issues
35
- - **UTC Consistency**: Store all timestamps in UTC for consistency across different timezones
36
- - **Avoiding Bugs**: Using `DateTime` with PostgreSQL causes:
37
- - Data loss during timezone conversions
38
- - Inconsistent timestamp comparisons
39
- - Ambiguous datetime values during DST transitions
40
-
41
- #### Correct Usage
42
-
43
- ```csharp
44
- // ✅ CORRECT - Use DateTimeOffset for timestamps
45
- public class UserEntity : AggregateRoot
46
- {
47
- public Guid Id { get; private set; }
48
- public string Email { get; private set; }
49
- public DateTimeOffset CreatedAt { get; private set; } = DateTimeOffset.UtcNow;
50
- public DateTimeOffset UpdatedAt { get; private set; } = DateTimeOffset.UtcNow;
51
- }
52
-
53
- // ✅ CORRECT - Use DateOnly for date-only fields
54
- public class ExpenseEntity : AggregateRoot
55
- {
56
- public Guid Id { get; private set; }
57
- public decimal Amount { get; private set; }
58
- public DateOnly ExpenseDate { get; private set; } // Date without time
59
- public DateTimeOffset CreatedAt { get; private set; } = DateTimeOffset.UtcNow;
60
- }
61
-
62
- // ❌ WRONG - Never use DateTime for timestamp fields
63
- public class UserEntity : AggregateRoot
64
- {
65
- public DateTime CreatedAt { get; private set; } // ❌ WRONG - causes PostgreSQL issues
66
- public DateTime UpdatedAt { get; private set; } // ❌ WRONG - causes PostgreSQL issues
67
- }
68
- ```
69
-
70
- #### Entity Framework Core Configuration
71
-
72
- ```csharp
73
- public class UserEntityConfiguration : IEntityTypeConfiguration<UserEntity>
74
- {
75
- public void Configure(EntityTypeBuilder<UserEntity> builder)
76
- {
77
- builder.ToTable("users");
78
-
79
- // DateTimeOffset fields - automatically map to TIMESTAMP WITH TIME ZONE
80
- builder.Property(u => u.CreatedAt)
81
- .IsRequired()
82
- .HasDefaultValueSql("NOW()"); // PostgreSQL auto-generates UTC timestamp
83
-
84
- builder.Property(u => u.UpdatedAt)
85
- .IsRequired()
86
- .HasDefaultValueSql("NOW()");
87
- }
88
- }
89
- ```
90
-
91
- #### Type Selection Guide
92
-
93
- | Use Case | Type | Example |
94
- |----------|------|---------|
95
- | Timestamp with timezone | `DateTimeOffset` | `CreatedAt`, `UpdatedAt`, `DeletedAt`, `LastLoginAt` |
96
- | Date only (no time) | `DateOnly` | `BirthDate`, `ExpenseDate`, `DueDate` |
97
- | Time only (no date) | `TimeOnly` | `OpeningTime`, `ClosingTime` |
98
- | Never use | `DateTime` | ❌ Not compatible with PostgreSQL TIMESTAMP WITH TIME ZONE |
99
-
100
- #### Best Practices
101
-
102
- 1. **Always use `DateTimeOffset`** for `CreatedAt`, `UpdatedAt`, and any timestamp field
103
- 2. **Always use UTC**: Set values with `DateTimeOffset.UtcNow`
104
- 3. **Configure EF Core**: Use `HasDefaultValueSql("NOW()")` for automatic timestamps
105
- 4. **DTOs must match**: DTOs also use `DateTimeOffset` (serializes to ISO 8601 with timezone)
106
- 5. **Never use `DateTime`** for entity timestamp fields in PostgreSQL projects
107
-
108
- ### ORM Strategy Guidelines
109
-
110
- #### When to Use Entity Framework Core 10
111
- ✔ **Primary ORM for:**
112
- - Standard CRUD operations
113
- - DDD entities with tracking (Aggregate Roots, Domain Events)
114
- - Simple to moderate queries
115
- - Navigation properties and relationships
116
- - Change tracking scenarios
117
-
118
- #### When to Use linq2db
119
- ✔ **Use for maximum performance:**
120
- - Highly optimized complex queries (subqueries, complex projections, multiple joins)
121
- - Queries that EF Core cannot translate efficiently
122
- - High-performance endpoints: dashboards, analytics, reports, high data volumes
123
- - Pure queries without tracking needs
124
- - When EF Core generates inefficient SQL
125
-
126
- 🚫 **Avoid when:**
127
- - Need complete DDD entities with aggregate lifecycle
128
- - Query participates in domain events or tracking
129
-
130
- #### When to Use DynamicLinq
131
- ✔ **Use for runtime flexibility:**
132
- - Dynamic filter systems: `?filter=Age > 30 AND Country == "CO"`
133
- - Simplified OData-style APIs
134
- - Configurable grids or data explorers
135
- - Variable column searches
136
-
137
- 🚫 **Avoid when:**
138
- - Filters are fully controlled in code
139
- - Require strict security (needs sanitization)
140
- - Need maximum performance (use linq2db or LinqKit)
141
-
142
- #### When to Use LinqKit
143
- ✔ **Use for type-safe composition:**
144
- - Complex business rules in queries with composable predicates
145
- - Dynamic filters with type safety (no strings → expressions)
146
- - DDD repositories with multiple criteria, conditional searches, reusable queries
147
- - Enhance EF Core when composing complex expressions
148
- - 100% compatible with EF Core translation
149
-
150
- 🚫 **Avoid when:**
151
- - Filters are extremely simple
152
- - Query is highly dynamic and text-based (use DynamicLinq)
153
- - Need maximum raw performance (use linq2db)
154
-
155
- ### Development Tools
156
- - **dotnet CLI**: Project management, build, test, and restore
157
- - **NuGet**: Package manager
158
- - **EF Core 10 Migrations**: Database schema version control
159
- - **Docker**: For production only
160
- - **Code Analyzers**: Static C# code analysis
161
- - **EditorConfig**: Code formatting standards
162
-
163
- ## Domain-Driven Design Implementation
164
-
165
- ### Entity Structure
166
- ```csharp
167
- public class UserEntity : AggregateRoot
168
- {
169
- // Parameterless constructor for EF Core (materialization from DB)
170
- private UserEntity() : base(Guid.Empty)
171
- {
172
- // EF Core needs this to reconstruct the entity from the database
173
- }
174
-
175
- private UserEntity(
176
- Guid id,
177
- EmailValueObject email,
178
- NameValueObject name) : base(id)
179
- {
180
- Email = email;
181
- Name = name;
182
- }
183
-
184
- public EmailValueObject Email { get; private set; } = null!;
185
- public NameValueObject Name { get; private set; } = null!;
186
-
187
- public static UserEntity Create(string email, string name)
188
- {
189
- var userEmail = EmailValueObject.Create(email);
190
- var userName = NameValueObject.Create(name);
191
-
192
- var user = new UserEntity(Guid.NewGuid(), userEmail, userName);
193
- user.AddDomainEvent(new UserCreatedEvent(user.Id));
194
-
195
- return user;
196
- }
197
-
198
- public void UpdateEmail(string newEmail)
199
- {
200
- var newEmailVO = EmailValueObject.Create(newEmail);
201
- if (Email.Equals(newEmailVO)) return;
202
-
203
- Email = newEmailVO;
204
- AddDomainEvent(new UserEmailUpdatedEvent(Id, Email));
205
- }
206
- }
207
- ```
208
-
209
- ### Value Object Structure
210
- ```csharp
211
- public class EmailValueObject : ValueObject
212
- {
213
- public string Value { get; }
214
-
215
- private EmailValueObject(string value)
216
- {
217
- Value = value;
218
- }
219
-
220
- public static EmailValueObject Create(string value)
221
- {
222
- if (string.IsNullOrWhiteSpace(value))
223
- throw new ArgumentException("Email cannot be empty", nameof(value));
224
-
225
- if (!IsValidEmail(value))
226
- throw new InvalidEmailException(value);
227
-
228
- return new EmailValueObject(value);
229
- }
230
-
231
- private static bool IsValidEmail(string email)
232
- {
233
- // Email validation logic
234
- return System.Text.RegularExpressions.Regex.IsMatch(
235
- email,
236
- @"^[^@\s]+@[^@\s]+\.[^@\s]+$");
237
- }
238
-
239
- protected override IEnumerable<object> GetEqualityComponents()
240
- {
241
- yield return Value;
242
- }
243
- }
244
- ```
245
-
246
- ### Repository Pattern
247
- ```csharp
248
- // Interface (in Application layer)
249
- public interface IUserRepository
250
- {
251
- Task<UserEntity> SaveAsync(UserEntity user, CancellationToken cancellationToken = default);
252
- Task<UserEntity?> FindByIdAsync(Guid id, CancellationToken cancellationToken = default);
253
- Task<UserEntity?> FindByEmailAsync(EmailValueObject email, CancellationToken cancellationToken = default);
254
- Task DeleteAsync(Guid id, CancellationToken cancellationToken = default);
255
- }
256
-
257
- // Implementation (in Infrastructure layer)
258
- public class UserRepository : IUserRepository
259
- {
260
- private readonly ApplicationDbContext _context;
261
-
262
- public UserRepository(ApplicationDbContext context)
263
- {
264
- _context = context;
265
- }
266
-
267
- public async Task<UserEntity> SaveAsync(UserEntity user, CancellationToken cancellationToken = default)
268
- {
269
- var existingUser = await _context.Users.FindAsync(new object[] { user.Id }, cancellationToken);
270
-
271
- if (existingUser == null)
272
- await _context.Users.AddAsync(user, cancellationToken);
273
- else
274
- _context.Users.Update(user);
275
-
276
- await _context.SaveChangesAsync(cancellationToken);
277
- return user;
278
- }
279
-
280
- public async Task<UserEntity?> FindByIdAsync(Guid id, CancellationToken cancellationToken = default)
281
- {
282
- return await _context.Users.FindAsync(new object[] { id }, cancellationToken);
283
- }
284
-
285
- public async Task<UserEntity?> FindByEmailAsync(EmailValueObject email, CancellationToken cancellationToken = default)
286
- {
287
- return await _context.Users
288
- .FirstOrDefaultAsync(u => u.Email.Value == email.Value, cancellationToken);
289
- }
290
-
291
- public async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
292
- {
293
- var user = await FindByIdAsync(id, cancellationToken);
294
- if (user != null)
295
- {
296
- _context.Users.Remove(user);
297
- await _context.SaveChangesAsync(cancellationToken);
298
- }
299
- }
300
- }
301
- ```
302
-
303
- ## Command/Query (CQRS) Standards
304
-
305
- ### Command Structure
306
- ```csharp
307
- public record CreateUserCommand(string Email, string Name);
308
-
309
- public class CreateUserCommandValidator : AbstractValidator<CreateUserCommand>
310
- {
311
- public CreateUserCommandValidator()
312
- {
313
- RuleFor(x => x.Email)
314
- .NotEmpty().WithMessage("Email is required")
315
- .EmailAddress().WithMessage("Email must be valid");
316
-
317
- RuleFor(x => x.Name)
318
- .NotEmpty().WithMessage("Name is required")
319
- .MaximumLength(100).WithMessage("Name must not exceed 100 characters");
320
- }
321
- }
322
-
323
- public class CreateUserCommandHandler
324
- {
325
- private readonly IUserRepository _userRepository;
326
- private readonly IValidator<CreateUserCommand> _validator;
327
-
328
- public CreateUserCommandHandler(
329
- IUserRepository userRepository,
330
- IValidator<CreateUserCommand> validator)
331
- {
332
- _userRepository = userRepository;
333
- _validator = validator;
334
- }
335
-
336
- public async Task<UserResponseDto> HandleAsync(
337
- CreateUserCommand command,
338
- CancellationToken cancellationToken = default)
339
- {
340
- // 1. Validate command
341
- await _validator.ValidateAndThrowAsync(command, cancellationToken);
342
-
343
- // 2. Validate business rules
344
- await ValidateUserDoesNotExistAsync(command.Email, cancellationToken);
345
-
346
- // 3. Create domain entity
347
- var user = UserEntity.Create(command.Email, command.Name);
348
-
349
- // 4. Persist entity
350
- var savedUser = await _userRepository.SaveAsync(user, cancellationToken);
351
-
352
- // 5. Return response DTO
353
- return UserResponseDto.FromEntity(savedUser);
354
- }
355
-
356
- private async Task ValidateUserDoesNotExistAsync(string email, CancellationToken cancellationToken)
357
- {
358
- var emailVO = EmailValueObject.Create(email);
359
- var existingUser = await _userRepository.FindByEmailAsync(emailVO, cancellationToken);
360
- if (existingUser != null)
361
- throw new UserAlreadyExistsException(email);
362
- }
363
- }
364
- ```
365
-
366
- ### Query Structure
367
- ```csharp
368
- public record GetUserByIdQuery(Guid Id);
369
-
370
- public class GetUserByIdQueryHandler
371
- {
372
- private readonly IUserRepository _userRepository;
373
-
374
- public GetUserByIdQueryHandler(IUserRepository userRepository)
375
- {
376
- _userRepository = userRepository;
377
- }
378
-
379
- public async Task<UserResponseDto?> HandleAsync(
380
- GetUserByIdQuery query,
381
- CancellationToken cancellationToken = default)
382
- {
383
- var user = await _userRepository.FindByIdAsync(query.Id, cancellationToken);
384
- return user != null ? UserResponseDto.FromEntity(user) : null;
385
- }
386
- }
387
- ```
388
-
389
- ### DTO Structure
390
- ```csharp
391
- public record UserResponseDto
392
- {
393
- public Guid Id { get; init; }
394
- public string Email { get; init; }
395
- public string Name { get; init; }
396
-
397
- public static UserResponseDto FromEntity(UserEntity user)
398
- {
399
- return new UserResponseDto
400
- {
401
- Id = user.Id,
402
- Email = user.Email.Value,
403
- Name = user.Name.Value
404
- };
405
- }
406
- }
407
-
408
- ```
409
-
410
- ## Minimal API Standards
411
-
412
- ### Endpoint Structure
413
- ```csharp
414
- // Program.cs or separate endpoint configuration
415
- public static class UserEndpoints
416
- {
417
- public static void MapUserEndpoints(this IEndpointRouteBuilder app)
418
- {
419
- var group = app.MapGroup("/api/users")
420
- .WithTags("Users")
421
- .WithOpenApi();
422
-
423
- group.MapPost("/", CreateUser)
424
- .WithName("CreateUser")
425
- .WithSummary("Create a new user")
426
- .Produces<UserResponseDto>(StatusCodes.Status201Created)
427
- .ProducesValidationProblem();
428
-
429
- group.MapGet("/{id:guid}", GetUserById)
430
- .WithName("GetUserById")
431
- .WithSummary("Get user by ID")
432
- .Produces<UserResponseDto>()
433
- .Produces(StatusCodes.Status404NotFound);
434
- }
435
-
436
- private static async Task<IResult> CreateUser(
437
- CreateUserCommand command,
438
- CreateUserCommandHandler handler,
439
- CancellationToken cancellationToken)
440
- {
441
- try
442
- {
443
- var result = await handler.HandleAsync(command, cancellationToken);
444
- return Results.Created($"/api/users/{result.Id}", result);
445
- }
446
- catch (ValidationException ex)
447
- {
448
- return Results.ValidationProblem(ex.Errors.ToDictionary(
449
- e => e.PropertyName,
450
- e => new[] { e.ErrorMessage }));
451
- }
452
- catch (UserAlreadyExistsException ex)
453
- {
454
- return Results.Conflict(new { message = ex.Message });
455
- }
456
- }
457
-
458
- private static async Task<IResult> GetUserById(
459
- Guid id,
460
- GetUserByIdQueryHandler handler,
461
- CancellationToken cancellationToken)
462
- {
463
- var result = await handler.HandleAsync(new GetUserByIdQuery(id), cancellationToken);
464
- return result != null ? Results.Ok(result) : Results.NotFound();
465
- }
466
- }
467
- ```
468
-
469
- ## Testing Standards
470
-
471
- ### Testing Strategy
472
- - **Unit Tests**: Domain entities, value objects, command/query handlers (isolated logic)
473
- - **Integration Tests**: Repository implementations, database operations with EF Core InMemory or Test Containers
474
- - **TDD Approach**: Write tests before or alongside implementation
475
- - **High Coverage**: Aim for >80% code coverage
476
-
477
- ### Test Structure (xUnit)
478
- ```csharp
479
- public class CreateUserCommandHandlerTests
480
- {
481
- private readonly Mock<IUserRepository> _userRepositoryMock;
482
- private readonly Mock<IValidator<CreateUserCommand>> _validatorMock;
483
- private readonly CreateUserCommandHandler _handler;
484
-
485
- public CreateUserCommandHandlerTests()
486
- {
487
- _userRepositoryMock = new Mock<IUserRepository>();
488
- _validatorMock = new Mock<IValidator<CreateUserCommand>>();
489
- _handler = new CreateUserCommandHandler(
490
- _userRepositoryMock.Object,
491
- _validatorMock.Object);
492
- }
493
-
494
- [Fact]
495
- public async Task HandleAsync_WithValidCommand_ShouldCreateUser()
496
- {
497
- // Arrange
498
- var command = new CreateUserCommand("test@example.com", "John Doe");
499
- _validatorMock
500
- .Setup(v => v.ValidateAndThrowAsync(command, It.IsAny<CancellationToken>()))
501
- .Returns(Task.CompletedTask);
502
- _userRepositoryMock
503
- .Setup(r => r.FindByEmailAsync(It.IsAny<EmailValueObject>(), It.IsAny<CancellationToken>()))
504
- .ReturnsAsync((UserEntity?)null);
505
- _userRepositoryMock
506
- .Setup(r => r.SaveAsync(It.IsAny<UserEntity>(), It.IsAny<CancellationToken>()))
507
- .ReturnsAsync((UserEntity u, CancellationToken _) => u);
508
-
509
- // Act
510
- var result = await _handler.HandleAsync(command, CancellationToken.None);
511
-
512
- // Assert
513
- Assert.NotNull(result);
514
- Assert.Equal(command.Email, result.Email);
515
- Assert.Equal(command.Name, result.Name);
516
- _userRepositoryMock.Verify(r => r.SaveAsync(It.IsAny<UserEntity>(), It.IsAny<CancellationToken>()), Times.Once);
517
- }
518
-
519
- [Fact]
520
- public async Task HandleAsync_WithExistingUser_ShouldThrowException()
521
- {
522
- // Arrange
523
- var command = new CreateUserCommand("test@example.com", "John Doe");
524
- var existingUser = UserEntity.Create("test@example.com", "Existing User");
525
- _validatorMock
526
- .Setup(v => v.ValidateAndThrowAsync(command, It.IsAny<CancellationToken>()))
527
- .Returns(Task.CompletedTask);
528
- _userRepositoryMock
529
- .Setup(r => r.FindByEmailAsync(It.IsAny<EmailValueObject>(), It.IsAny<CancellationToken>()))
530
- .ReturnsAsync(existingUser);
531
-
532
- // Act & Assert
533
- await Assert.ThrowsAsync<UserAlreadyExistsException>(() =>
534
- _handler.HandleAsync(command, CancellationToken.None));
535
- }
536
- }
537
- ```
538
-
539
- ### Integration Test with EF Core InMemory
540
- ```csharp
541
- public class UserRepositoryIntegrationTests : IDisposable
542
- {
543
- private readonly ApplicationDbContext _context;
544
- private readonly UserRepository _repository;
545
-
546
- public UserRepositoryIntegrationTests()
547
- {
548
- var options = new DbContextOptionsBuilder<ApplicationDbContext>()
549
- .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
550
- .Options;
551
-
552
- _context = new ApplicationDbContext(options);
553
- _repository = new UserRepository(_context);
554
- }
555
-
556
- [Fact]
557
- public async Task SaveAsync_ShouldPersistUser()
558
- {
559
- // Arrange
560
- var user = UserEntity.Create("test@example.com", "John Doe");
561
-
562
- // Act
563
- var savedUser = await _repository.SaveAsync(user);
564
-
565
- // Assert
566
- var retrievedUser = await _repository.FindByIdAsync(savedUser.Id);
567
- Assert.NotNull(retrievedUser);
568
- Assert.Equal(user.Email.Value, retrievedUser.Email.Value);
569
- }
570
-
571
- public void Dispose()
572
- {
573
- _context.Database.EnsureDeleted();
574
- _context.Dispose();
575
- }
576
- }
577
- ```
578
-
579
- ## EF Core Configuration Standards
580
-
581
- ### DbContext Configuration
582
- ```csharp
583
- public class ApplicationDbContext : DbContext
584
- {
585
- public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
586
- : base(options)
587
- {
588
- }
589
-
590
- public DbSet<UserEntity> Users { get; set; }
591
- public DbSet<QuoteEntity> Quotes { get; set; }
592
-
593
- protected override void OnModelCreating(ModelBuilder modelBuilder)
594
- {
595
- base.OnModelCreating(modelBuilder);
596
-
597
- // Apply all configurations from assembly
598
- modelBuilder.ApplyConfigurationsFromAssembly(typeof(ApplicationDbContext).Assembly);
599
- }
600
- }
601
- ```
602
-
603
- ### Entity Configuration
604
- ```csharp
605
- public class UserEntityConfiguration : IEntityTypeConfiguration<UserEntity>
606
- {
607
- public void Configure(EntityTypeBuilder<UserEntity> builder)
608
- {
609
- builder.ToTable("Users");
610
-
611
- builder.HasKey(u => u.Id);
612
-
613
- builder.Property(u => u.Id)
614
- .HasColumnType("uuid")
615
- .IsRequired();
616
-
617
- // Configure Value Object as owned entity
618
- builder.OwnsOne(u => u.Email, email =>
619
- {
620
- email.Property(e => e.Value)
621
- .HasColumnName("Email")
622
- .HasMaxLength(256)
623
- .IsRequired();
624
- });
625
-
626
- builder.OwnsOne(u => u.Name, name =>
627
- {
628
- name.Property(n => n.Value)
629
- .HasColumnName("Name")
630
- .HasMaxLength(100)
631
- .IsRequired();
632
- });
633
-
634
- // Ignore domain events (not persisted)
635
- builder.Ignore(u => u.DomainEvents);
636
- }
637
- }
638
- ```
639
-
640
- ## Security Standards
641
-
642
- ### Authentication & Authorization
643
- - **JWT Tokens**: Proper expiration and refresh token handling
644
- - **RBAC**: Role-based access control
645
- - **Validation**: Input validation on all endpoints (FluentValidation)
646
- - **Rate Limiting**: Throttle public endpoints to prevent abuse
647
- - **Environment**: HTTPS only in production, secrets in env variables
648
-
649
- ### Data Protection
650
- - Encrypt sensitive data at rest and in transit
651
- - Never commit secrets to repository
652
- - Implement audit logging for critical operations
653
- - OWASP Top 10 compliance
654
- - Regular dependency security audits with `dotnet list package --vulnerable`
655
-
656
- ## Performance Standards
657
-
658
- ### Database Optimization
659
- - Proper indexing on frequently queried fields
660
- - Connection pooling via EF Core 10
661
- - Pagination for large datasets (Skip/Take or cursor-based)
662
- - Avoid N+1 queries with `.Include()` and `.ThenInclude()`
663
- - Query monitoring and slow query logging
664
- - Use `AsNoTracking()` for read-only queries
665
-
666
- ### Caching Strategy
667
- - **Distributed Cache**: Redis for session data and frequently accessed data
668
- - **Memory Cache**: In-memory caching for configuration
669
- - **TTL Strategy**: Appropriate time-to-live for different data types
670
- - **Invalidation**: Event-driven cache invalidation
671
-
672
- ## Error Handling
673
-
674
- ### Exception Hierarchy
675
- - Domain exceptions for business rule violations
676
- - Application exceptions for use case errors
677
- - Infrastructure exceptions for external service failures
678
- - Global exception middleware for API responses
679
-
680
- ### Error Response Format (Problem Details RFC 7807)
681
- ```csharp
682
- public record ProblemDetailsResponse
683
- {
684
- public int Status { get; init; }
685
- public string Title { get; init; }
686
- public string Detail { get; init; }
687
- public string Instance { get; init; }
688
- public DateTimeOffset Timestamp { get; init; }
689
- public Dictionary<string, string[]>? Errors { get; init; }
690
- }
691
-
692
- // Example response
693
- {
694
- "status": 400,
695
- "title": "Validation Error",
696
- "detail": "One or more validation errors occurred",
697
- "instance": "/api/users",
698
- "timestamp": "2025-11-26T10:30:00Z",
699
- "errors": {
700
- "Email": ["Email is required", "Email must be valid"],
701
- "Name": ["Name is required"]
702
- }
703
- }
704
- ```
705
-
706
- ### Global Exception Middleware
707
- ```csharp
708
- public class ExceptionHandlingMiddleware
709
- {
710
- private readonly RequestDelegate _next;
711
- private readonly ILogger<ExceptionHandlingMiddleware> _logger;
712
-
713
- public ExceptionHandlingMiddleware(
714
- RequestDelegate next,
715
- ILogger<ExceptionHandlingMiddleware> logger)
716
- {
717
- _next = next;
718
- _logger = logger;
719
- }
720
-
721
- public async Task InvokeAsync(HttpContext context)
722
- {
723
- try
724
- {
725
- await _next(context);
726
- }
727
- catch (ValidationException ex)
728
- {
729
- await HandleValidationExceptionAsync(context, ex);
730
- }
731
- catch (DomainException ex)
732
- {
733
- await HandleDomainExceptionAsync(context, ex);
734
- }
735
- catch (Exception ex)
736
- {
737
- _logger.LogError(ex, "Unhandled exception occurred");
738
- await HandleUnhandledExceptionAsync(context, ex);
739
- }
740
- }
741
-
742
- private static Task HandleValidationExceptionAsync(HttpContext context, ValidationException exception)
743
- {
744
- context.Response.StatusCode = StatusCodes.Status400BadRequest;
745
- context.Response.ContentType = "application/problem+json";
746
-
747
- var problemDetails = new ProblemDetailsResponse
748
- {
749
- Status = StatusCodes.Status400BadRequest,
750
- Title = "Validation Error",
751
- Detail = "One or more validation errors occurred",
752
- Instance = context.Request.Path,
753
- Timestamp = DateTimeOffset.UtcNow,
754
- Errors = exception.Errors.GroupBy(e => e.PropertyName)
755
- .ToDictionary(g => g.Key, g => g.Select(e => e.ErrorMessage).ToArray())
756
- };
757
-
758
- return context.Response.WriteAsJsonAsync(problemDetails);
759
- }
760
- }
761
- ```
762
-
763
- ## Security Standards
764
-
765
- ### Authentication & Authorization
766
- - **JWT Tokens**: Proper expiration and refresh token handling
767
- - **RBAC**: Role-based access control with Authorization Policies
768
- - **Validation**: Input validation on all endpoints (FluentValidation)
769
- - **Rate Limiting**: ASP.NET Core Rate Limiting middleware
770
- - **Environment**: HTTPS only in production, secrets in Azure Key Vault or User Secrets
771
-
772
- ### Data Protection
773
- - Encrypt sensitive data at rest and in transit
774
- - Never commit secrets to repository
775
- - Implement audit logging for critical operations
776
- - OWASP Top 10 compliance
777
- - Regular dependency security audits with `dotnet list package --vulnerable`
778
-
779
- ## Performance Standards
780
-
781
- ### Database Optimization
782
- - Proper indexing on frequently queried fields
783
- - Connection pooling via EF Core (configured in connection string)
784
- - Pagination for large datasets (Skip/Take or Keyset pagination)
785
- - Avoid N+1 queries with `.Include()` and `.ThenInclude()`
786
- - Query monitoring and slow query logging
787
- - Use `AsNoTracking()` for read-only queries
788
-
789
- ### Caching Strategy
790
- - **Distributed Cache**: Redis or SQL Server for distributed scenarios
791
- - **Memory Cache**: `IMemoryCache` for single-instance caching
792
- - **TTL Strategy**: Appropriate time-to-live for different data types
793
- - **Invalidation**: Event-driven cache invalidation
794
- - **Response Caching**: Use `[ResponseCache]` attribute for GET endpoints
795
-
796
- ## Additional Standards
797
-
798
- ### Logging
799
- - Use `ILogger<T>` for structured logging
800
- - Log levels: Trace, Debug, Information, Warning, Error, Critical
801
- - Include correlation IDs for request tracing
802
- - Never log sensitive information (passwords, tokens, PII)
803
-
804
- ### API Versioning
805
- - Use URL versioning: `/api/v1/users`
806
- - Support multiple versions simultaneously during migration
807
- - Deprecation notices in response headers
808
-
809
- ### Health Checks
810
- - Implement `/health` endpoint for liveness
811
- - Implement `/health/ready` for readiness checks
1
+ # Backend Development Standards
2
+
3
+ > **Note**: For architecture patterns and principles (Clean Architecture, DDD, folder structure), see [architecture-patterns.md](./architecture-patterns.md)
4
+
5
+ ## Technology Stack Standards
6
+
7
+ ### Core Technologies
8
+ - **.NET 10**: Main framework with C#
9
+ - **C# Minimal API**: Lightweight and modern approach for APIs
10
+ - **Entity Framework Core 10**: ORM for database operations
11
+ - **xUnit**: Unit and integration testing framework
12
+ - **FluentValidation**: Validation for DTOs and models
13
+
14
+ ### Framework Standards
15
+ - **Default Framework**: .NET 10 with C# Minimal API
16
+ - **Database**: PostgreSQL with Entity Framework Core 10 (mandatory)
17
+ - **ORM Extensions**:
18
+ - **linq2db**: For highly optimized complex queries requiring maximum performance
19
+ - **DynamicLinq**: For runtime dynamic filters from user input or configurable scenarios
20
+ - **LinqKit**: For composable type-safe predicates in DDD repositories with complex business rules
21
+ - **Testing**: TDD approach with xUnit and high test coverage
22
+ - **Documentation**: Scalar (NO Swagger) auto-generated
23
+ - **Primary Keys**: UUID (Guid) for all entities
24
+
25
+ ## CRITICAL: DateTime Type Standards
26
+
27
+ ### ⚠️ Mandatory Rule: Use DateTimeOffset for Timestamps
28
+
29
+ **ALWAYS use `DateTimeOffset` instead of `DateTime`** for all timestamp fields in entities, DTOs, and database models.
30
+
31
+ #### Why DateTimeOffset?
32
+
33
+ - **PostgreSQL Compatibility**: PostgreSQL uses `TIMESTAMP WITH TIME ZONE` which maps correctly to `DateTimeOffset` but NOT to `DateTime`
34
+ - **Timezone Awareness**: `DateTimeOffset` preserves timezone information, preventing timezone conversion issues
35
+ - **UTC Consistency**: Store all timestamps in UTC for consistency across different timezones
36
+ - **Avoiding Bugs**: Using `DateTime` with PostgreSQL causes:
37
+ - Data loss during timezone conversions
38
+ - Inconsistent timestamp comparisons
39
+ - Ambiguous datetime values during DST transitions
40
+
41
+ #### Correct Usage
42
+
43
+ ```csharp
44
+ // ✅ CORRECT - Use DateTimeOffset for timestamps
45
+ public class UserEntity : AggregateRoot
46
+ {
47
+ public Guid Id { get; private set; }
48
+ public string Email { get; private set; }
49
+ public DateTimeOffset CreatedAt { get; private set; } = DateTimeOffset.UtcNow;
50
+ public DateTimeOffset UpdatedAt { get; private set; } = DateTimeOffset.UtcNow;
51
+ }
52
+
53
+ // ✅ CORRECT - Use DateOnly for date-only fields
54
+ public class ExpenseEntity : AggregateRoot
55
+ {
56
+ public Guid Id { get; private set; }
57
+ public decimal Amount { get; private set; }
58
+ public DateOnly ExpenseDate { get; private set; } // Date without time
59
+ public DateTimeOffset CreatedAt { get; private set; } = DateTimeOffset.UtcNow;
60
+ }
61
+
62
+ // ❌ WRONG - Never use DateTime for timestamp fields
63
+ public class UserEntity : AggregateRoot
64
+ {
65
+ public DateTime CreatedAt { get; private set; } // ❌ WRONG - causes PostgreSQL issues
66
+ public DateTime UpdatedAt { get; private set; } // ❌ WRONG - causes PostgreSQL issues
67
+ }
68
+ ```
69
+
70
+ #### Entity Framework Core Configuration
71
+
72
+ ```csharp
73
+ public class UserEntityConfiguration : IEntityTypeConfiguration<UserEntity>
74
+ {
75
+ public void Configure(EntityTypeBuilder<UserEntity> builder)
76
+ {
77
+ builder.ToTable("users");
78
+
79
+ // DateTimeOffset fields - automatically map to TIMESTAMP WITH TIME ZONE
80
+ builder.Property(u => u.CreatedAt)
81
+ .IsRequired()
82
+ .HasDefaultValueSql("NOW()"); // PostgreSQL auto-generates UTC timestamp
83
+
84
+ builder.Property(u => u.UpdatedAt)
85
+ .IsRequired()
86
+ .HasDefaultValueSql("NOW()");
87
+ }
88
+ }
89
+ ```
90
+
91
+ #### Type Selection Guide
92
+
93
+ | Use Case | Type | Example |
94
+ |----------|------|---------|
95
+ | Timestamp with timezone | `DateTimeOffset` | `CreatedAt`, `UpdatedAt`, `DeletedAt`, `LastLoginAt` |
96
+ | Date only (no time) | `DateOnly` | `BirthDate`, `ExpenseDate`, `DueDate` |
97
+ | Time only (no date) | `TimeOnly` | `OpeningTime`, `ClosingTime` |
98
+ | Never use | `DateTime` | ❌ Not compatible with PostgreSQL TIMESTAMP WITH TIME ZONE |
99
+
100
+ #### Best Practices
101
+
102
+ 1. **Always use `DateTimeOffset`** for `CreatedAt`, `UpdatedAt`, and any timestamp field
103
+ 2. **Always use UTC**: Set values with `DateTimeOffset.UtcNow`
104
+ 3. **Configure EF Core**: Use `HasDefaultValueSql("NOW()")` for automatic timestamps
105
+ 4. **DTOs must match**: DTOs also use `DateTimeOffset` (serializes to ISO 8601 with timezone)
106
+ 5. **Never use `DateTime`** for entity timestamp fields in PostgreSQL projects
107
+
108
+ ### ORM Strategy Guidelines
109
+
110
+ #### When to Use Entity Framework Core 10
111
+ ✔ **Primary ORM for:**
112
+ - Standard CRUD operations
113
+ - DDD entities with tracking (Aggregate Roots, Domain Events)
114
+ - Simple to moderate queries
115
+ - Navigation properties and relationships
116
+ - Change tracking scenarios
117
+
118
+ #### When to Use linq2db
119
+ ✔ **Use for maximum performance:**
120
+ - Highly optimized complex queries (subqueries, complex projections, multiple joins)
121
+ - Queries that EF Core cannot translate efficiently
122
+ - High-performance endpoints: dashboards, analytics, reports, high data volumes
123
+ - Pure queries without tracking needs
124
+ - When EF Core generates inefficient SQL
125
+
126
+ 🚫 **Avoid when:**
127
+ - Need complete DDD entities with aggregate lifecycle
128
+ - Query participates in domain events or tracking
129
+
130
+ #### When to Use DynamicLinq
131
+ ✔ **Use for runtime flexibility:**
132
+ - Dynamic filter systems: `?filter=Age > 30 AND Country == "CO"`
133
+ - Simplified OData-style APIs
134
+ - Configurable grids or data explorers
135
+ - Variable column searches
136
+
137
+ 🚫 **Avoid when:**
138
+ - Filters are fully controlled in code
139
+ - Require strict security (needs sanitization)
140
+ - Need maximum performance (use linq2db or LinqKit)
141
+
142
+ #### When to Use LinqKit
143
+ ✔ **Use for type-safe composition:**
144
+ - Complex business rules in queries with composable predicates
145
+ - Dynamic filters with type safety (no strings → expressions)
146
+ - DDD repositories with multiple criteria, conditional searches, reusable queries
147
+ - Enhance EF Core when composing complex expressions
148
+ - 100% compatible with EF Core translation
149
+
150
+ 🚫 **Avoid when:**
151
+ - Filters are extremely simple
152
+ - Query is highly dynamic and text-based (use DynamicLinq)
153
+ - Need maximum raw performance (use linq2db)
154
+
155
+ ### Development Tools
156
+ - **dotnet CLI**: Project management, build, test, and restore
157
+ - **NuGet**: Package manager
158
+ - **EF Core 10 Migrations**: Database schema version control
159
+ - **Docker**: For production only
160
+ - **Code Analyzers**: Static C# code analysis
161
+ - **EditorConfig**: Code formatting standards
162
+
163
+ ## Domain-Driven Design Implementation
164
+
165
+ ### Entity Structure
166
+ ```csharp
167
+ public class UserEntity : AggregateRoot
168
+ {
169
+ // Parameterless constructor for EF Core (materialization from DB)
170
+ private UserEntity() : base(Guid.Empty)
171
+ {
172
+ // EF Core needs this to reconstruct the entity from the database
173
+ }
174
+
175
+ private UserEntity(
176
+ Guid id,
177
+ EmailValueObject email,
178
+ NameValueObject name) : base(id)
179
+ {
180
+ Email = email;
181
+ Name = name;
182
+ }
183
+
184
+ public EmailValueObject Email { get; private set; } = null!;
185
+ public NameValueObject Name { get; private set; } = null!;
186
+
187
+ public static UserEntity Create(string email, string name)
188
+ {
189
+ var userEmail = EmailValueObject.Create(email);
190
+ var userName = NameValueObject.Create(name);
191
+
192
+ var user = new UserEntity(Guid.NewGuid(), userEmail, userName);
193
+ user.AddDomainEvent(new UserCreatedEvent(user.Id));
194
+
195
+ return user;
196
+ }
197
+
198
+ public void UpdateEmail(string newEmail)
199
+ {
200
+ var newEmailVO = EmailValueObject.Create(newEmail);
201
+ if (Email.Equals(newEmailVO)) return;
202
+
203
+ Email = newEmailVO;
204
+ AddDomainEvent(new UserEmailUpdatedEvent(Id, Email));
205
+ }
206
+ }
207
+ ```
208
+
209
+ ### Value Object Structure
210
+ ```csharp
211
+ public class EmailValueObject : ValueObject
212
+ {
213
+ public string Value { get; }
214
+
215
+ private EmailValueObject(string value)
216
+ {
217
+ Value = value;
218
+ }
219
+
220
+ public static EmailValueObject Create(string value)
221
+ {
222
+ if (string.IsNullOrWhiteSpace(value))
223
+ throw new ArgumentException("Email cannot be empty", nameof(value));
224
+
225
+ if (!IsValidEmail(value))
226
+ throw new InvalidEmailException(value);
227
+
228
+ return new EmailValueObject(value);
229
+ }
230
+
231
+ private static bool IsValidEmail(string email)
232
+ {
233
+ // Email validation logic
234
+ return System.Text.RegularExpressions.Regex.IsMatch(
235
+ email,
236
+ @"^[^@\s]+@[^@\s]+\.[^@\s]+$");
237
+ }
238
+
239
+ protected override IEnumerable<object> GetEqualityComponents()
240
+ {
241
+ yield return Value;
242
+ }
243
+ }
244
+ ```
245
+
246
+ ### Repository Pattern
247
+ ```csharp
248
+ // Interface (in Application layer)
249
+ public interface IUserRepository
250
+ {
251
+ Task<UserEntity> SaveAsync(UserEntity user, CancellationToken cancellationToken = default);
252
+ Task<UserEntity?> FindByIdAsync(Guid id, CancellationToken cancellationToken = default);
253
+ Task<UserEntity?> FindByEmailAsync(EmailValueObject email, CancellationToken cancellationToken = default);
254
+ Task DeleteAsync(Guid id, CancellationToken cancellationToken = default);
255
+ }
256
+
257
+ // Implementation (in Infrastructure layer)
258
+ public class UserRepository : IUserRepository
259
+ {
260
+ private readonly ApplicationDbContext _context;
261
+
262
+ public UserRepository(ApplicationDbContext context)
263
+ {
264
+ _context = context;
265
+ }
266
+
267
+ public async Task<UserEntity> SaveAsync(UserEntity user, CancellationToken cancellationToken = default)
268
+ {
269
+ var existingUser = await _context.Users.FindAsync(new object[] { user.Id }, cancellationToken);
270
+
271
+ if (existingUser == null)
272
+ await _context.Users.AddAsync(user, cancellationToken);
273
+ else
274
+ _context.Users.Update(user);
275
+
276
+ await _context.SaveChangesAsync(cancellationToken);
277
+ return user;
278
+ }
279
+
280
+ public async Task<UserEntity?> FindByIdAsync(Guid id, CancellationToken cancellationToken = default)
281
+ {
282
+ return await _context.Users.FindAsync(new object[] { id }, cancellationToken);
283
+ }
284
+
285
+ public async Task<UserEntity?> FindByEmailAsync(EmailValueObject email, CancellationToken cancellationToken = default)
286
+ {
287
+ return await _context.Users
288
+ .FirstOrDefaultAsync(u => u.Email.Value == email.Value, cancellationToken);
289
+ }
290
+
291
+ public async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
292
+ {
293
+ var user = await FindByIdAsync(id, cancellationToken);
294
+ if (user != null)
295
+ {
296
+ _context.Users.Remove(user);
297
+ await _context.SaveChangesAsync(cancellationToken);
298
+ }
299
+ }
300
+ }
301
+ ```
302
+
303
+ ## Command/Query (CQRS) Standards
304
+
305
+ ### Command Structure
306
+ ```csharp
307
+ public record CreateUserCommand(string Email, string Name);
308
+
309
+ public class CreateUserCommandValidator : AbstractValidator<CreateUserCommand>
310
+ {
311
+ public CreateUserCommandValidator()
312
+ {
313
+ RuleFor(x => x.Email)
314
+ .NotEmpty().WithMessage("Email is required")
315
+ .EmailAddress().WithMessage("Email must be valid");
316
+
317
+ RuleFor(x => x.Name)
318
+ .NotEmpty().WithMessage("Name is required")
319
+ .MaximumLength(100).WithMessage("Name must not exceed 100 characters");
320
+ }
321
+ }
322
+
323
+ public class CreateUserCommandHandler
324
+ {
325
+ private readonly IUserRepository _userRepository;
326
+ private readonly IValidator<CreateUserCommand> _validator;
327
+
328
+ public CreateUserCommandHandler(
329
+ IUserRepository userRepository,
330
+ IValidator<CreateUserCommand> validator)
331
+ {
332
+ _userRepository = userRepository;
333
+ _validator = validator;
334
+ }
335
+
336
+ public async Task<UserResponseDto> HandleAsync(
337
+ CreateUserCommand command,
338
+ CancellationToken cancellationToken = default)
339
+ {
340
+ // 1. Validate command
341
+ await _validator.ValidateAndThrowAsync(command, cancellationToken);
342
+
343
+ // 2. Validate business rules
344
+ await ValidateUserDoesNotExistAsync(command.Email, cancellationToken);
345
+
346
+ // 3. Create domain entity
347
+ var user = UserEntity.Create(command.Email, command.Name);
348
+
349
+ // 4. Persist entity
350
+ var savedUser = await _userRepository.SaveAsync(user, cancellationToken);
351
+
352
+ // 5. Return response DTO
353
+ return UserResponseDto.FromEntity(savedUser);
354
+ }
355
+
356
+ private async Task ValidateUserDoesNotExistAsync(string email, CancellationToken cancellationToken)
357
+ {
358
+ var emailVO = EmailValueObject.Create(email);
359
+ var existingUser = await _userRepository.FindByEmailAsync(emailVO, cancellationToken);
360
+ if (existingUser != null)
361
+ throw new UserAlreadyExistsException(email);
362
+ }
363
+ }
364
+ ```
365
+
366
+ ### Query Structure
367
+ ```csharp
368
+ public record GetUserByIdQuery(Guid Id);
369
+
370
+ public class GetUserByIdQueryHandler
371
+ {
372
+ private readonly IUserRepository _userRepository;
373
+
374
+ public GetUserByIdQueryHandler(IUserRepository userRepository)
375
+ {
376
+ _userRepository = userRepository;
377
+ }
378
+
379
+ public async Task<UserResponseDto?> HandleAsync(
380
+ GetUserByIdQuery query,
381
+ CancellationToken cancellationToken = default)
382
+ {
383
+ var user = await _userRepository.FindByIdAsync(query.Id, cancellationToken);
384
+ return user != null ? UserResponseDto.FromEntity(user) : null;
385
+ }
386
+ }
387
+ ```
388
+
389
+ ### DTO Structure
390
+ ```csharp
391
+ public record UserResponseDto
392
+ {
393
+ public Guid Id { get; init; }
394
+ public string Email { get; init; }
395
+ public string Name { get; init; }
396
+
397
+ public static UserResponseDto FromEntity(UserEntity user)
398
+ {
399
+ return new UserResponseDto
400
+ {
401
+ Id = user.Id,
402
+ Email = user.Email.Value,
403
+ Name = user.Name.Value
404
+ };
405
+ }
406
+ }
407
+
408
+ ```
409
+
410
+ ## Minimal API Standards
411
+
412
+ ### Endpoint Structure
413
+ ```csharp
414
+ // Program.cs or separate endpoint configuration
415
+ public static class UserEndpoints
416
+ {
417
+ public static void MapUserEndpoints(this IEndpointRouteBuilder app)
418
+ {
419
+ var group = app.MapGroup("/api/users")
420
+ .WithTags("Users")
421
+ .WithOpenApi();
422
+
423
+ group.MapPost("/", CreateUser)
424
+ .WithName("CreateUser")
425
+ .WithSummary("Create a new user")
426
+ .Produces<UserResponseDto>(StatusCodes.Status201Created)
427
+ .ProducesValidationProblem();
428
+
429
+ group.MapGet("/{id:guid}", GetUserById)
430
+ .WithName("GetUserById")
431
+ .WithSummary("Get user by ID")
432
+ .Produces<UserResponseDto>()
433
+ .Produces(StatusCodes.Status404NotFound);
434
+ }
435
+
436
+ private static async Task<IResult> CreateUser(
437
+ CreateUserCommand command,
438
+ CreateUserCommandHandler handler,
439
+ CancellationToken cancellationToken)
440
+ {
441
+ try
442
+ {
443
+ var result = await handler.HandleAsync(command, cancellationToken);
444
+ return Results.Created($"/api/users/{result.Id}", result);
445
+ }
446
+ catch (ValidationException ex)
447
+ {
448
+ return Results.ValidationProblem(ex.Errors.ToDictionary(
449
+ e => e.PropertyName,
450
+ e => new[] { e.ErrorMessage }));
451
+ }
452
+ catch (UserAlreadyExistsException ex)
453
+ {
454
+ return Results.Conflict(new { message = ex.Message });
455
+ }
456
+ }
457
+
458
+ private static async Task<IResult> GetUserById(
459
+ Guid id,
460
+ GetUserByIdQueryHandler handler,
461
+ CancellationToken cancellationToken)
462
+ {
463
+ var result = await handler.HandleAsync(new GetUserByIdQuery(id), cancellationToken);
464
+ return result != null ? Results.Ok(result) : Results.NotFound();
465
+ }
466
+ }
467
+ ```
468
+
469
+ ## Testing Standards
470
+
471
+ ### Testing Strategy
472
+ - **Unit Tests**: Domain entities, value objects, command/query handlers (isolated logic)
473
+ - **Integration Tests**: Repository implementations, database operations with EF Core InMemory or Test Containers
474
+ - **TDD Approach**: Write tests before or alongside implementation
475
+ - **High Coverage**: Aim for >80% code coverage
476
+
477
+ ### Test Structure (xUnit)
478
+ ```csharp
479
+ public class CreateUserCommandHandlerTests
480
+ {
481
+ private readonly Mock<IUserRepository> _userRepositoryMock;
482
+ private readonly Mock<IValidator<CreateUserCommand>> _validatorMock;
483
+ private readonly CreateUserCommandHandler _handler;
484
+
485
+ public CreateUserCommandHandlerTests()
486
+ {
487
+ _userRepositoryMock = new Mock<IUserRepository>();
488
+ _validatorMock = new Mock<IValidator<CreateUserCommand>>();
489
+ _handler = new CreateUserCommandHandler(
490
+ _userRepositoryMock.Object,
491
+ _validatorMock.Object);
492
+ }
493
+
494
+ [Fact]
495
+ public async Task HandleAsync_WithValidCommand_ShouldCreateUser()
496
+ {
497
+ // Arrange
498
+ var command = new CreateUserCommand("test@example.com", "John Doe");
499
+ _validatorMock
500
+ .Setup(v => v.ValidateAndThrowAsync(command, It.IsAny<CancellationToken>()))
501
+ .Returns(Task.CompletedTask);
502
+ _userRepositoryMock
503
+ .Setup(r => r.FindByEmailAsync(It.IsAny<EmailValueObject>(), It.IsAny<CancellationToken>()))
504
+ .ReturnsAsync((UserEntity?)null);
505
+ _userRepositoryMock
506
+ .Setup(r => r.SaveAsync(It.IsAny<UserEntity>(), It.IsAny<CancellationToken>()))
507
+ .ReturnsAsync((UserEntity u, CancellationToken _) => u);
508
+
509
+ // Act
510
+ var result = await _handler.HandleAsync(command, CancellationToken.None);
511
+
512
+ // Assert
513
+ Assert.NotNull(result);
514
+ Assert.Equal(command.Email, result.Email);
515
+ Assert.Equal(command.Name, result.Name);
516
+ _userRepositoryMock.Verify(r => r.SaveAsync(It.IsAny<UserEntity>(), It.IsAny<CancellationToken>()), Times.Once);
517
+ }
518
+
519
+ [Fact]
520
+ public async Task HandleAsync_WithExistingUser_ShouldThrowException()
521
+ {
522
+ // Arrange
523
+ var command = new CreateUserCommand("test@example.com", "John Doe");
524
+ var existingUser = UserEntity.Create("test@example.com", "Existing User");
525
+ _validatorMock
526
+ .Setup(v => v.ValidateAndThrowAsync(command, It.IsAny<CancellationToken>()))
527
+ .Returns(Task.CompletedTask);
528
+ _userRepositoryMock
529
+ .Setup(r => r.FindByEmailAsync(It.IsAny<EmailValueObject>(), It.IsAny<CancellationToken>()))
530
+ .ReturnsAsync(existingUser);
531
+
532
+ // Act & Assert
533
+ await Assert.ThrowsAsync<UserAlreadyExistsException>(() =>
534
+ _handler.HandleAsync(command, CancellationToken.None));
535
+ }
536
+ }
537
+ ```
538
+
539
+ ### Integration Test with EF Core InMemory
540
+ ```csharp
541
+ public class UserRepositoryIntegrationTests : IDisposable
542
+ {
543
+ private readonly ApplicationDbContext _context;
544
+ private readonly UserRepository _repository;
545
+
546
+ public UserRepositoryIntegrationTests()
547
+ {
548
+ var options = new DbContextOptionsBuilder<ApplicationDbContext>()
549
+ .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
550
+ .Options;
551
+
552
+ _context = new ApplicationDbContext(options);
553
+ _repository = new UserRepository(_context);
554
+ }
555
+
556
+ [Fact]
557
+ public async Task SaveAsync_ShouldPersistUser()
558
+ {
559
+ // Arrange
560
+ var user = UserEntity.Create("test@example.com", "John Doe");
561
+
562
+ // Act
563
+ var savedUser = await _repository.SaveAsync(user);
564
+
565
+ // Assert
566
+ var retrievedUser = await _repository.FindByIdAsync(savedUser.Id);
567
+ Assert.NotNull(retrievedUser);
568
+ Assert.Equal(user.Email.Value, retrievedUser.Email.Value);
569
+ }
570
+
571
+ public void Dispose()
572
+ {
573
+ _context.Database.EnsureDeleted();
574
+ _context.Dispose();
575
+ }
576
+ }
577
+ ```
578
+
579
+ ## EF Core Configuration Standards
580
+
581
+ ### DbContext Configuration
582
+ ```csharp
583
+ public class ApplicationDbContext : DbContext
584
+ {
585
+ public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
586
+ : base(options)
587
+ {
588
+ }
589
+
590
+ public DbSet<UserEntity> Users { get; set; }
591
+ public DbSet<QuoteEntity> Quotes { get; set; }
592
+
593
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
594
+ {
595
+ base.OnModelCreating(modelBuilder);
596
+
597
+ // Apply all configurations from assembly
598
+ modelBuilder.ApplyConfigurationsFromAssembly(typeof(ApplicationDbContext).Assembly);
599
+ }
600
+ }
601
+ ```
602
+
603
+ ### Entity Configuration
604
+ ```csharp
605
+ public class UserEntityConfiguration : IEntityTypeConfiguration<UserEntity>
606
+ {
607
+ public void Configure(EntityTypeBuilder<UserEntity> builder)
608
+ {
609
+ builder.ToTable("Users");
610
+
611
+ builder.HasKey(u => u.Id);
612
+
613
+ builder.Property(u => u.Id)
614
+ .HasColumnType("uuid")
615
+ .IsRequired();
616
+
617
+ // Configure Value Object as owned entity
618
+ builder.OwnsOne(u => u.Email, email =>
619
+ {
620
+ email.Property(e => e.Value)
621
+ .HasColumnName("Email")
622
+ .HasMaxLength(256)
623
+ .IsRequired();
624
+ });
625
+
626
+ builder.OwnsOne(u => u.Name, name =>
627
+ {
628
+ name.Property(n => n.Value)
629
+ .HasColumnName("Name")
630
+ .HasMaxLength(100)
631
+ .IsRequired();
632
+ });
633
+
634
+ // Ignore domain events (not persisted)
635
+ builder.Ignore(u => u.DomainEvents);
636
+ }
637
+ }
638
+ ```
639
+
640
+ ## Security Standards
641
+
642
+ ### Authentication & Authorization
643
+ - **JWT Tokens**: Proper expiration and refresh token handling
644
+ - **RBAC**: Role-based access control
645
+ - **Validation**: Input validation on all endpoints (FluentValidation)
646
+ - **Rate Limiting**: Throttle public endpoints to prevent abuse
647
+ - **Environment**: HTTPS only in production, secrets in env variables
648
+
649
+ ### Data Protection
650
+ - Encrypt sensitive data at rest and in transit
651
+ - Never commit secrets to repository
652
+ - Implement audit logging for critical operations
653
+ - OWASP Top 10 compliance
654
+ - Regular dependency security audits with `dotnet list package --vulnerable`
655
+
656
+ ## Performance Standards
657
+
658
+ ### Database Optimization
659
+ - Proper indexing on frequently queried fields
660
+ - Connection pooling via EF Core 10
661
+ - Pagination for large datasets (Skip/Take or cursor-based)
662
+ - Avoid N+1 queries with `.Include()` and `.ThenInclude()`
663
+ - Query monitoring and slow query logging
664
+ - Use `AsNoTracking()` for read-only queries
665
+
666
+ ### Caching Strategy
667
+ - **Distributed Cache**: Redis for session data and frequently accessed data
668
+ - **Memory Cache**: In-memory caching for configuration
669
+ - **TTL Strategy**: Appropriate time-to-live for different data types
670
+ - **Invalidation**: Event-driven cache invalidation
671
+
672
+ ## Error Handling
673
+
674
+ ### Exception Hierarchy
675
+ - Domain exceptions for business rule violations
676
+ - Application exceptions for use case errors
677
+ - Infrastructure exceptions for external service failures
678
+ - Global exception middleware for API responses
679
+
680
+ ### Error Response Format (Problem Details RFC 7807)
681
+ ```csharp
682
+ public record ProblemDetailsResponse
683
+ {
684
+ public int Status { get; init; }
685
+ public string Title { get; init; }
686
+ public string Detail { get; init; }
687
+ public string Instance { get; init; }
688
+ public DateTimeOffset Timestamp { get; init; }
689
+ public Dictionary<string, string[]>? Errors { get; init; }
690
+ }
691
+
692
+ // Example response
693
+ {
694
+ "status": 400,
695
+ "title": "Validation Error",
696
+ "detail": "One or more validation errors occurred",
697
+ "instance": "/api/users",
698
+ "timestamp": "2025-11-26T10:30:00Z",
699
+ "errors": {
700
+ "Email": ["Email is required", "Email must be valid"],
701
+ "Name": ["Name is required"]
702
+ }
703
+ }
704
+ ```
705
+
706
+ ### Global Exception Middleware
707
+ ```csharp
708
+ public class ExceptionHandlingMiddleware
709
+ {
710
+ private readonly RequestDelegate _next;
711
+ private readonly ILogger<ExceptionHandlingMiddleware> _logger;
712
+
713
+ public ExceptionHandlingMiddleware(
714
+ RequestDelegate next,
715
+ ILogger<ExceptionHandlingMiddleware> logger)
716
+ {
717
+ _next = next;
718
+ _logger = logger;
719
+ }
720
+
721
+ public async Task InvokeAsync(HttpContext context)
722
+ {
723
+ try
724
+ {
725
+ await _next(context);
726
+ }
727
+ catch (ValidationException ex)
728
+ {
729
+ await HandleValidationExceptionAsync(context, ex);
730
+ }
731
+ catch (DomainException ex)
732
+ {
733
+ await HandleDomainExceptionAsync(context, ex);
734
+ }
735
+ catch (Exception ex)
736
+ {
737
+ _logger.LogError(ex, "Unhandled exception occurred");
738
+ await HandleUnhandledExceptionAsync(context, ex);
739
+ }
740
+ }
741
+
742
+ private static Task HandleValidationExceptionAsync(HttpContext context, ValidationException exception)
743
+ {
744
+ context.Response.StatusCode = StatusCodes.Status400BadRequest;
745
+ context.Response.ContentType = "application/problem+json";
746
+
747
+ var problemDetails = new ProblemDetailsResponse
748
+ {
749
+ Status = StatusCodes.Status400BadRequest,
750
+ Title = "Validation Error",
751
+ Detail = "One or more validation errors occurred",
752
+ Instance = context.Request.Path,
753
+ Timestamp = DateTimeOffset.UtcNow,
754
+ Errors = exception.Errors.GroupBy(e => e.PropertyName)
755
+ .ToDictionary(g => g.Key, g => g.Select(e => e.ErrorMessage).ToArray())
756
+ };
757
+
758
+ return context.Response.WriteAsJsonAsync(problemDetails);
759
+ }
760
+ }
761
+ ```
762
+
763
+ ## Security Standards
764
+
765
+ ### Authentication & Authorization
766
+ - **JWT Tokens**: Proper expiration and refresh token handling
767
+ - **RBAC**: Role-based access control with Authorization Policies
768
+ - **Validation**: Input validation on all endpoints (FluentValidation)
769
+ - **Rate Limiting**: ASP.NET Core Rate Limiting middleware
770
+ - **Environment**: HTTPS only in production, secrets in Azure Key Vault or User Secrets
771
+
772
+ ### Data Protection
773
+ - Encrypt sensitive data at rest and in transit
774
+ - Never commit secrets to repository
775
+ - Implement audit logging for critical operations
776
+ - OWASP Top 10 compliance
777
+ - Regular dependency security audits with `dotnet list package --vulnerable`
778
+
779
+ ## Performance Standards
780
+
781
+ ### Database Optimization
782
+ - Proper indexing on frequently queried fields
783
+ - Connection pooling via EF Core (configured in connection string)
784
+ - Pagination for large datasets (Skip/Take or Keyset pagination)
785
+ - Avoid N+1 queries with `.Include()` and `.ThenInclude()`
786
+ - Query monitoring and slow query logging
787
+ - Use `AsNoTracking()` for read-only queries
788
+
789
+ ### Caching Strategy
790
+ - **Distributed Cache**: Redis or SQL Server for distributed scenarios
791
+ - **Memory Cache**: `IMemoryCache` for single-instance caching
792
+ - **TTL Strategy**: Appropriate time-to-live for different data types
793
+ - **Invalidation**: Event-driven cache invalidation
794
+ - **Response Caching**: Use `[ResponseCache]` attribute for GET endpoints
795
+
796
+ ## Additional Standards
797
+
798
+ ### Logging
799
+ - Use `ILogger<T>` for structured logging
800
+ - Log levels: Trace, Debug, Information, Warning, Error, Critical
801
+ - Include correlation IDs for request tracing
802
+ - Never log sensitive information (passwords, tokens, PII)
803
+
804
+ ### API Versioning
805
+ - Use URL versioning: `/api/v1/users`
806
+ - Support multiple versions simultaneously during migration
807
+ - Deprecation notices in response headers
808
+
809
+ ### Health Checks
810
+ - Implement `/health` endpoint for liveness
811
+ - Implement `/health/ready` for readiness checks
812
812
  - Include database, cache, and external service checks