@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,392 @@
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`)