swe-workflow-skills 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 (177) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +144 -0
  3. package/VERSION +1 -0
  4. package/bin/cli.mjs +44 -0
  5. package/catalog.json +225 -0
  6. package/commands/role.md +34 -0
  7. package/hooks/session-start.mjs +118 -0
  8. package/install.mjs +318 -0
  9. package/package.json +47 -0
  10. package/roles.json +194 -0
  11. package/scripts/resolve.mjs +296 -0
  12. package/skills/accessibility-design/SKILL.md +128 -0
  13. package/skills/accessibility-design/evals/evals.json +51 -0
  14. package/skills/accessibility-design/references/accessibility-patterns.md +321 -0
  15. package/skills/api-design/SKILL.md +144 -0
  16. package/skills/api-design/evals/evals.json +48 -0
  17. package/skills/api-design/references/rest-conventions.md +147 -0
  18. package/skills/api-design/templates/api-spec.md +156 -0
  19. package/skills/architecture-design/SKILL.md +86 -0
  20. package/skills/architecture-design/evals/evals.json +44 -0
  21. package/skills/architecture-design/references/clean-architecture.md +147 -0
  22. package/skills/architecture-design/references/component-principles.md +129 -0
  23. package/skills/architecture-design/references/principles.md +81 -0
  24. package/skills/architecture-design/references/solid-principles.md +106 -0
  25. package/skills/architecture-design/templates/adr.md +63 -0
  26. package/skills/architecture-documentation/SKILL.md +126 -0
  27. package/skills/architecture-documentation/evals/evals.json +44 -0
  28. package/skills/architecture-documentation/references/abstraction-levels.md +91 -0
  29. package/skills/architecture-documentation/references/diagram-tooling.md +141 -0
  30. package/skills/architecture-documentation/templates/architecture-doc.md +171 -0
  31. package/skills/bug-investigating/SKILL.md +133 -0
  32. package/skills/bug-investigating/evals/evals.json +56 -0
  33. package/skills/bug-investigating/references/common-bugs.md +62 -0
  34. package/skills/bug-investigating/references/debugging-patterns.md +94 -0
  35. package/skills/cicd-pipeline/SKILL.md +87 -0
  36. package/skills/cicd-pipeline/evals/evals.json +34 -0
  37. package/skills/cicd-pipeline/references/pipeline-patterns.md +206 -0
  38. package/skills/cicd-pipeline/templates/github-actions.md +206 -0
  39. package/skills/code-reviewing/SKILL.md +92 -0
  40. package/skills/code-reviewing/evals/evals.json +62 -0
  41. package/skills/code-reviewing/references/error-handling.md +108 -0
  42. package/skills/code-reviewing/references/review-checklist.md +144 -0
  43. package/skills/configuration-strategy/SKILL.md +109 -0
  44. package/skills/configuration-strategy/evals/evals.json +41 -0
  45. package/skills/configuration-strategy/references/config-patterns.md +161 -0
  46. package/skills/containerization/SKILL.md +90 -0
  47. package/skills/containerization/evals/evals.json +36 -0
  48. package/skills/containerization/references/dockerfile-patterns.md +168 -0
  49. package/skills/containerization/templates/dockerfile.md +154 -0
  50. package/skills/data-modeling/SKILL.md +83 -0
  51. package/skills/data-modeling/evals/evals.json +43 -0
  52. package/skills/data-modeling/references/conventions.md +57 -0
  53. package/skills/data-modeling/templates/schema.md +120 -0
  54. package/skills/dependency-impact-analysis/SKILL.md +113 -0
  55. package/skills/dependency-impact-analysis/evals/evals.json +41 -0
  56. package/skills/dependency-impact-analysis/references/impact-patterns.md +150 -0
  57. package/skills/dependency-management/SKILL.md +161 -0
  58. package/skills/dependency-management/evals/evals.json +48 -0
  59. package/skills/dependency-management/references/evaluation-checklist.md +127 -0
  60. package/skills/deployment-checklist/SKILL.md +132 -0
  61. package/skills/deployment-checklist/evals/evals.json +58 -0
  62. package/skills/deployment-checklist/references/pre-deploy-gates.md +91 -0
  63. package/skills/deployment-repo/SKILL.md +190 -0
  64. package/skills/deployment-repo/evals/evals.json +44 -0
  65. package/skills/deployment-repo/references/deployment-repo-patterns.md +258 -0
  66. package/skills/deployment-repo/references/version-compatibility.md +227 -0
  67. package/skills/deployment-repo/templates/deployment-repo-structure.md +226 -0
  68. package/skills/effort-estimation/SKILL.md +95 -0
  69. package/skills/effort-estimation/evals/evals.json +32 -0
  70. package/skills/effort-estimation/references/estimation-methods.md +154 -0
  71. package/skills/feature-planning/SKILL.md +84 -0
  72. package/skills/feature-planning/evals/evals.json +44 -0
  73. package/skills/feature-planning/templates/plan.md +55 -0
  74. package/skills/feature-planning/templates/task.md +26 -0
  75. package/skills/frontend-architecture/SKILL.md +154 -0
  76. package/skills/frontend-architecture/evals/evals.json +34 -0
  77. package/skills/frontend-architecture/references/component-patterns.md +264 -0
  78. package/skills/frontend-architecture/templates/folder-structure.md +203 -0
  79. package/skills/git-workflow/SKILL.md +127 -0
  80. package/skills/git-workflow/evals/evals.json +44 -0
  81. package/skills/git-workflow/references/conventions.md +142 -0
  82. package/skills/git-workflow/templates/pull-request.md +57 -0
  83. package/skills/gitops-delivery/SKILL.md +319 -0
  84. package/skills/gitops-delivery/evals/evals.json +44 -0
  85. package/skills/gitops-delivery/references/gitops-patterns.md +478 -0
  86. package/skills/gitops-delivery/templates/gitops-config.md +196 -0
  87. package/skills/incident-response/SKILL.md +130 -0
  88. package/skills/incident-response/evals/evals.json +55 -0
  89. package/skills/incident-response/references/communication-templates.md +134 -0
  90. package/skills/incident-response/references/severity-levels.md +77 -0
  91. package/skills/incident-response/templates/incident-timeline.md +57 -0
  92. package/skills/infrastructure-as-code/SKILL.md +86 -0
  93. package/skills/infrastructure-as-code/evals/evals.json +33 -0
  94. package/skills/infrastructure-as-code/references/iac-patterns.md +179 -0
  95. package/skills/infrastructure-as-code/templates/terraform-module.md +158 -0
  96. package/skills/metrics-and-okrs/SKILL.md +113 -0
  97. package/skills/metrics-and-okrs/evals/evals.json +33 -0
  98. package/skills/metrics-and-okrs/references/metric-catalog.md +90 -0
  99. package/skills/metrics-and-okrs/templates/okr-document.md +61 -0
  100. package/skills/ml-experiment-tracking/SKILL.md +96 -0
  101. package/skills/ml-experiment-tracking/evals/evals.json +32 -0
  102. package/skills/ml-experiment-tracking/references/tracking-tools.md +127 -0
  103. package/skills/ml-model-deployment/SKILL.md +106 -0
  104. package/skills/ml-model-deployment/evals/evals.json +34 -0
  105. package/skills/ml-model-deployment/references/serving-patterns.md +162 -0
  106. package/skills/ml-pipeline-design/SKILL.md +162 -0
  107. package/skills/ml-pipeline-design/evals/evals.json +34 -0
  108. package/skills/ml-pipeline-design/references/pipeline-components.md +174 -0
  109. package/skills/observability-design/SKILL.md +162 -0
  110. package/skills/observability-design/evals/evals.json +52 -0
  111. package/skills/observability-design/references/logging-patterns.md +229 -0
  112. package/skills/observability-design/references/slo-framework.md +151 -0
  113. package/skills/observability-design/templates/slo-document.md +80 -0
  114. package/skills/performance-optimization/SKILL.md +83 -0
  115. package/skills/performance-optimization/evals/evals.json +47 -0
  116. package/skills/performance-optimization/references/bottleneck-patterns.md +256 -0
  117. package/skills/performance-optimization/references/concurrency.md +101 -0
  118. package/skills/prd-writing/SKILL.md +109 -0
  119. package/skills/prd-writing/evals/evals.json +33 -0
  120. package/skills/prd-writing/references/prd-examples.md +132 -0
  121. package/skills/prd-writing/templates/prd.md +71 -0
  122. package/skills/prd-writing/templates/rfc.md +79 -0
  123. package/skills/project-documentation/SKILL.md +104 -0
  124. package/skills/project-documentation/evals/evals.json +48 -0
  125. package/skills/project-documentation/references/contributing-guide.md +100 -0
  126. package/skills/project-documentation/templates/changelog.md +59 -0
  127. package/skills/project-documentation/templates/readme.md +121 -0
  128. package/skills/project-proposal/SKILL.md +90 -0
  129. package/skills/project-proposal/evals/evals.json +31 -0
  130. package/skills/project-proposal/references/proposal-examples.md +140 -0
  131. package/skills/project-proposal/templates/proposal.md +76 -0
  132. package/skills/project-review/SKILL.md +111 -0
  133. package/skills/project-review/evals/evals.json +42 -0
  134. package/skills/refactoring/SKILL.md +90 -0
  135. package/skills/refactoring/evals/evals.json +44 -0
  136. package/skills/refactoring/references/transformations.md +132 -0
  137. package/skills/retrospective/SKILL.md +157 -0
  138. package/skills/retrospective/evals/evals.json +34 -0
  139. package/skills/retrospective/references/facilitation-guide.md +130 -0
  140. package/skills/retrospective/templates/post-mortem.md +121 -0
  141. package/skills/rollback-strategy/SKILL.md +116 -0
  142. package/skills/rollback-strategy/evals/evals.json +55 -0
  143. package/skills/rollback-strategy/references/rollback-patterns.md +125 -0
  144. package/skills/rollback-strategy/templates/rollback-plan.md +69 -0
  145. package/skills/security-audit/SKILL.md +146 -0
  146. package/skills/security-audit/evals/evals.json +66 -0
  147. package/skills/security-audit/references/owasp-top-10.md +167 -0
  148. package/skills/security-audit/templates/security-report.md +79 -0
  149. package/skills/skill-router/SKILL.md +171 -0
  150. package/skills/skill-router/evals/evals.json +39 -0
  151. package/skills/strategic-review/SKILL.md +106 -0
  152. package/skills/strategic-review/evals/evals.json +42 -0
  153. package/skills/strategic-review/templates/full-review-prompt.md +84 -0
  154. package/skills/tdd-workflow/SKILL.md +147 -0
  155. package/skills/tdd-workflow/evals/evals.json +58 -0
  156. package/skills/tdd-workflow/references/test-quality.md +71 -0
  157. package/skills/technical-debt-review/SKILL.md +113 -0
  158. package/skills/technical-debt-review/evals/evals.json +41 -0
  159. package/skills/technical-debt-review/references/debt-taxonomy.md +124 -0
  160. package/skills/technical-debt-review/templates/debt-audit.md +85 -0
  161. package/skills/test-data-strategy/SKILL.md +129 -0
  162. package/skills/test-data-strategy/evals/evals.json +49 -0
  163. package/skills/test-data-strategy/references/data-generation-patterns.md +341 -0
  164. package/skills/test-suite-design/SKILL.md +137 -0
  165. package/skills/test-suite-design/evals/evals.json +69 -0
  166. package/skills/test-suite-design/references/test-infrastructure.md +175 -0
  167. package/skills/test-suite-design/references/testing-pyramid.md +140 -0
  168. package/skills/ui-ux-design/SKILL.md +117 -0
  169. package/skills/ui-ux-design/evals/evals.json +35 -0
  170. package/skills/ui-ux-design/references/interaction-patterns.md +145 -0
  171. package/skills/ui-ux-design/templates/screen-spec.md +97 -0
  172. package/skills/verification-before-completion/SKILL.md +85 -0
  173. package/skills/verification-before-completion/evals/evals.json +53 -0
  174. package/skills/writing-skills/SKILL.md +87 -0
  175. package/skills/writing-skills/evals/evals.json +41 -0
  176. package/skills/writing-skills/references/pressure-testing.md +69 -0
  177. package/uninstall.mjs +182 -0
@@ -0,0 +1,321 @@
1
+ # Accessibility Patterns
2
+
3
+ ## Contents
4
+ - Common component patterns
5
+ - Form accessibility
6
+ - Modal and dialog patterns
7
+ - Navigation patterns
8
+ - Image and media accessibility
9
+ - React-specific patterns
10
+
11
+ ## Common Component Patterns
12
+
13
+ ### Button
14
+ ```html
15
+ <!-- GOOD: Native button — keyboard support, role, focus all built in -->
16
+ <button type="button" onClick={handleClick}>
17
+ Save Changes
18
+ </button>
19
+
20
+ <!-- GOOD: Button with loading state -->
21
+ <button type="button" disabled={isLoading} aria-busy={isLoading}>
22
+ {isLoading ? 'Saving...' : 'Save Changes'}
23
+ </button>
24
+
25
+ <!-- GOOD: Icon button with accessible label -->
26
+ <button type="button" aria-label="Delete item">
27
+ <TrashIcon aria-hidden="true" />
28
+ </button>
29
+
30
+ <!-- BAD: Div pretending to be a button — no keyboard, no role, no focus -->
31
+ <div className="btn" onClick={handleClick}>Save</div>
32
+ ```
33
+
34
+ ### Link vs Button
35
+ - Use `<a>` for navigation (goes somewhere)
36
+ - Use `<button>` for actions (does something)
37
+ - Never use `<a href="#">` as a button — use a real `<button>`
38
+
39
+ ### Toggle / Switch
40
+ ```html
41
+ <button
42
+ role="switch"
43
+ aria-checked={isEnabled}
44
+ onClick={() => setIsEnabled(!isEnabled)}
45
+ >
46
+ Dark mode
47
+ </button>
48
+ ```
49
+
50
+ ### Tabs
51
+ ```html
52
+ <div role="tablist" aria-label="Account settings">
53
+ <button role="tab" aria-selected={activeTab === 'general'}
54
+ aria-controls="panel-general" id="tab-general">
55
+ General
56
+ </button>
57
+ <button role="tab" aria-selected={activeTab === 'security'}
58
+ aria-controls="panel-security" id="tab-security">
59
+ Security
60
+ </button>
61
+ </div>
62
+ <div role="tabpanel" id="panel-general" aria-labelledby="tab-general"
63
+ hidden={activeTab !== 'general'}>
64
+ General settings content...
65
+ </div>
66
+ ```
67
+
68
+ Keyboard: Arrow keys between tabs, Tab moves focus into the active panel.
69
+
70
+ ### Accordion
71
+ ```html
72
+ <h3>
73
+ <button aria-expanded={isOpen} aria-controls="section-1">
74
+ FAQ Question
75
+ </button>
76
+ </h3>
77
+ <div id="section-1" role="region" hidden={!isOpen}>
78
+ Answer content...
79
+ </div>
80
+ ```
81
+
82
+ ## Form Accessibility
83
+
84
+ ### Labels
85
+ Every input MUST have an associated label. No exceptions.
86
+
87
+ ```html
88
+ <!-- GOOD: Explicit label with htmlFor -->
89
+ <label htmlFor="email">Email address</label>
90
+ <input id="email" type="email" />
91
+
92
+ <!-- GOOD: Wrapping label (implicit association) -->
93
+ <label>
94
+ Email address
95
+ <input type="email" />
96
+ </label>
97
+
98
+ <!-- GOOD: aria-label for visually hidden label -->
99
+ <input type="search" aria-label="Search projects" />
100
+
101
+ <!-- BAD: Placeholder as label — disappears on focus, low contrast -->
102
+ <input type="email" placeholder="Email address" />
103
+ ```
104
+
105
+ ### Error messages
106
+ ```html
107
+ <label htmlFor="email">Email address</label>
108
+ <input
109
+ id="email"
110
+ type="email"
111
+ aria-invalid={hasError}
112
+ aria-describedby={hasError ? "email-error" : undefined}
113
+ />
114
+ {hasError && (
115
+ <p id="email-error" role="alert">
116
+ Please enter a valid email address
117
+ </p>
118
+ )}
119
+ ```
120
+
121
+ Key: `aria-invalid` tells screen readers the field has an error. `aria-describedby` links the error message to the field. `role="alert"` announces the error immediately.
122
+
123
+ ### Required fields
124
+ ```html
125
+ <label htmlFor="name">
126
+ Name <span aria-hidden="true">*</span>
127
+ </label>
128
+ <input id="name" required aria-required="true" />
129
+ ```
130
+
131
+ The `*` is visual-only (`aria-hidden`). `aria-required` is the programmatic indicator.
132
+
133
+ ### Form submission feedback
134
+ ```html
135
+ <!-- Status region for form-level messages -->
136
+ <div aria-live="polite" role="status">
137
+ {submitSuccess && "Your changes have been saved."}
138
+ {submitError && "Failed to save. Please try again."}
139
+ </div>
140
+ ```
141
+
142
+ ## Modal and Dialog Patterns
143
+
144
+ ```html
145
+ <div
146
+ role="dialog"
147
+ aria-modal="true"
148
+ aria-labelledby="modal-title"
149
+ aria-describedby="modal-description"
150
+ >
151
+ <h2 id="modal-title">Delete Project</h2>
152
+ <p id="modal-description">
153
+ This will permanently delete "My Project" and all its data.
154
+ </p>
155
+ <button onClick={onCancel}>Cancel</button>
156
+ <button onClick={onConfirm}>Delete</button>
157
+ </div>
158
+ ```
159
+
160
+ **Required behaviors:**
161
+ 1. Focus moves to the first focusable element when modal opens
162
+ 2. Tab cycles within the modal (focus trap — focus cannot leave)
163
+ 3. Escape key closes the modal
164
+ 4. Focus returns to the triggering element when modal closes
165
+ 5. Background content has `aria-hidden="true"` and `inert` while modal is open
166
+
167
+ ### React focus trap implementation
168
+ ```typescript
169
+ function useFocusTrap(ref: RefObject<HTMLElement>) {
170
+ useEffect(() => {
171
+ const element = ref.current;
172
+ if (!element) return;
173
+
174
+ const focusableSelector = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
175
+ const focusable = element.querySelectorAll(focusableSelector);
176
+ const first = focusable[0] as HTMLElement;
177
+ const last = focusable[focusable.length - 1] as HTMLElement;
178
+
179
+ first?.focus();
180
+
181
+ const handleKeyDown = (e: KeyboardEvent) => {
182
+ if (e.key === 'Tab') {
183
+ if (e.shiftKey && document.activeElement === first) {
184
+ e.preventDefault();
185
+ last?.focus();
186
+ } else if (!e.shiftKey && document.activeElement === last) {
187
+ e.preventDefault();
188
+ first?.focus();
189
+ }
190
+ }
191
+ };
192
+
193
+ element.addEventListener('keydown', handleKeyDown);
194
+ return () => element.removeEventListener('keydown', handleKeyDown);
195
+ }, [ref]);
196
+ }
197
+ ```
198
+
199
+ ## Navigation Patterns
200
+
201
+ ### Skip link (required for keyboard users)
202
+ ```html
203
+ <!-- First element in the body -->
204
+ <a href="#main-content" className="sr-only focus:not-sr-only">
205
+ Skip to main content
206
+ </a>
207
+ <!-- ... header, nav ... -->
208
+ <main id="main-content">
209
+ Page content
210
+ </main>
211
+ ```
212
+
213
+ The skip link is visually hidden until focused (keyboard user presses Tab).
214
+
215
+ ### Landmarks
216
+ ```html
217
+ <header> <!-- banner landmark -->
218
+ <nav aria-label="Main navigation"> <!-- navigation landmark -->
219
+ ...
220
+ </nav>
221
+ </header>
222
+ <main> <!-- main landmark -->
223
+ <section aria-label="Dashboard"> <!-- region landmark -->
224
+ ...
225
+ </section>
226
+ </main>
227
+ <aside> <!-- complementary landmark -->
228
+ ...
229
+ </aside>
230
+ <footer> <!-- contentinfo landmark -->
231
+ ...
232
+ </footer>
233
+ ```
234
+
235
+ Screen reader users navigate by landmarks. Proper landmark structure lets them jump directly to the section they need.
236
+
237
+ ### Breadcrumbs
238
+ ```html
239
+ <nav aria-label="Breadcrumb">
240
+ <ol>
241
+ <li><a href="/">Home</a></li>
242
+ <li><a href="/projects">Projects</a></li>
243
+ <li><a href="/projects/123" aria-current="page">My Project</a></li>
244
+ </ol>
245
+ </nav>
246
+ ```
247
+
248
+ ## Image and Media Accessibility
249
+
250
+ ### Images
251
+ ```html
252
+ <!-- Informative image: describe what it shows -->
253
+ <img src="chart.png" alt="Revenue grew 25% from Q1 to Q2 2025" />
254
+
255
+ <!-- Decorative image: empty alt (don't omit alt entirely) -->
256
+ <img src="decoration.png" alt="" />
257
+
258
+ <!-- Complex image: describe + link to long description -->
259
+ <figure>
260
+ <img src="architecture.png" alt="System architecture overview" aria-describedby="arch-desc" />
261
+ <figcaption id="arch-desc">
262
+ The system consists of three services: API gateway, processing service, and database.
263
+ Requests flow from the gateway through the processor to the database.
264
+ </figcaption>
265
+ </figure>
266
+ ```
267
+
268
+ ### Video
269
+ - Provide captions (not just auto-generated)
270
+ - Provide a transcript for audio content
271
+ - Don't autoplay with sound
272
+ - Provide pause/stop controls
273
+
274
+ ## React-Specific Patterns
275
+
276
+ ### Route change announcements
277
+ Single-page apps don't trigger screen reader page announcements on navigation. Add an announcer:
278
+
279
+ ```typescript
280
+ function RouteAnnouncer() {
281
+ const location = useLocation();
282
+ const [announcement, setAnnouncement] = useState('');
283
+
284
+ useEffect(() => {
285
+ // Read the page title or a descriptive heading
286
+ const title = document.title || 'Page loaded';
287
+ setAnnouncement(title);
288
+ }, [location]);
289
+
290
+ return (
291
+ <div aria-live="assertive" aria-atomic="true" className="sr-only">
292
+ {announcement}
293
+ </div>
294
+ );
295
+ }
296
+ ```
297
+
298
+ ### Visually hidden utility (sr-only)
299
+ ```css
300
+ .sr-only {
301
+ position: absolute;
302
+ width: 1px;
303
+ height: 1px;
304
+ padding: 0;
305
+ margin: -1px;
306
+ overflow: hidden;
307
+ clip: rect(0, 0, 0, 0);
308
+ white-space: nowrap;
309
+ border-width: 0;
310
+ }
311
+ ```
312
+ Use for: skip links, form labels that are visually implied by context, additional screen reader context.
313
+
314
+ ### ESLint plugin
315
+ Add `eslint-plugin-jsx-a11y` to catch common issues at development time:
316
+ ```json
317
+ {
318
+ "extends": ["plugin:jsx-a11y/recommended"]
319
+ }
320
+ ```
321
+ This catches: missing alt text, invalid ARIA attributes, non-interactive elements with click handlers, missing form labels, and more.
@@ -0,0 +1,144 @@
1
+ ---
2
+ name: api-design
3
+ description: "Design RESTful and GraphQL APIs — endpoint naming, request/response contracts, error handling, pagination, versioning, auth patterns, OpenAPI specs. Triggers: design the API, API contract, REST API, GraphQL schema, error response format, pagination, API versioning, OpenAPI, swagger, endpoints. Use architecture-design for REST-vs-GraphQL or monolith-vs-microservices decisions."
4
+ model: sonnet
5
+ allowed-tools: Read, Grep, Glob, Write, Edit
6
+ ---
7
+
8
+ # API Design
9
+
10
+ Design APIs that are consistent, predictable, and easy to consume. A well-designed API is intuitive to use without reading documentation — but has great documentation anyway.
11
+
12
+ ## Scope Boundary
13
+
14
+ This skill designs the **contract** (endpoints, request/response shapes, error formats, pagination). For higher-level decisions (REST vs GraphQL, API gateway, authentication strategy), use the `architecture-design` skill first, then return here to design the specifics.
15
+
16
+ ## Workflow
17
+
18
+ ### Step 1: Identify Resources and Operations
19
+
20
+ Start from the domain model, not the UI:
21
+
22
+ - **What are the resources?** (nouns: users, orders, products, comments)
23
+ - **What operations exist?** (CRUD + domain-specific: archive, publish, approve)
24
+ - **What are the relationships?** (user has orders, order contains items)
25
+ - **Who consumes this API?** (web app, mobile app, third-party, internal service)
26
+
27
+ Map each resource to its operations before choosing URLs or methods.
28
+
29
+ ### Step 2: Design Endpoints
30
+
31
+ Apply RESTful naming conventions — see [references/rest-conventions.md](references/rest-conventions.md):
32
+
33
+ ```
34
+ GET /api/v1/users → List users
35
+ POST /api/v1/users → Create user
36
+ GET /api/v1/users/:id → Get user
37
+ PATCH /api/v1/users/:id → Update user (partial)
38
+ DELETE /api/v1/users/:id → Delete user
39
+
40
+ # Nested resources (when the child only makes sense in parent context)
41
+ GET /api/v1/users/:id/orders → List user's orders
42
+ POST /api/v1/users/:id/orders → Create order for user
43
+
44
+ # Actions that don't map to CRUD
45
+ POST /api/v1/orders/:id/cancel → Cancel an order
46
+ POST /api/v1/users/:id/verify → Verify a user's email
47
+ ```
48
+
49
+ Present the endpoint list to the user and refine before designing schemas.
50
+
51
+ ### Step 3: Define Request/Response Schemas
52
+
53
+ For each endpoint, define:
54
+
55
+ **Request**: Query parameters (for filtering/pagination), path parameters, request body with field types and validation rules.
56
+
57
+ **Response**: Status code, response body shape, included relationships.
58
+
59
+ Use consistent patterns across all endpoints — see [references/rest-conventions.md](references/rest-conventions.md) for standard shapes.
60
+
61
+ Key decisions to make with the user:
62
+ - **ID format**: Integer, UUID, or ULID? (be consistent)
63
+ - **Date format**: ISO 8601 always (`2025-03-05T14:30:00Z`)
64
+ - **Null vs absent**: Are missing fields returned as `null` or omitted?
65
+ - **Envelope or not**: `{ data: [...], meta: {...} }` vs flat response?
66
+
67
+ ### Step 4: Standardize Error Responses
68
+
69
+ Every API error should use the same shape. Recommend this format:
70
+
71
+ ```json
72
+ {
73
+ "error": {
74
+ "code": "VALIDATION_ERROR",
75
+ "message": "Human-readable description for developers",
76
+ "details": [
77
+ {
78
+ "field": "email",
79
+ "message": "Must be a valid email address"
80
+ }
81
+ ]
82
+ }
83
+ }
84
+ ```
85
+
86
+ Map HTTP status codes consistently:
87
+ - `400` — Client sent invalid data (validation errors)
88
+ - `401` — Authentication required or invalid
89
+ - `403` — Authenticated but not authorized for this action
90
+ - `404` — Resource not found
91
+ - `409` — Conflict (duplicate, state violation)
92
+ - `422` — Valid syntax but semantically invalid (business rule violation)
93
+ - `429` — Rate limited
94
+ - `500` — Server error (never expose internals)
95
+
96
+ ### Step 5: Design Pagination, Filtering, Sorting
97
+
98
+ For any list endpoint that could return many results:
99
+
100
+ **Pagination** (recommend cursor-based for most cases):
101
+ ```
102
+ GET /api/v1/orders?cursor=abc123&limit=20
103
+
104
+ Response:
105
+ {
106
+ "data": [...],
107
+ "pagination": {
108
+ "next_cursor": "def456",
109
+ "has_more": true
110
+ }
111
+ }
112
+ ```
113
+
114
+ **Filtering**: Use query parameters with clear naming:
115
+ ```
116
+ GET /api/v1/orders?status=pending&created_after=2025-01-01
117
+ ```
118
+
119
+ **Sorting**: Use a `sort` parameter with `-` prefix for descending:
120
+ ```
121
+ GET /api/v1/orders?sort=-created_at,total
122
+ ```
123
+
124
+ ### Step 6: Define Authentication and Authorization
125
+
126
+ For each endpoint, specify:
127
+ - **Authentication**: Required? What scheme? (Bearer token, API key, session)
128
+ - **Authorization**: What roles/permissions can access this? Document per-endpoint.
129
+ - **Public endpoints**: Explicitly mark which endpoints don't require auth.
130
+
131
+ ### Step 7: Produce the Specification
132
+
133
+ Output the API design as one of:
134
+ - **Markdown document** — for internal APIs and quick designs
135
+ - **OpenAPI 3.x spec** — for formal APIs, enables codegen and tooling
136
+
137
+ Use the template at [templates/api-spec.md](templates/api-spec.md) for markdown output.
138
+
139
+ ## Principles Applied
140
+
141
+ - **KISS**: Prefer flat resource URLs over deeply nested ones. `/orders?user_id=123` is simpler than `/users/123/orders/456/items/789`.
142
+ - **DRY**: Standardize error format, pagination, and envelope structure once. Don't reinvent per-endpoint.
143
+ - **YAGNI**: Don't add filtering, sorting, or pagination until a list endpoint actually needs them. Add later when the need is real.
144
+ - **Functional Independence**: Each endpoint should do one thing. Avoid "Swiss army knife" endpoints that change behavior based on query parameters.
@@ -0,0 +1,48 @@
1
+ {
2
+ "skill_name": "api-design",
3
+ "evals": [
4
+ {
5
+ "id": 1,
6
+ "prompt": "I need to design the API for a blog platform. We have users, posts, comments, and tags. Posts can have multiple tags. Comments are threaded (replies to other comments). Users can be authors or admins. The frontend is a Next.js app. Design the REST API.",
7
+ "expected_output": "Should identify all resources, design endpoints with proper RESTful naming, define request/response schemas, standardize errors, and include pagination for list endpoints.",
8
+ "assertions": [
9
+ "Identifies all resources (users, posts, comments, tags)",
10
+ "Uses plural nouns in URLs (/posts, /comments, /tags)",
11
+ "Handles the M:N relationship for posts and tags appropriately",
12
+ "Designs threaded comments without excessive URL nesting",
13
+ "Defines standard error response format",
14
+ "Includes pagination for list endpoints",
15
+ "Specifies auth requirements per endpoint",
16
+ "Distinguishes author vs admin permissions",
17
+ "Produces a complete API specification document"
18
+ ]
19
+ },
20
+ {
21
+ "id": 2,
22
+ "prompt": "design api endpoints for user registration, login, password reset, and profile management",
23
+ "expected_output": "Should design auth-related endpoints following security best practices, not expose sensitive information in responses, and use appropriate HTTP methods.",
24
+ "assertions": [
25
+ "POST for registration, login, and password reset (not GET)",
26
+ "Does not return password hash or sensitive data in responses",
27
+ "Includes email verification flow",
28
+ "Password reset uses a token-based flow (not sending password via email)",
29
+ "Login response includes token and token expiry",
30
+ "Profile endpoints require authentication",
31
+ "Standardized error responses for auth failures (401 vs 403)"
32
+ ]
33
+ },
34
+ {
35
+ "id": 3,
36
+ "prompt": "We have an existing API with these endpoints:\nGET /getUsers\nGET /getUserById?id=123\nPOST /createUser\nPOST /updateUser\nGET /deleteUser?id=123\n\nThis doesn't feel right. Can you redesign it following proper REST conventions?",
37
+ "expected_output": "Should identify specific violations (verbs in URLs, GET for delete, query params for identity) and redesign using proper REST conventions.",
38
+ "assertions": [
39
+ "Identifies that URLs use verbs instead of nouns",
40
+ "Identifies that DELETE uses GET method",
41
+ "Identifies that identity is in query params instead of path",
42
+ "Redesigns to: GET /users, GET /users/:id, POST /users, PATCH /users/:id, DELETE /users/:id",
43
+ "Explains WHY each change matters (not just 'this is the convention')",
44
+ "Notes that this is a breaking change requiring versioning or migration plan"
45
+ ]
46
+ }
47
+ ]
48
+ }
@@ -0,0 +1,147 @@
1
+ # REST API Conventions
2
+
3
+ ## Contents
4
+ - URL naming rules
5
+ - HTTP methods mapping
6
+ - Standard response shapes
7
+ - Pagination patterns
8
+ - Versioning strategies
9
+ - HATEOAS (when to use it)
10
+
11
+ ## URL Naming Rules
12
+
13
+ - Use **plural nouns** for resources: `/users`, `/orders`, `/products`
14
+ - Use **kebab-case** for multi-word resources: `/order-items`, `/payment-methods`
15
+ - Use **path parameters** for identity: `/users/:id`
16
+ - Use **query parameters** for filtering: `/users?role=admin`
17
+ - Use **verbs only for actions** that aren't CRUD: `/orders/:id/cancel`, `/reports/generate`
18
+ - **Max 2 levels** of nesting: `/users/:id/orders` is fine, `/users/:id/orders/:oid/items/:iid/comments` is too deep — flatten it
19
+
20
+ ## HTTP Methods Mapping
21
+
22
+ | Method | Meaning | Idempotent | Safe | Request Body |
23
+ |--------|---------|------------|------|-------------|
24
+ | GET | Read resource(s) | Yes | Yes | No |
25
+ | POST | Create resource or trigger action | No | No | Yes |
26
+ | PUT | Full replace of resource | Yes | No | Yes |
27
+ | PATCH | Partial update of resource | Yes | No | Yes (partial) |
28
+ | DELETE | Remove resource | Yes | No | No (usually) |
29
+
30
+ **PUT vs PATCH**: PUT replaces the entire resource (client sends all fields). PATCH updates only the fields provided. For most APIs, PATCH is more practical and less error-prone. Use PUT only when the client genuinely manages the full state.
31
+
32
+ ## Standard Response Shapes
33
+
34
+ ### Single resource
35
+ ```json
36
+ {
37
+ "data": {
38
+ "id": "usr_abc123",
39
+ "type": "user",
40
+ "name": "Jane Smith",
41
+ "email": "jane@example.com",
42
+ "created_at": "2025-03-05T14:30:00Z"
43
+ }
44
+ }
45
+ ```
46
+
47
+ ### Collection
48
+ ```json
49
+ {
50
+ "data": [
51
+ { "id": "usr_abc123", "name": "Jane Smith" },
52
+ { "id": "usr_def456", "name": "Bob Jones" }
53
+ ],
54
+ "pagination": {
55
+ "next_cursor": "eyJpZCI6MTAwfQ",
56
+ "has_more": true,
57
+ "total_count": 342
58
+ }
59
+ }
60
+ ```
61
+
62
+ ### Created resource (201)
63
+ ```json
64
+ {
65
+ "data": {
66
+ "id": "usr_ghi789",
67
+ "name": "New User",
68
+ "created_at": "2025-03-05T15:00:00Z"
69
+ }
70
+ }
71
+ ```
72
+
73
+ With `Location` header: `Location: /api/v1/users/usr_ghi789`
74
+
75
+ ### Deleted (204)
76
+ No body. Status 204 No Content.
77
+
78
+ ### Error
79
+ ```json
80
+ {
81
+ "error": {
82
+ "code": "NOT_FOUND",
83
+ "message": "User with id 'usr_xyz' not found"
84
+ }
85
+ }
86
+ ```
87
+
88
+ ## Pagination Patterns
89
+
90
+ ### Cursor-based (recommended for most cases)
91
+
92
+ Client sends: `?cursor=abc&limit=20`
93
+ Server returns: `{ pagination: { next_cursor: "def", has_more: true } }`
94
+
95
+ Advantages: Stable under inserts/deletes, efficient with indexes.
96
+ Disadvantage: Can't jump to page N directly.
97
+
98
+ Cursor is usually a base64-encoded identifier (e.g., `btoa(JSON.stringify({id: lastId}))`). Treat it as opaque — clients should never construct cursors.
99
+
100
+ ### Offset-based (for simple cases)
101
+
102
+ Client sends: `?page=3&per_page=20`
103
+ Server returns: `{ pagination: { page: 3, per_page: 20, total_count: 342, total_pages: 18 } }`
104
+
105
+ Advantages: Can jump to any page, easy to implement.
106
+ Disadvantage: Unstable when data changes between pages, slow for large offsets.
107
+
108
+ Use offset only when the dataset is small/stable and users need random page access.
109
+
110
+ ## Versioning Strategies
111
+
112
+ | Strategy | Example | When to Use |
113
+ |----------|---------|-------------|
114
+ | URL path | `/api/v1/users` | Default. Clear, cacheable, easy to route. |
115
+ | Header | `Accept: application/vnd.api+json;version=2` | When URL path isn't desirable (rare). |
116
+ | Query param | `/api/users?version=1` | Avoid. Caching and routing are harder. |
117
+
118
+ Recommended: URL path versioning (`/api/v1/`). Only create v2 when breaking changes are necessary. Additive changes (new fields, new endpoints) don't require a new version.
119
+
120
+ **Breaking changes** that require a new version:
121
+ - Removing or renaming a field
122
+ - Changing a field's type
123
+ - Changing the meaning of a status code
124
+ - Removing an endpoint
125
+
126
+ **Non-breaking changes** (safe within same version):
127
+ - Adding a new field to a response
128
+ - Adding a new endpoint
129
+ - Adding a new query parameter
130
+ - Adding a new optional field to a request body
131
+
132
+ ## HATEOAS
133
+
134
+ Hypermedia (links in responses) is useful for discoverability in public APIs:
135
+
136
+ ```json
137
+ {
138
+ "data": { "id": "ord_123", "status": "pending" },
139
+ "links": {
140
+ "self": "/api/v1/orders/ord_123",
141
+ "cancel": "/api/v1/orders/ord_123/cancel",
142
+ "items": "/api/v1/orders/ord_123/items"
143
+ }
144
+ }
145
+ ```
146
+
147
+ For internal APIs: skip it — your clients already know the URL structure. For public APIs: consider it — it makes the API more self-documenting.