@valentia-ai-skills/framework 1.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.
- package/README.md +103 -0
- package/bin/cli.js +482 -0
- package/package.json +42 -0
- package/scripts/postinstall.js +18 -0
- package/skills/global/api-design/SKILL.md +248 -0
- package/skills/global/api-design/tests/test-prompts.md +25 -0
- package/skills/global/code-standards/SKILL.md +245 -0
- package/skills/global/code-standards/tests/test-prompts.md +26 -0
- package/skills/global/deployment/SKILL.md +240 -0
- package/skills/global/deployment/tests/test-prompts.md +27 -0
- package/skills/global/documentation/SKILL.md +298 -0
- package/skills/global/documentation/tests/test-prompts.md +26 -0
- package/skills/global/git-workflow/SKILL.md +177 -0
- package/skills/global/git-workflow/tests/test-prompts.md +11 -0
- package/skills/global/security-baseline/SKILL.md +239 -0
- package/skills/global/security-baseline/tests/test-prompts.md +23 -0
- package/skills/global/testing-standards/SKILL.md +257 -0
- package/skills/global/testing-standards/tests/test-prompts.md +25 -0
- package/skills/onboarding/SKILL.md +110 -0
- package/skills/stack/devops/SKILL.md +220 -0
- package/skills/stack/devops/tests/test-prompts.md +29 -0
- package/skills/stack/node-backend/SKILL.md +304 -0
- package/skills/stack/node-backend/tests/test-prompts.md +27 -0
- package/skills/stack/python-backend/SKILL.md +304 -0
- package/skills/stack/python-backend/tests/test-prompts.md +27 -0
- package/skills/stack/react/SKILL.md +251 -0
- package/skills/stack/react/tests/test-prompts.md +26 -0
- package/skills/stack/react-native/SKILL.md +255 -0
- package/skills/stack/react-native/tests/test-prompts.md +26 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api-design
|
|
3
|
+
description: >
|
|
4
|
+
Organization-wide API design standards for REST and GraphQL APIs. Use this skill
|
|
5
|
+
whenever writing, reviewing, or designing API endpoints, routes, controllers,
|
|
6
|
+
resolvers, request/response schemas, error responses, pagination, filtering,
|
|
7
|
+
versioning, or any server-side request handling. Triggers on: "API", "endpoint",
|
|
8
|
+
"route", "controller", "REST", "GraphQL", "request", "response", "status code",
|
|
9
|
+
"pagination", "filtering", "versioning", "CRUD", "resource", "middleware",
|
|
10
|
+
"interceptor", "guard", "serializer", "DTO". Applies to all backend stacks.
|
|
11
|
+
version: "1.0.0"
|
|
12
|
+
scope: global
|
|
13
|
+
author: Framework Admin
|
|
14
|
+
last_reviewed: 2026-03-19
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# API Design Standards
|
|
18
|
+
|
|
19
|
+
## Overview
|
|
20
|
+
|
|
21
|
+
Consistent API design across all teams ensures that frontend developers, mobile
|
|
22
|
+
developers, and third-party consumers can predictably interact with any service
|
|
23
|
+
in the organization. These standards apply to both REST and GraphQL APIs.
|
|
24
|
+
|
|
25
|
+
## 1. URL Structure (REST)
|
|
26
|
+
|
|
27
|
+
### Resource Naming
|
|
28
|
+
- Use **plural nouns** for resources: `/users`, `/orders`, `/products`
|
|
29
|
+
- Use **kebab-case** for multi-word resources: `/order-items`, `/user-profiles`
|
|
30
|
+
- Nest resources to express relationships (max 2 levels deep)
|
|
31
|
+
- Never use verbs in URLs — HTTP methods express the action
|
|
32
|
+
|
|
33
|
+
✅ Good:
|
|
34
|
+
```
|
|
35
|
+
GET /users # list users
|
|
36
|
+
GET /users/:id # get single user
|
|
37
|
+
POST /users # create user
|
|
38
|
+
PATCH /users/:id # partial update
|
|
39
|
+
DELETE /users/:id # delete user
|
|
40
|
+
GET /users/:id/orders # list user's orders
|
|
41
|
+
GET /users/:id/orders/:orderId # specific order for user
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
❌ Bad:
|
|
45
|
+
```
|
|
46
|
+
GET /getUsers # verb in URL
|
|
47
|
+
GET /user/list # singular + verb
|
|
48
|
+
POST /createUser # verb in URL
|
|
49
|
+
GET /users/:id/orders/:orderId/items/:itemId/reviews # too deep (3 levels)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Nesting Rule
|
|
53
|
+
If nesting exceeds 2 levels, flatten with query parameters:
|
|
54
|
+
```
|
|
55
|
+
# Instead of: GET /users/:id/orders/:orderId/items
|
|
56
|
+
# Use: GET /order-items?orderId=123
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 2. HTTP Methods & Status Codes
|
|
60
|
+
|
|
61
|
+
### Method Usage
|
|
62
|
+
| Method | Purpose | Idempotent | Request Body |
|
|
63
|
+
|--------|---------|------------|-------------|
|
|
64
|
+
| GET | Read resource(s) | Yes | No |
|
|
65
|
+
| POST | Create resource | No | Yes |
|
|
66
|
+
| PATCH | Partial update | Yes | Yes (partial) |
|
|
67
|
+
| PUT | Full replace | Yes | Yes (complete) |
|
|
68
|
+
| DELETE | Remove resource | Yes | No |
|
|
69
|
+
|
|
70
|
+
### Status Code Reference
|
|
71
|
+
|
|
72
|
+
**Success:**
|
|
73
|
+
| Code | When to Use |
|
|
74
|
+
|------|------------|
|
|
75
|
+
| 200 | Successful GET, PATCH, PUT |
|
|
76
|
+
| 201 | Successful POST (resource created) |
|
|
77
|
+
| 204 | Successful DELETE (no response body) |
|
|
78
|
+
|
|
79
|
+
**Client Errors:**
|
|
80
|
+
| Code | When to Use |
|
|
81
|
+
|------|------------|
|
|
82
|
+
| 400 | Invalid request body / validation failure |
|
|
83
|
+
| 401 | Not authenticated (missing/invalid token) |
|
|
84
|
+
| 403 | Authenticated but not authorized |
|
|
85
|
+
| 404 | Resource not found |
|
|
86
|
+
| 409 | Conflict (duplicate, version mismatch) |
|
|
87
|
+
| 422 | Semantically invalid (valid JSON but bad data) |
|
|
88
|
+
| 429 | Rate limited |
|
|
89
|
+
|
|
90
|
+
**Server Errors:**
|
|
91
|
+
| Code | When to Use |
|
|
92
|
+
|------|------------|
|
|
93
|
+
| 500 | Unexpected server error |
|
|
94
|
+
| 502 | Bad gateway / upstream failure |
|
|
95
|
+
| 503 | Service unavailable (maintenance, overload) |
|
|
96
|
+
|
|
97
|
+
### Common Mistakes
|
|
98
|
+
- ❌ Returning 200 for errors with `{ success: false }` — use proper status codes
|
|
99
|
+
- ❌ Returning 500 for validation errors — use 400 or 422
|
|
100
|
+
- ❌ Returning 403 when you mean 401 — 401 = "who are you?", 403 = "you can't do that"
|
|
101
|
+
|
|
102
|
+
## 3. Request & Response Format
|
|
103
|
+
|
|
104
|
+
### Standard Response Envelope
|
|
105
|
+
|
|
106
|
+
All API responses follow this structure:
|
|
107
|
+
|
|
108
|
+
**Success (single resource):**
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"data": {
|
|
112
|
+
"id": "usr_abc123",
|
|
113
|
+
"email": "alice@example.com",
|
|
114
|
+
"name": "Alice",
|
|
115
|
+
"createdAt": "2026-03-19T10:30:00Z"
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Success (collection):**
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"data": [
|
|
124
|
+
{ "id": "usr_abc123", "name": "Alice" },
|
|
125
|
+
{ "id": "usr_def456", "name": "Bob" }
|
|
126
|
+
],
|
|
127
|
+
"pagination": {
|
|
128
|
+
"page": 1,
|
|
129
|
+
"pageSize": 20,
|
|
130
|
+
"totalItems": 156,
|
|
131
|
+
"totalPages": 8
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Error:**
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"error": {
|
|
140
|
+
"code": "VALIDATION_ERROR",
|
|
141
|
+
"message": "Invalid request data",
|
|
142
|
+
"details": [
|
|
143
|
+
{ "field": "email", "message": "Must be a valid email address" },
|
|
144
|
+
{ "field": "age", "message": "Must be at least 13" }
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Rules
|
|
151
|
+
- Always wrap data in a `data` key (even single resources)
|
|
152
|
+
- Always wrap errors in an `error` key with `code`, `message`, and optional `details`
|
|
153
|
+
- Use ISO 8601 for all dates: `2026-03-19T10:30:00Z`
|
|
154
|
+
- Use camelCase for JSON keys
|
|
155
|
+
- Use prefixed IDs where possible: `usr_abc123`, `ord_def456`
|
|
156
|
+
- Never expose internal database IDs or auto-increment integers to clients
|
|
157
|
+
|
|
158
|
+
## 4. Pagination
|
|
159
|
+
|
|
160
|
+
### Standard: Offset-Based (default)
|
|
161
|
+
```
|
|
162
|
+
GET /users?page=2&pageSize=20
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Response includes `pagination` object (see above).
|
|
166
|
+
|
|
167
|
+
### Alternative: Cursor-Based (for large datasets)
|
|
168
|
+
```
|
|
169
|
+
GET /users?cursor=eyJpZCI6MTIzfQ&limit=20
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Response:
|
|
173
|
+
```json
|
|
174
|
+
{
|
|
175
|
+
"data": [...],
|
|
176
|
+
"pagination": {
|
|
177
|
+
"nextCursor": "eyJpZCI6MTQzfQ",
|
|
178
|
+
"hasMore": true
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Rules
|
|
184
|
+
- Default page size: 20
|
|
185
|
+
- Maximum page size: 100
|
|
186
|
+
- Always include total count for offset pagination
|
|
187
|
+
- Use cursor pagination for feeds, timelines, or datasets > 10K records
|
|
188
|
+
|
|
189
|
+
## 5. Filtering & Sorting
|
|
190
|
+
|
|
191
|
+
### Filtering
|
|
192
|
+
```
|
|
193
|
+
GET /users?status=active&role=admin
|
|
194
|
+
GET /orders?createdAfter=2026-01-01&createdBefore=2026-03-01
|
|
195
|
+
GET /products?minPrice=10&maxPrice=100
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Sorting
|
|
199
|
+
```
|
|
200
|
+
GET /users?sort=createdAt:desc
|
|
201
|
+
GET /products?sort=price:asc,name:asc
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Format: `field:direction` with comma separation for multiple sorts.
|
|
205
|
+
|
|
206
|
+
## 6. Versioning
|
|
207
|
+
|
|
208
|
+
### URL-Based Versioning (preferred)
|
|
209
|
+
```
|
|
210
|
+
/api/v1/users
|
|
211
|
+
/api/v2/users
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Rules
|
|
215
|
+
- Version in the URL path, not headers
|
|
216
|
+
- Only bump major version for breaking changes
|
|
217
|
+
- Support previous version for minimum 6 months after deprecation
|
|
218
|
+
- Add `Sunset` header to deprecated versions:
|
|
219
|
+
```
|
|
220
|
+
Sunset: Sat, 01 Oct 2026 00:00:00 GMT
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## 7. Rate Limiting
|
|
224
|
+
|
|
225
|
+
All APIs must implement rate limiting:
|
|
226
|
+
|
|
227
|
+
- Include rate limit headers in every response:
|
|
228
|
+
```
|
|
229
|
+
X-RateLimit-Limit: 100
|
|
230
|
+
X-RateLimit-Remaining: 95
|
|
231
|
+
X-RateLimit-Reset: 1679290800
|
|
232
|
+
```
|
|
233
|
+
- Return 429 when limit exceeded
|
|
234
|
+
- Default limits: 100 requests/minute per authenticated user
|
|
235
|
+
|
|
236
|
+
## Checklist
|
|
237
|
+
|
|
238
|
+
Before finalizing any API code:
|
|
239
|
+
- [ ] URLs use plural nouns, kebab-case, no verbs
|
|
240
|
+
- [ ] Correct HTTP methods and status codes
|
|
241
|
+
- [ ] Response wrapped in `data` or `error` envelope
|
|
242
|
+
- [ ] Dates in ISO 8601 format
|
|
243
|
+
- [ ] JSON keys in camelCase
|
|
244
|
+
- [ ] Pagination included for list endpoints
|
|
245
|
+
- [ ] Input validation on all endpoints (see security-baseline skill)
|
|
246
|
+
- [ ] No internal IDs exposed to clients
|
|
247
|
+
- [ ] Rate limiting headers present
|
|
248
|
+
- [ ] API versioned in URL path
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
## Test 1: CRUD Endpoint Design
|
|
2
|
+
**Prompt**: "Design the REST API endpoints for a blog post system with posts, comments, and tags"
|
|
3
|
+
**Expected**:
|
|
4
|
+
- Plural nouns: /posts, /comments, /tags
|
|
5
|
+
- Proper nesting: /posts/:id/comments (max 2 levels)
|
|
6
|
+
- All CRUD methods with correct status codes
|
|
7
|
+
- Response envelope with data/error pattern
|
|
8
|
+
- Pagination on list endpoints
|
|
9
|
+
|
|
10
|
+
## Test 2: Error Handling
|
|
11
|
+
**Prompt**: "Write the error handling middleware for an Express API that returns consistent error responses"
|
|
12
|
+
**Expected**:
|
|
13
|
+
- Error envelope: { error: { code, message, details } }
|
|
14
|
+
- Correct status codes (400 for validation, 401 for auth, 404 for not found)
|
|
15
|
+
- No stack traces or internal details exposed
|
|
16
|
+
- Proper differentiation between 401 and 403
|
|
17
|
+
|
|
18
|
+
## Test 3: Complex Query Endpoint
|
|
19
|
+
**Prompt**: "Build a product search endpoint with filtering by price range, category, and rating, with sorting and pagination"
|
|
20
|
+
**Expected**:
|
|
21
|
+
- Query params: minPrice, maxPrice, category, minRating
|
|
22
|
+
- Sort format: sort=price:asc
|
|
23
|
+
- Offset pagination with page, pageSize, totalItems
|
|
24
|
+
- Default and max page sizes enforced
|
|
25
|
+
- Input validation on all query params
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-standards
|
|
3
|
+
description: >
|
|
4
|
+
Organization-wide coding standards and conventions. Use this skill whenever
|
|
5
|
+
writing, reviewing, or refactoring ANY code — regardless of language or stack.
|
|
6
|
+
Triggers on: writing functions, classes, components, modules, variables,
|
|
7
|
+
constants, files, folders, imports, exports, or any code structure. Also
|
|
8
|
+
triggers when asked to "clean up", "refactor", "fix style", "rename",
|
|
9
|
+
"restructure", or "organize" code. This skill applies to ALL programming
|
|
10
|
+
languages and stacks used in the organization.
|
|
11
|
+
version: "1.0.0"
|
|
12
|
+
scope: global
|
|
13
|
+
author: Framework Admin
|
|
14
|
+
last_reviewed: 2026-03-19
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Code Standards
|
|
18
|
+
|
|
19
|
+
## Overview
|
|
20
|
+
|
|
21
|
+
These are the organization-wide coding conventions that every team must follow.
|
|
22
|
+
They ensure consistency across all projects, make code reviews faster, and
|
|
23
|
+
reduce cognitive load when developers move between teams.
|
|
24
|
+
|
|
25
|
+
## 1. Naming Conventions
|
|
26
|
+
|
|
27
|
+
### Variables & Functions
|
|
28
|
+
- Use `camelCase` for variables, functions, and method names
|
|
29
|
+
- Use descriptive names — optimize for readability, not brevity
|
|
30
|
+
- Boolean variables start with `is`, `has`, `can`, `should`
|
|
31
|
+
- Functions that return booleans follow the same prefix pattern
|
|
32
|
+
- Event handlers prefixed with `handle` (components) or `on` (props)
|
|
33
|
+
|
|
34
|
+
✅ Good:
|
|
35
|
+
```
|
|
36
|
+
const isUserActive = true;
|
|
37
|
+
const hasPermission = checkPermission(user);
|
|
38
|
+
function calculateTotalPrice(items) { ... }
|
|
39
|
+
function handleFormSubmit(event) { ... }
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
❌ Bad:
|
|
43
|
+
```
|
|
44
|
+
const active = true; // unclear what is active
|
|
45
|
+
const flag = check(u); // meaningless names
|
|
46
|
+
function calc(i) { ... } // too abbreviated
|
|
47
|
+
function submit(e) { ... } // missing handle prefix
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Classes & Types
|
|
51
|
+
- Use `PascalCase` for classes, interfaces, types, enums
|
|
52
|
+
- Interfaces do NOT use `I` prefix (no `IUser`, just `User`)
|
|
53
|
+
- Type aliases use `PascalCase`
|
|
54
|
+
- Enum members use `UPPER_SNAKE_CASE`
|
|
55
|
+
|
|
56
|
+
✅ Good:
|
|
57
|
+
```
|
|
58
|
+
class UserService { ... }
|
|
59
|
+
interface UserProfile { ... }
|
|
60
|
+
type ApiResponse<T> = { ... }
|
|
61
|
+
enum UserRole { ADMIN, EDITOR, VIEWER }
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
❌ Bad:
|
|
65
|
+
```
|
|
66
|
+
class userService { ... } // wrong case
|
|
67
|
+
interface IUserProfile { ... } // no I prefix
|
|
68
|
+
enum UserRole { admin, Editor } // inconsistent casing
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Files & Folders
|
|
72
|
+
- Use `kebab-case` for file and folder names
|
|
73
|
+
- One primary export per file
|
|
74
|
+
- File name matches the primary export (in kebab-case)
|
|
75
|
+
- Test files: `{filename}.test.{ext}` or `{filename}.spec.{ext}`
|
|
76
|
+
|
|
77
|
+
✅ Good:
|
|
78
|
+
```
|
|
79
|
+
user-service.ts → exports class UserService
|
|
80
|
+
calculate-price.ts → exports function calculatePrice
|
|
81
|
+
user-profile.tsx → exports component UserProfile
|
|
82
|
+
user-service.test.ts → tests for UserService
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
❌ Bad:
|
|
86
|
+
```
|
|
87
|
+
UserService.ts // PascalCase file name
|
|
88
|
+
utils.ts // vague, multi-export dumping ground
|
|
89
|
+
helpers/misc.ts // meaningless names
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Constants
|
|
93
|
+
- Use `UPPER_SNAKE_CASE` for true constants (compile-time values)
|
|
94
|
+
- Use `camelCase` for runtime constants (values that don't change but are computed)
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
const MAX_RETRY_COUNT = 3; // true constant
|
|
98
|
+
const API_BASE_URL = "/api/v1"; // true constant
|
|
99
|
+
const defaultConfig = loadConfig(); // runtime constant
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 2. File Structure
|
|
103
|
+
|
|
104
|
+
### Maximum File Length
|
|
105
|
+
- **Hard limit**: 300 lines per file
|
|
106
|
+
- If a file exceeds 300 lines, it must be split into smaller modules
|
|
107
|
+
- Exception: generated files, data fixtures, and type definitions
|
|
108
|
+
|
|
109
|
+
### Import Order (enforced)
|
|
110
|
+
Group imports in this order, separated by blank lines:
|
|
111
|
+
1. External packages (node_modules)
|
|
112
|
+
2. Internal packages / aliases (@ paths)
|
|
113
|
+
3. Relative imports (../ and ./)
|
|
114
|
+
4. Type-only imports
|
|
115
|
+
5. Side-effect imports
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
// 1. External
|
|
119
|
+
import express from "express";
|
|
120
|
+
import { z } from "zod";
|
|
121
|
+
|
|
122
|
+
// 2. Internal
|
|
123
|
+
import { UserService } from "@/services/user-service";
|
|
124
|
+
import { logger } from "@/lib/logger";
|
|
125
|
+
|
|
126
|
+
// 3. Relative
|
|
127
|
+
import { formatDate } from "../utils/date";
|
|
128
|
+
import { Button } from "./button";
|
|
129
|
+
|
|
130
|
+
// 4. Types
|
|
131
|
+
import type { User } from "@/types/user";
|
|
132
|
+
|
|
133
|
+
// 5. Side effects
|
|
134
|
+
import "./styles.css";
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Export Rules
|
|
138
|
+
- Prefer named exports over default exports (except React components)
|
|
139
|
+
- One primary export per file
|
|
140
|
+
- Re-export from index files for clean public APIs
|
|
141
|
+
|
|
142
|
+
## 3. Functions
|
|
143
|
+
|
|
144
|
+
### Size & Complexity
|
|
145
|
+
- Maximum 40 lines per function
|
|
146
|
+
- Maximum 3 levels of nesting
|
|
147
|
+
- Maximum 4 parameters (use an options object for more)
|
|
148
|
+
- Single responsibility — each function does ONE thing
|
|
149
|
+
|
|
150
|
+
### Parameter Objects
|
|
151
|
+
When a function needs more than 4 parameters, use a typed options object:
|
|
152
|
+
|
|
153
|
+
✅ Good:
|
|
154
|
+
```typescript
|
|
155
|
+
interface CreateUserOptions {
|
|
156
|
+
name: string;
|
|
157
|
+
email: string;
|
|
158
|
+
role: UserRole;
|
|
159
|
+
department: string;
|
|
160
|
+
managerId?: string;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function createUser(options: CreateUserOptions) { ... }
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
❌ Bad:
|
|
167
|
+
```typescript
|
|
168
|
+
function createUser(name, email, role, dept, managerId, isActive) { ... }
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Return Early
|
|
172
|
+
Use early returns to reduce nesting:
|
|
173
|
+
|
|
174
|
+
✅ Good:
|
|
175
|
+
```typescript
|
|
176
|
+
function processOrder(order: Order) {
|
|
177
|
+
if (!order) return null;
|
|
178
|
+
if (!order.isValid) return { error: "Invalid order" };
|
|
179
|
+
if (order.isPaid) return order;
|
|
180
|
+
|
|
181
|
+
return processPayment(order);
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
❌ Bad:
|
|
186
|
+
```typescript
|
|
187
|
+
function processOrder(order: Order) {
|
|
188
|
+
if (order) {
|
|
189
|
+
if (order.isValid) {
|
|
190
|
+
if (!order.isPaid) {
|
|
191
|
+
return processPayment(order);
|
|
192
|
+
} else {
|
|
193
|
+
return order;
|
|
194
|
+
}
|
|
195
|
+
} else {
|
|
196
|
+
return { error: "Invalid order" };
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## 4. Error Handling
|
|
204
|
+
|
|
205
|
+
- Never swallow errors silently — always log or rethrow
|
|
206
|
+
- Use custom error classes for domain-specific errors
|
|
207
|
+
- Include context in error messages (what failed, with what input)
|
|
208
|
+
- Use try/catch at service boundaries, not around every line
|
|
209
|
+
|
|
210
|
+
✅ Good:
|
|
211
|
+
```typescript
|
|
212
|
+
try {
|
|
213
|
+
const user = await userService.findById(userId);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
logger.error("Failed to fetch user", { userId, error: error.message });
|
|
216
|
+
throw new UserNotFoundError(`User ${userId} not found`, { cause: error });
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
❌ Bad:
|
|
221
|
+
```typescript
|
|
222
|
+
try {
|
|
223
|
+
const user = await userService.findById(userId);
|
|
224
|
+
} catch (e) {
|
|
225
|
+
// silently ignored
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## 5. Comments
|
|
230
|
+
|
|
231
|
+
- Code should be self-documenting — comments explain WHY, not WHAT
|
|
232
|
+
- Use JSDoc/docstrings for public APIs and exported functions
|
|
233
|
+
- Delete commented-out code — that's what git history is for
|
|
234
|
+
- TODO comments must include a ticket number: `// TODO(PROJ-123): description`
|
|
235
|
+
|
|
236
|
+
## 6. Formatting Checklist
|
|
237
|
+
|
|
238
|
+
Before finalizing any code output, verify:
|
|
239
|
+
- [ ] All names follow the casing conventions above
|
|
240
|
+
- [ ] File is under 300 lines
|
|
241
|
+
- [ ] Functions are under 40 lines with ≤ 3 nesting levels
|
|
242
|
+
- [ ] Imports are grouped in the correct order
|
|
243
|
+
- [ ] No silent error swallowing
|
|
244
|
+
- [ ] No commented-out code
|
|
245
|
+
- [ ] Boolean variables use is/has/can/should prefix
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
## Test 1: New Function Creation
|
|
2
|
+
**Prompt**: "Write a function that fetches a user from the database by email, checks if they're active, and returns their profile with recent orders"
|
|
3
|
+
**Expected**:
|
|
4
|
+
- Function named descriptively (e.g., `getUserProfileWithOrders`)
|
|
5
|
+
- Parameters use camelCase
|
|
6
|
+
- Boolean check uses `isActive` pattern
|
|
7
|
+
- Error handling with context
|
|
8
|
+
- Under 40 lines, early returns
|
|
9
|
+
|
|
10
|
+
## Test 2: Refactoring Messy Code
|
|
11
|
+
**Prompt**: "Refactor this: `function do_stuff(a, b, c, d, e, f) { try { if (a) { if (b) { if (c) { return process(d, e, f); } } } } catch(e) {} }`"
|
|
12
|
+
**Expected**:
|
|
13
|
+
- Renamed to descriptive name
|
|
14
|
+
- Parameters grouped into options object (>4 params)
|
|
15
|
+
- Nesting reduced via early returns
|
|
16
|
+
- Error handling added (not swallowed)
|
|
17
|
+
- camelCase naming
|
|
18
|
+
|
|
19
|
+
## Test 3: File Organization
|
|
20
|
+
**Prompt**: "Create a user registration module with validation, database save, email notification, and audit logging"
|
|
21
|
+
**Expected**:
|
|
22
|
+
- Split into multiple files (not one 500-line file)
|
|
23
|
+
- kebab-case file names
|
|
24
|
+
- Proper import ordering
|
|
25
|
+
- Named exports
|
|
26
|
+
- Each file has single responsibility
|