@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,322 @@
1
+ # Stub-Driven TDD Workflow
2
+
3
+ Complete workflow examples showing the Stub → Test → Implement → Refactor pattern.
4
+
5
+ ## The Four-Step Pattern
6
+
7
+ ```
8
+ 1. Stub → Create minimal interface/function signatures
9
+ 2. Test → Write tests against stubs
10
+ 3. Implement → Make tests pass with real implementation
11
+ 4. Refactor → Improve code while keeping tests green
12
+ ```
13
+
14
+ ## Why Stub-Driven?
15
+
16
+ **Traditional TDD problem:** Can't write tests until implementation exists
17
+
18
+ **Stub-Driven solution:** Write interface/type signatures first, test against those, then implement
19
+
20
+ **Benefits:**
21
+ - Tests define behavior before implementation
22
+ - Interfaces emerge from use cases, not speculation
23
+ - Refactoring is safe (tests validate behavior)
24
+ - Fast feedback loop (stub → test → implement)
25
+
26
+ ## Complete Order Service Example
27
+
28
+ ### Step 1: Stub
29
+
30
+ Define the interface and service class with stub methods:
31
+
32
+ ```typescript
33
+ // Define repository interface from use case
34
+ interface OrderRepository {
35
+ save(order: OrderRecord): Promise<OrderRecord>;
36
+ findById(id: string): Promise<OrderRecord | null>;
37
+ delete(id: string): Promise<void>;
38
+ }
39
+
40
+ // Service uses stub - methods throw NotImplemented
41
+ class OrderService {
42
+ constructor(private repo: OrderRepository) {}
43
+
44
+ async createOrder(request: CreateOrderRequest): Promise<Result<Order>> {
45
+ throw new Error('Not implemented');
46
+ }
47
+
48
+ async cancelOrder(id: string): Promise<Result<void>> {
49
+ throw new Error('Not implemented');
50
+ }
51
+
52
+ async getOrder(id: string): Promise<Result<Order>> {
53
+ throw new Error('Not implemented');
54
+ }
55
+ }
56
+
57
+ // Export for testing
58
+ export { OrderService, OrderRepository };
59
+ ```
60
+
61
+ ### Step 2: Test
62
+
63
+ Write comprehensive tests against the stubs:
64
+
65
+ ```typescript
66
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
67
+ import { OrderService, OrderRepository } from './order-service';
68
+ import { CreateOrderRequest, OrderRecord, Order } from './order';
69
+ import { Ok, Err } from './result';
70
+
71
+ describe('OrderService', () => {
72
+ let service: OrderService;
73
+ let mockRepo: OrderRepository;
74
+
75
+ beforeEach(() => {
76
+ // Create stub implementation
77
+ mockRepo = {
78
+ save: vi.fn(),
79
+ findById: vi.fn(),
80
+ delete: vi.fn()
81
+ };
82
+ service = new OrderService(mockRepo);
83
+ });
84
+
85
+ describe('createOrder', () => {
86
+ it('should save valid order', async () => {
87
+ mockRepo.save.mockResolvedValue({
88
+ id: '123',
89
+ customer_id: 'C1',
90
+ items: '[]',
91
+ status: 'pending',
92
+ total: 0
93
+ });
94
+
95
+ const result = await service.createOrder({
96
+ customerId: 'C1',
97
+ items: [{ productId: 'P1', quantity: 2, price: 10 }]
98
+ });
99
+
100
+ expect(result.ok).toBe(true);
101
+ expect(mockRepo.save).toHaveBeenCalledWith(
102
+ expect.objectContaining({
103
+ customer_id: 'C1',
104
+ status: 'pending'
105
+ })
106
+ );
107
+ });
108
+
109
+ it('should validate order before saving', async () => {
110
+ const result = await service.createOrder({
111
+ customerId: 'C1',
112
+ items: [] // Invalid: empty items
113
+ });
114
+
115
+ expect(result.ok).toBe(false);
116
+ expect(mockRepo.save).not.toHaveBeenCalled();
117
+ });
118
+
119
+ it('should calculate total correctly', async () => {
120
+ mockRepo.save.mockResolvedValue({
121
+ id: '123',
122
+ customer_id: 'C1',
123
+ items: '[]',
124
+ status: 'pending',
125
+ total: 0
126
+ });
127
+
128
+ await service.createOrder({
129
+ customerId: 'C1',
130
+ items: [
131
+ { productId: 'P1', quantity: 2, price: 10 },
132
+ { productId: 'P2', quantity: 1, price: 15 }
133
+ ]
134
+ });
135
+
136
+ expect(mockRepo.save).toHaveBeenCalledWith(
137
+ expect.objectContaining({ total: 35 })
138
+ );
139
+ });
140
+ });
141
+
142
+ describe('cancelOrder', () => {
143
+ it('should cancel pending order', async () => {
144
+ mockRepo.findById.mockResolvedValue({
145
+ id: '123',
146
+ customer_id: 'C1',
147
+ items: '[]',
148
+ status: 'pending',
149
+ total: 0
150
+ });
151
+ mockRepo.delete.mockResolvedValue(undefined);
152
+
153
+ const result = await service.cancelOrder('123');
154
+
155
+ expect(result.ok).toBe(true);
156
+ expect(mockRepo.delete).toHaveBeenCalledWith('123');
157
+ });
158
+
159
+ it('should reject canceling shipped order', async () => {
160
+ mockRepo.findById.mockResolvedValue({
161
+ id: '123',
162
+ customer_id: 'C1',
163
+ items: '[]',
164
+ status: 'shipped',
165
+ total: 0
166
+ });
167
+
168
+ const result = await service.cancelOrder('123');
169
+
170
+ expect(result.ok).toBe(false);
171
+ expect(mockRepo.delete).not.toHaveBeenCalled();
172
+ });
173
+
174
+ it('should reject canceling non-existent order', async () => {
175
+ mockRepo.findById.mockResolvedValue(null);
176
+
177
+ const result = await service.cancelOrder('999');
178
+
179
+ expect(result.ok).toBe(false);
180
+ });
181
+ });
182
+
183
+ describe('getOrder', () => {
184
+ it('should retrieve order by id', async () => {
185
+ mockRepo.findById.mockResolvedValue({
186
+ id: '123',
187
+ customer_id: 'C1',
188
+ items: '[]',
189
+ status: 'pending',
190
+ total: 0
191
+ });
192
+
193
+ const result = await service.getOrder('123');
194
+
195
+ expect(result.ok).toBe(true);
196
+ if (result.ok) {
197
+ expect(result.value.id).toBe('123');
198
+ }
199
+ });
200
+
201
+ it('should return error for non-existent order', async () => {
202
+ mockRepo.findById.mockResolvedValue(null);
203
+
204
+ const result = await service.getOrder('999');
205
+
206
+ expect(result.ok).toBe(false);
207
+ });
208
+ });
209
+ });
210
+ ```
211
+
212
+ ### Step 3: Implement
213
+
214
+ Make tests pass with real implementation:
215
+
216
+ ```typescript
217
+ class OrderService {
218
+ constructor(private repo: OrderRepository) {}
219
+
220
+ async createOrder(request: CreateOrderRequest): Promise<Result<Order>> {
221
+ // Transform request to entity
222
+ const order = Order.fromRequest(request);
223
+
224
+ // Validate
225
+ const validation = order.validate();
226
+ if (!validation.ok) return validation;
227
+
228
+ // Save to repository
229
+ const record = order.toRecord();
230
+ const saved = await this.repo.save(record);
231
+
232
+ // Transform back to entity
233
+ return Ok(Order.fromRecord(saved));
234
+ }
235
+
236
+ async cancelOrder(id: string): Promise<Result<void>> {
237
+ // Find order
238
+ const record = await this.repo.findById(id);
239
+ if (!record) return Err('Order not found');
240
+
241
+ // Transform to entity
242
+ const order = Order.fromRecord(record);
243
+
244
+ // Check business rule
245
+ if (!order.canCancel()) {
246
+ return Err(`Cannot cancel ${order.status} order`);
247
+ }
248
+
249
+ // Delete
250
+ await this.repo.delete(id);
251
+ return Ok(undefined);
252
+ }
253
+
254
+ async getOrder(id: string): Promise<Result<Order>> {
255
+ // Find order
256
+ const record = await this.repo.findById(id);
257
+ if (!record) return Err('Order not found');
258
+
259
+ // Transform to entity
260
+ return Ok(Order.fromRecord(record));
261
+ }
262
+ }
263
+ ```
264
+
265
+ ### Step 4: Refactor
266
+
267
+ Improve code while keeping tests green:
268
+
269
+ ```typescript
270
+ class OrderService {
271
+ constructor(private repo: OrderRepository) {}
272
+
273
+ async createOrder(request: CreateOrderRequest): Promise<Result<Order>> {
274
+ const order = Order.fromRequest(request);
275
+ return await this.validateAndSave(order);
276
+ }
277
+
278
+ async cancelOrder(id: string): Promise<Result<void>> {
279
+ const order = await this.findOrderOrError(id);
280
+ if (!order.ok) return order;
281
+
282
+ return await this.checkCancellableAndDelete(order.value);
283
+ }
284
+
285
+ async getOrder(id: string): Promise<Result<Order>> {
286
+ return await this.findOrderOrError(id);
287
+ }
288
+
289
+ private async validateAndSave(order: Order): Promise<Result<Order>> {
290
+ const validation = order.validate();
291
+ if (!validation.ok) return validation;
292
+
293
+ const record = order.toRecord();
294
+ const saved = await this.repo.save(record);
295
+ return Ok(Order.fromRecord(saved));
296
+ }
297
+
298
+ private async findOrderOrError(id: string): Promise<Result<Order>> {
299
+ const record = await this.repo.findById(id);
300
+ if (!record) return Err('Order not found');
301
+ return Ok(Order.fromRecord(record));
302
+ }
303
+
304
+ private async checkCancellableAndDelete(order: Order): Promise<Result<void>> {
305
+ if (!order.canCancel()) {
306
+ return Err(`Cannot cancel ${order.status} order`);
307
+ }
308
+ await this.repo.delete(order.id);
309
+ return Ok(undefined);
310
+ }
311
+ }
312
+ ```
313
+
314
+ All tests still pass after refactoring - behavior is unchanged, only implementation improved.
315
+
316
+ ## Key Takeaways
317
+
318
+ 1. **Start with stubs** - Define interfaces before implementation
319
+ 2. **Test against contracts** - Test the interface, not the implementation
320
+ 3. **Implement once tests are clear** - Make tests pass with real code
321
+ 4. **Refactor with confidence** - Tests validate behavior doesn't change
322
+ 5. **Keep feedback loop fast** - Each step is quick and focused
@@ -0,0 +1,164 @@
1
+ ---
2
+ name: oracle-thinkdeep
3
+ description: Extended reasoning analysis using sequential thinking. Use for deep exploration, comprehensive analysis, complex decisions, or when you need fresh perspectives on difficult problems.
4
+ user-invocable: true
5
+ ---
6
+
7
+ # ThinkDeep: Extended Reasoning Analysis
8
+
9
+ ## Step 1: Parse Request Parameters
10
+
11
+ <strategist>
12
+ @agent-oracle
13
+
14
+ Analyze the thinkdeep request: $ARGUMENTS
15
+
16
+ **Parameter Extraction:**
17
+ - **Main prompt**: [extract core thinking request]
18
+ - **Focus areas**: [extract "architecture, performance, security" etc]
19
+ - **File references**: [extract "reference to file.py" patterns]
20
+ - **Problem context**: [extract additional context provided]
21
+
22
+ **Parsed Configuration:**
23
+ - Prompt: [core request]
24
+ - Focus areas: [identified areas]
25
+ - File references: [any files mentioned]
26
+ - Problem context: [additional context]
27
+ </strategist>
28
+
29
+ ## Step 2: Deep Sequential Analysis
30
+
31
+ <strategist>
32
+ @agent-oracle
33
+
34
+ Use sequential thinking (mcp__sequential-thinking__sequentialthinking) for extended reasoning:
35
+
36
+ ### Thought 1: Context Understanding
37
+ Analyze the current session context to understand:
38
+ - What has been discussed so far
39
+ - Previous decisions and analyses made
40
+ - User's specific constraints and goals
41
+ - Existing solutions or approaches tried
42
+
43
+ ### Thought 2: Problem Decomposition
44
+ Break down the core issue into:
45
+ - Primary problem statement
46
+ - Key sub-problems or components
47
+ - Underlying assumptions and constraints
48
+ - Success criteria and desired outcomes
49
+
50
+ ### Thought 3: Assumption Challenge
51
+ Question the underlying assumptions:
52
+ - What assumptions are we making?
53
+ - Are these assumptions valid in this context?
54
+ - What if the opposite were true?
55
+ - Alternative perspectives to consider
56
+
57
+ ### Thought 4: Alternative Approaches Exploration
58
+ Explore different solution paths:
59
+ - Conventional approaches and their pros/cons
60
+ - Unconventional or innovative solutions
61
+ - Trade-offs between different options
62
+ - Hybrid or combined approaches
63
+
64
+ ### Thought 5: Context Integration
65
+ Incorporate relevant context:
66
+ - File references and code patterns
67
+ - Previous session insights
68
+ - User's specific technical stack
69
+ - Business or project constraints
70
+
71
+ ### Thought 6: Edge Case Analysis
72
+ Identify potential issues:
73
+ - What could go wrong with each approach?
74
+ - Edge cases and failure modes
75
+ - Scalability and performance concerns
76
+ - Security and maintenance implications
77
+
78
+ ### Thought 7: Risk Assessment
79
+ Evaluate risks for each option:
80
+ - Implementation complexity
81
+ - Technical debt potential
82
+ - Team skill requirements
83
+ - Timeline and resource impacts
84
+
85
+ ### Thought 8: Solution Synthesis
86
+ Combine insights into recommendations:
87
+ - Primary recommended approach
88
+ - Backup or alternative options
89
+ - Implementation considerations
90
+ - Next steps and validation points
91
+
92
+ Continue sequential thinking until satisfaction, using:
93
+ - `isRevision: true` to refine previous thoughts
94
+ - `branchFromThought` to explore alternative reasoning paths
95
+ - `needsMoreThoughts: true` to extend analysis if needed
96
+ </strategist>
97
+
98
+ ## Step 3: Critical Evaluation & Synthesis
99
+
100
+ **Self-Critique Questions:**
101
+ - Does the analysis address the user's specific context?
102
+ - Are the recommendations practical and implementable?
103
+ - Have we considered the most important constraints?
104
+ - Are there any blind spots or missing perspectives?
105
+
106
+ **Contextual Validation:**
107
+ - Fit with user's technical stack and preferences
108
+ - Alignment with previous decisions in session
109
+ - Practicality given team skills and resources
110
+ - Integration with existing systems or patterns
111
+
112
+ **Final Synthesis:**
113
+ - **Primary Recommendation**: [best approach with rationale]
114
+ - **Alternative Options**: [backup plans with trade-offs]
115
+ - **Implementation Guidance**: [key considerations and next steps]
116
+ - **Risk Mitigation**: [how to address identified concerns]
117
+
118
+ ---
119
+
120
+ ## Usage Examples
121
+
122
+ **Basic deep analysis:**
123
+ ```
124
+ /atelier-thinkdeep "Analyze my authentication architecture"
125
+ ```
126
+
127
+ **With file references:**
128
+ ```
129
+ /atelier-thinkdeep "Evaluate my database schema with reference to models/user.py"
130
+ ```
131
+
132
+ **With focus areas:**
133
+ ```
134
+ /atelier-thinkdeep "Assess my microservices design focusing on performance and security"
135
+ ```
136
+
137
+ **Complex architectural decisions:**
138
+ ```
139
+ /atelier-thinkdeep "Should I use GraphQL or REST for my API considering team skills and scalability needs"
140
+ ```
141
+
142
+ ## When to Use ThinkDeep
143
+
144
+ - **Architecture decisions**: When choosing between major design approaches
145
+ - **Complex problem solving**: Multi-faceted issues requiring deep analysis
146
+ - **Assumption validation**: Challenging conventional wisdom or previous decisions
147
+ - **Alternative exploration**: When stuck and need fresh perspectives
148
+ - **Risk assessment**: Before major implementation decisions
149
+
150
+ ## ThinkDeep vs Challenge
151
+
152
+ **Use /atelier-thinkdeep**: Deep exploration, comprehensive analysis, alternative discovery, complex decisions
153
+ **Use /atelier-challenge**: Question assumptions, test validity, assess risks, prevent automatic agreement
154
+
155
+ **Key distinction**: ThinkDeep = deep exploration, Challenge = critical evaluation
156
+
157
+ ## Expected Outcomes
158
+
159
+ After using this command:
160
+ - Comprehensive understanding of the problem space
161
+ - Multiple approaches evaluated with trade-offs
162
+ - Clear recommendation with solid reasoning
163
+ - Risk assessment and mitigation strategies
164
+ - Actionable next steps for implementation
@@ -0,0 +1,148 @@
1
+ ---
2
+ name: python-architecture
3
+ description: Python application architecture with functional core, effectful shell, DDD, and data modeling. Use when designing application layers, separating pure business logic from IO, defining domain models, implementing validation, or structuring bounded contexts.
4
+ user-invocable: false
5
+ ---
6
+
7
+ # Python Application Architecture
8
+
9
+ Modern Python application architecture following functional core / imperative shell pattern, Domain-Driven Design, and type-safe data modeling.
10
+
11
+ ## Core Principle: Functional Core / Imperative Shell
12
+
13
+ Separate pure business logic from side effects:
14
+
15
+ - **Functional Core**: Pure functions, business logic, no IO
16
+ - **Imperative Shell**: Coordinates external dependencies, handles side effects
17
+
18
+ See [references/functional-core.md](references/functional-core.md) for detailed patterns and examples.
19
+
20
+ ## Layered Architecture
21
+
22
+ Follow bottom-up dependency flow:
23
+
24
+ ```
25
+ Router/Handler → Service → Repository → Entity → Database
26
+ ```
27
+
28
+ Each layer depends only on layers below.
29
+
30
+ **Responsibilities:**
31
+ - **Entity**: Domain models, validation, business rules, data transformations (fromRequest, toRecord, toResponse)
32
+ - **Repository**: Abstract storage interface, returns domain entities
33
+ - **Service**: Business workflows, orchestrates entities and repositories
34
+ - **Router/Handler**: HTTP handling, delegates to services
35
+
36
+ ## Domain Models
37
+
38
+ ### Entity Example
39
+
40
+ ```python
41
+ from dataclasses import dataclass
42
+ from uuid import UUID
43
+ from decimal import Decimal
44
+
45
+ @dataclass
46
+ class Order:
47
+ """Entity - has identity and encapsulated behavior"""
48
+ id: UUID
49
+ customer_id: UUID
50
+ total: Decimal
51
+ status: str
52
+
53
+ def apply_discount(self, rate: Decimal) -> None:
54
+ """Business rule - encapsulated in entity"""
55
+ if self.status == "pending":
56
+ self.total = self.total * (1 - rate)
57
+
58
+ @classmethod
59
+ def from_request(cls, req, customer_id: UUID) -> "Order":
60
+ """Transform API request → entity"""
61
+ return cls(id=uuid4(), customer_id=customer_id, total=Decimal("0"), status="pending")
62
+
63
+ def to_response(self):
64
+ """Transform entity → API response"""
65
+ return {"id": self.id, "total": self.total, "status": self.status}
66
+ ```
67
+
68
+ ### Value Object Example
69
+
70
+ ```python
71
+ from dataclasses import dataclass
72
+
73
+ @dataclass(frozen=True)
74
+ class Money:
75
+ """Value object - immutable, no identity"""
76
+ amount: Decimal
77
+ currency: str
78
+
79
+ def add(self, other: "Money") -> "Money":
80
+ if self.currency != other.currency:
81
+ raise ValueError("Cannot add different currencies")
82
+ return Money(self.amount + other.amount, self.currency)
83
+ ```
84
+
85
+ See [references/ddd.md](references/ddd.md) for aggregates, bounded contexts, and domain services.
86
+
87
+ ## Repository Pattern
88
+
89
+ Abstract storage behind interface:
90
+
91
+ ```python
92
+ from abc import ABC, abstractmethod
93
+ from typing import Optional
94
+
95
+ class OrderRepository(ABC):
96
+ """Abstract repository - interface only"""
97
+
98
+ @abstractmethod
99
+ def get(self, order_id: UUID) -> Optional[Order]:
100
+ pass
101
+
102
+ @abstractmethod
103
+ def save(self, order: Order) -> None:
104
+ pass
105
+
106
+ class PostgresOrderRepository(OrderRepository):
107
+ """Concrete implementation"""
108
+
109
+ def get(self, order_id: UUID) -> Optional[Order]:
110
+ record = self.session.get(OrderRecord, order_id)
111
+ return Order.from_record(record) if record else None
112
+
113
+ def save(self, order: Order) -> None:
114
+ record = order.to_record()
115
+ self.session.merge(record)
116
+ self.session.commit()
117
+ ```
118
+
119
+ ## Data Modeling
120
+
121
+ - **dataclasses**: Domain models and internal logic (lightweight, standard library)
122
+ - **Pydantic**: API boundaries (validation, JSON schema, OpenAPI)
123
+ - **Entity transformations**: `from_request()`, `to_response()`, `from_record()`, `to_record()`
124
+
125
+ See [references/data-modeling.md](references/data-modeling.md) for validation patterns, Pydantic features, and transformation examples.
126
+
127
+ ## Best Practices
128
+
129
+ 1. **Pure functions first** - Write business logic without IO dependencies
130
+ 2. **Entity encapsulation** - Keep business rules inside entities
131
+ 3. **Repository abstraction** - Hide storage details, work with domain entities
132
+ 4. **Validate at boundaries** - Use Pydantic at API edges, simple validation in entities
133
+ 5. **Immutable value objects** - Always use `frozen=True`
134
+ 6. **Single Responsibility** - Each layer has one reason to change
135
+ 7. **Dependency direction** - Always depend on abstractions, not implementations
136
+
137
+ ## Anti-Patterns
138
+
139
+ ❌ **Anemic Domain Model** - Entities with only getters/setters, all logic in services
140
+ ❌ **Transaction Script** - All logic in service layer, entities just data
141
+ ❌ **Leaky Abstraction** - Repository exposing database details
142
+ ❌ **God Object** - Entity with too many responsibilities
143
+ ❌ **Mixed Concerns** - Business logic calling IO directly
144
+
145
+ For detailed examples, patterns, and decision trees, see the reference materials:
146
+ - [references/functional-core.md](references/functional-core.md) - Core vs shell separation
147
+ - [references/ddd.md](references/ddd.md) - DDD patterns, aggregates, bounded contexts
148
+ - [references/data-modeling.md](references/data-modeling.md) - dataclasses, Pydantic, transformations