@nano-step/skill-manager 5.6.0 → 5.6.2
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/dist/utils.d.ts +1 -1
- package/dist/utils.js +1 -1
- package/package.json +1 -1
- package/private-catalog.json +5 -0
- package/skills/deep-design/SKILL.md +402 -0
- package/skills/deep-design/evals/evals.json +23 -0
- package/skills/deep-design/skill.json +7 -0
- package/skills/feature-analysis/SKILL.md +290 -0
- package/skills/feature-analysis/skill.json +15 -0
- package/skills/nano-brain/AGENTS_SNIPPET.md +0 -9
- package/skills/nano-brain/skill.json +7 -0
- package/skills/pr-code-reviewer/CHANGELOG.md +287 -0
- package/skills/pr-code-reviewer/RESEARCH.md +60 -0
- package/skills/pr-code-reviewer/SKILL.md +530 -0
- package/skills/pr-code-reviewer/assets/config.json +47 -0
- package/skills/pr-code-reviewer/checklists/backend-express.md +357 -0
- package/skills/pr-code-reviewer/checklists/ci-cd.md +428 -0
- package/skills/pr-code-reviewer/checklists/consumer-search-matrix.md +339 -0
- package/skills/pr-code-reviewer/checklists/database.md +382 -0
- package/skills/pr-code-reviewer/checklists/frontend-vue-nuxt.md +426 -0
- package/skills/pr-code-reviewer/checklists/review-checklist.md +116 -0
- package/skills/pr-code-reviewer/references/framework-rules/express.md +39 -0
- package/skills/pr-code-reviewer/references/framework-rules/nestjs.md +41 -0
- package/skills/pr-code-reviewer/references/framework-rules/typeorm.md +52 -0
- package/skills/pr-code-reviewer/references/framework-rules/typescript.md +50 -0
- package/skills/pr-code-reviewer/references/framework-rules/vue-nuxt.md +53 -0
- package/skills/pr-code-reviewer/references/nano-brain-integration.md +61 -0
- package/skills/pr-code-reviewer/references/performance-patterns.md +26 -0
- package/skills/pr-code-reviewer/references/quality-patterns.md +25 -0
- package/skills/pr-code-reviewer/references/report-template.md +167 -0
- package/skills/pr-code-reviewer/references/security-patterns.md +31 -0
- package/skills/pr-code-reviewer/references/subagent-prompts.md +323 -0
- package/skills/pr-code-reviewer/skill.json +15 -0
- package/skills/rri-t-testing/SKILL.md +224 -0
- package/skills/rri-t-testing/assets/rri-t-coverage-dashboard.md +138 -0
- package/skills/rri-t-testing/assets/rri-t-memory-protocol.md +271 -0
- package/skills/rri-t-testing/assets/rri-t-persona-interview.md +249 -0
- package/skills/rri-t-testing/assets/rri-t-quality-scorecard.md +122 -0
- package/skills/rri-t-testing/assets/rri-t-risk-matrix.md +87 -0
- package/skills/rri-t-testing/assets/rri-t-stress-matrix.md +100 -0
- package/skills/rri-t-testing/assets/rri-t-test-case.md +181 -0
- package/skills/rri-t-testing/assets/rri-t-testability-gate.md +131 -0
- package/skills/rri-t-testing/assets/rri-t-traceability-matrix.md +105 -0
- package/skills/rri-t-testing/skill.json +9 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
# Backend Express Checklist
|
|
2
|
+
|
|
3
|
+
Comprehensive review checklist for Express.js backend PRs (tradeit-backend, tradeit-service, etc.)
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Error Handling
|
|
8
|
+
|
|
9
|
+
### CRITICAL - Must Check
|
|
10
|
+
|
|
11
|
+
| Check | Pattern | Why |
|
|
12
|
+
|-------|---------|-----|
|
|
13
|
+
| All async routes wrapped | `asyncHandler()` or try/catch | Unhandled rejection crashes server |
|
|
14
|
+
| Errors logged with context | `logger.error(err, { context: {...} })` | Debugging requires context |
|
|
15
|
+
| No empty catch blocks | `catch(e) {}` | Swallows errors silently |
|
|
16
|
+
| Errors have proper status codes | `res.fail()` not `res.json({ success: false })` | Consistent API responses |
|
|
17
|
+
|
|
18
|
+
### Detection Patterns
|
|
19
|
+
|
|
20
|
+
```javascript
|
|
21
|
+
// CRITICAL: Unhandled async - will crash on error
|
|
22
|
+
router.get('/api', async (req, res) => {
|
|
23
|
+
const data = await fetchData() // if throws, server crashes
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
// SECURE: Wrapped with asyncHandler
|
|
27
|
+
router.get('/api', asyncHandler(async (req, res) => {
|
|
28
|
+
const data = await fetchData()
|
|
29
|
+
}))
|
|
30
|
+
|
|
31
|
+
// CRITICAL: Empty catch
|
|
32
|
+
try {
|
|
33
|
+
await riskyOperation()
|
|
34
|
+
} catch (e) {} // Error swallowed!
|
|
35
|
+
|
|
36
|
+
// SECURE: Logged with context
|
|
37
|
+
try {
|
|
38
|
+
await riskyOperation()
|
|
39
|
+
} catch (e) {
|
|
40
|
+
logger.error(e, { context: { step: 'riskyOperation', userId } })
|
|
41
|
+
throw e
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 2. Database Operations
|
|
48
|
+
|
|
49
|
+
### CRITICAL - Must Check
|
|
50
|
+
|
|
51
|
+
| Check | Pattern | Why |
|
|
52
|
+
|-------|---------|-----|
|
|
53
|
+
| Named parameters used | `:paramName` not `?` | Readability, prevents order bugs |
|
|
54
|
+
| No string concatenation in SQL | `WHERE id = ${id}` | SQL injection |
|
|
55
|
+
| Transactions have ROLLBACK | `catch { ROLLBACK }` | Data consistency |
|
|
56
|
+
| Large queries have LIMIT | `LIMIT 1000` | Memory/performance |
|
|
57
|
+
|
|
58
|
+
### Detection Patterns
|
|
59
|
+
|
|
60
|
+
```javascript
|
|
61
|
+
// CRITICAL: SQL injection
|
|
62
|
+
await mysql.query(`SELECT * FROM users WHERE id = ${userId}`)
|
|
63
|
+
|
|
64
|
+
// SECURE: Named parameters
|
|
65
|
+
await mysql.query('SELECT * FROM users WHERE id = :userId', { userId })
|
|
66
|
+
|
|
67
|
+
// CRITICAL: Transaction without rollback
|
|
68
|
+
await mysql.query('START TRANSACTION')
|
|
69
|
+
await mysql.query('INSERT INTO orders ...')
|
|
70
|
+
await mysql.query('UPDATE inventory ...')
|
|
71
|
+
await mysql.query('COMMIT') // What if UPDATE fails?
|
|
72
|
+
|
|
73
|
+
// SECURE: Transaction with rollback
|
|
74
|
+
try {
|
|
75
|
+
await mysql.query('START TRANSACTION')
|
|
76
|
+
await mysql.query('INSERT INTO orders ...')
|
|
77
|
+
await mysql.query('UPDATE inventory ...')
|
|
78
|
+
await mysql.query('COMMIT')
|
|
79
|
+
} catch (e) {
|
|
80
|
+
await mysql.query('ROLLBACK')
|
|
81
|
+
throw e
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// WARNING: Unbounded query
|
|
85
|
+
await mysql.query('SELECT * FROM items WHERE status = :status', { status })
|
|
86
|
+
|
|
87
|
+
// SECURE: With limit
|
|
88
|
+
await mysql.query('SELECT * FROM items WHERE status = :status LIMIT 1000', { status })
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 3. Redis Operations
|
|
94
|
+
|
|
95
|
+
### CRITICAL - Must Check
|
|
96
|
+
|
|
97
|
+
| Check | Pattern | Why |
|
|
98
|
+
|-------|---------|-----|
|
|
99
|
+
| setEx has TTL | `Redis.setEx(key, TTL, value)` | Memory leak without TTL |
|
|
100
|
+
| Not using set() for cache | `Redis.set()` without TTL | Use setEx instead |
|
|
101
|
+
| Key patterns consistent | `prefix:${id}:suffix` | Maintainability |
|
|
102
|
+
| Large values compressed | `compressed` suffix | Memory efficiency |
|
|
103
|
+
|
|
104
|
+
### Detection Patterns
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
// WARNING: No TTL - memory leak
|
|
108
|
+
await Redis.set(`cache:${userId}`, JSON.stringify(data))
|
|
109
|
+
|
|
110
|
+
// SECURE: With TTL
|
|
111
|
+
await Redis.setEx(`cache:${userId}`, 3600, JSON.stringify(data))
|
|
112
|
+
|
|
113
|
+
// WARNING: Inconsistent key pattern
|
|
114
|
+
await Redis.get(`user_${userId}`) // underscore
|
|
115
|
+
await Redis.get(`user:${userId}`) // colon
|
|
116
|
+
|
|
117
|
+
// SECURE: Consistent pattern
|
|
118
|
+
const CACHE_PREFIX = 'user:'
|
|
119
|
+
await Redis.get(`${CACHE_PREFIX}${userId}`)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 4. External API Calls
|
|
125
|
+
|
|
126
|
+
### CRITICAL - Must Check
|
|
127
|
+
|
|
128
|
+
| Check | Pattern | Why |
|
|
129
|
+
|-------|---------|-----|
|
|
130
|
+
| Timeout configured | `{ timeout: 30000 }` | Prevents hanging requests |
|
|
131
|
+
| Retry logic for transient errors | Retry on 5xx, network errors | Resilience |
|
|
132
|
+
| Circuit breaker for critical APIs | After N failures, fail fast | Prevents cascade failures |
|
|
133
|
+
| Response validated | Check expected fields exist | Defensive coding |
|
|
134
|
+
|
|
135
|
+
### Detection Patterns
|
|
136
|
+
|
|
137
|
+
```javascript
|
|
138
|
+
// CRITICAL: No timeout - can hang forever
|
|
139
|
+
const response = await axios.get('https://api.steam.com/...')
|
|
140
|
+
|
|
141
|
+
// SECURE: With timeout
|
|
142
|
+
const response = await axios.get('https://api.steam.com/...', {
|
|
143
|
+
timeout: 30000 // 30 seconds
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
// CRITICAL: AI/LLM call without timeout (PR #1101 issue)
|
|
147
|
+
const aiResponse = await openai.chat.completions.create({
|
|
148
|
+
model: 'gpt-4',
|
|
149
|
+
messages: [...]
|
|
150
|
+
}) // Can hang for minutes!
|
|
151
|
+
|
|
152
|
+
// SECURE: With timeout
|
|
153
|
+
const aiResponse = await openai.chat.completions.create({
|
|
154
|
+
model: 'gpt-4',
|
|
155
|
+
messages: [...],
|
|
156
|
+
timeout: 60000 // 60 seconds max
|
|
157
|
+
})
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## 5. Response Handling
|
|
163
|
+
|
|
164
|
+
### CRITICAL - Must Check
|
|
165
|
+
|
|
166
|
+
| Check | Pattern | Why |
|
|
167
|
+
|-------|---------|-----|
|
|
168
|
+
| Use res.success() / res.fail() | Not raw res.json() | Consistent API format |
|
|
169
|
+
| No sensitive data in responses | No passwords, tokens, internal IDs | Security |
|
|
170
|
+
| Response fields documented | JSDoc or TypeScript | API contract |
|
|
171
|
+
| Conditional fields have fallbacks | `field: value || default` | Prevents undefined |
|
|
172
|
+
|
|
173
|
+
### Detection Patterns
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
// WARNING: Raw response
|
|
177
|
+
res.json({ success: true, data })
|
|
178
|
+
|
|
179
|
+
// SECURE: Standard response
|
|
180
|
+
res.success(data)
|
|
181
|
+
|
|
182
|
+
// CRITICAL: Conditional removed (PR #1101 issue!)
|
|
183
|
+
// BEFORE - safe
|
|
184
|
+
imgURL: iconUrl
|
|
185
|
+
? `https://cdn.steam.com/${iconUrl}`
|
|
186
|
+
: `${API_URL}/fallback/${groupId}.webp`
|
|
187
|
+
|
|
188
|
+
// AFTER - breaks when iconUrl is undefined
|
|
189
|
+
imgURL: `https://cdn.steam.com/${iconUrl}` // undefined in URL!
|
|
190
|
+
|
|
191
|
+
// SECURE: Keep fallback or ensure iconUrl always exists
|
|
192
|
+
imgURL: iconUrl
|
|
193
|
+
? `https://cdn.steam.com/${iconUrl}`
|
|
194
|
+
: getFallbackImage(groupId)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## 6. Middleware & Context
|
|
200
|
+
|
|
201
|
+
### CRITICAL - Must Check
|
|
202
|
+
|
|
203
|
+
| Check | Pattern | Why |
|
|
204
|
+
|-------|---------|-----|
|
|
205
|
+
| Middleware order correct | Auth before business logic | Security |
|
|
206
|
+
| httpContext values set before use | `httpContext.set()` in middleware | Runtime errors |
|
|
207
|
+
| Removed middleware has no consumers | Search for `httpContext.get()` | Breaking change |
|
|
208
|
+
|
|
209
|
+
### Detection Patterns
|
|
210
|
+
|
|
211
|
+
```javascript
|
|
212
|
+
// CRITICAL: Middleware removed but consumers exist
|
|
213
|
+
// In index.js - REMOVED:
|
|
214
|
+
// app.use(analyticsMiddleware)
|
|
215
|
+
|
|
216
|
+
// But in controller - STILL USED:
|
|
217
|
+
const analytics = httpContext.get('analytics') // undefined!
|
|
218
|
+
analytics.track(...) // TypeError!
|
|
219
|
+
|
|
220
|
+
// Before removing middleware, search:
|
|
221
|
+
grep -rn "httpContext.get('analytics')" server/
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## 7. Service Logic
|
|
227
|
+
|
|
228
|
+
### CRITICAL - Must Check
|
|
229
|
+
|
|
230
|
+
| Check | Pattern | Why |
|
|
231
|
+
|-------|---------|-----|
|
|
232
|
+
| Default case in switch | `default: throw new Error()` | Handles unexpected values |
|
|
233
|
+
| Null checks before property access | `item?.property` | Prevents TypeError |
|
|
234
|
+
| Array bounds checked | `arr[0]` after `arr.length > 0` | Prevents undefined |
|
|
235
|
+
| Enum values validated | Check against known values | Prevents invalid state |
|
|
236
|
+
|
|
237
|
+
### Detection Patterns
|
|
238
|
+
|
|
239
|
+
```javascript
|
|
240
|
+
// CRITICAL: Default case logic changed (PR #1101 issue!)
|
|
241
|
+
// BEFORE - generates content for all slugs
|
|
242
|
+
switch (slug) {
|
|
243
|
+
case 'knives': return generateKnivesContent()
|
|
244
|
+
case 'gloves': return generateGlovesContent()
|
|
245
|
+
default: return generateGenericContent(slug) // Works for any slug
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// AFTER - only works for root
|
|
249
|
+
switch (slug) {
|
|
250
|
+
case 'knives': return generateKnivesContent()
|
|
251
|
+
case 'gloves': return generateGlovesContent()
|
|
252
|
+
default: return null // Breaks category pages!
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// WARNING: No null check
|
|
256
|
+
const price = item.prices.steam // TypeError if prices undefined
|
|
257
|
+
|
|
258
|
+
// SECURE: Optional chaining
|
|
259
|
+
const price = item?.prices?.steam ?? 0
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## 8. Breaking Change Signals
|
|
265
|
+
|
|
266
|
+
### Auto-Flag These Changes
|
|
267
|
+
|
|
268
|
+
| Signal | Severity | Action |
|
|
269
|
+
|--------|----------|--------|
|
|
270
|
+
| Response field removed | CRITICAL | Search all frontend consumers |
|
|
271
|
+
| Conditional/ternary removed | CRITICAL | Verify fallback not needed |
|
|
272
|
+
| Default case changed | WARNING | Verify all callers handle |
|
|
273
|
+
| Middleware removed | WARNING | Search httpContext consumers |
|
|
274
|
+
| Route path changed | CRITICAL | Update all API consumers |
|
|
275
|
+
| HTTP method changed | CRITICAL | Update all API consumers |
|
|
276
|
+
|
|
277
|
+
### Consumer Search Required
|
|
278
|
+
|
|
279
|
+
When any of the above detected, MUST search:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
# For tradeit-backend changes
|
|
283
|
+
grep -rn "{fieldName}" ../tradeit/
|
|
284
|
+
grep -rn "{fieldName}" ../tradeit-admin/
|
|
285
|
+
grep -rn "{fieldName}" ../tradeit-extension/
|
|
286
|
+
|
|
287
|
+
# For route changes
|
|
288
|
+
grep -rn "/api/v2/{path}" ../tradeit/network/
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## 9. Performance Checks
|
|
294
|
+
|
|
295
|
+
### WARNING - Should Check
|
|
296
|
+
|
|
297
|
+
| Check | Pattern | Why |
|
|
298
|
+
|-------|---------|-----|
|
|
299
|
+
| No N+1 queries | Query in loop | Performance |
|
|
300
|
+
| Batch operations used | `INSERT ... VALUES (...), (...)` | Efficiency |
|
|
301
|
+
| Indexes exist for WHERE clauses | Check migration files | Query speed |
|
|
302
|
+
| Large responses paginated | `limit`, `offset` params | Memory |
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## 10. Security Checks
|
|
307
|
+
|
|
308
|
+
### CRITICAL - Must Check
|
|
309
|
+
|
|
310
|
+
| Check | Pattern | Why |
|
|
311
|
+
|-------|---------|-----|
|
|
312
|
+
| Auth middleware on protected routes | `requireAuth` middleware | Unauthorized access |
|
|
313
|
+
| Input validated | `express-validator` | Injection attacks |
|
|
314
|
+
| Rate limiting on public endpoints | `express-rate-limit` | DoS protection |
|
|
315
|
+
| No secrets in code | API keys, passwords | Security breach |
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Quick Checklist
|
|
320
|
+
|
|
321
|
+
Copy this for PR reviews:
|
|
322
|
+
|
|
323
|
+
```markdown
|
|
324
|
+
## Express Backend Review
|
|
325
|
+
|
|
326
|
+
### Error Handling
|
|
327
|
+
- [ ] All async routes wrapped in try/catch or asyncHandler
|
|
328
|
+
- [ ] Errors logged with context
|
|
329
|
+
- [ ] No empty catch blocks
|
|
330
|
+
|
|
331
|
+
### Database
|
|
332
|
+
- [ ] Named parameters used (not ?)
|
|
333
|
+
- [ ] No SQL string concatenation
|
|
334
|
+
- [ ] Transactions have ROLLBACK
|
|
335
|
+
|
|
336
|
+
### Redis
|
|
337
|
+
- [ ] setEx used with TTL (not set)
|
|
338
|
+
- [ ] Key patterns consistent
|
|
339
|
+
|
|
340
|
+
### External APIs
|
|
341
|
+
- [ ] Timeout configured on all external calls
|
|
342
|
+
- [ ] AI/LLM calls have timeout
|
|
343
|
+
|
|
344
|
+
### Response
|
|
345
|
+
- [ ] res.success()/res.fail() used
|
|
346
|
+
- [ ] Conditionals preserved (no fallback removal)
|
|
347
|
+
|
|
348
|
+
### Breaking Changes
|
|
349
|
+
- [ ] No response fields removed without frontend update
|
|
350
|
+
- [ ] No middleware removed without consumer check
|
|
351
|
+
- [ ] Default case logic unchanged (or verified)
|
|
352
|
+
|
|
353
|
+
### Consumer Search (if breaking change detected)
|
|
354
|
+
- [ ] Searched tradeit frontend
|
|
355
|
+
- [ ] Searched tradeit-admin
|
|
356
|
+
- [ ] Searched tradeit-extension
|
|
357
|
+
```
|