@martinffx/atelier 1.4.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 (93) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +95 -220
  3. package/agents/architect.md +6 -6
  4. package/agents/oracle.md +1 -1
  5. package/agents/{recon.md → sentinel.md} +3 -3
  6. package/dist/atelier.js +167 -26
  7. package/package.json +2 -1
  8. package/skills/atelier-orchestrator/SKILL.md +180 -0
  9. package/skills/atelier-setup/SKILL.md +80 -0
  10. package/skills/code-review/SKILL.md +2 -2
  11. package/skills/code-review/references/reviewers.md +3 -3
  12. package/skills/code-review/references/rq.md +9 -9
  13. package/skills/code-subagents/SKILL.md +44 -75
  14. package/skills/code-subagents/references/batch-reviewer-prompt.md +44 -0
  15. package/skills/code-subagents/references/implementor-prompt.md +10 -11
  16. package/skills/spec-brainstorm/SKILL.md +21 -16
  17. package/skills/spec-finish/SKILL.md +14 -14
  18. package/skills/spec-implement/SKILL.md +42 -42
  19. package/skills/spec-plan/SKILL.md +72 -26
  20. package/skills/spec-plan/references/plan_template.md +77 -0
  21. package/skills/code-subagents/references/code-quality-reviewer-prompt.md +0 -48
  22. package/skills/code-subagents/references/spec-reviewer-prompt.md +0 -62
  23. package/skills/python-architecture/SKILL.md +0 -148
  24. package/skills/python-architecture/references/data-modeling.md +0 -558
  25. package/skills/python-architecture/references/ddd.md +0 -569
  26. package/skills/python-architecture/references/functional-core.md +0 -337
  27. package/skills/python-build-tools/SKILL.md +0 -153
  28. package/skills/python-build-tools/references/basedpyright.md +0 -321
  29. package/skills/python-build-tools/references/ruff.md +0 -225
  30. package/skills/python-build-tools/references/uv.md +0 -257
  31. package/skills/python-fastapi/SKILL.md +0 -184
  32. package/skills/python-fastapi/references/api-design.md +0 -563
  33. package/skills/python-fastapi/references/dependencies.md +0 -479
  34. package/skills/python-fastapi/references/middleware.md +0 -475
  35. package/skills/python-fastapi/references/validation.md +0 -497
  36. package/skills/python-modern-python/SKILL.md +0 -201
  37. package/skills/python-modern-python/references/async.md +0 -76
  38. package/skills/python-modern-python/references/pattern-matching.md +0 -89
  39. package/skills/python-modern-python/references/typing.md +0 -96
  40. package/skills/python-monorepo/SKILL.md +0 -146
  41. package/skills/python-monorepo/references/docker.md +0 -515
  42. package/skills/python-monorepo/references/namespace-packages.md +0 -426
  43. package/skills/python-monorepo/references/workspace-config.md +0 -341
  44. package/skills/python-sqlalchemy/SKILL.md +0 -119
  45. package/skills/python-sqlalchemy/references/async.md +0 -51
  46. package/skills/python-sqlalchemy/references/models.md +0 -67
  47. package/skills/python-sqlalchemy/references/queries.md +0 -57
  48. package/skills/python-temporal/SKILL.md +0 -128
  49. package/skills/python-temporal/references/patterns.md +0 -87
  50. package/skills/python-temporal/references/testing.md +0 -54
  51. package/skills/python-testing/SKILL.md +0 -161
  52. package/skills/python-testing/references/boundaries.md +0 -449
  53. package/skills/python-testing/references/mocking.md +0 -449
  54. package/skills/python-testing/references/pytest.md +0 -524
  55. package/skills/spec-orchestrator/SKILL.md +0 -145
  56. package/skills/typescript-api-design/SKILL.md +0 -396
  57. package/skills/typescript-api-design/references/error-responses.md +0 -469
  58. package/skills/typescript-build-tools/SKILL.md +0 -447
  59. package/skills/typescript-build-tools/references/biome.md +0 -436
  60. package/skills/typescript-build-tools/references/bun.md +0 -432
  61. package/skills/typescript-build-tools/references/turborepo.md +0 -426
  62. package/skills/typescript-build-tools/references/vitest.md +0 -518
  63. package/skills/typescript-drizzle-orm/SKILL.md +0 -398
  64. package/skills/typescript-drizzle-orm/references/cloudflare.md +0 -392
  65. package/skills/typescript-drizzle-orm/references/entity-pattern.md +0 -412
  66. package/skills/typescript-drizzle-orm/references/postgresql.md +0 -191
  67. package/skills/typescript-drizzle-orm/references/repository-pattern.md +0 -479
  68. package/skills/typescript-drizzle-orm/references/sqlite.md +0 -291
  69. package/skills/typescript-dynamodb-toolbox/SKILL.md +0 -370
  70. package/skills/typescript-dynamodb-toolbox/references/entity-layer.md +0 -574
  71. package/skills/typescript-dynamodb-toolbox/references/error-handling.md +0 -495
  72. package/skills/typescript-dynamodb-toolbox/references/modeling.md +0 -332
  73. package/skills/typescript-dynamodb-toolbox/references/repository-layer.md +0 -631
  74. package/skills/typescript-dynamodb-toolbox/references/testing.md +0 -718
  75. package/skills/typescript-dynamodb-toolbox/references/transactions.md +0 -423
  76. package/skills/typescript-effect-ts/SKILL.md +0 -341
  77. package/skills/typescript-effect-ts/references/core.md +0 -412
  78. package/skills/typescript-effect-ts/references/error-handling.md +0 -468
  79. package/skills/typescript-effect-ts/references/resources.md +0 -476
  80. package/skills/typescript-effect-ts/references/schema.md +0 -536
  81. package/skills/typescript-effect-ts/references/services.md +0 -461
  82. package/skills/typescript-fastify/SKILL.md +0 -405
  83. package/skills/typescript-fastify/references/plugins.md +0 -329
  84. package/skills/typescript-fastify/references/typeid.md +0 -315
  85. package/skills/typescript-functional-patterns/SKILL.md +0 -402
  86. package/skills/typescript-functional-patterns/references/adts.md +0 -497
  87. package/skills/typescript-functional-patterns/references/branded-types.md +0 -542
  88. package/skills/typescript-functional-patterns/references/migration-guide.md +0 -695
  89. package/skills/typescript-functional-patterns/references/option-result.md +0 -585
  90. package/skills/typescript-testing/SKILL.md +0 -353
  91. package/skills/typescript-testing/references/mocking.md +0 -675
  92. package/skills/typescript-testing/references/msw.md +0 -852
  93. package/skills/typescript-testing/references/snapshot-testing.md +0 -774
@@ -1,332 +0,0 @@
1
- # DynamoDB Data Modeling Methodology
2
-
3
- This guide walks through the complete data modeling process for DynamoDB single-table design.
4
-
5
- ## When to Use DynamoDB
6
-
7
- ### Ideal Scenarios
8
-
9
- ✓ **Well-defined, stable access patterns** - You can enumerate every query upfront
10
- ✓ **Predictable sub-10ms performance** - Need consistent latency at scale
11
- ✓ **Microservices with clear boundaries** - Domain-driven service design
12
- ✓ **Cost predictability matters** - Known capacity or pay-per-request
13
- ✓ **Operational workloads** - CRUD operations over analytics
14
-
15
- ### Avoid DynamoDB When
16
-
17
- ✗ **Prototyping** - Requirements remain fluid
18
- ✗ **Ad-hoc reporting/analytics** - Need flexible querying
19
- ✗ **Team lacks expertise** - Learning curve is steep
20
- ✗ **GraphQL resolvers** - Unpredictable query patterns
21
- ✗ **Complex JOINs required** - Better suited for relational
22
-
23
- > **The Phase Transition Problem**: Simple key-value feels magical initially, but complexity balloons when modeling real relationships. Teams either abandon DynamoDB or commit fully to single-table patterns—there's no comfortable middle ground.
24
-
25
- ## Modeling Process
26
-
27
- ### Step 1: Define Entity Relationships (ERD)
28
-
29
- Create an Entity-Relationship Diagram showing all entities and their relationships.
30
-
31
- **Example: GitHub-like System**
32
-
33
- ```mermaid
34
- erDiagram
35
- User ||--o{ Organization : "belongs to"
36
- User ||--o{ Repository : "owns"
37
- User }o--o{ Repository : "stars"
38
-
39
- Organization ||--o{ Repository : "owns"
40
- Organization ||--o{ User : "has members"
41
-
42
- Repository ||--o{ Issue : "has"
43
- Repository ||--o{ PullRequest : "has"
44
- Repository ||--o{ Fork : "forked to"
45
-
46
- Issue ||--o{ IssueComment : "has"
47
- Issue ||--o{ Reaction : "has"
48
-
49
- PullRequest ||--o{ PRComment : "has"
50
- PullRequest ||--o{ Reaction : "has"
51
-
52
- User {
53
- string Username PK
54
- string Email
55
- string Bio
56
- }
57
-
58
- Repository {
59
- string Owner
60
- string RepoName
61
- string Description
62
- boolean IsPrivate
63
- datetime UpdatedAt
64
- }
65
-
66
- Issue {
67
- string RepoOwner
68
- string RepoName
69
- number IssueNumber
70
- string Title
71
- string Status
72
- string Author
73
- }
74
- ```
75
-
76
- **Key Questions:**
77
- - What are the core entities?
78
- - What are the relationships (1:1, 1:N, N:M)?
79
- - What attributes belong to each entity?
80
-
81
- ### Step 2: Create Entity Chart (PK/SK Patterns)
82
-
83
- Map each entity to its Primary Key (PK) and Sort Key (SK) pattern.
84
-
85
- **GitHub Example - Main Table:**
86
-
87
- | Entity | Partition Key (PK) | Sort Key (SK) | Purpose |
88
- |--------|-------------------|---------------|---------|
89
- | **User** | `ACCOUNT#{username}` | `ACCOUNT#{username}` | Direct user access |
90
- | **Organization** | `ACCOUNT#{org_name}` | `ACCOUNT#{org_name}` | Direct org access |
91
- | **Repository** | `REPO#{owner}#{repo_name}` | `REPO#{owner}#{repo_name}` | Direct repo access |
92
- | **Issue** | `ISSUE#{owner}#{repo}#{padded_num}` | `ISSUE#{owner}#{repo}#{padded_num}` | Direct issue access |
93
- | **IssueComment** | `REPO#{owner}#{repo}` | `ISSUE#{padded_num}#COMMENT#{id}` | Comments under issue |
94
- | **Star** | `ACCOUNT#{username}` | `STAR#{owner}#{repo}#{timestamp}` | User's starred repos |
95
- | **Fork** | `REPO#{original_owner}#{original_repo}` | `FORK#{fork_owner}` | Forks of original |
96
- | **Counter** | `COUNTER#{org}#{repo}` | `METADATA` | Issue number sequence |
97
-
98
- **Key Pattern Rules:**
99
-
100
- 1. **Simple Entity**: `ENTITY#{id}` - Single identifier (User, Organization)
101
- 2. **Composite Entity**: `ENTITY#{parent}#{child}` - Multiple identifiers (Repository, Issue)
102
- 3. **Hierarchical**: `PARENT#{id}` / `CHILD#{id}#...` - Parent/child split (Comments under Issue)
103
- 4. **Adjacency List**: Same PK, different SK prefixes - Many-to-many (Stars, Memberships)
104
- 5. **Temporal Sorting**: Include `#{timestamp}` in SK - Time-ordered (Stars, Activities)
105
-
106
- **Zero-Padding for Numeric IDs:**
107
- ```
108
- Issue #1 → ISSUE#owner#repo#00000001
109
- Issue #999 → ISSUE#owner#repo#00000999
110
- ```
111
- Ensures lexicographic sorting matches numeric order.
112
-
113
- ### Step 3: Design GSI Strategy
114
-
115
- Plan Global Secondary Indexes for secondary access patterns.
116
-
117
- **GSI Design Principles:**
118
- - GSI1/GSI2: Alternate entity lookups, inverted relationships
119
- - GSI3: Parent-child queries with temporal sorting
120
- - GSI4: Status-based or filtered queries
121
-
122
- **GitHub Example - GSI Tables:**
123
-
124
- #### GSI1: Collection Queries
125
-
126
- | Entity | GSI1PK | GSI1SK | Access Pattern |
127
- |--------|--------|--------|----------------|
128
- | **User** | `ACCOUNT#{username}` | `ACCOUNT#{username}` | Account lookup |
129
- | **Organization** | `ACCOUNT#{org_name}` | `ACCOUNT#{org_name}` | Account lookup |
130
- | **Repository** | `REPO#{owner}#{repo}` | `REPO#{owner}#{repo}` | Repo self-reference |
131
- | **Issue** | `ISSUE#{owner}#{repo}` | `ISSUE#{padded_number}` | **List issues by repo** |
132
- | **PullRequest** | `PR#{owner}#{repo}` | `PR#{padded_number}` | **List PRs by repo** |
133
- | **Star** | `REPO#{owner}#{repo}` | `STAR#{username}#{timestamp}` | **List stargazers** |
134
-
135
- #### GSI2: Entity-Specific Queries
136
-
137
- | Entity | GSI2PK | GSI2SK | Access Pattern |
138
- |--------|--------|--------|----------------|
139
- | **Repository** | `REPO#{owner}#{repo}` | `REPO#{owner}#{repo}` | Repo self-lookup |
140
- | **Fork** | `REPO#{original_owner}#{original_repo}` | `FORK#{fork_owner}` | **Find all forks of original repo** |
141
-
142
- #### GSI3: Temporal Hierarchical Queries
143
-
144
- | Entity | GSI3PK | GSI3SK | Access Pattern |
145
- |--------|--------|--------|----------------|
146
- | **User** | `ACCOUNT#{username}` | `ACCOUNT#{username}` | User lookup |
147
- | **Organization** | `ACCOUNT#{org_name}` | `ACCOUNT#{org_name}` | Org lookup |
148
- | **Repository** | `ACCOUNT#{owner}` | `#{updated_at}` | **List repos by owner, sorted by date** |
149
-
150
- The `#` prefix on GSI3SK ensures repositories sort before the account record itself.
151
-
152
- #### GSI4: Status-Based Filtering
153
-
154
- | Entity | GSI4PK | GSI4SK | Access Pattern |
155
- |--------|--------|--------|----------------|
156
- | **Repository** | `REPO#{owner}#{repo}` | `#REPO#{owner}#{repo}` | Repo metadata |
157
- | **Open Issue** | `ISSUE#{owner}#{repo}` | `ISSUE#OPEN#{reverse_padded_num}` | **Open issues (newest first)** |
158
- | **Closed Issue** | `ISSUE#{owner}#{repo}` | `#ISSUE#CLOSED#{padded_num}` | **Closed issues (oldest first)** |
159
-
160
- **Smart Sort Key Design:**
161
- ```typescript
162
- // Open issues: Reverse numbering for newest-first
163
- const reverseNumber = String(99999999 - issue_number).padStart(8, "0")
164
- GSI4SK = `ISSUE#OPEN#${reverseNumber}`
165
-
166
- // Closed issues: Normal numbering for oldest-first
167
- const paddedNumber = String(issue_number).padStart(8, "0")
168
- GSI4SK = `#ISSUE#CLOSED#${paddedNumber}`
169
- ```
170
-
171
- The `#` prefix ensures closed issues sort after open issues when querying without range filter.
172
-
173
- ### Step 4: Document Access Patterns
174
-
175
- List every query the application needs and map to table or GSI.
176
-
177
- **Format:**
178
-
179
- | Access Pattern | Query Type | Table/Index | Partition Key | Sort Key Condition |
180
- |----------------|-----------|-------------|---------------|-------------------|
181
- | Get user by username | GetItem | Main | `ACCOUNT#{username}` | Equal |
182
- | List repos by owner | Query | GSI3 | `ACCOUNT#{owner}` | `beginsWith("#")` |
183
- | List issues for repo | Query | GSI1 | `ISSUE#{owner}#{repo}` | All |
184
- | List open issues for repo | Query | GSI4 | `ISSUE#{owner}#{repo}` | `beginsWith("ISSUE#OPEN#")` |
185
- | Get stargazers for repo | Query | GSI1 | `REPO#{owner}#{repo}` | `beginsWith("STAR#")` |
186
- | Get user's starred repos | Query | Main | `ACCOUNT#{username}` | `beginsWith("STAR#")` |
187
- | Find forks of repo | Query | GSI2 | `REPO#{owner}#{repo}` | `beginsWith("FORK#")` |
188
-
189
- **Critical Rule:** If you can't map an access pattern to a GetItem or Query, you need to redesign your keys or add a GSI. **Never rely on Scan in production.**
190
-
191
- ## Key Design Patterns
192
-
193
- ### 1. Overloaded Attributes
194
-
195
- Use the same key pattern for multiple entity types.
196
-
197
- **Example:** `ACCOUNT#` prefix for both Users and Organizations
198
- - Simplifies queries when you want "all accounts"
199
- - Use entity type attribute (`_et`) to distinguish in code
200
-
201
- ### 2. Item Collections
202
-
203
- Group related items under the same partition key.
204
-
205
- **Example:** Comments under an issue
206
- ```
207
- PK: REPO#owner#repo
208
- SK: ISSUE#00000001#COMMENT#c1
209
- SK: ISSUE#00000001#COMMENT#c2
210
- SK: ISSUE#00000001#COMMENT#c3
211
- ```
212
-
213
- Query with `partition = "REPO#owner#repo"` and `range.beginsWith("ISSUE#00000001#COMMENT#")`
214
-
215
- ### 3. Adjacency List (Many-to-Many)
216
-
217
- Store both sides of the relationship as separate items.
218
-
219
- **Example:** Stars (Users ↔ Repositories)
220
-
221
- Main Table:
222
- ```
223
- PK: ACCOUNT#alice SK: STAR#owner#repo1#2024-01-01 (Alice starred repo1)
224
- PK: ACCOUNT#bob SK: STAR#owner#repo1#2024-01-02 (Bob starred repo1)
225
- ```
226
-
227
- GSI1:
228
- ```
229
- GSI1PK: REPO#owner#repo1 GSI1SK: STAR#alice#2024-01-01 (repo1 starred by Alice)
230
- GSI1PK: REPO#owner#repo1 GSI1SK: STAR#bob#2024-01-02 (repo1 starred by Bob)
231
- ```
232
-
233
- Enables bidirectional queries:
234
- - User's starred repos: Query main table with `PK = ACCOUNT#alice`, `SK begins_with STAR#`
235
- - Repo's stargazers: Query GSI1 with `GSI1PK = REPO#owner#repo1`, `GSI1SK begins_with STAR#`
236
-
237
- ### 4. Sparse Indexes
238
-
239
- Only items with the GSI attributes appear in the GSI. Use this to filter item types.
240
-
241
- **Example:** Not all entities have GSI4PK/SK - only repositories and issues appear in GSI4.
242
-
243
- ### 5. Composite Sort Keys
244
-
245
- Enable complex querying and sorting by encoding multiple values in SK.
246
-
247
- **Example:** Status + reverse number for newest-open-issues-first
248
-
249
- ## Modeling Checklist
250
-
251
- Before writing code:
252
-
253
- - [ ] **ERD Complete** - All entities and relationships documented
254
- - [ ] **Entity Chart Complete** - Every entity has PK/SK pattern
255
- - [ ] **GSI Strategy Defined** - Each GSI has clear purpose
256
- - [ ] **Access Patterns Documented** - Every query mapped to table/GSI
257
- - [ ] **No Scan Operations** - All queries use GetItem or Query
258
- - [ ] **Numeric IDs Zero-Padded** - For lexicographic sorting
259
- - [ ] **Temporal Fields Include Prefix** - `#` prefix for correct ordering
260
- - [ ] **Many-to-Many Uses Adjacency List** - Both directions queryable
261
-
262
- ## Common Pitfalls
263
-
264
- ### ❌ Forgetting Zero-Padding
265
-
266
- ```typescript
267
- // WRONG - "Issue 2" sorts after "Issue 10"
268
- SK: `ISSUE#${owner}#${repo}#${issue_number}`
269
-
270
- // RIGHT - Proper lexicographic order
271
- SK: `ISSUE#${owner}#${repo}#${String(issue_number).padStart(8, "0")}`
272
- ```
273
-
274
- ### ❌ Missing Temporal Prefix
275
-
276
- ```typescript
277
- // WRONG - Timestamps sort before entity records
278
- GSI3SK: new Date().toISOString() // "2024-01-01..." sorts before "ACCOUNT#..."
279
-
280
- // RIGHT - # prefix ensures entity sorts first
281
- GSI3SK: `#${new Date().toISOString()}`
282
- ```
283
-
284
- ### ❌ Not Planning for Many-to-Many
285
-
286
- ```typescript
287
- // WRONG - Can only query one direction
288
- PK: ACCOUNT#{user} SK: REPO#{owner}#{repo}
289
-
290
- // RIGHT - Use adjacency list with GSI inversion
291
- PK: ACCOUNT#{user} SK: STAR#{owner}#{repo}#{timestamp}
292
- GSI1PK: REPO#{owner}#{repo} GSI1SK: STAR#{user}#{timestamp}
293
- ```
294
-
295
- ### ❌ Overusing GSIs
296
-
297
- Each GSI doubles storage costs. Evaluate if access pattern is needed or if client-side filtering suffices.
298
-
299
- ## Example: Full Modeling Session
300
-
301
- **Requirement:** Model a GitHub-like system
302
-
303
- **1. ERD:** (See diagram above)
304
-
305
- **2. Entity Chart:**
306
- - User: `ACCOUNT#{username}` / `ACCOUNT#{username}`
307
- - Repository: `REPO#{owner}#{repo}` / `REPO#{owner}#{repo}`
308
- - Issue: `ISSUE#{owner}#{repo}#{padded_num}` / same
309
- - IssueComment: `REPO#{owner}#{repo}` / `ISSUE#{padded_num}#COMMENT#{id}`
310
- - Star: `ACCOUNT#{user}` / `STAR#{owner}#{repo}#{timestamp}`
311
-
312
- **3. GSI Strategy:**
313
- - GSI1: Collection queries (issues by repo, stargazers)
314
- - GSI2: Fork relationships
315
- - GSI3: Temporal owner queries (repos by owner with sorting)
316
- - GSI4: Status filtering (open vs closed issues)
317
-
318
- **4. Access Patterns:**
319
- - ✓ Get user → Main table GetItem
320
- - ✓ List user's repos → GSI3 Query with reverse sort
321
- - ✓ List issues for repo → GSI1 Query
322
- - ✓ List open issues → GSI4 Query with beginsWith
323
- - ✓ Get stargazers → GSI1 Query
324
- - ✓ Get user's stars → Main table Query
325
-
326
- **5. Validate:**
327
- - No Scan operations needed ✓
328
- - All numeric IDs padded ✓
329
- - Temporal fields prefixed ✓
330
- - Many-to-many (stars) use adjacency list ✓
331
-
332
- **Ready to implement!**