@martinffx/atelier 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +94 -253
  3. package/package.json +1 -1
  4. package/skills/{spec-orchestrator → atelier-orchestrator}/SKILL.md +3 -3
  5. package/skills/atelier-setup/SKILL.md +80 -0
  6. package/skills/code-review/references/reviewers.md +3 -3
  7. package/skills/code-review/references/rq.md +6 -6
  8. package/skills/spec-brainstorm/SKILL.md +5 -5
  9. package/skills/spec-implement/SKILL.md +2 -3
  10. package/skills/spec-plan/SKILL.md +21 -29
  11. package/skills/spec-plan/references/plan_template.md +77 -0
  12. package/skills/python-architecture/SKILL.md +0 -148
  13. package/skills/python-architecture/references/data-modeling.md +0 -558
  14. package/skills/python-architecture/references/ddd.md +0 -569
  15. package/skills/python-architecture/references/functional-core.md +0 -337
  16. package/skills/python-build-tools/SKILL.md +0 -153
  17. package/skills/python-build-tools/references/basedpyright.md +0 -321
  18. package/skills/python-build-tools/references/ruff.md +0 -225
  19. package/skills/python-build-tools/references/uv.md +0 -257
  20. package/skills/python-fastapi/SKILL.md +0 -184
  21. package/skills/python-fastapi/references/api-design.md +0 -563
  22. package/skills/python-fastapi/references/dependencies.md +0 -479
  23. package/skills/python-fastapi/references/middleware.md +0 -475
  24. package/skills/python-fastapi/references/validation.md +0 -497
  25. package/skills/python-modern-python/SKILL.md +0 -201
  26. package/skills/python-modern-python/references/async.md +0 -76
  27. package/skills/python-modern-python/references/pattern-matching.md +0 -89
  28. package/skills/python-modern-python/references/typing.md +0 -96
  29. package/skills/python-monorepo/SKILL.md +0 -146
  30. package/skills/python-monorepo/references/docker.md +0 -515
  31. package/skills/python-monorepo/references/namespace-packages.md +0 -426
  32. package/skills/python-monorepo/references/workspace-config.md +0 -341
  33. package/skills/python-sqlalchemy/SKILL.md +0 -119
  34. package/skills/python-sqlalchemy/references/async.md +0 -51
  35. package/skills/python-sqlalchemy/references/models.md +0 -67
  36. package/skills/python-sqlalchemy/references/queries.md +0 -57
  37. package/skills/python-temporal/SKILL.md +0 -128
  38. package/skills/python-temporal/references/patterns.md +0 -87
  39. package/skills/python-temporal/references/testing.md +0 -54
  40. package/skills/python-testing/SKILL.md +0 -161
  41. package/skills/python-testing/references/boundaries.md +0 -449
  42. package/skills/python-testing/references/mocking.md +0 -449
  43. package/skills/python-testing/references/pytest.md +0 -524
  44. package/skills/typescript-api-design/SKILL.md +0 -396
  45. package/skills/typescript-api-design/references/error-responses.md +0 -469
  46. package/skills/typescript-build-tools/SKILL.md +0 -447
  47. package/skills/typescript-build-tools/references/biome.md +0 -436
  48. package/skills/typescript-build-tools/references/bun.md +0 -432
  49. package/skills/typescript-build-tools/references/turborepo.md +0 -426
  50. package/skills/typescript-build-tools/references/vitest.md +0 -518
  51. package/skills/typescript-drizzle-orm/SKILL.md +0 -398
  52. package/skills/typescript-drizzle-orm/references/cloudflare.md +0 -392
  53. package/skills/typescript-drizzle-orm/references/entity-pattern.md +0 -412
  54. package/skills/typescript-drizzle-orm/references/postgresql.md +0 -191
  55. package/skills/typescript-drizzle-orm/references/repository-pattern.md +0 -479
  56. package/skills/typescript-drizzle-orm/references/sqlite.md +0 -291
  57. package/skills/typescript-dynamodb-toolbox/SKILL.md +0 -370
  58. package/skills/typescript-dynamodb-toolbox/references/entity-layer.md +0 -574
  59. package/skills/typescript-dynamodb-toolbox/references/error-handling.md +0 -495
  60. package/skills/typescript-dynamodb-toolbox/references/modeling.md +0 -332
  61. package/skills/typescript-dynamodb-toolbox/references/repository-layer.md +0 -631
  62. package/skills/typescript-dynamodb-toolbox/references/testing.md +0 -718
  63. package/skills/typescript-dynamodb-toolbox/references/transactions.md +0 -423
  64. package/skills/typescript-effect-ts/SKILL.md +0 -341
  65. package/skills/typescript-effect-ts/references/core.md +0 -412
  66. package/skills/typescript-effect-ts/references/error-handling.md +0 -468
  67. package/skills/typescript-effect-ts/references/resources.md +0 -476
  68. package/skills/typescript-effect-ts/references/schema.md +0 -536
  69. package/skills/typescript-effect-ts/references/services.md +0 -461
  70. package/skills/typescript-fastify/SKILL.md +0 -405
  71. package/skills/typescript-fastify/references/plugins.md +0 -329
  72. package/skills/typescript-fastify/references/typeid.md +0 -315
  73. package/skills/typescript-functional-patterns/SKILL.md +0 -402
  74. package/skills/typescript-functional-patterns/references/adts.md +0 -497
  75. package/skills/typescript-functional-patterns/references/branded-types.md +0 -542
  76. package/skills/typescript-functional-patterns/references/migration-guide.md +0 -695
  77. package/skills/typescript-functional-patterns/references/option-result.md +0 -585
  78. package/skills/typescript-testing/SKILL.md +0 -353
  79. package/skills/typescript-testing/references/mocking.md +0 -675
  80. package/skills/typescript-testing/references/msw.md +0 -852
  81. package/skills/typescript-testing/references/snapshot-testing.md +0 -774
@@ -1,392 +0,0 @@
1
- # Cloudflare Patterns with Drizzle ORM
2
-
3
- Drizzle ORM patterns for Cloudflare D1 and Durable Objects SQLite storage.
4
-
5
- ## Cloudflare D1
6
-
7
- D1 is Cloudflare's managed SQLite database service. Use it for shared data accessed by multiple Workers.
8
-
9
- ### D1 Connection
10
-
11
- ```typescript
12
- import { drizzle } from 'drizzle-orm/d1'
13
- import * as schema from './schema'
14
-
15
- export interface Env {
16
- DB: D1Database
17
- }
18
-
19
- export default {
20
- async fetch(request: Request, env: Env) {
21
- const db = drizzle(env.DB, { schema })
22
-
23
- // Use db for queries
24
- const users = await db.query.users.findMany()
25
-
26
- return Response.json(users)
27
- },
28
- }
29
- ```
30
-
31
- ### D1 Binding Configuration
32
-
33
- ```jsonc
34
- // wrangler.jsonc
35
- {
36
- "$schema": "./node_modules/wrangler/config-schema.json",
37
- "name": "my-worker",
38
- "main": "./src/index.ts",
39
- "compatibility_date": "2024-11-01",
40
- "d1_databases": [
41
- {
42
- "binding": "DB",
43
- "database_name": "my-database",
44
- "database_id": "xxxx-xxxx-xxxx-xxxx"
45
- }
46
- ]
47
- }
48
- ```
49
-
50
- ### D1 Migrations Configuration
51
-
52
- ```typescript
53
- // drizzle.config.ts
54
- import { defineConfig } from 'drizzle-kit'
55
-
56
- export default defineConfig({
57
- schema: './src/db/schema.ts',
58
- out: './drizzle',
59
- dialect: 'sqlite',
60
- driver: 'd1-http',
61
- dbCredentials: {
62
- accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
63
- databaseId: process.env.CLOUDFLARE_DATABASE_ID!,
64
- token: process.env.CLOUDFLARE_D1_TOKEN!,
65
- },
66
- })
67
- ```
68
-
69
- ### Running D1 Migrations
70
-
71
- ```bash
72
- # Generate migration SQL files
73
- npx drizzle-kit generate
74
-
75
- # Apply migrations via wrangler
76
- npx wrangler d1 migrations apply <DATABASE_NAME>
77
-
78
- # Or apply specific migration
79
- npx wrangler d1 execute <DATABASE_NAME> --file=./drizzle/0001_migration.sql
80
- ```
81
-
82
- ### Local D1 Development
83
-
84
- ```bash
85
- # Use --local flag for development
86
- npx wrangler dev --local
87
-
88
- # Create local D1 database
89
- npx wrangler d1 create <DATABASE_NAME> --local
90
-
91
- # Apply migrations locally
92
- npx wrangler d1 migrations apply <DATABASE_NAME> --local
93
- ```
94
-
95
- ## Durable Objects SQLite
96
-
97
- Durable Objects with SQLite provide per-object isolated storage. Each DO instance has its own SQLite database.
98
-
99
- ### DO Connection (from budget app)
100
-
101
- ```typescript
102
- import { DurableObject } from 'cloudflare:workers'
103
- import { drizzle } from 'drizzle-orm/durable-sqlite'
104
- import { migrate } from 'drizzle-orm/durable-sqlite/migrator'
105
- import * as schema from './schema'
106
- import migrations from '../drizzle/migrations'
107
-
108
- export interface Env {
109
- USER_LEDGER: DurableObjectNamespace<UserLedger>
110
- }
111
-
112
- export class UserLedger extends DurableObject {
113
- private readonly db: ReturnType<typeof drizzle>
114
-
115
- constructor(ctx: DurableObjectState, env: Env) {
116
- super(ctx, env)
117
-
118
- // Initialize Drizzle with DO storage
119
- this.db = drizzle(ctx.storage, { schema })
120
-
121
- // Run migrations on first instantiation
122
- ctx.blockConcurrencyWhile(async () => {
123
- migrate(this.db, migrations)
124
- })
125
- }
126
-
127
- async fetch(request: Request): Promise<Response> {
128
- // Use this.db for queries
129
- const users = await this.db.query.users.findMany()
130
- return Response.json(users)
131
- }
132
- }
133
- ```
134
-
135
- ### DO Binding Configuration
136
-
137
- ```jsonc
138
- // wrangler.jsonc
139
- {
140
- "$schema": "./node_modules/wrangler/config-schema.json",
141
- "name": "budget",
142
- "main": "./workers/app.ts",
143
- "compatibility_date": "2024-11-01",
144
- "durable_objects": {
145
- "bindings": [
146
- {
147
- "name": "USER_LEDGER",
148
- "class_name": "UserLedger"
149
- }
150
- ]
151
- },
152
- "migrations": [
153
- {
154
- "tag": "v1",
155
- "new_sqlite_classes": ["UserLedger"]
156
- }
157
- ]
158
- }
159
- ```
160
-
161
- ### DO Migrations Configuration
162
-
163
- ```typescript
164
- // drizzle.config.ts
165
- import { defineConfig } from 'drizzle-kit'
166
-
167
- export default defineConfig({
168
- schema: './app/repositories/schema.ts',
169
- out: './drizzle',
170
- dialect: 'sqlite',
171
- driver: 'durable-sqlite',
172
- })
173
- ```
174
-
175
- ### Running DO Migrations
176
-
177
- Migrations run automatically when the DO is first instantiated:
178
-
179
- ```typescript
180
- constructor(ctx: DurableObjectState, env: Env) {
181
- super(ctx, env)
182
- this.db = drizzle(ctx.storage, { schema })
183
-
184
- // Block concurrent requests during migration
185
- ctx.blockConcurrencyWhile(async () => {
186
- migrate(this.db, migrations)
187
- })
188
- }
189
- ```
190
-
191
- ### Importing Migrations
192
-
193
- ```typescript
194
- // drizzle/migrations.ts (auto-generated by drizzle-kit)
195
- export default [
196
- {
197
- sql: 'CREATE TABLE users ...',
198
- batchIdx: 0,
199
- },
200
- // ... more migrations
201
- ]
202
-
203
- // Import in DO
204
- import migrations from '../drizzle/migrations'
205
- migrate(this.db, migrations)
206
- ```
207
-
208
- ## Testing with Cloudflare Workers
209
-
210
- ### Testing D1
211
-
212
- Use `better-sqlite3` for local testing (see [sqlite.md](./sqlite.md)):
213
-
214
- ```typescript
215
- import Database from 'better-sqlite3'
216
- import { drizzle } from 'drizzle-orm/better-sqlite3'
217
- import * as schema from './schema'
218
-
219
- const sqlite = new Database(':memory:')
220
- const db = drizzle(sqlite, { schema })
221
- ```
222
-
223
- ### Testing Durable Objects (from budget app)
224
-
225
- Use `@cloudflare/vitest-pool-workers` to run tests inside actual DO instances:
226
-
227
- ```typescript
228
- // vitest.config.ts
229
- import { defineWorkersConfig } from '@cloudflare/vitest-pool-workers/config'
230
-
231
- export default defineWorkersConfig({
232
- test: {
233
- pool: '@cloudflare/vitest-pool-workers',
234
- poolOptions: {
235
- workers: {
236
- wrangler: { configPath: './wrangler.jsonc' },
237
- },
238
- },
239
- },
240
- })
241
- ```
242
-
243
- ```typescript
244
- // test/database.ts - Test helper
245
- import { env, runInDurableObject } from 'cloudflare:test'
246
- import { drizzle } from 'drizzle-orm/durable-sqlite'
247
- import * as schema from '~/repositories/schema'
248
-
249
- export async function runWithTestDB(
250
- fn: (db: ReturnType<typeof drizzle>) => Promise<void>
251
- ): Promise<void> {
252
- // Create a unique Durable Object instance for this test
253
- const id = env.USER_LEDGER.newUniqueId()
254
- const stub = env.USER_LEDGER.get(id)
255
-
256
- return await runInDurableObject(stub, async (_instance, state) => {
257
- const db = drizzle(state.storage, { schema })
258
- return fn(db)
259
- })
260
- }
261
- ```
262
-
263
- ```typescript
264
- // repository.test.ts
265
- import { test, expect } from 'vitest'
266
- import { runWithTestDB } from '../test/database'
267
- import { UserRepository } from './UserRepository'
268
-
269
- test('create user', async () => {
270
- await runWithTestDB(async (db) => {
271
- const repo = new UserRepository(db)
272
- const user = await repo.create({
273
- id: crypto.randomUUID(),
274
- name: 'Alice',
275
- email: 'alice@example.com',
276
- })
277
-
278
- expect(user.name).toBe('Alice')
279
- })
280
- })
281
- ```
282
-
283
- ### Key Testing Differences
284
-
285
- | Approach | D1 | Durable Objects |
286
- |----------|----|-----------------|
287
- | Test Driver | `better-sqlite3` (in-memory) | `@cloudflare/vitest-pool-workers` |
288
- | Test Environment | Node.js process | Miniflare DO instance |
289
- | Migration | Manual `migrate()` call | Automatic via DO constructor |
290
- | Isolation | Per-test database | Per-test DO instance |
291
-
292
- ## When to Use D1 vs Durable Objects
293
-
294
- ### Use D1 When:
295
-
296
- - **Shared database** - Multiple Workers access the same data
297
- - **Traditional patterns** - Standard REST API, CRUD operations
298
- - **External tooling** - Need HTTP API access for migrations/admin
299
- - **Familiar architecture** - Workers query database over network
300
- - **Simple deployment** - Don't want to manage per-user isolation
301
-
302
- ### Use Durable Objects SQLite When:
303
-
304
- - **Per-user isolation** - Each user has their own database
305
- - **Colocated compute+storage** - Business logic runs next to data
306
- - **Strong consistency** - Single-threaded execution guarantees
307
- - **Real-time coordination** - WebSocket connections, presence, sessions
308
- - **Stateful actors** - Per-entity business logic (e.g., game rooms, chat)
309
-
310
- ### Architecture Comparison
311
-
312
- **D1 Architecture:**
313
- ```
314
- Worker → (network) → D1 Database
315
- Worker → (network) → D1 Database
316
- Worker → (network) → D1 Database
317
- ```
318
-
319
- **Durable Objects Architecture:**
320
- ```
321
- Worker → DO Instance (compute + SQLite)
322
- Worker → DO Instance (compute + SQLite)
323
- Worker → DO Instance (compute + SQLite)
324
- ```
325
-
326
- ### Performance Considerations
327
-
328
- - **D1**: Network latency between Worker and database
329
- - Use Smart Placement to colocate Worker near D1
330
- - Good for read-heavy workloads
331
-
332
- - **DO**: Zero network latency (storage is local)
333
- - Single-threaded (one request at a time per DO)
334
- - Good for write-heavy, per-user workloads
335
-
336
- ### Pricing (as of 2024)
337
-
338
- **D1:**
339
- - Shared database across all requests
340
- - Billed per row read/written
341
- - Free tier: 5M row reads, 100K row writes/day
342
-
343
- **Durable Objects SQLite:**
344
- - Per-DO instance billing
345
- - Billed per SQL query + storage
346
- - Free tier: SQLite-backed DO only (no KV-backed)
347
-
348
- ## Migration Strategy
349
-
350
- If starting with D1 and need to migrate to DO SQLite:
351
-
352
- 1. Schema is the same (both use `sqlite-core`)
353
- 2. Change `drizzle-orm/d1` → `drizzle-orm/durable-sqlite`
354
- 3. Change connection from `env.DB` → `ctx.storage`
355
- 4. Add DO routing logic in Worker
356
- 5. Migrate data (custom script needed)
357
-
358
- ```typescript
359
- // Before (D1)
360
- const db = drizzle(env.DB, { schema })
361
-
362
- // After (DO)
363
- const db = drizzle(ctx.storage, { schema })
364
- ```
365
-
366
- ## Best Practices
367
-
368
- ### D1
369
-
370
- - Use connection pooling (handled by Workers runtime)
371
- - Batch queries when possible
372
- - Index frequently queried columns
373
- - Use prepared statements (automatic with Drizzle)
374
- - Monitor query performance via Cloudflare dashboard
375
-
376
- ### Durable Objects
377
-
378
- - Keep DO instances lightweight (single responsibility)
379
- - Use `blockConcurrencyWhile()` for initialization
380
- - Run migrations on first instantiation
381
- - Handle alarms for periodic cleanup
382
- - Design for single-threaded execution
383
- - Avoid long-running operations in constructor
384
-
385
- ### Both
386
-
387
- - Use transactions for multi-step operations
388
- - Define foreign keys for data integrity
389
- - Create indexes for query performance
390
- - Use type inference (`$inferSelect`, `$inferInsert`)
391
- - Follow repository pattern for data access
392
- - Test with actual CF runtime (`vitest-pool-workers` or `better-sqlite3`)