@zimezone/z-command 1.1.1 → 1.1.4

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 (288) hide show
  1. package/README.md +13 -1
  2. package/dist/cli.js +1 -1
  3. package/dist/commands/init.d.ts.map +1 -1
  4. package/dist/commands/init.js +42 -10
  5. package/dist/commands/init.js.map +1 -1
  6. package/dist/platforms.d.ts.map +1 -1
  7. package/dist/platforms.js +11 -1
  8. package/dist/platforms.js.map +1 -1
  9. package/dist/types.d.ts +2 -0
  10. package/dist/types.d.ts.map +1 -1
  11. package/package.json +8 -3
  12. package/templates.zip +0 -0
  13. package/templates/agents/accessibility-expert.agent.md +0 -56
  14. package/templates/agents/ai-engineer.agent.md +0 -61
  15. package/templates/agents/angular-architect.agent.md +0 -49
  16. package/templates/agents/api-designer.agent.md +0 -40
  17. package/templates/agents/api-documenter.agent.md +0 -161
  18. package/templates/agents/architect-review.agent.md +0 -146
  19. package/templates/agents/arm-cortex-expert.agent.md +0 -288
  20. package/templates/agents/azure-infra-engineer.agent.md +0 -57
  21. package/templates/agents/backend-architect.agent.md +0 -309
  22. package/templates/agents/backend-developer.agent.md +0 -61
  23. package/templates/agents/backend-security-coder.agent.md +0 -152
  24. package/templates/agents/bash-pro.agent.md +0 -285
  25. package/templates/agents/blockchain-developer.agent.md +0 -57
  26. package/templates/agents/build-engineer.agent.md +0 -56
  27. package/templates/agents/business-analyst.agent.md +0 -47
  28. package/templates/agents/c-pro.agent.md +0 -35
  29. package/templates/agents/c4-code.agent.md +0 -320
  30. package/templates/agents/c4-component.agent.md +0 -227
  31. package/templates/agents/c4-container.agent.md +0 -248
  32. package/templates/agents/c4-context.agent.md +0 -235
  33. package/templates/agents/cli-developer.agent.md +0 -57
  34. package/templates/agents/cloud-architect.agent.md +0 -56
  35. package/templates/agents/code-architect.agent.md +0 -63
  36. package/templates/agents/code-reviewer.agent.md +0 -49
  37. package/templates/agents/competitive-analyst.agent.md +0 -48
  38. package/templates/agents/conductor-validator.agent.md +0 -245
  39. package/templates/agents/context-manager.agent.md +0 -55
  40. package/templates/agents/cpp-pro.agent.md +0 -59
  41. package/templates/agents/csharp-developer.agent.md +0 -57
  42. package/templates/agents/csharp-pro.agent.md +0 -38
  43. package/templates/agents/customer-support.agent.md +0 -148
  44. package/templates/agents/data-engineer.agent.md +0 -55
  45. package/templates/agents/data-researcher.agent.md +0 -55
  46. package/templates/agents/data-scientist.agent.md +0 -56
  47. package/templates/agents/database-admin.agent.md +0 -142
  48. package/templates/agents/database-administrator.agent.md +0 -50
  49. package/templates/agents/database-architect.agent.md +0 -238
  50. package/templates/agents/database-optimizer.agent.md +0 -144
  51. package/templates/agents/debugger.agent.md +0 -30
  52. package/templates/agents/deployment-engineer.agent.md +0 -0
  53. package/templates/agents/devops-engineer.agent.md +0 -59
  54. package/templates/agents/devops-troubleshooter.agent.md +0 -138
  55. package/templates/agents/django-developer.agent.md +0 -50
  56. package/templates/agents/django-pro.agent.md +0 -159
  57. package/templates/agents/docs-architect.agent.md +0 -77
  58. package/templates/agents/documentation-engineer.agent.md +0 -57
  59. package/templates/agents/dotnet-architect.agent.md +0 -175
  60. package/templates/agents/dx-optimizer.agent.md +0 -63
  61. package/templates/agents/electron-pro.agent.md +0 -56
  62. package/templates/agents/elixir-pro.agent.md +0 -38
  63. package/templates/agents/embedded-systems.agent.md +0 -55
  64. package/templates/agents/error-detective.agent.md +0 -32
  65. package/templates/agents/event-sourcing-architect.agent.md +0 -42
  66. package/templates/agents/fastapi-pro.agent.md +0 -171
  67. package/templates/agents/fintech-engineer.agent.md +0 -57
  68. package/templates/agents/firmware-analyst.agent.md +0 -330
  69. package/templates/agents/flutter-expert.agent.md +0 -50
  70. package/templates/agents/frontend-developer.agent.md +0 -59
  71. package/templates/agents/frontend-security-coder.agent.md +0 -149
  72. package/templates/agents/fullstack-developer.agent.md +0 -46
  73. package/templates/agents/git-workflow-manager.agent.md +0 -57
  74. package/templates/agents/golang-pro.agent.md +0 -50
  75. package/templates/agents/graphql-architect.agent.md +0 -48
  76. package/templates/agents/haskell-pro.agent.md +0 -37
  77. package/templates/agents/hr-pro.agent.md +0 -105
  78. package/templates/agents/incident-responder.agent.md +0 -190
  79. package/templates/agents/ios-developer.agent.md +0 -198
  80. package/templates/agents/iot-engineer.agent.md +0 -56
  81. package/templates/agents/java-architect.agent.md +0 -48
  82. package/templates/agents/java-pro.agent.md +0 -156
  83. package/templates/agents/javascript-pro.agent.md +0 -35
  84. package/templates/agents/julia-pro.agent.md +0 -187
  85. package/templates/agents/kotlin-specialist.agent.md +0 -50
  86. package/templates/agents/laravel-specialist.agent.md +0 -50
  87. package/templates/agents/legacy-modernizer.agent.md +0 -56
  88. package/templates/agents/legal-advisor.agent.md +0 -49
  89. package/templates/agents/llm-architect.agent.md +0 -58
  90. package/templates/agents/malware-analyst.agent.md +0 -272
  91. package/templates/agents/mcp-developer.agent.md +0 -54
  92. package/templates/agents/mermaid-expert.agent.md +0 -39
  93. package/templates/agents/microservices-architect.agent.md +0 -47
  94. package/templates/agents/minecraft-bukkit-pro.agent.md +0 -104
  95. package/templates/agents/ml-engineer.agent.md +0 -56
  96. package/templates/agents/mlops-engineer.agent.md +0 -56
  97. package/templates/agents/mobile-developer.agent.md +0 -45
  98. package/templates/agents/mobile-security-coder.agent.md +0 -163
  99. package/templates/agents/monorepo-architect.agent.md +0 -44
  100. package/templates/agents/multi-agent-coordinator.agent.md +0 -55
  101. package/templates/agents/network-engineer.agent.md +0 -57
  102. package/templates/agents/nextjs-developer.agent.md +0 -48
  103. package/templates/agents/nlp-engineer.agent.md +0 -58
  104. package/templates/agents/observability-engineer.agent.md +0 -228
  105. package/templates/agents/payment-integration.agent.md +0 -56
  106. package/templates/agents/performance-engineer.agent.md +0 -167
  107. package/templates/agents/performance-optimizer.agent.md +0 -57
  108. package/templates/agents/php-pro.agent.md +0 -43
  109. package/templates/agents/platform-engineer.agent.md +0 -57
  110. package/templates/agents/posix-shell-pro.agent.md +0 -284
  111. package/templates/agents/postgres-pro.agent.md +0 -58
  112. package/templates/agents/product-manager.agent.md +0 -55
  113. package/templates/agents/project-manager.agent.md +0 -57
  114. package/templates/agents/prompt-engineer.agent.md +0 -58
  115. package/templates/agents/python-pro.agent.md +0 -48
  116. package/templates/agents/quant-analyst.agent.md +0 -32
  117. package/templates/agents/rails-expert.agent.md +0 -50
  118. package/templates/agents/react-specialist.agent.md +0 -49
  119. package/templates/agents/refactoring-specialist.agent.md +0 -56
  120. package/templates/agents/reference-builder.agent.md +0 -167
  121. package/templates/agents/research-analyst.agent.md +0 -63
  122. package/templates/agents/reverse-engineer.agent.md +0 -202
  123. package/templates/agents/risk-manager.agent.md +0 -41
  124. package/templates/agents/ruby-pro.agent.md +0 -35
  125. package/templates/agents/rust-pro.agent.md +0 -156
  126. package/templates/agents/sales-automator.agent.md +0 -35
  127. package/templates/agents/scala-pro.agent.md +0 -60
  128. package/templates/agents/scrum-master.agent.md +0 -54
  129. package/templates/agents/search-specialist.agent.md +0 -59
  130. package/templates/agents/security-analyst.agent.md +0 -57
  131. package/templates/agents/security-auditor.agent.md +0 -138
  132. package/templates/agents/security-engineer.agent.md +0 -57
  133. package/templates/agents/seo-authority-builder.agent.md +0 -116
  134. package/templates/agents/seo-cannibalization-detector.agent.md +0 -103
  135. package/templates/agents/seo-content-auditor.agent.md +0 -63
  136. package/templates/agents/seo-content-planner.agent.md +0 -88
  137. package/templates/agents/seo-content-refresher.agent.md +0 -98
  138. package/templates/agents/seo-content-writer.agent.md +0 -76
  139. package/templates/agents/seo-keyword-strategist.agent.md +0 -75
  140. package/templates/agents/seo-meta-optimizer.agent.md +0 -72
  141. package/templates/agents/seo-snippet-hunter.agent.md +0 -94
  142. package/templates/agents/seo-specialist.agent.md +0 -57
  143. package/templates/agents/seo-structure-architect.agent.md +0 -88
  144. package/templates/agents/service-mesh-expert.agent.md +0 -41
  145. package/templates/agents/sql-pro.agent.md +0 -146
  146. package/templates/agents/sre-engineer.agent.md +0 -58
  147. package/templates/agents/swift-expert.agent.md +0 -49
  148. package/templates/agents/task-distributor.agent.md +0 -47
  149. package/templates/agents/tdd-orchestrator.agent.md +0 -183
  150. package/templates/agents/technical-writer.agent.md +0 -48
  151. package/templates/agents/temporal-python-pro.agent.md +0 -349
  152. package/templates/agents/terraform-engineer.agent.md +0 -57
  153. package/templates/agents/terraform-specialist.agent.md +0 -137
  154. package/templates/agents/test-automator.agent.md +0 -203
  155. package/templates/agents/test-engineer.agent.md +0 -55
  156. package/templates/agents/threat-modeling-expert.agent.md +0 -44
  157. package/templates/agents/trend-analyst.agent.md +0 -47
  158. package/templates/agents/tutorial-engineer.agent.md +0 -118
  159. package/templates/agents/typescript-pro.agent.md +0 -48
  160. package/templates/agents/ui-designer.agent.md +0 -48
  161. package/templates/agents/ui-ux-designer.agent.md +0 -188
  162. package/templates/agents/ui-visual-validator.agent.md +0 -192
  163. package/templates/agents/ux-researcher.agent.md +0 -48
  164. package/templates/agents/vector-database-engineer.agent.md +0 -43
  165. package/templates/agents/vue-expert.agent.md +0 -48
  166. package/templates/agents/websocket-engineer.agent.md +0 -49
  167. package/templates/agents/workflow-orchestrator.agent.md +0 -48
  168. package/templates/skills/angular-migration/SKILL.md +0 -410
  169. package/templates/skills/api-design-principles/SKILL.md +0 -528
  170. package/templates/skills/api-design-principles/assets/api-design-checklist.md +0 -155
  171. package/templates/skills/api-design-principles/assets/rest-api-template.py +0 -182
  172. package/templates/skills/api-design-principles/references/graphql-schema-design.md +0 -583
  173. package/templates/skills/api-design-principles/references/rest-best-practices.md +0 -408
  174. package/templates/skills/architecture-decision-records/SKILL.md +0 -428
  175. package/templates/skills/architecture-patterns/SKILL.md +0 -494
  176. package/templates/skills/async-python-patterns/SKILL.md +0 -694
  177. package/templates/skills/auth-implementation-patterns/SKILL.md +0 -634
  178. package/templates/skills/changelog-automation/SKILL.md +0 -552
  179. package/templates/skills/code-review/SKILL.md +0 -62
  180. package/templates/skills/code-review-excellence/SKILL.md +0 -520
  181. package/templates/skills/competitive-landscape/SKILL.md +0 -479
  182. package/templates/skills/context-driven-development/SKILL.md +0 -385
  183. package/templates/skills/cost-optimization/SKILL.md +0 -274
  184. package/templates/skills/cqrs-implementation/SKILL.md +0 -554
  185. package/templates/skills/data-quality-frameworks/SKILL.md +0 -587
  186. package/templates/skills/data-storytelling/SKILL.md +0 -453
  187. package/templates/skills/database-migration/SKILL.md +0 -424
  188. package/templates/skills/dbt-transformation-patterns/SKILL.md +0 -561
  189. package/templates/skills/debugging-strategies/SKILL.md +0 -527
  190. package/templates/skills/defi-protocol-templates/SKILL.md +0 -454
  191. package/templates/skills/dependency-upgrade/SKILL.md +0 -409
  192. package/templates/skills/deployment-pipeline-design/SKILL.md +0 -359
  193. package/templates/skills/distributed-tracing/SKILL.md +0 -438
  194. package/templates/skills/dotnet-backend-patterns/SKILL.md +0 -815
  195. package/templates/skills/dotnet-backend-patterns/assets/repository-template.cs +0 -523
  196. package/templates/skills/dotnet-backend-patterns/assets/service-template.cs +0 -336
  197. package/templates/skills/dotnet-backend-patterns/references/dapper-patterns.md +0 -544
  198. package/templates/skills/dotnet-backend-patterns/references/ef-core-best-practices.md +0 -355
  199. package/templates/skills/e2e-testing-patterns/SKILL.md +0 -547
  200. package/templates/skills/employment-contract-templates/SKILL.md +0 -507
  201. package/templates/skills/error-handling-patterns/SKILL.md +0 -636
  202. package/templates/skills/event-store-design/SKILL.md +0 -437
  203. package/templates/skills/fastapi-templates/SKILL.md +0 -567
  204. package/templates/skills/git-advanced-workflows/SKILL.md +0 -400
  205. package/templates/skills/github-actions-templates/SKILL.md +0 -333
  206. package/templates/skills/go-concurrency-patterns/SKILL.md +0 -655
  207. package/templates/skills/grafana-dashboards/SKILL.md +0 -369
  208. package/templates/skills/helm-chart-scaffolding/SKILL.md +0 -544
  209. package/templates/skills/helm-chart-scaffolding/assets/Chart.yaml.template +0 -42
  210. package/templates/skills/helm-chart-scaffolding/assets/values.yaml.template +0 -185
  211. package/templates/skills/helm-chart-scaffolding/references/chart-structure.md +0 -500
  212. package/templates/skills/helm-chart-scaffolding/scripts/validate-chart.sh +0 -244
  213. package/templates/skills/javascript-testing-patterns/SKILL.md +0 -1025
  214. package/templates/skills/langchain-architecture/SKILL.md +0 -338
  215. package/templates/skills/llm-evaluation/SKILL.md +0 -471
  216. package/templates/skills/microservices-patterns/SKILL.md +0 -595
  217. package/templates/skills/modern-javascript-patterns/SKILL.md +0 -911
  218. package/templates/skills/monorepo-management/SKILL.md +0 -622
  219. package/templates/skills/nextjs-app-router-patterns/SKILL.md +0 -544
  220. package/templates/skills/nodejs-backend-patterns/SKILL.md +0 -1020
  221. package/templates/skills/nx-workspace-patterns/SKILL.md +0 -452
  222. package/templates/skills/openapi-spec-generation/SKILL.md +0 -1028
  223. package/templates/skills/paypal-integration/SKILL.md +0 -467
  224. package/templates/skills/pci-compliance/SKILL.md +0 -466
  225. package/templates/skills/postgresql/SKILL.md +0 -204
  226. package/templates/skills/projection-patterns/SKILL.md +0 -490
  227. package/templates/skills/prometheus-configuration/SKILL.md +0 -392
  228. package/templates/skills/prompt-engineering-patterns/SKILL.md +0 -201
  229. package/templates/skills/prompt-engineering-patterns/assets/few-shot-examples.json +0 -106
  230. package/templates/skills/prompt-engineering-patterns/assets/prompt-template-library.md +0 -246
  231. package/templates/skills/prompt-engineering-patterns/references/chain-of-thought.md +0 -399
  232. package/templates/skills/prompt-engineering-patterns/references/few-shot-learning.md +0 -369
  233. package/templates/skills/prompt-engineering-patterns/references/prompt-optimization.md +0 -414
  234. package/templates/skills/prompt-engineering-patterns/references/prompt-templates.md +0 -470
  235. package/templates/skills/prompt-engineering-patterns/references/system-prompts.md +0 -189
  236. package/templates/skills/prompt-engineering-patterns/scripts/optimize-prompt.py +0 -279
  237. package/templates/skills/python-packaging/SKILL.md +0 -870
  238. package/templates/skills/python-performance-optimization/SKILL.md +0 -869
  239. package/templates/skills/python-testing-patterns/SKILL.md +0 -907
  240. package/templates/skills/rag-implementation/SKILL.md +0 -403
  241. package/templates/skills/react-modernization/SKILL.md +0 -513
  242. package/templates/skills/react-native-architecture/SKILL.md +0 -671
  243. package/templates/skills/react-state-management/SKILL.md +0 -429
  244. package/templates/skills/risk-metrics-calculation/SKILL.md +0 -555
  245. package/templates/skills/rust-async-patterns/SKILL.md +0 -517
  246. package/templates/skills/secrets-management/SKILL.md +0 -346
  247. package/templates/skills/security-requirement-extraction/SKILL.md +0 -677
  248. package/templates/skills/security-review/SKILL.md +0 -78
  249. package/templates/skills/shellcheck-configuration/SKILL.md +0 -454
  250. package/templates/skills/similarity-search-patterns/SKILL.md +0 -558
  251. package/templates/skills/slo-implementation/SKILL.md +0 -329
  252. package/templates/skills/sql-optimization-patterns/SKILL.md +0 -493
  253. package/templates/skills/stripe-integration/SKILL.md +0 -442
  254. package/templates/skills/systematic-debugging/SKILL.md +0 -57
  255. package/templates/skills/tailwind-design-system/SKILL.md +0 -666
  256. package/templates/skills/temporal-python-testing/SKILL.md +0 -158
  257. package/templates/skills/temporal-python-testing/resources/integration-testing.md +0 -455
  258. package/templates/skills/temporal-python-testing/resources/local-setup.md +0 -553
  259. package/templates/skills/temporal-python-testing/resources/replay-testing.md +0 -462
  260. package/templates/skills/temporal-python-testing/resources/unit-testing.md +0 -328
  261. package/templates/skills/terraform-module-library/SKILL.md +0 -249
  262. package/templates/skills/terraform-module-library/references/aws-modules.md +0 -63
  263. package/templates/skills/test-driven-development/SKILL.md +0 -46
  264. package/templates/skills/threat-mitigation-mapping/SKILL.md +0 -745
  265. package/templates/skills/track-management/SKILL.md +0 -593
  266. package/templates/skills/typescript-advanced-types/SKILL.md +0 -717
  267. package/templates/skills/ui-ux-pro-max/SKILL.md +0 -352
  268. package/templates/skills/ui-ux-pro-max/data/charts.csv +0 -26
  269. package/templates/skills/ui-ux-pro-max/data/colors.csv +0 -97
  270. package/templates/skills/ui-ux-pro-max/data/icons.csv +0 -101
  271. package/templates/skills/ui-ux-pro-max/data/landing.csv +0 -31
  272. package/templates/skills/ui-ux-pro-max/data/products.csv +0 -97
  273. package/templates/skills/ui-ux-pro-max/data/prompts.csv +0 -24
  274. package/templates/skills/ui-ux-pro-max/data/react-performance.csv +0 -45
  275. package/templates/skills/ui-ux-pro-max/data/styles.csv +0 -59
  276. package/templates/skills/ui-ux-pro-max/data/typography.csv +0 -58
  277. package/templates/skills/ui-ux-pro-max/data/ui-reasoning.csv +0 -101
  278. package/templates/skills/ui-ux-pro-max/data/ux-guidelines.csv +0 -100
  279. package/templates/skills/ui-ux-pro-max/data/web-interface.csv +0 -31
  280. package/templates/skills/ui-ux-pro-max/scripts/core.py +0 -258
  281. package/templates/skills/ui-ux-pro-max/scripts/design_system.py +0 -547
  282. package/templates/skills/ui-ux-pro-max/scripts/search.py +0 -76
  283. package/templates/skills/uv-package-manager/SKILL.md +0 -831
  284. package/templates/skills/vector-index-tuning/SKILL.md +0 -521
  285. package/templates/skills/wcag-audit-patterns/SKILL.md +0 -555
  286. package/templates/skills/workflow-orchestration-patterns/SKILL.md +0 -316
  287. package/templates/skills/workflow-patterns/SKILL.md +0 -623
  288. package/templates/skills/writing-plans/SKILL.md +0 -64
@@ -1,490 +0,0 @@
1
- ---
2
- name: projection-patterns
3
- description: Build read models and projections from event streams. Use when implementing CQRS read sides, building materialized views, or optimizing query performance in event-sourced systems.
4
- ---
5
-
6
- # Projection Patterns
7
-
8
- Comprehensive guide to building projections and read models for event-sourced systems.
9
-
10
- ## When to Use This Skill
11
-
12
- - Building CQRS read models
13
- - Creating materialized views from events
14
- - Optimizing query performance
15
- - Implementing real-time dashboards
16
- - Building search indexes from events
17
- - Aggregating data across streams
18
-
19
- ## Core Concepts
20
-
21
- ### 1. Projection Architecture
22
-
23
- ```
24
- ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
25
- │ Event Store │────►│ Projector │────►│ Read Model │
26
- │ │ │ │ │ (Database) │
27
- │ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │
28
- │ │ Events │ │ │ │ Handler │ │ │ │ Tables │ │
29
- │ └─────────┘ │ │ │ Logic │ │ │ │ Views │ │
30
- │ │ │ └─────────┘ │ │ │ Cache │ │
31
- └─────────────┘ └─────────────┘ └─────────────┘
32
- ```
33
-
34
- ### 2. Projection Types
35
-
36
- | Type | Description | Use Case |
37
- | -------------- | --------------------------- | ---------------------- |
38
- | **Live** | Real-time from subscription | Current state queries |
39
- | **Catchup** | Process historical events | Rebuilding read models |
40
- | **Persistent** | Stores checkpoint | Resume after restart |
41
- | **Inline** | Same transaction as write | Strong consistency |
42
-
43
- ## Templates
44
-
45
- ### Template 1: Basic Projector
46
-
47
- ```python
48
- from abc import ABC, abstractmethod
49
- from dataclasses import dataclass
50
- from typing import Dict, Any, Callable, List
51
- import asyncpg
52
-
53
- @dataclass
54
- class Event:
55
- stream_id: str
56
- event_type: str
57
- data: dict
58
- version: int
59
- global_position: int
60
-
61
-
62
- class Projection(ABC):
63
- """Base class for projections."""
64
-
65
- @property
66
- @abstractmethod
67
- def name(self) -> str:
68
- """Unique projection name for checkpointing."""
69
- pass
70
-
71
- @abstractmethod
72
- def handles(self) -> List[str]:
73
- """List of event types this projection handles."""
74
- pass
75
-
76
- @abstractmethod
77
- async def apply(self, event: Event) -> None:
78
- """Apply event to the read model."""
79
- pass
80
-
81
-
82
- class Projector:
83
- """Runs projections from event store."""
84
-
85
- def __init__(self, event_store, checkpoint_store):
86
- self.event_store = event_store
87
- self.checkpoint_store = checkpoint_store
88
- self.projections: List[Projection] = []
89
-
90
- def register(self, projection: Projection):
91
- self.projections.append(projection)
92
-
93
- async def run(self, batch_size: int = 100):
94
- """Run all projections continuously."""
95
- while True:
96
- for projection in self.projections:
97
- await self._run_projection(projection, batch_size)
98
- await asyncio.sleep(0.1)
99
-
100
- async def _run_projection(self, projection: Projection, batch_size: int):
101
- checkpoint = await self.checkpoint_store.get(projection.name)
102
- position = checkpoint or 0
103
-
104
- events = await self.event_store.read_all(position, batch_size)
105
-
106
- for event in events:
107
- if event.event_type in projection.handles():
108
- await projection.apply(event)
109
-
110
- await self.checkpoint_store.save(
111
- projection.name,
112
- event.global_position
113
- )
114
-
115
- async def rebuild(self, projection: Projection):
116
- """Rebuild a projection from scratch."""
117
- await self.checkpoint_store.delete(projection.name)
118
- # Optionally clear read model tables
119
- await self._run_projection(projection, batch_size=1000)
120
- ```
121
-
122
- ### Template 2: Order Summary Projection
123
-
124
- ```python
125
- class OrderSummaryProjection(Projection):
126
- """Projects order events to a summary read model."""
127
-
128
- def __init__(self, db_pool: asyncpg.Pool):
129
- self.pool = db_pool
130
-
131
- @property
132
- def name(self) -> str:
133
- return "order_summary"
134
-
135
- def handles(self) -> List[str]:
136
- return [
137
- "OrderCreated",
138
- "OrderItemAdded",
139
- "OrderItemRemoved",
140
- "OrderShipped",
141
- "OrderCompleted",
142
- "OrderCancelled"
143
- ]
144
-
145
- async def apply(self, event: Event) -> None:
146
- handlers = {
147
- "OrderCreated": self._handle_created,
148
- "OrderItemAdded": self._handle_item_added,
149
- "OrderItemRemoved": self._handle_item_removed,
150
- "OrderShipped": self._handle_shipped,
151
- "OrderCompleted": self._handle_completed,
152
- "OrderCancelled": self._handle_cancelled,
153
- }
154
-
155
- handler = handlers.get(event.event_type)
156
- if handler:
157
- await handler(event)
158
-
159
- async def _handle_created(self, event: Event):
160
- async with self.pool.acquire() as conn:
161
- await conn.execute(
162
- """
163
- INSERT INTO order_summaries
164
- (order_id, customer_id, status, total_amount, item_count, created_at)
165
- VALUES ($1, $2, $3, $4, $5, $6)
166
- """,
167
- event.data['order_id'],
168
- event.data['customer_id'],
169
- 'pending',
170
- 0,
171
- 0,
172
- event.data['created_at']
173
- )
174
-
175
- async def _handle_item_added(self, event: Event):
176
- async with self.pool.acquire() as conn:
177
- await conn.execute(
178
- """
179
- UPDATE order_summaries
180
- SET total_amount = total_amount + $2,
181
- item_count = item_count + 1,
182
- updated_at = NOW()
183
- WHERE order_id = $1
184
- """,
185
- event.data['order_id'],
186
- event.data['price'] * event.data['quantity']
187
- )
188
-
189
- async def _handle_item_removed(self, event: Event):
190
- async with self.pool.acquire() as conn:
191
- await conn.execute(
192
- """
193
- UPDATE order_summaries
194
- SET total_amount = total_amount - $2,
195
- item_count = item_count - 1,
196
- updated_at = NOW()
197
- WHERE order_id = $1
198
- """,
199
- event.data['order_id'],
200
- event.data['price'] * event.data['quantity']
201
- )
202
-
203
- async def _handle_shipped(self, event: Event):
204
- async with self.pool.acquire() as conn:
205
- await conn.execute(
206
- """
207
- UPDATE order_summaries
208
- SET status = 'shipped',
209
- shipped_at = $2,
210
- updated_at = NOW()
211
- WHERE order_id = $1
212
- """,
213
- event.data['order_id'],
214
- event.data['shipped_at']
215
- )
216
-
217
- async def _handle_completed(self, event: Event):
218
- async with self.pool.acquire() as conn:
219
- await conn.execute(
220
- """
221
- UPDATE order_summaries
222
- SET status = 'completed',
223
- completed_at = $2,
224
- updated_at = NOW()
225
- WHERE order_id = $1
226
- """,
227
- event.data['order_id'],
228
- event.data['completed_at']
229
- )
230
-
231
- async def _handle_cancelled(self, event: Event):
232
- async with self.pool.acquire() as conn:
233
- await conn.execute(
234
- """
235
- UPDATE order_summaries
236
- SET status = 'cancelled',
237
- cancelled_at = $2,
238
- cancellation_reason = $3,
239
- updated_at = NOW()
240
- WHERE order_id = $1
241
- """,
242
- event.data['order_id'],
243
- event.data['cancelled_at'],
244
- event.data.get('reason')
245
- )
246
- ```
247
-
248
- ### Template 3: Elasticsearch Search Projection
249
-
250
- ```python
251
- from elasticsearch import AsyncElasticsearch
252
-
253
- class ProductSearchProjection(Projection):
254
- """Projects product events to Elasticsearch for full-text search."""
255
-
256
- def __init__(self, es_client: AsyncElasticsearch):
257
- self.es = es_client
258
- self.index = "products"
259
-
260
- @property
261
- def name(self) -> str:
262
- return "product_search"
263
-
264
- def handles(self) -> List[str]:
265
- return [
266
- "ProductCreated",
267
- "ProductUpdated",
268
- "ProductPriceChanged",
269
- "ProductDeleted"
270
- ]
271
-
272
- async def apply(self, event: Event) -> None:
273
- if event.event_type == "ProductCreated":
274
- await self.es.index(
275
- index=self.index,
276
- id=event.data['product_id'],
277
- document={
278
- 'name': event.data['name'],
279
- 'description': event.data['description'],
280
- 'category': event.data['category'],
281
- 'price': event.data['price'],
282
- 'tags': event.data.get('tags', []),
283
- 'created_at': event.data['created_at']
284
- }
285
- )
286
-
287
- elif event.event_type == "ProductUpdated":
288
- await self.es.update(
289
- index=self.index,
290
- id=event.data['product_id'],
291
- doc={
292
- 'name': event.data['name'],
293
- 'description': event.data['description'],
294
- 'category': event.data['category'],
295
- 'tags': event.data.get('tags', []),
296
- 'updated_at': event.data['updated_at']
297
- }
298
- )
299
-
300
- elif event.event_type == "ProductPriceChanged":
301
- await self.es.update(
302
- index=self.index,
303
- id=event.data['product_id'],
304
- doc={
305
- 'price': event.data['new_price'],
306
- 'price_updated_at': event.data['changed_at']
307
- }
308
- )
309
-
310
- elif event.event_type == "ProductDeleted":
311
- await self.es.delete(
312
- index=self.index,
313
- id=event.data['product_id']
314
- )
315
- ```
316
-
317
- ### Template 4: Aggregating Projection
318
-
319
- ```python
320
- class DailySalesProjection(Projection):
321
- """Aggregates sales data by day for reporting."""
322
-
323
- def __init__(self, db_pool: asyncpg.Pool):
324
- self.pool = db_pool
325
-
326
- @property
327
- def name(self) -> str:
328
- return "daily_sales"
329
-
330
- def handles(self) -> List[str]:
331
- return ["OrderCompleted", "OrderRefunded"]
332
-
333
- async def apply(self, event: Event) -> None:
334
- if event.event_type == "OrderCompleted":
335
- await self._increment_sales(event)
336
- elif event.event_type == "OrderRefunded":
337
- await self._decrement_sales(event)
338
-
339
- async def _increment_sales(self, event: Event):
340
- date = event.data['completed_at'][:10] # YYYY-MM-DD
341
- async with self.pool.acquire() as conn:
342
- await conn.execute(
343
- """
344
- INSERT INTO daily_sales (date, total_orders, total_revenue, total_items)
345
- VALUES ($1, 1, $2, $3)
346
- ON CONFLICT (date) DO UPDATE SET
347
- total_orders = daily_sales.total_orders + 1,
348
- total_revenue = daily_sales.total_revenue + $2,
349
- total_items = daily_sales.total_items + $3,
350
- updated_at = NOW()
351
- """,
352
- date,
353
- event.data['total_amount'],
354
- event.data['item_count']
355
- )
356
-
357
- async def _decrement_sales(self, event: Event):
358
- date = event.data['original_completed_at'][:10]
359
- async with self.pool.acquire() as conn:
360
- await conn.execute(
361
- """
362
- UPDATE daily_sales SET
363
- total_orders = total_orders - 1,
364
- total_revenue = total_revenue - $2,
365
- total_refunds = total_refunds + $2,
366
- updated_at = NOW()
367
- WHERE date = $1
368
- """,
369
- date,
370
- event.data['refund_amount']
371
- )
372
- ```
373
-
374
- ### Template 5: Multi-Table Projection
375
-
376
- ```python
377
- class CustomerActivityProjection(Projection):
378
- """Projects customer activity across multiple tables."""
379
-
380
- def __init__(self, db_pool: asyncpg.Pool):
381
- self.pool = db_pool
382
-
383
- @property
384
- def name(self) -> str:
385
- return "customer_activity"
386
-
387
- def handles(self) -> List[str]:
388
- return [
389
- "CustomerCreated",
390
- "OrderCompleted",
391
- "ReviewSubmitted",
392
- "CustomerTierChanged"
393
- ]
394
-
395
- async def apply(self, event: Event) -> None:
396
- async with self.pool.acquire() as conn:
397
- async with conn.transaction():
398
- if event.event_type == "CustomerCreated":
399
- # Insert into customers table
400
- await conn.execute(
401
- """
402
- INSERT INTO customers (customer_id, email, name, tier, created_at)
403
- VALUES ($1, $2, $3, 'bronze', $4)
404
- """,
405
- event.data['customer_id'],
406
- event.data['email'],
407
- event.data['name'],
408
- event.data['created_at']
409
- )
410
- # Initialize activity summary
411
- await conn.execute(
412
- """
413
- INSERT INTO customer_activity_summary
414
- (customer_id, total_orders, total_spent, total_reviews)
415
- VALUES ($1, 0, 0, 0)
416
- """,
417
- event.data['customer_id']
418
- )
419
-
420
- elif event.event_type == "OrderCompleted":
421
- # Update activity summary
422
- await conn.execute(
423
- """
424
- UPDATE customer_activity_summary SET
425
- total_orders = total_orders + 1,
426
- total_spent = total_spent + $2,
427
- last_order_at = $3
428
- WHERE customer_id = $1
429
- """,
430
- event.data['customer_id'],
431
- event.data['total_amount'],
432
- event.data['completed_at']
433
- )
434
- # Insert into order history
435
- await conn.execute(
436
- """
437
- INSERT INTO customer_order_history
438
- (customer_id, order_id, amount, completed_at)
439
- VALUES ($1, $2, $3, $4)
440
- """,
441
- event.data['customer_id'],
442
- event.data['order_id'],
443
- event.data['total_amount'],
444
- event.data['completed_at']
445
- )
446
-
447
- elif event.event_type == "ReviewSubmitted":
448
- await conn.execute(
449
- """
450
- UPDATE customer_activity_summary SET
451
- total_reviews = total_reviews + 1,
452
- last_review_at = $2
453
- WHERE customer_id = $1
454
- """,
455
- event.data['customer_id'],
456
- event.data['submitted_at']
457
- )
458
-
459
- elif event.event_type == "CustomerTierChanged":
460
- await conn.execute(
461
- """
462
- UPDATE customers SET tier = $2, updated_at = NOW()
463
- WHERE customer_id = $1
464
- """,
465
- event.data['customer_id'],
466
- event.data['new_tier']
467
- )
468
- ```
469
-
470
- ## Best Practices
471
-
472
- ### Do's
473
-
474
- - **Make projections idempotent** - Safe to replay
475
- - **Use transactions** - For multi-table updates
476
- - **Store checkpoints** - Resume after failures
477
- - **Monitor lag** - Alert on projection delays
478
- - **Plan for rebuilds** - Design for reconstruction
479
-
480
- ### Don'ts
481
-
482
- - **Don't couple projections** - Each is independent
483
- - **Don't skip error handling** - Log and alert on failures
484
- - **Don't ignore ordering** - Events must be processed in order
485
- - **Don't over-normalize** - Denormalize for query patterns
486
-
487
- ## Resources
488
-
489
- - [CQRS Pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/cqrs)
490
- - [Projection Building Blocks](https://zimarev.com/blog/event-sourcing/projections/)