@wazir-dev/cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (629) hide show
  1. package/AGENTS.md +111 -0
  2. package/CHANGELOG.md +14 -0
  3. package/CONTRIBUTING.md +101 -0
  4. package/LICENSE +21 -0
  5. package/README.md +314 -0
  6. package/assets/composition-engine.mmd +34 -0
  7. package/assets/demo-script.sh +17 -0
  8. package/assets/logo-dark.svg +14 -0
  9. package/assets/logo.svg +14 -0
  10. package/assets/pipeline.mmd +39 -0
  11. package/assets/record-demo.sh +51 -0
  12. package/docs/README.md +51 -0
  13. package/docs/adapters/context-mode.md +60 -0
  14. package/docs/concepts/architecture.md +87 -0
  15. package/docs/concepts/artifact-model.md +60 -0
  16. package/docs/concepts/composition-engine.md +36 -0
  17. package/docs/concepts/indexing-and-recall.md +160 -0
  18. package/docs/concepts/observability.md +41 -0
  19. package/docs/concepts/roles-and-workflows.md +59 -0
  20. package/docs/concepts/terminology-policy.md +27 -0
  21. package/docs/getting-started/01-installation.md +78 -0
  22. package/docs/getting-started/02-first-run.md +102 -0
  23. package/docs/getting-started/03-adding-to-project.md +15 -0
  24. package/docs/getting-started/04-host-setup.md +15 -0
  25. package/docs/guides/ci-integration.md +15 -0
  26. package/docs/guides/creating-skills.md +15 -0
  27. package/docs/guides/expertise-module-authoring.md +15 -0
  28. package/docs/guides/hook-development.md +15 -0
  29. package/docs/guides/memory-and-learnings.md +34 -0
  30. package/docs/guides/multi-host-export.md +15 -0
  31. package/docs/guides/troubleshooting.md +101 -0
  32. package/docs/guides/writing-custom-roles.md +15 -0
  33. package/docs/plans/2026-03-15-cli-pipeline-integration-design.md +592 -0
  34. package/docs/plans/2026-03-15-cli-pipeline-integration-plan.md +598 -0
  35. package/docs/plans/2026-03-15-docs-enforcement-plan.md +238 -0
  36. package/docs/readmes/INDEX.md +99 -0
  37. package/docs/readmes/features/expertise/README.md +171 -0
  38. package/docs/readmes/features/exports/README.md +222 -0
  39. package/docs/readmes/features/hooks/README.md +103 -0
  40. package/docs/readmes/features/hooks/loop-cap-guard.md +133 -0
  41. package/docs/readmes/features/hooks/post-tool-capture.md +121 -0
  42. package/docs/readmes/features/hooks/post-tool-lint.md +130 -0
  43. package/docs/readmes/features/hooks/pre-compact-summary.md +122 -0
  44. package/docs/readmes/features/hooks/pre-tool-capture-route.md +100 -0
  45. package/docs/readmes/features/hooks/protected-path-write-guard.md +128 -0
  46. package/docs/readmes/features/hooks/session-start.md +119 -0
  47. package/docs/readmes/features/hooks/stop-handoff-harvest.md +125 -0
  48. package/docs/readmes/features/roles/README.md +157 -0
  49. package/docs/readmes/features/roles/clarifier.md +152 -0
  50. package/docs/readmes/features/roles/content-author.md +190 -0
  51. package/docs/readmes/features/roles/designer.md +193 -0
  52. package/docs/readmes/features/roles/executor.md +184 -0
  53. package/docs/readmes/features/roles/learner.md +210 -0
  54. package/docs/readmes/features/roles/planner.md +182 -0
  55. package/docs/readmes/features/roles/researcher.md +164 -0
  56. package/docs/readmes/features/roles/reviewer.md +184 -0
  57. package/docs/readmes/features/roles/specifier.md +162 -0
  58. package/docs/readmes/features/roles/verifier.md +215 -0
  59. package/docs/readmes/features/schemas/README.md +178 -0
  60. package/docs/readmes/features/skills/README.md +63 -0
  61. package/docs/readmes/features/skills/brainstorming.md +96 -0
  62. package/docs/readmes/features/skills/debugging.md +148 -0
  63. package/docs/readmes/features/skills/design.md +120 -0
  64. package/docs/readmes/features/skills/prepare-next.md +109 -0
  65. package/docs/readmes/features/skills/run-audit.md +159 -0
  66. package/docs/readmes/features/skills/scan-project.md +109 -0
  67. package/docs/readmes/features/skills/self-audit.md +176 -0
  68. package/docs/readmes/features/skills/tdd.md +137 -0
  69. package/docs/readmes/features/skills/using-skills.md +92 -0
  70. package/docs/readmes/features/skills/verification.md +120 -0
  71. package/docs/readmes/features/skills/writing-plans.md +104 -0
  72. package/docs/readmes/features/tooling/README.md +320 -0
  73. package/docs/readmes/features/workflows/README.md +186 -0
  74. package/docs/readmes/features/workflows/author.md +181 -0
  75. package/docs/readmes/features/workflows/clarify.md +154 -0
  76. package/docs/readmes/features/workflows/design-review.md +171 -0
  77. package/docs/readmes/features/workflows/design.md +169 -0
  78. package/docs/readmes/features/workflows/discover.md +162 -0
  79. package/docs/readmes/features/workflows/execute.md +173 -0
  80. package/docs/readmes/features/workflows/learn.md +167 -0
  81. package/docs/readmes/features/workflows/plan-review.md +165 -0
  82. package/docs/readmes/features/workflows/plan.md +170 -0
  83. package/docs/readmes/features/workflows/prepare-next.md +167 -0
  84. package/docs/readmes/features/workflows/review.md +169 -0
  85. package/docs/readmes/features/workflows/run-audit.md +191 -0
  86. package/docs/readmes/features/workflows/spec-challenge.md +159 -0
  87. package/docs/readmes/features/workflows/specify.md +160 -0
  88. package/docs/readmes/features/workflows/verify.md +177 -0
  89. package/docs/readmes/packages/README.md +50 -0
  90. package/docs/readmes/packages/ajv.md +117 -0
  91. package/docs/readmes/packages/context-mode.md +118 -0
  92. package/docs/readmes/packages/gray-matter.md +116 -0
  93. package/docs/readmes/packages/node-test.md +137 -0
  94. package/docs/readmes/packages/yaml.md +112 -0
  95. package/docs/reference/configuration-reference.md +159 -0
  96. package/docs/reference/expertise-index.md +52 -0
  97. package/docs/reference/git-flow.md +43 -0
  98. package/docs/reference/hooks.md +87 -0
  99. package/docs/reference/host-exports.md +50 -0
  100. package/docs/reference/launch-checklist.md +172 -0
  101. package/docs/reference/marketplace-listings.md +76 -0
  102. package/docs/reference/release-process.md +34 -0
  103. package/docs/reference/roles-reference.md +77 -0
  104. package/docs/reference/skills.md +33 -0
  105. package/docs/reference/templates.md +29 -0
  106. package/docs/reference/tooling-cli.md +94 -0
  107. package/docs/truth-claims.yaml +222 -0
  108. package/expertise/PROGRESS.md +63 -0
  109. package/expertise/README.md +18 -0
  110. package/expertise/antipatterns/PROGRESS.md +56 -0
  111. package/expertise/antipatterns/backend/api-design-antipatterns.md +1271 -0
  112. package/expertise/antipatterns/backend/auth-antipatterns.md +1195 -0
  113. package/expertise/antipatterns/backend/caching-antipatterns.md +622 -0
  114. package/expertise/antipatterns/backend/database-antipatterns.md +1038 -0
  115. package/expertise/antipatterns/backend/index.md +24 -0
  116. package/expertise/antipatterns/backend/microservices-antipatterns.md +850 -0
  117. package/expertise/antipatterns/code/architecture-antipatterns.md +919 -0
  118. package/expertise/antipatterns/code/async-antipatterns.md +622 -0
  119. package/expertise/antipatterns/code/code-smells.md +1186 -0
  120. package/expertise/antipatterns/code/dependency-antipatterns.md +1209 -0
  121. package/expertise/antipatterns/code/error-handling-antipatterns.md +1360 -0
  122. package/expertise/antipatterns/code/index.md +27 -0
  123. package/expertise/antipatterns/code/naming-and-abstraction.md +1118 -0
  124. package/expertise/antipatterns/code/state-management-antipatterns.md +1076 -0
  125. package/expertise/antipatterns/code/testing-antipatterns.md +1053 -0
  126. package/expertise/antipatterns/design/accessibility-antipatterns.md +1136 -0
  127. package/expertise/antipatterns/design/dark-patterns.md +1121 -0
  128. package/expertise/antipatterns/design/index.md +22 -0
  129. package/expertise/antipatterns/design/ui-antipatterns.md +1202 -0
  130. package/expertise/antipatterns/design/ux-antipatterns.md +680 -0
  131. package/expertise/antipatterns/frontend/css-layout-antipatterns.md +691 -0
  132. package/expertise/antipatterns/frontend/flutter-antipatterns.md +1827 -0
  133. package/expertise/antipatterns/frontend/index.md +23 -0
  134. package/expertise/antipatterns/frontend/mobile-antipatterns.md +573 -0
  135. package/expertise/antipatterns/frontend/react-antipatterns.md +1128 -0
  136. package/expertise/antipatterns/frontend/spa-antipatterns.md +1235 -0
  137. package/expertise/antipatterns/index.md +31 -0
  138. package/expertise/antipatterns/performance/index.md +20 -0
  139. package/expertise/antipatterns/performance/performance-antipatterns.md +1013 -0
  140. package/expertise/antipatterns/performance/premature-optimization.md +623 -0
  141. package/expertise/antipatterns/performance/scaling-antipatterns.md +785 -0
  142. package/expertise/antipatterns/process/ai-coding-antipatterns.md +853 -0
  143. package/expertise/antipatterns/process/code-review-antipatterns.md +656 -0
  144. package/expertise/antipatterns/process/deployment-antipatterns.md +920 -0
  145. package/expertise/antipatterns/process/index.md +23 -0
  146. package/expertise/antipatterns/process/technical-debt-antipatterns.md +647 -0
  147. package/expertise/antipatterns/security/index.md +20 -0
  148. package/expertise/antipatterns/security/secrets-antipatterns.md +849 -0
  149. package/expertise/antipatterns/security/security-theater.md +843 -0
  150. package/expertise/antipatterns/security/vulnerability-patterns.md +801 -0
  151. package/expertise/architecture/PROGRESS.md +70 -0
  152. package/expertise/architecture/data/caching-architecture.md +671 -0
  153. package/expertise/architecture/data/data-consistency.md +574 -0
  154. package/expertise/architecture/data/data-modeling.md +536 -0
  155. package/expertise/architecture/data/event-streams-and-queues.md +634 -0
  156. package/expertise/architecture/data/index.md +25 -0
  157. package/expertise/architecture/data/search-architecture.md +663 -0
  158. package/expertise/architecture/data/sql-vs-nosql.md +708 -0
  159. package/expertise/architecture/decisions/architecture-decision-records.md +640 -0
  160. package/expertise/architecture/decisions/build-vs-buy.md +616 -0
  161. package/expertise/architecture/decisions/index.md +23 -0
  162. package/expertise/architecture/decisions/monolith-to-microservices.md +790 -0
  163. package/expertise/architecture/decisions/technology-selection.md +616 -0
  164. package/expertise/architecture/distributed/cap-theorem-and-tradeoffs.md +800 -0
  165. package/expertise/architecture/distributed/circuit-breaker-bulkhead.md +741 -0
  166. package/expertise/architecture/distributed/consensus-and-coordination.md +796 -0
  167. package/expertise/architecture/distributed/distributed-systems-fundamentals.md +564 -0
  168. package/expertise/architecture/distributed/idempotency-and-retry.md +796 -0
  169. package/expertise/architecture/distributed/index.md +25 -0
  170. package/expertise/architecture/distributed/saga-pattern.md +797 -0
  171. package/expertise/architecture/foundations/architectural-thinking.md +460 -0
  172. package/expertise/architecture/foundations/coupling-and-cohesion.md +770 -0
  173. package/expertise/architecture/foundations/design-principles-solid.md +649 -0
  174. package/expertise/architecture/foundations/domain-driven-design.md +719 -0
  175. package/expertise/architecture/foundations/index.md +25 -0
  176. package/expertise/architecture/foundations/separation-of-concerns.md +472 -0
  177. package/expertise/architecture/foundations/twelve-factor-app.md +797 -0
  178. package/expertise/architecture/index.md +34 -0
  179. package/expertise/architecture/integration/api-design-graphql.md +638 -0
  180. package/expertise/architecture/integration/api-design-grpc.md +804 -0
  181. package/expertise/architecture/integration/api-design-rest.md +892 -0
  182. package/expertise/architecture/integration/index.md +25 -0
  183. package/expertise/architecture/integration/third-party-integration.md +795 -0
  184. package/expertise/architecture/integration/webhooks-and-callbacks.md +1152 -0
  185. package/expertise/architecture/integration/websockets-realtime.md +791 -0
  186. package/expertise/architecture/mobile-architecture/index.md +22 -0
  187. package/expertise/architecture/mobile-architecture/mobile-app-architecture.md +780 -0
  188. package/expertise/architecture/mobile-architecture/mobile-backend-for-frontend.md +670 -0
  189. package/expertise/architecture/mobile-architecture/offline-first.md +719 -0
  190. package/expertise/architecture/mobile-architecture/push-and-sync.md +782 -0
  191. package/expertise/architecture/patterns/cqrs-event-sourcing.md +717 -0
  192. package/expertise/architecture/patterns/event-driven.md +797 -0
  193. package/expertise/architecture/patterns/hexagonal-clean-architecture.md +870 -0
  194. package/expertise/architecture/patterns/index.md +27 -0
  195. package/expertise/architecture/patterns/layered-architecture.md +736 -0
  196. package/expertise/architecture/patterns/microservices.md +753 -0
  197. package/expertise/architecture/patterns/modular-monolith.md +692 -0
  198. package/expertise/architecture/patterns/monolith.md +626 -0
  199. package/expertise/architecture/patterns/plugin-architecture.md +735 -0
  200. package/expertise/architecture/patterns/serverless.md +780 -0
  201. package/expertise/architecture/scaling/database-scaling.md +615 -0
  202. package/expertise/architecture/scaling/feature-flags-and-rollouts.md +757 -0
  203. package/expertise/architecture/scaling/horizontal-vs-vertical.md +606 -0
  204. package/expertise/architecture/scaling/index.md +24 -0
  205. package/expertise/architecture/scaling/multi-tenancy.md +800 -0
  206. package/expertise/architecture/scaling/stateless-design.md +787 -0
  207. package/expertise/backend/embedded-firmware.md +625 -0
  208. package/expertise/backend/go.md +853 -0
  209. package/expertise/backend/index.md +24 -0
  210. package/expertise/backend/java-spring.md +448 -0
  211. package/expertise/backend/node-typescript.md +625 -0
  212. package/expertise/backend/python-fastapi.md +724 -0
  213. package/expertise/backend/rust.md +458 -0
  214. package/expertise/backend/solidity.md +711 -0
  215. package/expertise/composition-map.yaml +443 -0
  216. package/expertise/content/foundations/content-modeling.md +395 -0
  217. package/expertise/content/foundations/editorial-standards.md +449 -0
  218. package/expertise/content/foundations/index.md +24 -0
  219. package/expertise/content/foundations/microcopy.md +455 -0
  220. package/expertise/content/foundations/terminology-governance.md +509 -0
  221. package/expertise/content/index.md +34 -0
  222. package/expertise/content/patterns/accessibility-copy.md +518 -0
  223. package/expertise/content/patterns/index.md +24 -0
  224. package/expertise/content/patterns/notification-content.md +433 -0
  225. package/expertise/content/patterns/sample-content.md +486 -0
  226. package/expertise/content/patterns/state-copy.md +439 -0
  227. package/expertise/design/PROGRESS.md +58 -0
  228. package/expertise/design/disciplines/dark-mode-theming.md +577 -0
  229. package/expertise/design/disciplines/design-systems.md +595 -0
  230. package/expertise/design/disciplines/index.md +25 -0
  231. package/expertise/design/disciplines/information-architecture.md +800 -0
  232. package/expertise/design/disciplines/interaction-design.md +788 -0
  233. package/expertise/design/disciplines/responsive-design.md +552 -0
  234. package/expertise/design/disciplines/usability-testing.md +516 -0
  235. package/expertise/design/disciplines/user-research.md +792 -0
  236. package/expertise/design/foundations/accessibility-design.md +796 -0
  237. package/expertise/design/foundations/color-theory.md +797 -0
  238. package/expertise/design/foundations/iconography.md +795 -0
  239. package/expertise/design/foundations/index.md +26 -0
  240. package/expertise/design/foundations/motion-and-animation.md +653 -0
  241. package/expertise/design/foundations/rtl-design.md +585 -0
  242. package/expertise/design/foundations/spacing-and-layout.md +607 -0
  243. package/expertise/design/foundations/typography.md +800 -0
  244. package/expertise/design/foundations/visual-hierarchy.md +761 -0
  245. package/expertise/design/index.md +32 -0
  246. package/expertise/design/patterns/authentication-flows.md +474 -0
  247. package/expertise/design/patterns/content-consumption.md +789 -0
  248. package/expertise/design/patterns/data-display.md +618 -0
  249. package/expertise/design/patterns/e-commerce.md +1494 -0
  250. package/expertise/design/patterns/feedback-and-states.md +642 -0
  251. package/expertise/design/patterns/forms-and-input.md +819 -0
  252. package/expertise/design/patterns/gamification.md +801 -0
  253. package/expertise/design/patterns/index.md +31 -0
  254. package/expertise/design/patterns/microinteractions.md +449 -0
  255. package/expertise/design/patterns/navigation.md +800 -0
  256. package/expertise/design/patterns/notifications.md +705 -0
  257. package/expertise/design/patterns/onboarding.md +700 -0
  258. package/expertise/design/patterns/search-and-filter.md +601 -0
  259. package/expertise/design/patterns/settings-and-preferences.md +768 -0
  260. package/expertise/design/patterns/social-and-community.md +748 -0
  261. package/expertise/design/platforms/desktop-native.md +612 -0
  262. package/expertise/design/platforms/index.md +25 -0
  263. package/expertise/design/platforms/mobile-android.md +825 -0
  264. package/expertise/design/platforms/mobile-cross-platform.md +983 -0
  265. package/expertise/design/platforms/mobile-ios.md +699 -0
  266. package/expertise/design/platforms/tablet.md +794 -0
  267. package/expertise/design/platforms/web-dashboard.md +790 -0
  268. package/expertise/design/platforms/web-responsive.md +550 -0
  269. package/expertise/design/psychology/behavioral-nudges.md +449 -0
  270. package/expertise/design/psychology/cognitive-load.md +1191 -0
  271. package/expertise/design/psychology/error-psychology.md +778 -0
  272. package/expertise/design/psychology/index.md +22 -0
  273. package/expertise/design/psychology/persuasive-design.md +736 -0
  274. package/expertise/design/psychology/user-mental-models.md +623 -0
  275. package/expertise/design/tooling/open-pencil.md +266 -0
  276. package/expertise/frontend/angular.md +1073 -0
  277. package/expertise/frontend/desktop-electron.md +546 -0
  278. package/expertise/frontend/flutter.md +782 -0
  279. package/expertise/frontend/index.md +27 -0
  280. package/expertise/frontend/native-android.md +409 -0
  281. package/expertise/frontend/native-ios.md +490 -0
  282. package/expertise/frontend/react-native.md +1160 -0
  283. package/expertise/frontend/react.md +808 -0
  284. package/expertise/frontend/vue.md +1089 -0
  285. package/expertise/humanize/domain-rules-code.md +79 -0
  286. package/expertise/humanize/domain-rules-content.md +67 -0
  287. package/expertise/humanize/domain-rules-technical-docs.md +56 -0
  288. package/expertise/humanize/index.md +35 -0
  289. package/expertise/humanize/self-audit-checklist.md +87 -0
  290. package/expertise/humanize/sentence-patterns.md +218 -0
  291. package/expertise/humanize/vocabulary-blacklist.md +105 -0
  292. package/expertise/i18n/PROGRESS.md +65 -0
  293. package/expertise/i18n/advanced/accessibility-and-i18n.md +28 -0
  294. package/expertise/i18n/advanced/bidirectional-text-algorithm.md +38 -0
  295. package/expertise/i18n/advanced/complex-scripts.md +30 -0
  296. package/expertise/i18n/advanced/performance-and-i18n.md +27 -0
  297. package/expertise/i18n/advanced/testing-i18n.md +28 -0
  298. package/expertise/i18n/content/content-adaptation.md +23 -0
  299. package/expertise/i18n/content/locale-specific-formatting.md +23 -0
  300. package/expertise/i18n/content/machine-translation-integration.md +28 -0
  301. package/expertise/i18n/content/translation-management.md +29 -0
  302. package/expertise/i18n/foundations/date-time-calendars.md +67 -0
  303. package/expertise/i18n/foundations/i18n-architecture.md +272 -0
  304. package/expertise/i18n/foundations/locale-and-language-tags.md +79 -0
  305. package/expertise/i18n/foundations/numbers-currency-units.md +61 -0
  306. package/expertise/i18n/foundations/pluralization-and-gender.md +109 -0
  307. package/expertise/i18n/foundations/string-externalization.md +236 -0
  308. package/expertise/i18n/foundations/text-direction-bidi.md +241 -0
  309. package/expertise/i18n/foundations/unicode-and-encoding.md +86 -0
  310. package/expertise/i18n/index.md +38 -0
  311. package/expertise/i18n/platform/backend-i18n.md +31 -0
  312. package/expertise/i18n/platform/flutter-i18n.md +148 -0
  313. package/expertise/i18n/platform/native-android-i18n.md +36 -0
  314. package/expertise/i18n/platform/native-ios-i18n.md +36 -0
  315. package/expertise/i18n/platform/react-i18n.md +103 -0
  316. package/expertise/i18n/platform/web-css-i18n.md +81 -0
  317. package/expertise/i18n/rtl/arabic-specific.md +175 -0
  318. package/expertise/i18n/rtl/hebrew-specific.md +149 -0
  319. package/expertise/i18n/rtl/rtl-animations-and-transitions.md +111 -0
  320. package/expertise/i18n/rtl/rtl-forms-and-input.md +161 -0
  321. package/expertise/i18n/rtl/rtl-fundamentals.md +211 -0
  322. package/expertise/i18n/rtl/rtl-icons-and-images.md +181 -0
  323. package/expertise/i18n/rtl/rtl-layout-mirroring.md +252 -0
  324. package/expertise/i18n/rtl/rtl-navigation-and-gestures.md +107 -0
  325. package/expertise/i18n/rtl/rtl-testing-and-qa.md +147 -0
  326. package/expertise/i18n/rtl/rtl-typography.md +160 -0
  327. package/expertise/index.md +113 -0
  328. package/expertise/index.yaml +216 -0
  329. package/expertise/infrastructure/cloud-aws.md +597 -0
  330. package/expertise/infrastructure/cloud-gcp.md +599 -0
  331. package/expertise/infrastructure/cybersecurity.md +816 -0
  332. package/expertise/infrastructure/database-mongodb.md +447 -0
  333. package/expertise/infrastructure/database-postgres.md +400 -0
  334. package/expertise/infrastructure/devops-cicd.md +787 -0
  335. package/expertise/infrastructure/index.md +27 -0
  336. package/expertise/performance/PROGRESS.md +50 -0
  337. package/expertise/performance/backend/api-latency.md +1204 -0
  338. package/expertise/performance/backend/background-jobs.md +506 -0
  339. package/expertise/performance/backend/connection-pooling.md +1209 -0
  340. package/expertise/performance/backend/database-query-optimization.md +515 -0
  341. package/expertise/performance/backend/index.md +23 -0
  342. package/expertise/performance/backend/rate-limiting-and-throttling.md +971 -0
  343. package/expertise/performance/foundations/algorithmic-complexity.md +954 -0
  344. package/expertise/performance/foundations/caching-strategies.md +489 -0
  345. package/expertise/performance/foundations/concurrency-and-parallelism.md +847 -0
  346. package/expertise/performance/foundations/index.md +24 -0
  347. package/expertise/performance/foundations/measuring-and-profiling.md +440 -0
  348. package/expertise/performance/foundations/memory-management.md +964 -0
  349. package/expertise/performance/foundations/performance-budgets.md +1314 -0
  350. package/expertise/performance/index.md +31 -0
  351. package/expertise/performance/infrastructure/auto-scaling.md +1059 -0
  352. package/expertise/performance/infrastructure/cdn-and-edge.md +1081 -0
  353. package/expertise/performance/infrastructure/index.md +22 -0
  354. package/expertise/performance/infrastructure/load-balancing.md +1081 -0
  355. package/expertise/performance/infrastructure/observability.md +1079 -0
  356. package/expertise/performance/mobile/index.md +23 -0
  357. package/expertise/performance/mobile/mobile-animations.md +544 -0
  358. package/expertise/performance/mobile/mobile-memory-battery.md +416 -0
  359. package/expertise/performance/mobile/mobile-network.md +452 -0
  360. package/expertise/performance/mobile/mobile-rendering.md +599 -0
  361. package/expertise/performance/mobile/mobile-startup-time.md +505 -0
  362. package/expertise/performance/platform-specific/flutter-performance.md +647 -0
  363. package/expertise/performance/platform-specific/index.md +22 -0
  364. package/expertise/performance/platform-specific/node-performance.md +1307 -0
  365. package/expertise/performance/platform-specific/postgres-performance.md +1366 -0
  366. package/expertise/performance/platform-specific/react-performance.md +1403 -0
  367. package/expertise/performance/web/bundle-optimization.md +1239 -0
  368. package/expertise/performance/web/image-and-media.md +636 -0
  369. package/expertise/performance/web/index.md +24 -0
  370. package/expertise/performance/web/network-optimization.md +1133 -0
  371. package/expertise/performance/web/rendering-performance.md +1098 -0
  372. package/expertise/performance/web/ssr-and-hydration.md +918 -0
  373. package/expertise/performance/web/web-vitals.md +1374 -0
  374. package/expertise/quality/accessibility.md +985 -0
  375. package/expertise/quality/evidence-based-verification.md +499 -0
  376. package/expertise/quality/index.md +24 -0
  377. package/expertise/quality/ml-model-audit.md +614 -0
  378. package/expertise/quality/performance.md +600 -0
  379. package/expertise/quality/testing-api.md +891 -0
  380. package/expertise/quality/testing-mobile.md +496 -0
  381. package/expertise/quality/testing-web.md +849 -0
  382. package/expertise/security/PROGRESS.md +54 -0
  383. package/expertise/security/agentic-identity.md +540 -0
  384. package/expertise/security/compliance-frameworks.md +601 -0
  385. package/expertise/security/data/data-encryption.md +364 -0
  386. package/expertise/security/data/data-privacy-gdpr.md +692 -0
  387. package/expertise/security/data/database-security.md +1171 -0
  388. package/expertise/security/data/index.md +22 -0
  389. package/expertise/security/data/pii-handling.md +531 -0
  390. package/expertise/security/foundations/authentication.md +1041 -0
  391. package/expertise/security/foundations/authorization.md +603 -0
  392. package/expertise/security/foundations/cryptography.md +1001 -0
  393. package/expertise/security/foundations/index.md +25 -0
  394. package/expertise/security/foundations/owasp-top-10.md +1354 -0
  395. package/expertise/security/foundations/secrets-management.md +1217 -0
  396. package/expertise/security/foundations/secure-sdlc.md +700 -0
  397. package/expertise/security/foundations/supply-chain-security.md +698 -0
  398. package/expertise/security/index.md +31 -0
  399. package/expertise/security/infrastructure/cloud-security-aws.md +1296 -0
  400. package/expertise/security/infrastructure/cloud-security-gcp.md +1376 -0
  401. package/expertise/security/infrastructure/container-security.md +721 -0
  402. package/expertise/security/infrastructure/incident-response.md +1295 -0
  403. package/expertise/security/infrastructure/index.md +24 -0
  404. package/expertise/security/infrastructure/logging-and-monitoring.md +1618 -0
  405. package/expertise/security/infrastructure/network-security.md +1337 -0
  406. package/expertise/security/mobile/index.md +23 -0
  407. package/expertise/security/mobile/mobile-android-security.md +1218 -0
  408. package/expertise/security/mobile/mobile-binary-protection.md +1229 -0
  409. package/expertise/security/mobile/mobile-data-storage.md +1265 -0
  410. package/expertise/security/mobile/mobile-ios-security.md +1401 -0
  411. package/expertise/security/mobile/mobile-network-security.md +1520 -0
  412. package/expertise/security/smart-contract-security.md +594 -0
  413. package/expertise/security/testing/index.md +22 -0
  414. package/expertise/security/testing/penetration-testing.md +1258 -0
  415. package/expertise/security/testing/security-code-review.md +1765 -0
  416. package/expertise/security/testing/threat-modeling.md +1074 -0
  417. package/expertise/security/testing/vulnerability-scanning.md +1062 -0
  418. package/expertise/security/web/api-security.md +586 -0
  419. package/expertise/security/web/cors-and-headers.md +433 -0
  420. package/expertise/security/web/csrf.md +562 -0
  421. package/expertise/security/web/file-upload.md +1477 -0
  422. package/expertise/security/web/index.md +25 -0
  423. package/expertise/security/web/injection.md +1375 -0
  424. package/expertise/security/web/session-management.md +1101 -0
  425. package/expertise/security/web/xss.md +1158 -0
  426. package/exports/README.md +17 -0
  427. package/exports/hosts/claude/.claude/agents/clarifier.md +42 -0
  428. package/exports/hosts/claude/.claude/agents/content-author.md +63 -0
  429. package/exports/hosts/claude/.claude/agents/designer.md +55 -0
  430. package/exports/hosts/claude/.claude/agents/executor.md +55 -0
  431. package/exports/hosts/claude/.claude/agents/learner.md +51 -0
  432. package/exports/hosts/claude/.claude/agents/planner.md +53 -0
  433. package/exports/hosts/claude/.claude/agents/researcher.md +43 -0
  434. package/exports/hosts/claude/.claude/agents/reviewer.md +54 -0
  435. package/exports/hosts/claude/.claude/agents/specifier.md +47 -0
  436. package/exports/hosts/claude/.claude/agents/verifier.md +71 -0
  437. package/exports/hosts/claude/.claude/commands/author.md +42 -0
  438. package/exports/hosts/claude/.claude/commands/clarify.md +38 -0
  439. package/exports/hosts/claude/.claude/commands/design-review.md +46 -0
  440. package/exports/hosts/claude/.claude/commands/design.md +44 -0
  441. package/exports/hosts/claude/.claude/commands/discover.md +37 -0
  442. package/exports/hosts/claude/.claude/commands/execute.md +48 -0
  443. package/exports/hosts/claude/.claude/commands/learn.md +38 -0
  444. package/exports/hosts/claude/.claude/commands/plan-review.md +42 -0
  445. package/exports/hosts/claude/.claude/commands/plan.md +39 -0
  446. package/exports/hosts/claude/.claude/commands/prepare-next.md +37 -0
  447. package/exports/hosts/claude/.claude/commands/review.md +40 -0
  448. package/exports/hosts/claude/.claude/commands/run-audit.md +41 -0
  449. package/exports/hosts/claude/.claude/commands/spec-challenge.md +41 -0
  450. package/exports/hosts/claude/.claude/commands/specify.md +38 -0
  451. package/exports/hosts/claude/.claude/commands/verify.md +37 -0
  452. package/exports/hosts/claude/.claude/settings.json +34 -0
  453. package/exports/hosts/claude/CLAUDE.md +19 -0
  454. package/exports/hosts/claude/export.manifest.json +38 -0
  455. package/exports/hosts/claude/host-package.json +67 -0
  456. package/exports/hosts/codex/AGENTS.md +19 -0
  457. package/exports/hosts/codex/export.manifest.json +38 -0
  458. package/exports/hosts/codex/host-package.json +41 -0
  459. package/exports/hosts/cursor/.cursor/hooks.json +16 -0
  460. package/exports/hosts/cursor/.cursor/rules/wazir-core.mdc +19 -0
  461. package/exports/hosts/cursor/export.manifest.json +38 -0
  462. package/exports/hosts/cursor/host-package.json +42 -0
  463. package/exports/hosts/gemini/GEMINI.md +19 -0
  464. package/exports/hosts/gemini/export.manifest.json +38 -0
  465. package/exports/hosts/gemini/host-package.json +41 -0
  466. package/hooks/README.md +18 -0
  467. package/hooks/definitions/loop_cap_guard.yaml +21 -0
  468. package/hooks/definitions/post_tool_capture.yaml +24 -0
  469. package/hooks/definitions/pre_compact_summary.yaml +19 -0
  470. package/hooks/definitions/pre_tool_capture_route.yaml +19 -0
  471. package/hooks/definitions/protected_path_write_guard.yaml +19 -0
  472. package/hooks/definitions/session_start.yaml +19 -0
  473. package/hooks/definitions/stop_handoff_harvest.yaml +20 -0
  474. package/hooks/loop-cap-guard +17 -0
  475. package/hooks/post-tool-lint +36 -0
  476. package/hooks/protected-path-write-guard +17 -0
  477. package/hooks/session-start +41 -0
  478. package/llms-full.txt +2355 -0
  479. package/llms.txt +43 -0
  480. package/package.json +79 -0
  481. package/roles/README.md +20 -0
  482. package/roles/clarifier.md +42 -0
  483. package/roles/content-author.md +63 -0
  484. package/roles/designer.md +55 -0
  485. package/roles/executor.md +55 -0
  486. package/roles/learner.md +51 -0
  487. package/roles/planner.md +53 -0
  488. package/roles/researcher.md +43 -0
  489. package/roles/reviewer.md +54 -0
  490. package/roles/specifier.md +47 -0
  491. package/roles/verifier.md +71 -0
  492. package/schemas/README.md +24 -0
  493. package/schemas/accepted-learning.schema.json +20 -0
  494. package/schemas/author-artifact.schema.json +156 -0
  495. package/schemas/clarification.schema.json +19 -0
  496. package/schemas/design-artifact.schema.json +80 -0
  497. package/schemas/docs-claim.schema.json +18 -0
  498. package/schemas/export-manifest.schema.json +20 -0
  499. package/schemas/hook.schema.json +67 -0
  500. package/schemas/host-export-package.schema.json +18 -0
  501. package/schemas/implementation-plan.schema.json +19 -0
  502. package/schemas/proposed-learning.schema.json +19 -0
  503. package/schemas/research.schema.json +18 -0
  504. package/schemas/review.schema.json +29 -0
  505. package/schemas/run-manifest.schema.json +18 -0
  506. package/schemas/spec-challenge.schema.json +18 -0
  507. package/schemas/spec.schema.json +20 -0
  508. package/schemas/usage.schema.json +102 -0
  509. package/schemas/verification-proof.schema.json +29 -0
  510. package/schemas/wazir-manifest.schema.json +173 -0
  511. package/skills/README.md +40 -0
  512. package/skills/brainstorming/SKILL.md +77 -0
  513. package/skills/debugging/SKILL.md +50 -0
  514. package/skills/design/SKILL.md +61 -0
  515. package/skills/dispatching-parallel-agents/SKILL.md +128 -0
  516. package/skills/executing-plans/SKILL.md +70 -0
  517. package/skills/finishing-a-development-branch/SKILL.md +169 -0
  518. package/skills/humanize/SKILL.md +123 -0
  519. package/skills/init-pipeline/SKILL.md +124 -0
  520. package/skills/prepare-next/SKILL.md +20 -0
  521. package/skills/receiving-code-review/SKILL.md +123 -0
  522. package/skills/requesting-code-review/SKILL.md +105 -0
  523. package/skills/requesting-code-review/code-reviewer.md +108 -0
  524. package/skills/run-audit/SKILL.md +197 -0
  525. package/skills/scan-project/SKILL.md +41 -0
  526. package/skills/self-audit/SKILL.md +153 -0
  527. package/skills/subagent-driven-development/SKILL.md +154 -0
  528. package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
  529. package/skills/subagent-driven-development/implementer-prompt.md +102 -0
  530. package/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
  531. package/skills/tdd/SKILL.md +23 -0
  532. package/skills/using-git-worktrees/SKILL.md +163 -0
  533. package/skills/using-skills/SKILL.md +95 -0
  534. package/skills/verification/SKILL.md +22 -0
  535. package/skills/wazir/SKILL.md +463 -0
  536. package/skills/writing-plans/SKILL.md +30 -0
  537. package/skills/writing-skills/SKILL.md +157 -0
  538. package/skills/writing-skills/anthropic-best-practices.md +122 -0
  539. package/skills/writing-skills/persuasion-principles.md +50 -0
  540. package/templates/README.md +20 -0
  541. package/templates/artifacts/README.md +10 -0
  542. package/templates/artifacts/accepted-learning.md +19 -0
  543. package/templates/artifacts/accepted-learning.template.json +12 -0
  544. package/templates/artifacts/author.md +74 -0
  545. package/templates/artifacts/author.template.json +19 -0
  546. package/templates/artifacts/clarification.md +21 -0
  547. package/templates/artifacts/clarification.template.json +12 -0
  548. package/templates/artifacts/execute-notes.md +19 -0
  549. package/templates/artifacts/implementation-plan.md +21 -0
  550. package/templates/artifacts/implementation-plan.template.json +11 -0
  551. package/templates/artifacts/learning-proposal.md +19 -0
  552. package/templates/artifacts/next-run-handoff.md +21 -0
  553. package/templates/artifacts/plan-review.md +19 -0
  554. package/templates/artifacts/proposed-learning.template.json +12 -0
  555. package/templates/artifacts/research.md +21 -0
  556. package/templates/artifacts/research.template.json +12 -0
  557. package/templates/artifacts/review-findings.md +19 -0
  558. package/templates/artifacts/review.template.json +11 -0
  559. package/templates/artifacts/run-manifest.template.json +8 -0
  560. package/templates/artifacts/spec-challenge.md +19 -0
  561. package/templates/artifacts/spec-challenge.template.json +11 -0
  562. package/templates/artifacts/spec.md +21 -0
  563. package/templates/artifacts/spec.template.json +12 -0
  564. package/templates/artifacts/verification-proof.md +19 -0
  565. package/templates/artifacts/verification-proof.template.json +11 -0
  566. package/templates/examples/accepted-learning.example.json +14 -0
  567. package/templates/examples/author.example.json +152 -0
  568. package/templates/examples/clarification.example.json +15 -0
  569. package/templates/examples/docs-claim.example.json +8 -0
  570. package/templates/examples/export-manifest.example.json +7 -0
  571. package/templates/examples/host-export-package.example.json +11 -0
  572. package/templates/examples/implementation-plan.example.json +17 -0
  573. package/templates/examples/proposed-learning.example.json +13 -0
  574. package/templates/examples/research.example.json +15 -0
  575. package/templates/examples/research.example.md +6 -0
  576. package/templates/examples/review.example.json +17 -0
  577. package/templates/examples/run-manifest.example.json +9 -0
  578. package/templates/examples/spec-challenge.example.json +14 -0
  579. package/templates/examples/spec.example.json +21 -0
  580. package/templates/examples/verification-proof.example.json +21 -0
  581. package/templates/examples/wazir-manifest.example.yaml +65 -0
  582. package/templates/task-definition-schema.md +99 -0
  583. package/tooling/README.md +20 -0
  584. package/tooling/src/adapters/context-mode.js +50 -0
  585. package/tooling/src/capture/command.js +376 -0
  586. package/tooling/src/capture/store.js +99 -0
  587. package/tooling/src/capture/usage.js +270 -0
  588. package/tooling/src/checks/branches.js +50 -0
  589. package/tooling/src/checks/brand-truth.js +110 -0
  590. package/tooling/src/checks/changelog.js +231 -0
  591. package/tooling/src/checks/command-registry.js +36 -0
  592. package/tooling/src/checks/commits.js +102 -0
  593. package/tooling/src/checks/docs-drift.js +103 -0
  594. package/tooling/src/checks/docs-truth.js +201 -0
  595. package/tooling/src/checks/runtime-surface.js +156 -0
  596. package/tooling/src/cli.js +116 -0
  597. package/tooling/src/command-options.js +56 -0
  598. package/tooling/src/commands/validate.js +320 -0
  599. package/tooling/src/doctor/command.js +91 -0
  600. package/tooling/src/export/command.js +77 -0
  601. package/tooling/src/export/compiler.js +498 -0
  602. package/tooling/src/guards/loop-cap-guard.js +52 -0
  603. package/tooling/src/guards/protected-path-write-guard.js +67 -0
  604. package/tooling/src/index/command.js +152 -0
  605. package/tooling/src/index/storage.js +1061 -0
  606. package/tooling/src/index/summarizers.js +261 -0
  607. package/tooling/src/loaders.js +18 -0
  608. package/tooling/src/project-root.js +22 -0
  609. package/tooling/src/recall/command.js +225 -0
  610. package/tooling/src/schema-validator.js +30 -0
  611. package/tooling/src/state-root.js +40 -0
  612. package/tooling/src/status/command.js +71 -0
  613. package/wazir.manifest.yaml +135 -0
  614. package/workflows/README.md +19 -0
  615. package/workflows/author.md +42 -0
  616. package/workflows/clarify.md +38 -0
  617. package/workflows/design-review.md +46 -0
  618. package/workflows/design.md +44 -0
  619. package/workflows/discover.md +37 -0
  620. package/workflows/execute.md +48 -0
  621. package/workflows/learn.md +38 -0
  622. package/workflows/plan-review.md +42 -0
  623. package/workflows/plan.md +39 -0
  624. package/workflows/prepare-next.md +37 -0
  625. package/workflows/review.md +40 -0
  626. package/workflows/run-audit.md +41 -0
  627. package/workflows/spec-challenge.md +41 -0
  628. package/workflows/specify.md +38 -0
  629. package/workflows/verify.md +37 -0
@@ -0,0 +1,717 @@
1
+ # CQRS and Event Sourcing — Architecture Expertise Module
2
+
3
+ > CQRS separates read and write models. Event Sourcing stores state as a sequence of immutable events. They often appear together but are independent patterns — CQRS is common and useful; Event Sourcing is powerful but niche and complex.
4
+
5
+ > **Category:** Pattern
6
+ > **Complexity:** Expert
7
+ > **Applies when:** Systems with asymmetric read/write loads, audit requirements, temporal queries, or complex domain logic needing full history
8
+
9
+ ---
10
+
11
+ ## What This Is (and What It Isn't)
12
+
13
+ ### CQRS: Command Query Responsibility Segregation
14
+
15
+ Gregory Young coined the term CQRS around 2010, building on Bertrand Meyer's Command Query Separation (CQS) principle from 1988. CQS says a method should either change state (command) or return data (query), never both. CQRS elevates this from a method-level principle to an architectural-level one: the system should have **separate models** for writing data and reading data.
16
+
17
+ The **command side** receives commands (intentions to change state), validates them against business rules, and applies state changes. The **query side** reads data and returns it in whatever shape the consumer needs. These two sides can have entirely different data models, different optimization strategies, and — crucially — can be scaled independently.
18
+
19
+ **What CQRS does NOT require:**
20
+
21
+ - **Two databases.** The simplest CQRS implementation uses a single database with separate read and write models in the application layer. The read model might be a set of denormalized views or materialized query objects. The write model might be a rich domain model. They share a database, and that is fine.
22
+ - **Event Sourcing.** CQRS works perfectly with a traditional relational database using CRUD persistence. You can have a normalized write model and denormalized read projections in the same PostgreSQL instance.
23
+ - **Eventual consistency.** If both models share a database, reads are strongly consistent. Eventual consistency only enters when you separate the read database from the write database and synchronize them asynchronously.
24
+ - **Messaging infrastructure.** You can implement CQRS without a message bus. Commands can be method calls. Queries can be method calls. The pattern is about model separation, not infrastructure separation.
25
+
26
+ ### Event Sourcing: State as a Sequence of Facts
27
+
28
+ Event Sourcing stores the state of a system as an append-only sequence of immutable events, rather than as a mutable current-state record. Instead of storing "account balance = $500", you store the series of events that led to that balance: `AccountOpened($0)`, `MoneyDeposited($1000)`, `MoneyWithdrawn($300)`, `MoneyDeposited($200)`, `MoneyWithdrawn($400)`.
29
+
30
+ The current state is derived by replaying events from the beginning (or from a snapshot). The event log is the single source of truth. The current-state representation is a disposable projection that can be rebuilt at any time.
31
+
32
+ **What Event Sourcing IS:**
33
+
34
+ - An **append-only** store of domain events. Events are never updated or deleted.
35
+ - A **complete audit trail** by construction, not as an afterthought.
36
+ - A mechanism for **temporal queries** — you can reconstruct the state of the system at any point in time by replaying events up to that moment.
37
+ - A foundation for **event replay** — you can rebuild projections, fix bugs in projection logic, and create new read models from historical events.
38
+
39
+ **What Event Sourcing IS NOT:**
40
+
41
+ - **Not event-driven architecture.** Publishing events between services (via Kafka, RabbitMQ, etc.) is event-driven architecture. Storing state as events is event sourcing. You can have event-driven architecture without event sourcing, and event sourcing without event-driven architecture (though they complement each other).
42
+ - **Not a logging mechanism.** An event log is not an application log. Events are domain-meaningful state transitions, not debug output. `OrderPlaced` is an event. `Database query took 200ms` is a log entry.
43
+ - **Not a message queue.** The event store is a database, not a transport. Events are persisted for state reconstruction, not for delivery to consumers (though consumers can subscribe to them).
44
+
45
+ ### They Are Separate Patterns
46
+
47
+ This is the most critical misconception to address. Greg Young himself has stated that while he introduced CQRS and Event Sourcing together, they are independent patterns. His later reflection: "You need to look at CQRS not as being the main thing. CQRS was a product of its time and meant to be a stepping stone towards the ideas of Event Sourcing."
48
+
49
+ However, there is an asymmetry: **you can use CQRS without Event Sourcing** (and this is the more common case), but **if you use Event Sourcing, you almost always need CQRS**. The reason is pragmatic: querying an event store directly for read operations is extremely inefficient. You would need to replay events for every query. Projections (read models) solve this, and projections are the query side of CQRS.
50
+
51
+ **The four combinations:**
52
+
53
+ | | Without CQRS | With CQRS |
54
+ |---|---|---|
55
+ | **Without ES** | Traditional CRUD (most apps) | CQRS with CRUD persistence (common, useful) |
56
+ | **With ES** | Technically possible but impractical | ES with CQRS (the canonical ES setup) |
57
+
58
+ ### Common Misconceptions
59
+
60
+ **"CQRS means two databases."** No. CQRS is about separate models, not separate storage. A single PostgreSQL instance with a normalized write schema and denormalized read views is CQRS. Read replicas alone are NOT CQRS — they are infrastructure scaling. CQRS requires different data models for reads and writes, not just copies of the same model.
61
+
62
+ **"Event Sourcing gives you free debugging."** Partially true. You can replay events to reproduce state, but most production bugs in event-sourced systems come from bad events caused by human error or flawed business logic, not from application crashes. Replaying bad events reproduces the bad state faithfully — that is not debugging, that is archaeology.
63
+
64
+ **"Event Sourcing means you never lose data."** You never lose the history of what happened. But if your projection logic has a bug, your read model can diverge from reality silently for months. The events are correct; the interpretation of them is where data loss happens.
65
+
66
+ **"We need Event Sourcing for our audit trail."** Maybe. But an audit table (a separate append-only log of changes) achieves 80% of the audit benefit at 10% of the complexity. Event Sourcing is warranted when you need the audit trail AND temporal queries AND event replay AND the ability to rebuild state from scratch. If you just need "who changed what, when" for compliance, a CDC-based audit log or database triggers may suffice.
67
+
68
+ ---
69
+
70
+ ## When to Use It
71
+
72
+ ### When to Use CQRS (Without Event Sourcing)
73
+
74
+ **Asymmetric read/write loads.** When reads outnumber writes by 5:1 or more, and the read access patterns differ from the write model's shape. An e-commerce catalog where writes update product details (normalized) but reads need denormalized product cards with pricing, images, reviews, and availability. A social media feed where writes are individual posts but reads need aggregated, ranked, filtered timelines.
75
+
76
+ **Complex domain logic on the write side.** When the write model involves rich validation, business rules, and invariant enforcement that would be polluted by read-side concerns. A financial trading platform where order placement involves margin checks, position limits, and risk calculations — but the read side just needs a dashboard of open positions. Keeping these models separate prevents the query optimization from contaminating the command validation.
77
+
78
+ **Multiple read representations of the same data.** A single write model needs to produce different read models for different consumers: an API response, an analytics dashboard, a search index, a report. Rather than one monolithic model that serves all purposes poorly, CQRS lets each read model be optimized for its consumer.
79
+
80
+ **Teams with separate read/write ownership.** When the write side is owned by the domain team and the read side is owned by the platform or analytics team, CQRS provides a natural boundary for team ownership and independent deployment.
81
+
82
+ **Real-world example — FinTech trading platform.** A medium-sized fintech company built a real-time trading platform. The write model handled order validation, risk checks, and position management with strict consistency. The read model served real-time dashboards, historical trade views, and compliance reports — each as separate projections. CQRS let them scale the read side independently to handle thousands of concurrent dashboard sessions without impacting order processing latency.
83
+
84
+ ### When to Use Event Sourcing
85
+
86
+ **Legal or regulatory audit requirements with temporal queries.** Financial services, healthcare, and government systems where regulators require not just "what is the current state" but "what was the state at 3:47 PM on March 15th, and how did it get there." Event Sourcing provides this by construction. Banking transaction histories, clinical decision audit trails, and securities trading records are canonical examples.
87
+
88
+ **Event replay for projection rebuilding.** When you need the ability to create new read models from historical data without re-processing source systems. A retail platform that decides, six months after launch, to build a recommendation engine — with Event Sourcing, they can replay all historical purchase events through the new recommendation projection without touching the source systems.
89
+
90
+ **Complex event-driven workflows.** Systems where the same events trigger multiple downstream processes: an `OrderPlaced` event triggers inventory reservation, payment processing, shipping notification, and analytics update. Event Sourcing provides a reliable, replayable source for all these consumers.
91
+
92
+ **Debugging and root-cause analysis in high-stakes domains.** Air traffic management, medical device monitoring, financial settlement — domains where understanding exactly how the system reached a particular state is not optional but legally mandated. The Air Traffic Management domain example: computing and persisting flight data where every state transition must be traceable.
93
+
94
+ **Real-world example — healthcare records.** A healthcare system storing patient treatment histories as event streams. Each clinical event (medication prescribed, test ordered, diagnosis recorded) is immutable. State at any point in time can be reconstructed for malpractice reviews. New projections (drug interaction analysis, treatment outcome tracking) can be built retroactively from the complete event history.
95
+
96
+ ---
97
+
98
+ ## When NOT to Use It
99
+
100
+ This section is as important as the previous one. Both patterns are frequently over-applied, producing unnecessary complexity, slower development, and justified frustration from teams who then dismiss the patterns entirely.
101
+
102
+ ### When NOT to Use CQRS
103
+
104
+ **Simple CRUD applications.** If the application reads and writes the same shape of data with minimal business logic, CQRS adds model duplication for no return. A 5-entity admin dashboard for managing users, roles, and settings does not benefit from separate read and write models. The "command" is a data save. The "query" is a data load. They are the same operation wearing different hats.
105
+
106
+ **Real-world cautionary tale:** A startup adopted full CQRS with MediatR, separate command/query handlers, and DTOs for an internal employee directory. The application had four entities: Employee, Department, Role, and Office. Every feature required writing a command handler, a command validator, a query handler, a query DTO, and mapping logic. Development velocity dropped to 40% of what a simple controller-service-repository pattern would have achieved. The team reverted after three months.
107
+
108
+ **Symmetric read/write patterns.** If every read operation returns exactly the data shape that the write operation stores, separate models provide no optimization opportunity. A key-value configuration store, a simple blog engine, or a settings management interface typically reads and writes the same structure.
109
+
110
+ **Small team with limited experience.** CQRS introduces cognitive overhead. Every feature touches two models instead of one. Debugging spans two code paths. If the team has not built a CQRS system before, the learning curve is steep and the initial velocity drop is significant. For teams under five developers building their first production system, the overhead often exceeds the benefit.
111
+
112
+ **No independent scaling requirements.** If reads and writes have similar load characteristics and can share the same database connection pool without contention, the complexity of separate models is not justified by operational need.
113
+
114
+ ### When NOT to Use Event Sourcing
115
+
116
+ **This list is longer than the "when to use" list. This is intentional. Event Sourcing is a powerful, niche pattern that is correct for a narrow set of problems and actively harmful for the rest.**
117
+
118
+ **"Simple queries" become projections.** This is the single biggest hidden cost. In a CRUD system, querying for "all orders placed last week" is a database query. In an event-sourced system, that data lives in a projection that had to be designed, built, deployed, monitored, and kept in sync. Every new query shape requires a new projection or a modification to an existing one. Teams consistently underestimate this cost by an order of magnitude.
119
+
120
+ **Schema evolution is extremely hard.** Events are immutable. But business requirements change. When a `CustomerRegistered` event gains a new required field (`phoneNumber`), you have two options: (1) make the field optional and handle its absence in every projection, or (2) write an upcaster that transforms old `CustomerRegistered` events to include a default phone number at read time. Both options create accretion of complexity over years. A study of industrial event-sourced systems found that schema evolution is the primary source of maintenance burden, with some organizations accepting scheduled downtime for event migrations.
121
+
122
+ **Five versioning strategies, none of them free:**
123
+
124
+ 1. **Weak schema** — consumers tolerate missing/extra fields. Works for additive changes; breaks on semantic changes.
125
+ 2. **Upcasting** — transforms old event versions to new versions at read time. Upcasters accumulate: version 1 → 2 → 3 → 4. Each must be maintained and tested.
126
+ 3. **In-place transformation** — rewrite events in the store. Destroys immutability, the core premise of event sourcing.
127
+ 4. **Copy-and-transform** — create a new event stream with migrated events. Requires coordinated switchover and doubles storage temporarily.
128
+ 5. **Versioned events** — maintain handlers for every event version. Code complexity grows linearly with the number of versions.
129
+
130
+ **Snapshotting is eventually required.** Aggregates with long lifespans accumulate thousands of events. Loading an aggregate requires replaying all of them. A bank account opened in 2015 with daily transactions has ~3,000 events by 2025. Replaying all of them for every command is prohibitively slow. Snapshots solve this but introduce their own complexity: snapshot versioning, snapshot invalidation, snapshot storage, and the interaction between snapshots and event upcasting.
131
+
132
+ **Event Sourcing is not a "move fast" architecture.** Building the core infrastructure (event store, projection engine, snapshot mechanism, event versioning) takes months. Frameworks help but are heavyweight. Teams report that the first six months with Event Sourcing involve building plumbing, not features.
133
+
134
+ **Real-world cautionary tale — the projection nightmare.** A team adopted Event Sourcing for an order management system. Three months in, they were drowning in eventual consistency bugs. The event store became difficult to manage as users saw stale data on dashboards and orders were processed twice due to projection lag. The root cause: they treated Event Sourcing as a storage mechanism and underestimated the operational complexity of managing projections, replay, and consistency guarantees.
135
+
136
+ **GDPR and data deletion.** Event Sourcing stores everything forever. GDPR requires the ability to delete personal data. These are fundamentally in tension. Solutions exist (crypto-shredding, where personal data is encrypted with a per-user key that is deleted on request) but add significant complexity. If your domain has strong data deletion requirements, Event Sourcing's immutability becomes a liability rather than an asset.
137
+
138
+ **Reporting and analytics.** If the primary use case is generating reports across aggregates, Event Sourcing forces you to build and maintain projections for every report. A traditional database with SQL queries is dramatically simpler for ad-hoc reporting. Event-sourced systems often end up with a "reporting database" that is a CRUD projection of the event store — at which point you have built and are maintaining both systems.
139
+
140
+ ---
141
+
142
+ ## How It Works
143
+
144
+ ### CQRS Mechanics
145
+
146
+ ```
147
+ ┌──────────────┐ ┌──────────────────────┐ ┌──────────────┐
148
+ │ │ │ COMMAND SIDE │ │ │
149
+ │ Client │────>│ (Write Model) │────>│ Database │
150
+ │ (UI/API) │ │ - Validate │ │ (Write) │
151
+ │ │ │ - Apply rules │ │ │
152
+ └──────────────┘ │ - Persist state │ └──────┬───────┘
153
+ │ └──────────────────────┘ │
154
+ │ Sync (async
155
+ │ or via DB)
156
+ │ ┌──────────────────────┐ │
157
+ │ │ QUERY SIDE │ ┌──────▼───────┐
158
+ └────────────>│ (Read Model) │<────│ Database │
159
+ │ - Denormalized │ │ (Read) │
160
+ │ - Optimized views │ │ │
161
+ └──────────────────────┘ └──────────────┘
162
+ ```
163
+
164
+ **Level 1 — Same database, separate models.** The command side uses a rich domain model with validation and business rules. The query side uses lightweight DTOs or database views. Both hit the same database. No eventual consistency. No synchronization mechanism. This is the simplest and most common CQRS implementation.
165
+
166
+ **Level 2 — Same database, separate schemas.** The write side uses normalized tables. The read side uses materialized views or denormalized tables in the same database. A database trigger or application-level synchronization keeps them in sync. Still strongly consistent if done within a transaction.
167
+
168
+ **Level 3 — Separate databases.** The write database is normalized and optimized for transactional integrity. The read database is denormalized and optimized for query performance (could be Elasticsearch, Redis, a read replica with materialized views). Synchronization is asynchronous, introducing eventual consistency. This level requires careful handling of stale reads.
169
+
170
+ ### Event Sourcing Mechanics
171
+
172
+ ```
173
+ ┌─────────┐ ┌───────────────┐ ┌────────────────────────────────────┐
174
+ │ Command │───>│ Aggregate │───>│ Event Store │
175
+ │ │ │ (Load state │ │ ┌────────────────────────────────┐ │
176
+ └─────────┘ │ from events,│ │ │ StreamId │ Version │ Event │ │
177
+ │ validate, │ │ ├──────────┼─────────┼──────────┤ │
178
+ │ emit new │ │ │ order-1 │ 1 │ Created │ │
179
+ │ events) │ │ │ order-1 │ 2 │ ItemAdded│ │
180
+ └───────────────┘ │ │ order-1 │ 3 │ Paid │ │
181
+ │ │ order-1 │ 4 │ Shipped │ │
182
+ │ └────────────────────────────────┘ │
183
+ └──────────────┬─────────────────────┘
184
+
185
+ ┌─────────▼──────────┐
186
+ │ Projection │
187
+ │ (Subscribe to │
188
+ │ events, build │
189
+ │ read models) │
190
+ └─────────┬──────────┘
191
+
192
+ ┌─────────▼──────────┐
193
+ │ Read Database │
194
+ │ (Denormalized, │
195
+ │ query-optimized) │
196
+ └────────────────────┘
197
+ ```
198
+
199
+ **The aggregate lifecycle:**
200
+
201
+ 1. **Receive command.** A `PlaceOrder` command arrives.
202
+ 2. **Load aggregate.** The `Order` aggregate is loaded by replaying all events for that stream ID from the event store: `OrderCreated`, `ItemAdded`, `ItemAdded`.
203
+ 3. **Validate.** The aggregate applies business rules against its current in-memory state: is the order still open? Does the customer have sufficient credit?
204
+ 4. **Emit events.** If valid, the aggregate emits new events: `OrderPlaced`. Events are domain facts — they describe what happened, not what was requested.
205
+ 5. **Persist events.** New events are appended to the event store with an expected version number for optimistic concurrency.
206
+ 6. **Publish events.** After persistence, events are published to projections and external subscribers.
207
+
208
+ ### Snapshots
209
+
210
+ When an aggregate has accumulated many events (hundreds or thousands), replaying all of them for every command becomes slow. Snapshots solve this by periodically capturing the aggregate's current state.
211
+
212
+ ```
213
+ Events: [1] [2] [3] ... [500] [SNAPSHOT @ 500] [501] [502] [503]
214
+
215
+ Load: Read snapshot ──────────────>│ Replay 501, 502, 503
216
+ (skip events 1-500) │ Current state
217
+ ```
218
+
219
+ **Snapshot considerations:**
220
+ - Snapshots must be versioned alongside events. If the aggregate's shape changes, old snapshots need migration.
221
+ - Snapshot frequency is a trade-off: too frequent wastes storage, too infrequent slows loading.
222
+ - A common strategy: snapshot every N events (e.g., every 100) or when load time exceeds a threshold.
223
+ - Snapshots are an optimization, not a requirement. The system must be able to rebuild state from events alone.
224
+
225
+ ### Projections
226
+
227
+ Projections (also called read models, materialized views, or denormalizers) subscribe to events and build query-optimized data structures.
228
+
229
+ **Inline projections** run within the same transaction as event persistence. The read model is updated atomically with the write. No eventual consistency. Used when strong consistency is required for specific read models.
230
+
231
+ **Asynchronous projections** subscribe to the event stream and update read models in the background. Eventually consistent. Used for search indexes, analytics, dashboards, and any read model that tolerates latency.
232
+
233
+ **Projection rebuilding** is a key advantage of Event Sourcing: if a projection has a bug, you fix the code and replay all events through the corrected projection. This produces a new, correct read model without touching the event store.
234
+
235
+ **Projection lifecycle management:**
236
+ - Projections must track their position in the event stream (a checkpoint or offset).
237
+ - If a projection crashes and restarts, it resumes from its last checkpoint.
238
+ - New projections start from the beginning of the event stream and "catch up" to the present.
239
+
240
+ ### Sagas and Process Managers
241
+
242
+ Long-running business processes that span multiple aggregates or services are coordinated by **process managers** (sometimes called sagas, though the term "saga" has a different, older meaning in database theory).
243
+
244
+ A process manager listens to events and issues commands:
245
+
246
+ ```
247
+ OrderPlaced ──> Process Manager ──> ReserveInventory (command)
248
+ InventoryReserved ──> Process Manager ──> ChargePayment (command)
249
+ PaymentCharged ──> Process Manager ──> ShipOrder (command)
250
+ ShipmentFailed ──> Process Manager ──> RefundPayment (command)
251
+ ──> ReleaseInventory (command)
252
+ ```
253
+
254
+ The process manager itself can be event-sourced, ensuring that its coordination state survives crashes and restarts.
255
+
256
+ ### Event Versioning in Practice
257
+
258
+ Events evolve as the domain evolves. A real system must handle multiple event versions simultaneously.
259
+
260
+ **Upcasting example:**
261
+
262
+ ```
263
+ // Version 1: CustomerRegistered { name, email }
264
+ // Version 2: CustomerRegistered { firstName, lastName, email, phone }
265
+
266
+ // Upcaster transforms V1 → V2 at read time:
267
+ function upcast(event) {
268
+ if (event.version === 1) {
269
+ const [firstName, ...rest] = event.data.name.split(' ');
270
+ return {
271
+ ...event,
272
+ version: 2,
273
+ data: {
274
+ firstName,
275
+ lastName: rest.join(' ') || 'Unknown',
276
+ email: event.data.email,
277
+ phone: null // field did not exist in V1
278
+ }
279
+ };
280
+ }
281
+ return event;
282
+ }
283
+ ```
284
+
285
+ Upcasting preserves immutability (events are not modified in the store) but adds a transformation layer that accumulates complexity over time. Every version transition must be maintained, tested, and composed correctly: V1 → V2 → V3 → V4.
286
+
287
+ ---
288
+
289
+ ## Trade-Offs Matrix
290
+
291
+ | Dimension | CQRS (without ES) | CQRS + Event Sourcing | Neither (CRUD) |
292
+ |---|---|---|---|
293
+ | **Initial complexity** | Moderate — two models instead of one | Very high — event store, projections, versioning | Low — single model |
294
+ | **Read performance** | Excellent — read model optimized per use case | Excellent — projections denormalized for queries | Limited by normalization |
295
+ | **Write performance** | Good — write model normalized | Excellent — append-only writes are fast | Good — standard CRUD |
296
+ | **Query flexibility** | High — can add new read models | Very high — replay events to build new projections | Limited — requires schema migration |
297
+ | **Audit trail** | Requires separate implementation | Built-in by construction | Requires separate implementation |
298
+ | **Temporal queries** | Not supported natively | Built-in — replay to any point in time | Not supported |
299
+ | **Schema evolution** | Standard DB migrations | Very hard — event versioning, upcasting | Standard DB migrations |
300
+ | **Debugging** | Moderate — two models to trace | Hard — projection drift, eventual consistency | Simple — single model, single state |
301
+ | **Data deletion (GDPR)** | Standard deletion | Complex — crypto-shredding or event redaction | Standard deletion |
302
+ | **Team onboarding** | Moderate learning curve | Steep learning curve | Minimal |
303
+ | **Consistency model** | Configurable — strong or eventual | Typically eventual for read models | Strong (within transactions) |
304
+ | **Operational overhead** | Moderate — sync mechanism | High — event store, projections, snapshots | Low |
305
+ | **Recovery from bugs** | Fix and migrate | Fix projection and replay (powerful but slow) | Fix and migrate |
306
+ | **Infrastructure cost** | Moderate — potential second DB | High — event store + read DB(s) + projection infra | Low — single DB |
307
+
308
+ ---
309
+
310
+ ## Evolution Path
311
+
312
+ The path from simple CRUD to CQRS to Event Sourcing should be driven by concrete pain, not speculative architecture. Each step has a cost, and each step should be taken only when the previous level demonstrably cannot handle the requirements.
313
+
314
+ ### Stage 1: CRUD with Good Boundaries
315
+
316
+ Start here. Always. A well-structured CRUD application with a clean service layer, proper validation, and clear API contracts handles the vast majority of business applications. The key is clean boundaries and good abstractions — these make later evolution possible without requiring a rewrite.
317
+
318
+ ```
319
+ Controller → Service → Repository → Database
320
+ ```
321
+
322
+ **Move to Stage 2 when:** Read and write access patterns diverge significantly. The single model is being tortured to serve both transactional writes and complex queries. Query performance degrades because the normalized write schema is inefficient for reads. Multiple consumers need different shapes of the same data.
323
+
324
+ ### Stage 2: CQRS with Same Database
325
+
326
+ Introduce separate read and write models that share a database. The write side uses a rich domain model with validation. The read side uses denormalized views, materialized queries, or separate DTOs. No infrastructure changes. No eventual consistency.
327
+
328
+ ```
329
+ Command → Write Model → Database ← Read Model ← Query
330
+
331
+ (views / denormalized tables)
332
+ ```
333
+
334
+ **Move to Stage 3 when:** The read side needs a fundamentally different storage technology (full-text search, graph queries, key-value lookups). The write database cannot handle both read and write load. Read and write scaling requirements diverge by an order of magnitude.
335
+
336
+ ### Stage 3: CQRS with Separate Read Storage
337
+
338
+ Split the read database from the write database. Synchronize via Change Data Capture (CDC), domain events published from the write side, or database replication with transformation. Accept eventual consistency on the read side.
339
+
340
+ ```
341
+ Command → Write Model → Write DB ──(CDC/events)──> Read DB ← Query
342
+ ```
343
+
344
+ **Move to Stage 4 when:** You need a complete audit trail with temporal queries. You need event replay capability. You need to reconstruct state at any point in time. Regulatory requirements demand immutable, append-only records of all state changes. These requirements must be concrete and verified — not speculative.
345
+
346
+ ### Stage 4: Event Sourcing (for Specific Aggregates)
347
+
348
+ Apply Event Sourcing to the specific aggregates that require it. Not the entire system. An e-commerce platform might event-source the `Order` aggregate (for audit and temporal queries) while keeping `Product`, `User`, and `Category` as CRUD. This is the recommended approach: surgical Event Sourcing for aggregates that earn it.
349
+
350
+ ```
351
+ Command → Aggregate → Event Store ──(projections)──> Read DB(s)
352
+
353
+ (append-only, immutable)
354
+ ```
355
+
356
+ **Critical principle:** Each stage should be a conscious, reversible decision driven by measured need. Skipping stages — going from CRUD to full Event Sourcing — almost always results in over-engineering and regret.
357
+
358
+ ---
359
+
360
+ ## Failure Modes
361
+
362
+ ### Projection Drift
363
+
364
+ **What happens:** The projection (read model) diverges from the event store. Users see stale or incorrect data. The event store is correct, but the projection's interpretation of events contains a bug that has been silently producing wrong results for weeks.
365
+
366
+ **Why it happens:** A projection handler does not account for a new event type. An upcaster introduces a subtle data transformation error. A projection crashes and misses events before its checkpoint is updated. An event's semantics change but the projection handler is not updated.
367
+
368
+ **Real-world impact:** A fintech team discovered that their account balance projection had been off by fractions of a cent for three months due to a rounding error in the projection handler. The event store was correct. The fix required replaying 200 million events through the corrected projection — a process that took 18 hours and required a maintenance window.
369
+
370
+ **Mitigation:** Regularly compare projection state against event-store-derived state for critical aggregates. Implement projection health checks that verify key invariants. Maintain the ability to rebuild any projection from scratch within an acceptable time window.
371
+
372
+ ### Schema Evolution Breaking Projections
373
+
374
+ **What happens:** The domain team adds a field to an event, splits an event into two, or changes an event's semantics. Projections that consume this event break — either by crashing on the new schema or by silently misinterpreting the changed data.
375
+
376
+ **Why it happens:** Events cross ownership boundaries. The team that emits events and the team that builds projections may be different. Event schema changes are not coordinated across all consumers. There is no schema registry enforcing compatibility.
377
+
378
+ **Real-world impact:** An e-commerce platform split `OrderUpdated` into `OrderItemAdded` and `OrderItemRemoved`. Three downstream projections still expected `OrderUpdated` and silently stopped updating, leading to stale inventory counts for two weeks before the discrepancy was detected.
379
+
380
+ **Mitigation:** Treat events as a public API with a compatibility contract. Use a schema registry (Confluent Schema Registry, AWS Glue Schema Registry). Prefer additive changes (new optional fields) over breaking changes (renamed or removed fields). Run all projections against event schema changes in CI before deploying.
381
+
382
+ ### Snapshot Corruption and Versioning
383
+
384
+ **What happens:** A snapshot was taken when the aggregate had shape A. The aggregate code is updated to shape B. Loading the old snapshot into the new code produces corrupt or incomplete state. Events replayed on top of the corrupt snapshot compound the error.
385
+
386
+ **Why it happens:** Snapshots are serialized representations of in-memory state. When the aggregate's class structure changes (fields added, removed, renamed, types changed), old snapshots become incompatible. Unlike events, snapshots are not typically versioned or upcasted.
387
+
388
+ **Mitigation:** Version snapshots explicitly. When the aggregate shape changes, invalidate old snapshots and let them be rebuilt from events. Include a version field in every snapshot and validate it on load. Test snapshot deserialization as part of the CI pipeline.
389
+
390
+ ### Aggregate Loading Performance Degradation
391
+
392
+ **What happens:** An aggregate with a long lifespan (years) accumulates thousands of events. Loading it requires replaying all events sequentially. Command processing latency grows from milliseconds to seconds.
393
+
394
+ **Why it happens:** No snapshotting strategy was implemented. Or snapshots were implemented but snapshot frequency is too low. Or the aggregate was designed as a single long-lived entity when it should have been split into shorter-lived aggregates.
395
+
396
+ **Real-world example:** A bank account aggregate storing every transaction as an event. An account opened in 2015 with daily transactions accumulated ~3,600 events by 2025. Without snapshots, loading the account took 800ms. With snapshots every 100 events, loading dropped to 12ms. The initial design omitted snapshots because "we'll add them later." "Later" arrived when customers complained about payment processing latency.
397
+
398
+ **Mitigation:** Implement snapshotting from the start for any aggregate expected to accumulate more than 100 events. Monitor aggregate load times. Consider splitting long-lived aggregates into time-bounded chunks (e.g., monthly account statement aggregates instead of lifetime account aggregates).
399
+
400
+ ### Eventual Consistency UX Failures
401
+
402
+ **What happens:** A user submits a command, is redirected to a page that queries the read model, and sees stale data. They submitted an order but the order list shows no new order. They updated their profile but the profile page shows the old data.
403
+
404
+ **Why it happens:** The read model is eventually consistent. The projection has not processed the new events by the time the query executes.
405
+
406
+ **Real-world impact:** Users click "submit" again, creating duplicate orders. Users contact support thinking the system is broken. Trust in the application erodes.
407
+
408
+ **Mitigation:** Return the command result (including the new entity ID and version) directly to the client, bypassing the read model for the immediate response. Use inline projections for user-facing read models that must reflect the latest write. Implement "read your own writes" semantics by routing the user's next query to the write database with a version fence.
409
+
410
+ ### Event Store Operational Challenges
411
+
412
+ **What happens:** The event store grows without bound. Backup and restore times increase linearly. Disk usage becomes a cost concern. Archiving old events is complex because projections may need to replay from the beginning.
413
+
414
+ **Mitigation:** Implement event archival strategies — move old events to cold storage while maintaining the ability to replay from archives. Use event store compaction for streams where only recent events matter. Monitor event store growth and plan storage capacity proactively.
415
+
416
+ ---
417
+
418
+ ## Technology Landscape
419
+
420
+ ### Event Store Databases
421
+
422
+ **EventStoreDB (Kurrent)** — Purpose-built event store by Greg Young's team. First-class support for event streams, subscriptions, projections, and optimistic concurrency. The most mature dedicated event store. Supports competing consumers for horizontal scaling of projections. Written in C#, runs on Linux/Windows/macOS. Open source (server) with commercial support.
423
+
424
+ **Marten** — .NET library that uses PostgreSQL as an event store and document database. Pragmatic choice for .NET teams that want Event Sourcing without a separate database. Provides event storage, projections (inline and async), and snapshotting using PostgreSQL's JSONB columns. Strong integration with the .NET ecosystem.
425
+
426
+ **PostgreSQL (with custom schema)** — Many teams implement Event Sourcing on top of PostgreSQL with a simple `events` table (`stream_id`, `version`, `event_type`, `data JSONB`, `metadata JSONB`, `timestamp`). No framework required. Full control over the schema. Lacks built-in subscription/projection support — you build that yourself.
427
+
428
+ **Apache Kafka** — Used as an event store by some teams, though Kafka was designed as a message broker, not a database. Kafka provides append-only, partitioned, replayed logs. Limitations as an event store: no native support for loading a single aggregate's events efficiently (requires filtering a partition), log compaction conflicts with immutability, retention policies may delete old events.
429
+
430
+ ### CQRS Frameworks and Libraries
431
+
432
+ **MediatR (.NET)** — In-process mediator pattern library. Not CQRS-specific, but widely used to implement the command/query dispatch pattern in .NET. Provides pipeline behaviors for cross-cutting concerns (validation, logging, authorization). Lightweight — does not impose infrastructure.
433
+
434
+ **Axon Framework (Java/Kotlin)** — Full CQRS + Event Sourcing framework. Provides command bus, event bus, query bus, saga support, and event store integration. Can use Axon Server (commercial) or other event stores. Opinionated and heavyweight but comprehensive.
435
+
436
+ **NestJS CQRS Module (TypeScript/Node.js)** — Built-in CQRS module for the NestJS framework. Provides command bus, query bus, and event bus abstractions. Lightweight and well-integrated with NestJS's dependency injection. Does not include an event store — you bring your own.
437
+
438
+ **Eventuous (.NET)** — Modern .NET library for Event Sourcing. Supports EventStoreDB, PostgreSQL, and other stores. Provides aggregate base classes, command services, subscriptions, and projections. Actively maintained with a focus on simplicity.
439
+
440
+ **Commanded (Elixir)** — CQRS/ES framework for Elixir. Leverages Elixir's actor model (GenServer) for aggregate processes. Event store backed by PostgreSQL. Strong fit for systems that benefit from Elixir's concurrency model.
441
+
442
+ ### Supporting Infrastructure
443
+
444
+ **Schema registries** — Confluent Schema Registry, AWS Glue Schema Registry. Enforce event schema compatibility across producers and consumers. Essential for multi-team event-sourced systems.
445
+
446
+ **CDC tools** — Debezium, AWS DMS. Capture changes from the write database and propagate them to read databases. Useful for CQRS without Event Sourcing, where the write side uses CRUD and the read side needs to be synchronized.
447
+
448
+ **Projection monitoring** — Custom health checks, Prometheus metrics on projection lag, alerting on projection checkpoint drift. No standard tooling — most teams build their own.
449
+
450
+ ---
451
+
452
+ ## Decision Tree
453
+
454
+ ```
455
+ START: Do you need separate read and write models?
456
+
457
+ ├─ NO: Read and write shapes are identical or nearly so
458
+ │ └─► Use standard CRUD. Revisit when read/write divergence emerges.
459
+
460
+ ├─ YES: Read and write have different shapes, loads, or optimization needs
461
+ │ │
462
+ │ ├─ Is a single database sufficient for both models?
463
+ │ │ ├─ YES: Use CQRS Level 1 (same DB, separate models)
464
+ │ │ └─ NO: Use CQRS Level 2-3 (separate read storage)
465
+ │ │
466
+ │ └─ Do you need an immutable, append-only audit trail?
467
+ │ │
468
+ │ ├─ NO: CQRS without Event Sourcing is sufficient
469
+ │ │ └─► Audit via CDC, triggers, or a separate audit table
470
+ │ │
471
+ │ └─ YES: Do you also need temporal queries and event replay?
472
+ │ │
473
+ │ ├─ NO: An append-only audit table is simpler
474
+ │ │ └─► CQRS + audit table. Not Event Sourcing.
475
+ │ │
476
+ │ └─ YES: Event Sourcing is warranted
477
+ │ │
478
+ │ ├─ For ALL aggregates?
479
+ │ │ ├─ Rarely. Apply ES only to aggregates that need it.
480
+ │ │ └─► Event Source specific aggregates, CRUD the rest.
481
+ │ │
482
+ │ └─ GDPR/data deletion requirements?
483
+ │ ├─ YES: Plan crypto-shredding from day one.
484
+ │ └─ NO: Standard ES implementation.
485
+ ```
486
+
487
+ **Quick-reference decision rules:**
488
+
489
+ - **Legal audit requirement + temporal queries** → Event Sourcing for the relevant aggregates.
490
+ - **Asymmetric reads (5:1 or higher) with different shapes** → CQRS (without ES).
491
+ - **Simple CRUD with <10 entities** → Neither. Standard architecture.
492
+ - **Multiple read representations** → CQRS (without ES).
493
+ - **Need to replay history for new projections** → Event Sourcing.
494
+ - **"We might need it someday"** → Do not adopt. Wait for concrete need.
495
+ - **Startup MVP** → Neither. Ship features. Introduce patterns when complexity demands them.
496
+
497
+ ---
498
+
499
+ ## Implementation Sketch
500
+
501
+ ### CQRS Without Event Sourcing (TypeScript)
502
+
503
+ ```typescript
504
+ // ─── Command Side ───────────────────────────────────────
505
+
506
+ interface PlaceOrderCommand {
507
+ customerId: string;
508
+ items: { productId: string; quantity: number }[];
509
+ shippingAddress: Address;
510
+ }
511
+
512
+ class PlaceOrderHandler {
513
+ constructor(
514
+ private orderRepo: OrderRepository,
515
+ private inventoryService: InventoryService,
516
+ private eventPublisher: EventPublisher
517
+ ) {}
518
+
519
+ async handle(cmd: PlaceOrderCommand): Promise<string> {
520
+ // Validate against business rules
521
+ const customer = await this.customerRepo.findById(cmd.customerId);
522
+ if (!customer) throw new CustomerNotFoundError(cmd.customerId);
523
+ for (const item of cmd.items) {
524
+ const available = await this.inventoryService.checkAvailability(
525
+ item.productId, item.quantity
526
+ );
527
+ if (!available) throw new InsufficientInventoryError(item.productId);
528
+ }
529
+
530
+ // Create and persist via write model (normalized)
531
+ const order = Order.create({ ...cmd });
532
+ await this.orderRepo.save(order);
533
+
534
+ // Publish event for read model synchronization
535
+ await this.eventPublisher.publish(new OrderPlacedEvent({
536
+ orderId: order.id, customerId: cmd.customerId,
537
+ items: cmd.items, total: order.calculateTotal(), placedAt: order.placedAt,
538
+ }));
539
+ return order.id;
540
+ }
541
+ }
542
+
543
+ // ─── Query Side ─────────────────────────────────────────
544
+
545
+ class GetOrderSummariesHandler {
546
+ constructor(private readDb: ReadDatabase) {}
547
+
548
+ async handle(query: OrderSummaryQuery): Promise<OrderSummaryDto[]> {
549
+ // Query denormalized read model — no domain logic, no joins
550
+ return this.readDb.query(`
551
+ SELECT order_id, status, total, item_count, placed_at
552
+ FROM order_summaries WHERE customer_id = $1
553
+ ORDER BY placed_at DESC LIMIT $2 OFFSET $3
554
+ `, [query.customerId, query.pageSize, query.page * query.pageSize]);
555
+ }
556
+ }
557
+
558
+ // ─── Read Model Synchronization ─────────────────────────
559
+
560
+ class OrderSummaryProjection {
561
+ constructor(private readDb: ReadDatabase) {}
562
+
563
+ async onOrderPlaced(event: OrderPlacedEvent): Promise<void> {
564
+ await this.readDb.upsert('order_summaries', {
565
+ order_id: event.orderId, customer_id: event.customerId,
566
+ status: 'placed', total: event.total,
567
+ item_count: event.items.length, placed_at: event.placedAt,
568
+ });
569
+ }
570
+ }
571
+ ```
572
+
573
+ ### Event Sourcing (TypeScript)
574
+
575
+ ```typescript
576
+ // ─── Domain Events ──────────────────────────────────────
577
+
578
+ interface DomainEvent {
579
+ eventId: string; eventType: string; aggregateId: string;
580
+ version: number; timestamp: Date; data: Record<string, unknown>;
581
+ }
582
+
583
+ // Concrete events: OrderCreated, OrderItemAdded, OrderPlaced
584
+ // Each carries only the data relevant to that state transition.
585
+
586
+ // ─── Aggregate (core pattern) ───────────────────────────
587
+
588
+ class OrderAggregate {
589
+ private items: Map<string, { quantity: number; price: number }> = new Map();
590
+ private status: 'draft' | 'placed' | 'shipped' | 'cancelled' = 'draft';
591
+ private version = 0;
592
+ private uncommittedEvents: DomainEvent[] = [];
593
+
594
+ // Reconstitute from event history
595
+ static fromEvents(events: DomainEvent[]): OrderAggregate {
596
+ const agg = new OrderAggregate();
597
+ for (const e of events) agg.apply(e, false);
598
+ return agg;
599
+ }
600
+
601
+ // Command method: validates, then emits event
602
+ place(): void {
603
+ if (this.status !== 'draft') throw new Error('Order already placed');
604
+ if (this.items.size === 0) throw new Error('Cannot place empty order');
605
+ const total = Array.from(this.items.values())
606
+ .reduce((sum, i) => sum + i.quantity * i.price, 0);
607
+ this.apply(new OrderPlaced(/* ... total, placedAt ... */), true);
608
+ }
609
+
610
+ // Single apply method handles both replay and new events
611
+ private apply(event: DomainEvent, isNew: boolean): void {
612
+ switch (event.eventType) {
613
+ case 'OrderCreated': /* set id, customerId, initial items */ break;
614
+ case 'OrderItemAdded': /* add/update item in map */ break;
615
+ case 'OrderPlaced': this.status = 'placed'; break;
616
+ }
617
+ this.version = event.version;
618
+ if (isNew) this.uncommittedEvents.push(event);
619
+ }
620
+
621
+ getUncommittedEvents(): DomainEvent[] { return [...this.uncommittedEvents]; }
622
+ }
623
+
624
+ // ─── Event Store Interface ──────────────────────────────
625
+
626
+ interface EventStore {
627
+ append(streamId: string, events: DomainEvent[],
628
+ expectedVersion: number): Promise<void>; // optimistic concurrency
629
+ loadStream(streamId: string): Promise<DomainEvent[]>; // full replay
630
+ loadStreamFrom(streamId: string,
631
+ fromVersion: number): Promise<DomainEvent[]>; // snapshot + replay
632
+ subscribe(fromPosition: bigint,
633
+ handler: (event: DomainEvent) => Promise<void>): Subscription;
634
+ }
635
+
636
+ // ─── Command Handler ────────────────────────────────────
637
+
638
+ class PlaceOrderHandler {
639
+ constructor(private eventStore: EventStore, private snapshotStore: SnapshotStore) {}
640
+
641
+ async handle(orderId: string): Promise<void> {
642
+ // 1. Load: snapshot (if available) + replay remaining events
643
+ const snapshot = await this.snapshotStore.load(orderId);
644
+ const events = snapshot
645
+ ? await this.eventStore.loadStreamFrom(orderId, snapshot.version + 1)
646
+ : await this.eventStore.loadStream(orderId);
647
+ const order = OrderAggregate.fromEvents(events);
648
+
649
+ // 2. Execute command (business logic + validation)
650
+ order.place();
651
+
652
+ // 3. Persist new events with optimistic concurrency
653
+ await this.eventStore.append(orderId, order.getUncommittedEvents(),
654
+ order.version - order.getUncommittedEvents().length);
655
+ }
656
+ }
657
+
658
+ // ─── Projection ─────────────────────────────────────────
659
+
660
+ class OrderDashboardProjection {
661
+ async start(): Promise<void> {
662
+ const checkpoint = await this.readDb.getCheckpoint('order-dashboard');
663
+ this.eventStore.subscribe(checkpoint, async (event) => {
664
+ switch (event.eventType) {
665
+ case 'OrderCreated':
666
+ await this.readDb.insert('order_dashboard', { /* denormalized row */ });
667
+ break;
668
+ case 'OrderPlaced':
669
+ await this.readDb.update('order_dashboard',
670
+ { order_id: event.aggregateId },
671
+ { status: 'placed', total: event.data.total });
672
+ break;
673
+ }
674
+ await this.readDb.setCheckpoint('order-dashboard', event.position);
675
+ });
676
+ }
677
+
678
+ // Rebuild: truncate, reset checkpoint, re-subscribe from position 0
679
+ async rebuild(): Promise<void> {
680
+ await this.readDb.truncate('order_dashboard');
681
+ await this.readDb.setCheckpoint('order-dashboard', 0n);
682
+ await this.start();
683
+ }
684
+ }
685
+ ```
686
+
687
+ ---
688
+
689
+ ## Cross-References
690
+
691
+ - **[Event-Driven Architecture](../integration/event-driven.md)** — CQRS and ES often exist within event-driven systems, but they are distinct patterns. Event-driven architecture is about communication between components; CQRS is about model separation; ES is about state persistence.
692
+ - **[Domain-Driven Design](../foundations/domain-driven-design.md)** — CQRS and ES are most effective within a DDD context. Aggregates, bounded contexts, and ubiquitous language provide the domain model that CQRS separates and ES persists.
693
+ - **[Data Consistency Patterns](../data/consistency.md)** — Eventual consistency in CQRS read models and the saga/process manager pattern for distributed transactions.
694
+ - **[Saga Pattern](../distributed/saga-pattern.md)** — Long-running processes that coordinate multiple aggregates in an event-sourced system use sagas or process managers.
695
+
696
+ ---
697
+
698
+ ## Sources
699
+
700
+ - [1 Year of Event Sourcing and CQRS — Teiva Harsanyi](https://itnext.io/1-year-of-event-sourcing-and-cqrs-fb9033ccd1c6)
701
+ - [Event Sourcing, CQRS and Micro Services: Real FinTech Example — Lukas Niessen](https://dev.to/lukasniessen/event-sourcing-cqrs-and-micro-services-real-fintech-example-from-my-consulting-career-1j9b)
702
+ - [Don't Let the Internet Dupe You, Event Sourcing is Hard — Chris Kiehl](https://chriskiehl.com/article/event-sourcing-is-hard)
703
+ - [Day Two Problems When Using CQRS and Event Sourcing — InfoQ](https://www.infoq.com/news/2019/09/cqrs-event-sourcing-production/)
704
+ - [The Ugly of Event Sourcing: Real-world Production Issues — Dennis Doomen](https://www.dennisdoomen.com/2017/11/the-ugly-of-event-sourcingreal-world.html)
705
+ - [Event Stores and Event Sourcing: Some Practical Disadvantages — Ben Morris](https://www.ben-morris.com/event-stores-and-event-sourcing-some-practical-disadvantages-and-problems/)
706
+ - [When Not to Use Event Sourcing — Oskar Dudycz](https://event-driven.io/en/when_not_to_use_event_sourcing/)
707
+ - [CQRS Facts and Myths Explained — Oskar Dudycz](https://event-driven.io/en/cqrs_facts_and_myths_explained/)
708
+ - [Simple Patterns for Events Schema Versioning — Oskar Dudycz](https://event-driven.io/en/simple_events_versioning_patterns/)
709
+ - [CQRS Documents — Greg Young (2010)](https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf)
710
+ - [CQRS — Martin Fowler](https://martinfowler.com/bliki/CQRS.html)
711
+ - [CQRS Pattern — Microsoft Azure Architecture Center](https://learn.microsoft.com/en-us/azure/architecture/patterns/cqrs)
712
+ - [When to Avoid CQRS — Udi Dahan](https://udidahan.com/2011/04/22/when-to-avoid-cqrs/)
713
+ - [Event Sourcing Looked Perfect in the Book. Production Was a Nightmare.](https://medium.com/lets-code-future/event-sourcing-looked-perfect-in-the-book-production-was-a-nightmare-04c15eb5cea8)
714
+ - [Eventual Consistency is a UX Nightmare — CodeOpinion](https://codeopinion.com/eventual-consistency-is-a-ux-nightmare/)
715
+ - [The Dark Side of Event Sourcing: Managing Data Conversion — Michiel Overeem et al.](https://www.movereem.nl/files/2017SANER-eventsourcing.pdf)
716
+ - [Event Sourcing: What is Upcasting? A Deep Dive — Artium](https://artium.ai/insights/event-sourcing-what-is-upcasting-a-deep-dive)
717
+ - [An Empirical Characterization of Event Sourced Systems and Their Schema Evolution — ScienceDirect](https://www.sciencedirect.com/science/article/pii/S0164121221000674)