@martinffx/atelier 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/LICENSE +21 -0
  3. package/README.md +285 -0
  4. package/agents/architect.md +38 -0
  5. package/agents/oracle.md +40 -0
  6. package/agents/recon.md +39 -0
  7. package/dist/atelier.js +33082 -0
  8. package/package.json +44 -0
  9. package/skills/code-conventional-commit/SKILL.md +134 -0
  10. package/skills/code-conventional-commit/evals/evals.json +23 -0
  11. package/skills/code-conventional-commit/workspace/iteration-1/eval-0/with_skill/outputs/commit-message.txt +4 -0
  12. package/skills/code-conventional-commit/workspace/iteration-1/eval-0/with_skill/outputs/eval_metadata.json +6 -0
  13. package/skills/code-conventional-commit/workspace/iteration-1/eval-1/with_skill/outputs/eval_metadata.json +6 -0
  14. package/skills/code-conventional-commit/workspace/iteration-1/eval-1/with_skill/outputs/validation-result.txt +16 -0
  15. package/skills/code-conventional-commit/workspace/iteration-1/eval-2/with_skill/outputs/commit-message.txt +8 -0
  16. package/skills/code-conventional-commit/workspace/iteration-1/eval-2/with_skill/outputs/eval_metadata.json +6 -0
  17. package/skills/code-conventional-commit/workspace/iteration-1/report.html +1325 -0
  18. package/skills/code-debug/SKILL.md +271 -0
  19. package/skills/code-debug/references/language-tools.md +139 -0
  20. package/skills/code-debug/references/techniques.md +117 -0
  21. package/skills/code-docs/SKILL.md +171 -0
  22. package/skills/code-docs/references/api-docs.md +116 -0
  23. package/skills/code-docs/references/changelog.md +64 -0
  24. package/skills/code-docs/references/readme-structure.md +94 -0
  25. package/skills/code-git-worktrees/SKILL.md +218 -0
  26. package/skills/code-perf/SKILL.md +163 -0
  27. package/skills/code-perf/references/common-bottlenecks.md +124 -0
  28. package/skills/code-perf/references/optimization-patterns.md +167 -0
  29. package/skills/code-perf/references/profiling-tools.md +126 -0
  30. package/skills/code-review/SKILL.md +78 -0
  31. package/skills/code-review/references/output.md +200 -0
  32. package/skills/code-review/references/reviewers.md +719 -0
  33. package/skills/code-review/references/rq.md +357 -0
  34. package/skills/code-review/references/rs.md +30 -0
  35. package/skills/code-security/SKILL.md +183 -0
  36. package/skills/code-security/references/owasp-top-10.md +129 -0
  37. package/skills/code-security/references/security-tools.md +102 -0
  38. package/skills/code-security/references/vulnerability-patterns.md +129 -0
  39. package/skills/code-stacked-commit/SKILL.md +155 -0
  40. package/skills/code-subagents/SKILL.md +184 -0
  41. package/skills/code-subagents/references/code-quality-reviewer-prompt.md +48 -0
  42. package/skills/code-subagents/references/implementor-prompt.md +79 -0
  43. package/skills/code-subagents/references/spec-reviewer-prompt.md +62 -0
  44. package/skills/oracle-architect/SKILL.md +246 -0
  45. package/skills/oracle-architect/references/api-design.md +345 -0
  46. package/skills/oracle-architect/references/data-modeling.md +318 -0
  47. package/skills/oracle-architect/references/ddd-patterns.md +247 -0
  48. package/skills/oracle-challenge/SKILL.md +126 -0
  49. package/skills/oracle-testing/SKILL.md +237 -0
  50. package/skills/oracle-testing/references/anti-patterns.md +618 -0
  51. package/skills/oracle-testing/references/boundaries.md +579 -0
  52. package/skills/oracle-testing/references/core-testing.md +691 -0
  53. package/skills/oracle-testing/references/edge-testing.md +794 -0
  54. package/skills/oracle-testing/references/stub-driven-tdd.md +322 -0
  55. package/skills/oracle-thinkdeep/SKILL.md +164 -0
  56. package/skills/python-architecture/SKILL.md +148 -0
  57. package/skills/python-architecture/references/data-modeling.md +558 -0
  58. package/skills/python-architecture/references/ddd.md +569 -0
  59. package/skills/python-architecture/references/functional-core.md +337 -0
  60. package/skills/python-build-tools/SKILL.md +153 -0
  61. package/skills/python-build-tools/references/basedpyright.md +321 -0
  62. package/skills/python-build-tools/references/ruff.md +225 -0
  63. package/skills/python-build-tools/references/uv.md +257 -0
  64. package/skills/python-fastapi/SKILL.md +184 -0
  65. package/skills/python-fastapi/references/api-design.md +563 -0
  66. package/skills/python-fastapi/references/dependencies.md +479 -0
  67. package/skills/python-fastapi/references/middleware.md +475 -0
  68. package/skills/python-fastapi/references/validation.md +497 -0
  69. package/skills/python-modern-python/SKILL.md +201 -0
  70. package/skills/python-modern-python/references/async.md +76 -0
  71. package/skills/python-modern-python/references/pattern-matching.md +89 -0
  72. package/skills/python-modern-python/references/typing.md +96 -0
  73. package/skills/python-monorepo/SKILL.md +146 -0
  74. package/skills/python-monorepo/references/docker.md +515 -0
  75. package/skills/python-monorepo/references/namespace-packages.md +426 -0
  76. package/skills/python-monorepo/references/workspace-config.md +341 -0
  77. package/skills/python-sqlalchemy/SKILL.md +119 -0
  78. package/skills/python-sqlalchemy/references/async.md +51 -0
  79. package/skills/python-sqlalchemy/references/models.md +67 -0
  80. package/skills/python-sqlalchemy/references/queries.md +57 -0
  81. package/skills/python-temporal/SKILL.md +128 -0
  82. package/skills/python-temporal/references/patterns.md +87 -0
  83. package/skills/python-temporal/references/testing.md +54 -0
  84. package/skills/python-testing/SKILL.md +161 -0
  85. package/skills/python-testing/references/boundaries.md +449 -0
  86. package/skills/python-testing/references/mocking.md +449 -0
  87. package/skills/python-testing/references/pytest.md +524 -0
  88. package/skills/spec-brainstorm/SKILL.md +325 -0
  89. package/skills/spec-finish/SKILL.md +159 -0
  90. package/skills/spec-implement/SKILL.md +296 -0
  91. package/skills/spec-orchestrator/SKILL.md +156 -0
  92. package/skills/spec-plan/SKILL.md +248 -0
  93. package/skills/typescript-api-design/SKILL.md +396 -0
  94. package/skills/typescript-api-design/references/error-responses.md +469 -0
  95. package/skills/typescript-build-tools/SKILL.md +447 -0
  96. package/skills/typescript-build-tools/references/biome.md +436 -0
  97. package/skills/typescript-build-tools/references/bun.md +432 -0
  98. package/skills/typescript-build-tools/references/turborepo.md +426 -0
  99. package/skills/typescript-build-tools/references/vitest.md +518 -0
  100. package/skills/typescript-drizzle-orm/SKILL.md +398 -0
  101. package/skills/typescript-drizzle-orm/references/cloudflare.md +392 -0
  102. package/skills/typescript-drizzle-orm/references/entity-pattern.md +412 -0
  103. package/skills/typescript-drizzle-orm/references/postgresql.md +191 -0
  104. package/skills/typescript-drizzle-orm/references/repository-pattern.md +479 -0
  105. package/skills/typescript-drizzle-orm/references/sqlite.md +291 -0
  106. package/skills/typescript-dynamodb-toolbox/SKILL.md +370 -0
  107. package/skills/typescript-dynamodb-toolbox/references/entity-layer.md +574 -0
  108. package/skills/typescript-dynamodb-toolbox/references/error-handling.md +495 -0
  109. package/skills/typescript-dynamodb-toolbox/references/modeling.md +332 -0
  110. package/skills/typescript-dynamodb-toolbox/references/repository-layer.md +631 -0
  111. package/skills/typescript-dynamodb-toolbox/references/testing.md +718 -0
  112. package/skills/typescript-dynamodb-toolbox/references/transactions.md +423 -0
  113. package/skills/typescript-effect-ts/SKILL.md +341 -0
  114. package/skills/typescript-effect-ts/references/core.md +412 -0
  115. package/skills/typescript-effect-ts/references/error-handling.md +468 -0
  116. package/skills/typescript-effect-ts/references/resources.md +476 -0
  117. package/skills/typescript-effect-ts/references/schema.md +536 -0
  118. package/skills/typescript-effect-ts/references/services.md +461 -0
  119. package/skills/typescript-fastify/SKILL.md +405 -0
  120. package/skills/typescript-fastify/references/plugins.md +329 -0
  121. package/skills/typescript-fastify/references/typeid.md +315 -0
  122. package/skills/typescript-functional-patterns/SKILL.md +402 -0
  123. package/skills/typescript-functional-patterns/references/adts.md +497 -0
  124. package/skills/typescript-functional-patterns/references/branded-types.md +542 -0
  125. package/skills/typescript-functional-patterns/references/migration-guide.md +695 -0
  126. package/skills/typescript-functional-patterns/references/option-result.md +585 -0
  127. package/skills/typescript-testing/SKILL.md +353 -0
  128. package/skills/typescript-testing/references/mocking.md +675 -0
  129. package/skills/typescript-testing/references/msw.md +852 -0
  130. package/skills/typescript-testing/references/snapshot-testing.md +774 -0
@@ -0,0 +1,318 @@
1
+ # Data Modeling Reference
2
+
3
+ Entity design principles, schema patterns, and access pattern optimization.
4
+
5
+ ## Entity Design
6
+
7
+ ### Design Process
8
+ 1. Start with domain concepts from product requirements
9
+ 2. Identify aggregates and their boundaries
10
+ 3. Define attributes and relationships
11
+ 4. Add validation rules and invariants
12
+ 5. Include transformation methods (fromRequest, toRecord, toResponse)
13
+
14
+ ### Entity Structure
15
+
16
+ **Core transformation methods:**
17
+ ```typescript
18
+ class Order {
19
+ // Create from external request
20
+ static fromRequest(req: CreateOrderRequest): Order
21
+
22
+ // Create from database record
23
+ static fromRecord(record: OrderRecord): Order
24
+
25
+ // Convert to database record
26
+ toRecord(): OrderRecord
27
+
28
+ // Convert to API response
29
+ toResponse(): OrderResponse
30
+
31
+ // Validate invariants
32
+ validate(): Result<Order>
33
+ }
34
+ ```
35
+
36
+ ### Example Entity Design
37
+
38
+ ```typescript
39
+ class Order {
40
+ constructor(
41
+ public readonly id: string,
42
+ public readonly customerId: string,
43
+ public readonly items: OrderItem[],
44
+ public readonly status: OrderStatus,
45
+ public readonly total: number,
46
+ public readonly createdAt: Date,
47
+ public readonly metadata: OrderMetadata
48
+ ) {}
49
+
50
+ static fromRequest(req: CreateOrderRequest): Order {
51
+ return new Order(
52
+ generateId(),
53
+ req.customerId,
54
+ req.items.map(i => new OrderItem(i)),
55
+ 'pending',
56
+ req.items.reduce((sum, i) => sum + i.price * i.quantity, 0),
57
+ new Date(),
58
+ { source: req.source || 'web' }
59
+ );
60
+ }
61
+
62
+ toRecord(): OrderRecord {
63
+ return {
64
+ id: this.id,
65
+ customer_id: this.customerId,
66
+ items: JSON.stringify(this.items),
67
+ status: this.status,
68
+ total: this.total,
69
+ created_at: this.createdAt.toISOString(),
70
+ metadata: this.metadata
71
+ };
72
+ }
73
+
74
+ toResponse(): OrderResponse {
75
+ return {
76
+ id: this.id,
77
+ customerId: this.customerId,
78
+ items: this.items,
79
+ status: this.status,
80
+ total: this.total,
81
+ createdAt: this.createdAt.toISOString()
82
+ };
83
+ }
84
+
85
+ validate(): Result<Order> {
86
+ if (this.items.length === 0) {
87
+ return Err('Order must have at least one item');
88
+ }
89
+ if (this.total < 0) {
90
+ return Err('Order total cannot be negative');
91
+ }
92
+ return Ok(this);
93
+ }
94
+ }
95
+ ```
96
+
97
+ ## Schema Patterns
98
+
99
+ ### Relational Design
100
+
101
+ **Orders table:**
102
+ ```sql
103
+ CREATE TABLE orders (
104
+ id UUID PRIMARY KEY,
105
+ customer_id UUID NOT NULL REFERENCES customers(id),
106
+ status VARCHAR(20) NOT NULL CHECK (status IN ('pending', 'confirmed', 'shipped', 'delivered')),
107
+ total DECIMAL(10,2) NOT NULL,
108
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
109
+ updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
110
+ );
111
+
112
+ CREATE INDEX idx_orders_customer ON orders(customer_id);
113
+ CREATE INDEX idx_orders_status ON orders(status);
114
+ CREATE INDEX idx_orders_created ON orders(created_at DESC);
115
+ ```
116
+
117
+ **Order items (normalized):**
118
+ ```sql
119
+ CREATE TABLE order_items (
120
+ id UUID PRIMARY KEY,
121
+ order_id UUID NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
122
+ product_id UUID NOT NULL,
123
+ quantity INT NOT NULL CHECK (quantity > 0),
124
+ price DECIMAL(10,2) NOT NULL,
125
+ UNIQUE(order_id, product_id)
126
+ );
127
+
128
+ CREATE INDEX idx_order_items_order ON order_items(order_id);
129
+ ```
130
+
131
+ ### DynamoDB Single Table Design
132
+
133
+ **Items structure:**
134
+ ```typescript
135
+ {
136
+ PK: 'ORDER#123',
137
+ SK: 'ORDER#123',
138
+ type: 'Order',
139
+ customerId: 'CUST#456',
140
+ status: 'pending',
141
+ total: 99.99,
142
+ items: [...],
143
+ createdAt: '2024-01-21T10:00:00Z',
144
+
145
+ // GSI for customer lookup
146
+ GSI1PK: 'CUST#456',
147
+ GSI1SK: 'ORDER#2024-01-21T10:00:00Z',
148
+
149
+ // GSI for status lookup
150
+ GSI2PK: 'pending',
151
+ GSI2SK: 'ORDER#2024-01-21T10:00:00Z'
152
+ }
153
+
154
+ {
155
+ PK: 'ORDER#123',
156
+ SK: 'ITEM#item-001',
157
+ type: 'OrderItem',
158
+ productId: 'PROD#999',
159
+ quantity: 2,
160
+ price: 49.99
161
+ }
162
+ ```
163
+
164
+ **Key design:**
165
+ - PK = partition key (primary lookup)
166
+ - SK = sort key (range queries)
167
+ - GSI = global secondary index (alternative queries)
168
+
169
+ ## Access Patterns
170
+
171
+ ### Define Patterns First
172
+
173
+ List all data access patterns **before** designing schema:
174
+
175
+ 1. **Find order by ID**
176
+ - Query: `PK = ORDER#123, SK = ORDER#123`
177
+ - Index: Primary key
178
+
179
+ 2. **List orders by customer**
180
+ - Query: `GSI1PK = CUST#456`
181
+ - Index: Global secondary index
182
+
183
+ 3. **List pending orders by date**
184
+ - Query: `GSI2PK = pending, GSI2SK > date`
185
+ - Index: Global secondary index sorted by date
186
+
187
+ 4. **Count orders by status**
188
+ - Query: Scan with filter (or GSI)
189
+ - Performance: Consider status table
190
+
191
+ 5. **Get recent orders for customer**
192
+ - Query: `GSI1PK = CUST#456` sorted by date DESC
193
+ - Index: Global secondary index
194
+
195
+ ### Query Optimization
196
+
197
+ **N+1 Problem:**
198
+ ```typescript
199
+ // BAD: N+1 queries
200
+ const orders = await orderRepo.findByCustomer(customerId);
201
+ const itemsPerOrder = await Promise.all(
202
+ orders.map(o => itemRepo.findByOrder(o.id)) // N queries
203
+ );
204
+
205
+ // GOOD: Single query with denormalization
206
+ const orderData = await db.orders
207
+ .where({ customerId })
208
+ .select(['*', 'items']) // Includes denormalized items
209
+ .sort({ createdAt: 'DESC' });
210
+ ```
211
+
212
+ **Index Coverage:**
213
+ ```sql
214
+ -- Bad: Full table scan
215
+ SELECT * FROM orders WHERE customer_id = $1;
216
+
217
+ -- Good: Index-covered query
218
+ CREATE INDEX idx_orders_customer_status
219
+ ON orders(customer_id, status);
220
+
221
+ SELECT * FROM orders
222
+ WHERE customer_id = $1 AND status = 'pending';
223
+ ```
224
+
225
+ ## Data Transformation Patterns
226
+
227
+ ### Request → Entity → Record → Response Flow
228
+
229
+ ```typescript
230
+ // 1. HTTP Request arrives
231
+ POST /orders
232
+ {
233
+ "customerId": "cust-123",
234
+ "items": [{ "productId": "prod-1", "quantity": 2 }]
235
+ }
236
+
237
+ // 2. Router parses to request type
238
+ const request: CreateOrderRequest = req.body;
239
+
240
+ // 3. Entity transforms from request (with ID generation)
241
+ const order = Order.fromRequest(request);
242
+
243
+ // 4. Entity validates business rules
244
+ const validation = order.validate();
245
+ if (!validation.ok) return error;
246
+
247
+ // 5. Service performs logic, uses repository
248
+ await repo.save(order.toRecord());
249
+
250
+ // 6. Repository converts to database record
251
+ {
252
+ id: "order-abc",
253
+ customer_id: "cust-123",
254
+ items: "[...]",
255
+ status: "pending",
256
+ created_at: "2024-01-21T10:00:00Z"
257
+ }
258
+
259
+ // 7. Response converts from record
260
+ const response = order.toResponse();
261
+
262
+ // 8. HTTP Response sends
263
+ {
264
+ "id": "order-abc",
265
+ "customerId": "cust-123",
266
+ "items": [...],
267
+ "status": "pending"
268
+ }
269
+ ```
270
+
271
+ ### Transformation Considerations
272
+
273
+ **Immutability:**
274
+ ```typescript
275
+ // Bad: Mutation during transform
276
+ toRecord(): OrderRecord {
277
+ this.items.forEach(i => i.status = 'recorded');
278
+ return { items: this.items };
279
+ }
280
+
281
+ // Good: No side effects
282
+ toRecord(): OrderRecord {
283
+ return {
284
+ items: this.items.map(i => ({
285
+ ...i,
286
+ // Transform properties as needed
287
+ }))
288
+ };
289
+ }
290
+ ```
291
+
292
+ **Versioning:**
293
+ ```typescript
294
+ // Handle multiple API versions
295
+ toResponse(version: 'v1' | 'v2'): OrderResponse {
296
+ const base = {
297
+ id: this.id,
298
+ customerId: this.customerId,
299
+ status: this.status
300
+ };
301
+
302
+ if (version === 'v2') {
303
+ return { ...base, total: this.total };
304
+ }
305
+ return base;
306
+ }
307
+ ```
308
+
309
+ **Partial Loading:**
310
+ ```typescript
311
+ // Only load fields needed for the operation
312
+ async findOrderSummary(id: string): Promise<OrderSummary> {
313
+ const record = await db.orders
314
+ .select(['id', 'status', 'total'])
315
+ .findOne({ id });
316
+ return { id: record.id, status: record.status, total: record.total };
317
+ }
318
+ ```
@@ -0,0 +1,247 @@
1
+ # DDD Patterns Reference
2
+
3
+ Domain-Driven Design patterns for modeling business domains and enforcing consistency.
4
+
5
+ ## Aggregates
6
+
7
+ **Definition:** Cluster of domain objects treated as a single unit for data changes
8
+
9
+ **Rules:**
10
+ - One entity is the aggregate root (e.g., Order)
11
+ - External references only to the root
12
+ - Changes go through the root
13
+ - Root enforces invariants
14
+
15
+ **Example:**
16
+ ```typescript
17
+ class Order { // Aggregate root
18
+ private items: OrderItem[]; // Part of aggregate
19
+
20
+ addItem(item: OrderItem): Result<Order> {
21
+ // Root enforces invariants
22
+ if (this.items.length >= 100) {
23
+ return Err('Order cannot have more than 100 items');
24
+ }
25
+ this.items.push(item);
26
+ return Ok(this);
27
+ }
28
+ }
29
+ ```
30
+
31
+ **Business Rules Enforcement:**
32
+ ```typescript
33
+ class Order {
34
+ private status: OrderStatus;
35
+ private appliedDiscounts: Discount[] = [];
36
+
37
+ applyDiscount(discount: Discount): Result<void> {
38
+ // Business rule: can't apply discount to shipped orders
39
+ if (this.status === 'shipped') {
40
+ return Err('Cannot discount shipped orders');
41
+ }
42
+
43
+ // Business rule: no duplicate discounts
44
+ if (this.appliedDiscounts.some(d => d.id === discount.id)) {
45
+ return Err('Discount already applied');
46
+ }
47
+
48
+ this.appliedDiscounts.push(discount);
49
+ return Ok(undefined);
50
+ }
51
+ }
52
+ ```
53
+
54
+ ## Value Objects
55
+
56
+ **Definition:** Immutable objects defined by their attributes, not identity
57
+
58
+ **Characteristics:**
59
+ - No identity (equality by value)
60
+ - Immutable
61
+ - Self-validating
62
+ - Encapsulate validation logic
63
+
64
+ **Example:**
65
+ ```typescript
66
+ class Money {
67
+ constructor(
68
+ public readonly amount: number,
69
+ public readonly currency: string
70
+ ) {
71
+ if (amount < 0) throw new Error('Amount cannot be negative');
72
+ if (!['USD', 'EUR', 'GBP'].includes(currency)) {
73
+ throw new Error('Unsupported currency');
74
+ }
75
+ }
76
+
77
+ add(other: Money): Money {
78
+ if (this.currency !== other.currency) {
79
+ throw new Error('Cannot add different currencies');
80
+ }
81
+ return new Money(this.amount + other.amount, this.currency);
82
+ }
83
+
84
+ equals(other: Money): boolean {
85
+ return this.amount === other.amount && this.currency === other.currency;
86
+ }
87
+
88
+ static fromCents(cents: number, currency: string): Money {
89
+ return new Money(cents / 100, currency);
90
+ }
91
+ }
92
+ ```
93
+
94
+ **More Examples:**
95
+ ```typescript
96
+ // Email VO with validation
97
+ class Email {
98
+ readonly value: string;
99
+
100
+ constructor(value: string) {
101
+ if (!this.isValid(value)) throw new Error('Invalid email');
102
+ this.value = value.toLowerCase();
103
+ }
104
+
105
+ private isValid(email: string): boolean {
106
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
107
+ }
108
+
109
+ equals(other: Email): boolean {
110
+ return this.value === other.value;
111
+ }
112
+ }
113
+
114
+ // Address VO with composition
115
+ class Address {
116
+ constructor(
117
+ public readonly street: string,
118
+ public readonly city: string,
119
+ public readonly zipCode: string,
120
+ public readonly country: string
121
+ ) {}
122
+
123
+ equals(other: Address): boolean {
124
+ return this.street === other.street &&
125
+ this.city === other.city &&
126
+ this.zipCode === other.zipCode &&
127
+ this.country === other.country;
128
+ }
129
+ }
130
+ ```
131
+
132
+ ## Domain Events
133
+
134
+ **Definition:** Something that happened in the domain that domain experts care about
135
+
136
+ **Characteristics:**
137
+ - Immutable facts about what happened
138
+ - Named in past tense
139
+ - Include context about what changed
140
+ - Timestamped
141
+
142
+ **Example:**
143
+ ```typescript
144
+ class OrderPlaced {
145
+ constructor(
146
+ public readonly orderId: string,
147
+ public readonly customerId: string,
148
+ public readonly total: number,
149
+ public readonly occurredAt: Date
150
+ ) {}
151
+ }
152
+
153
+ // Service publishes events
154
+ const order = await orderService.createOrder(request);
155
+ await eventBus.publish(
156
+ new OrderPlaced(order.id, order.customerId, order.total, new Date())
157
+ );
158
+
159
+ // Events cross bounded contexts
160
+ class OrderShipped {
161
+ constructor(
162
+ public readonly orderId: string,
163
+ public readonly shippingAddress: Address,
164
+ public readonly trackingNumber: string,
165
+ public readonly occurredAt: Date
166
+ ) {}
167
+ }
168
+ ```
169
+
170
+ **Event-Driven Workflows:**
171
+ ```typescript
172
+ // Order context publishes OrderPlaced
173
+ // Inventory context listens and consumes
174
+ class InventoryService {
175
+ async handleOrderPlaced(event: OrderPlaced): Promise<Result<void>> {
176
+ // Reserve inventory in response to order
177
+ const result = await this.inventoryRepo.reserve(event.orderId);
178
+ if (!result.ok) {
179
+ // Handle reservation failure
180
+ await this.eventBus.publish(new InventoryReservationFailed(event.orderId));
181
+ }
182
+ return result;
183
+ }
184
+ }
185
+ ```
186
+
187
+ ## Bounded Contexts
188
+
189
+ **Definition:** Explicit boundaries where a domain model applies
190
+
191
+ **Guidelines:**
192
+ - Each context has its own ubiquitous language
193
+ - Contexts communicate via well-defined contracts
194
+ - Same concept may have different models in different contexts
195
+ - Example: "Customer" in Sales context vs "User" in Auth context
196
+
197
+ **Context Composition:**
198
+ ```
199
+ Bounded Context: "Orders"
200
+ ┌────────────────────────────────────────────────────────────────┐
201
+ │ │
202
+ │ Effectful Edge Functional Core │
203
+ │ ┌──────────────────┐ ┌──────────────────┐ │
204
+ │ │ Router │────────────▶│ Service │ │
205
+ │ │ POST /orders │ │ OrderService │ │
206
+ │ └──────────────────┘ └────────┬─────────┘ │
207
+ │ │ │
208
+ │ ┌──────────────────┐ ┌────────▼─────────┐ │
209
+ │ │ Repository │◀────────────│ Aggregate │ │
210
+ │ │ OrderRepository │ │ Order (root) │ │
211
+ │ └──────────────────┘ │ └─ OrderItem[] │ │
212
+ │ │ └─ Money (VO) │ │
213
+ │ ┌──────────────────┐ └──────────────────┘ │
214
+ │ │ Producer │◀── Domain Event: OrderPlaced │
215
+ │ └────────┬─────────┘ │
216
+ └────────────│───────────────────────────────────────────────────┘
217
+ │
218
+ ▼ Events cross context boundaries
219
+ ┌────────────────────────────────────────────────────────────────┐
220
+ │ Bounded Context: "Inventory" │
221
+ │ Consumer ──▶ InventoryService ──▶ StockLevel (Aggregate) │
222
+ └────────────────────────────────────────────────────────────────┘
223
+ ```
224
+
225
+ **Context Anti-Patterns:**
226
+ - Shared database (breaks boundary enforcement)
227
+ - Generic "core" or "common" domain (pollutes context boundaries)
228
+ - Cross-context validation (move validation to appropriate context)
229
+ - Tight coupling via shared types (use context-specific DTOs)
230
+
231
+ ## Composition Rules
232
+
233
+ | DDD Pattern | Maps To | Location |
234
+ |-------------|---------|----------|
235
+ | Bounded Context | Module/Package boundary | Contains all layers |
236
+ | Aggregate | Entity cluster | Functional Core |
237
+ | Aggregate Root | Primary Entity | Entity layer |
238
+ | Value Object | Immutable type | Entity layer |
239
+ | Domain Event | Event class | Published from Service, consumed by edge |
240
+ | Repository | Data access | Effectful Edge (interface in Core) |
241
+
242
+ **Key Interactions:**
243
+ 1. **Router → Service**: HTTP request parsed, passed to service
244
+ 2. **Service → Aggregate**: Service orchestrates aggregate operations
245
+ 3. **Aggregate → Repository**: Service uses repository to persist aggregate
246
+ 4. **Service → Producer**: Service publishes domain events after state change
247
+ 5. **Consumer → Service**: Events from other contexts trigger service operations
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: oracle-challenge
3
+ description: Challenge an approach with critical thinking. Use when questioning assumptions, validating decisions, testing approach validity, or preventing automatic agreement.
4
+ user-invocable: true
5
+ ---
6
+
7
+ # Challenge: Critical Thinking Prompt
8
+
9
+ ## Step 1: Parse Challenge Request
10
+
11
+ <strategist>
12
+ @agent-oracle
13
+
14
+ Analyze the challenge request: $ARGUMENTS
15
+
16
+ **Challenge Extraction:**
17
+ - **Core concern**: Extract the main doubt or question
18
+ - **Target approach**: Identify what is being challenged
19
+ - **Context**: Relevant background from current session
20
+ - **Specific aspects**: Particular elements to question
21
+
22
+ **Challenge Summary:**
23
+ You're challenging: [identified approach]
24
+ Because: [extracted concern]
25
+ In context of: [session context]
26
+ </strategist>
27
+
28
+ ## Step 2: Set Up Critical Thinking Framework
29
+
30
+ <framework>
31
+ **What to Question:**
32
+ - **Underlying assumptions**: What beliefs support this approach?
33
+ - **Evidence base**: What data or experience validates it?
34
+ - **Context fit**: How well does it work in your specific situation?
35
+ - **Alternatives considered**: What other options were explored?
36
+ - **Risk factors**: What could go wrong with this approach?
37
+
38
+ **Critical Thinking Prompts:**
39
+ - Is this approach solving the right problem?
40
+ - Are the underlying assumptions still valid?
41
+ - What evidence contradicts this direction?
42
+ - How does this fit with your constraints and goals?
43
+ - What are the opportunity costs?
44
+ </framework>
45
+
46
+ ## Step 3: Sequential Thinking Analysis
47
+
48
+ <strategist>
49
+ @agent-oracle
50
+
51
+ Use sequential thinking (mcp__sequential-thinking__sequentialthinking) to analyze this challenge:
52
+
53
+ **Thought 1**: Question the fundamental assumptions
54
+ **Thought 2**: Examine contradictory evidence
55
+ **Thought 3**: Explore alternative approaches
56
+ **Thought 4**: Assess context-specific fit
57
+ **Thought 5**: Evaluate risks and trade-offs
58
+ **Thought 6**: Synthesize findings into recommendation
59
+
60
+ Build systematically through evidence, alternatives, and risks.
61
+ Continue until you reach a clear conclusion.
62
+ </strategist>
63
+
64
+ ## Step 4: Critical Evaluation Output
65
+
66
+ **Self-Critique Questions:**
67
+ - Does the analysis address the user's specific context?
68
+ - Are the recommendations practical and implementable?
69
+ - Have we considered the most important constraints?
70
+ - Are there any blind spots or missing perspectives?
71
+
72
+ **Final Synthesis:**
73
+ - **Assumption validity**: Are the underlying assumptions sound?
74
+ - **Evidence assessment**: Does evidence support or contradict?
75
+ - **Alternative recommendation**: If current approach is problematic, what instead?
76
+ - **Risk mitigation**: How to address identified concerns?
77
+
78
+ ---
79
+
80
+ ## Usage Examples
81
+
82
+ **Challenge Technical Decisions:**
83
+ ```
84
+ /atelier-challenge "Do we really need a microservices architecture for this simple app?"
85
+ ```
86
+
87
+ **Challenge Implementation Approach:**
88
+ ```
89
+ /atelier-challenge "I think this caching strategy will actually slow things down"
90
+ ```
91
+
92
+ **Challenge Requirements:**
93
+ ```
94
+ /atelier-challenge "Are we solving the right problem with this feature?"
95
+ ```
96
+
97
+ **Challenge Architectural Patterns:**
98
+ ```
99
+ /atelier-challenge "Should we really use event sourcing for this use case?"
100
+ ```
101
+
102
+ ## When to Use Challenge
103
+
104
+ **Before Major Decisions:**
105
+ - Architecture choices
106
+ - Technology stack decisions
107
+ - Design pattern selection
108
+ - Implementation approach
109
+
110
+ **When Something Feels Off:**
111
+ - "This seems overly complex"
112
+ - "I'm not sure this solves the real problem"
113
+ - "This approach feels wrong"
114
+ - "Are we over-engineering this?"
115
+
116
+ **To Prevent Automatic Agreement:**
117
+ - When you want genuine critical evaluation
118
+ - When you need to challenge conventional wisdom
119
+ - When you want to test your own assumptions
120
+
121
+ ## Challenge vs ThinkDeep
122
+
123
+ **Use /atelier-challenge**: Question assumptions, test validity, assess risks, prevent automatic agreement
124
+ **Use /atelier-thinkdeep**: Deep exploration, comprehensive analysis, alternative discovery, complex decisions
125
+
126
+ **Key distinction**: Challenge = critical evaluation, ThinkDeep = deep exploration