@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.
Files changed (44) hide show
  1. package/dist/utils.d.ts +1 -1
  2. package/dist/utils.js +1 -1
  3. package/package.json +1 -1
  4. package/private-catalog.json +5 -0
  5. package/skills/deep-design/SKILL.md +402 -0
  6. package/skills/deep-design/evals/evals.json +23 -0
  7. package/skills/deep-design/skill.json +7 -0
  8. package/skills/feature-analysis/SKILL.md +290 -0
  9. package/skills/feature-analysis/skill.json +15 -0
  10. package/skills/nano-brain/AGENTS_SNIPPET.md +0 -9
  11. package/skills/nano-brain/skill.json +7 -0
  12. package/skills/pr-code-reviewer/CHANGELOG.md +287 -0
  13. package/skills/pr-code-reviewer/RESEARCH.md +60 -0
  14. package/skills/pr-code-reviewer/SKILL.md +530 -0
  15. package/skills/pr-code-reviewer/assets/config.json +47 -0
  16. package/skills/pr-code-reviewer/checklists/backend-express.md +357 -0
  17. package/skills/pr-code-reviewer/checklists/ci-cd.md +428 -0
  18. package/skills/pr-code-reviewer/checklists/consumer-search-matrix.md +339 -0
  19. package/skills/pr-code-reviewer/checklists/database.md +382 -0
  20. package/skills/pr-code-reviewer/checklists/frontend-vue-nuxt.md +426 -0
  21. package/skills/pr-code-reviewer/checklists/review-checklist.md +116 -0
  22. package/skills/pr-code-reviewer/references/framework-rules/express.md +39 -0
  23. package/skills/pr-code-reviewer/references/framework-rules/nestjs.md +41 -0
  24. package/skills/pr-code-reviewer/references/framework-rules/typeorm.md +52 -0
  25. package/skills/pr-code-reviewer/references/framework-rules/typescript.md +50 -0
  26. package/skills/pr-code-reviewer/references/framework-rules/vue-nuxt.md +53 -0
  27. package/skills/pr-code-reviewer/references/nano-brain-integration.md +61 -0
  28. package/skills/pr-code-reviewer/references/performance-patterns.md +26 -0
  29. package/skills/pr-code-reviewer/references/quality-patterns.md +25 -0
  30. package/skills/pr-code-reviewer/references/report-template.md +167 -0
  31. package/skills/pr-code-reviewer/references/security-patterns.md +31 -0
  32. package/skills/pr-code-reviewer/references/subagent-prompts.md +323 -0
  33. package/skills/pr-code-reviewer/skill.json +15 -0
  34. package/skills/rri-t-testing/SKILL.md +224 -0
  35. package/skills/rri-t-testing/assets/rri-t-coverage-dashboard.md +138 -0
  36. package/skills/rri-t-testing/assets/rri-t-memory-protocol.md +271 -0
  37. package/skills/rri-t-testing/assets/rri-t-persona-interview.md +249 -0
  38. package/skills/rri-t-testing/assets/rri-t-quality-scorecard.md +122 -0
  39. package/skills/rri-t-testing/assets/rri-t-risk-matrix.md +87 -0
  40. package/skills/rri-t-testing/assets/rri-t-stress-matrix.md +100 -0
  41. package/skills/rri-t-testing/assets/rri-t-test-case.md +181 -0
  42. package/skills/rri-t-testing/assets/rri-t-testability-gate.md +131 -0
  43. package/skills/rri-t-testing/assets/rri-t-traceability-matrix.md +105 -0
  44. package/skills/rri-t-testing/skill.json +9 -0
@@ -0,0 +1,339 @@
1
+ # Consumer Search Matrix
2
+
3
+ When reviewing PRs, use this matrix to determine WHAT to search and WHERE.
4
+
5
+ ## Quick Reference
6
+
7
+ | Change Type | Search Repos | Search Patterns | Severity |
8
+ |-------------|--------------|-----------------|----------|
9
+ | API response field removed/renamed | tradeit, tradeit-admin, tradeit-extension | `.{fieldName}`, `{fieldName}:`, `data.{fieldName}` | 🔴 CRITICAL |
10
+ | API endpoint path changed | All frontend repos | `/api/v2/{path}`, network/*.js | 🔴 CRITICAL |
11
+ | Database column removed | From by-database.md readers | `{column_name}`, `{camelCaseName}` | 🔴 CRITICAL |
12
+ | Redis key pattern changed | tradeit-backend, tradeit-socket-server | Exact key string, key prefix | 🟡 WARNING |
13
+ | External URL pattern changed | tradeit, tradeit-admin | Field name holding URL | 🔴 CRITICAL |
14
+ | Middleware removed | Same repo | `httpContext.get()`, middleware name | 🟡 WARNING |
15
+ | Socket event changed | tradeit-socket-server, tradeit | `socket.on()`, `socket.emit()` | 🔴 CRITICAL |
16
+ | Enum/constant changed | All repos importing enums | Enum name, literal value | 🟡 WARNING |
17
+
18
+ ---
19
+
20
+ ## 1. API Response Field Changes
21
+
22
+ ### Detection
23
+ - Diff shows field removed/renamed in `res.success()` or return statement
24
+ - Controller response shape changed
25
+ - Service return value modified
26
+
27
+ ### Search Scope
28
+
29
+ **tradeit-backend changes → Search:**
30
+ | Repo | Location | Pattern |
31
+ |------|----------|---------|
32
+ | tradeit | `network/*.js` | Response destructuring |
33
+ | tradeit | `composables/*.js` | Data field access |
34
+ | tradeit | `components/**/*.vue` | Template bindings |
35
+ | tradeit-admin | `api/*.js`, `services/*.js` | API consumers |
36
+ | tradeit-extension | `src/background/*.js` | Extension API calls |
37
+
38
+ ### Search Patterns
39
+ ```bash
40
+ # Field removed: "imgURL"
41
+ grep -rn "\.imgURL" tradeit/
42
+ grep -rn "imgURL:" tradeit/
43
+ grep -rn "item\.imgURL" tradeit/
44
+ grep -rn "data\.imgURL" tradeit/
45
+
46
+ # Destructuring pattern
47
+ grep -rn "{ imgURL" tradeit/
48
+ grep -rn "{ .*imgURL.*}" tradeit/
49
+ ```
50
+
51
+ ### Critical Fields (NEVER remove without migration)
52
+
53
+ **User Data** (`/api/v2/user/data`):
54
+ - `balance`, `storeBalance`, `steamId`, `email`
55
+ - `firstTradeBonus`, `stripeAccountId`
56
+ - `likedItemMap`, `likedAssetMap`
57
+ - `currencyPreference`, `tickets`
58
+
59
+ **Inventory** (`/api/v2/inventory/*`):
60
+ - `items[]`, `reserveAssetIds`, `tradeAwayAssetIds`
61
+ - `assetId`, `imgURL`, `price`, `name`
62
+ - `chartData`, `appId`, `groupId`
63
+
64
+ **Trade** (`/api/v2/trade/*`):
65
+ - `success`, `message`, `tradesInfo`
66
+ - `trades[]`, `tradeId`, `status`
67
+
68
+ **Insight** (`/api/v2/insight/*`):
69
+ - `chartData`, `stockData`, `marketContent`
70
+ - `sections`, `stats`
71
+
72
+ ---
73
+
74
+ ## 2. API Endpoint Path Changes
75
+
76
+ ### Detection
77
+ - Route definition changed in `routes/*.js`
78
+ - HTTP method changed (GET→POST)
79
+ - Path parameter renamed
80
+
81
+ ### Search Scope
82
+ ```bash
83
+ # Search all frontend repos for API path
84
+ grep -rn "/api/v2/insight" tradeit/network/
85
+ grep -rn "/api/v2/insight" tradeit-admin/
86
+ grep -rn "insight" tradeit/network/*.js
87
+ ```
88
+
89
+ ### Network File Mapping
90
+
91
+ | Backend Route File | Frontend Network File |
92
+ |-------------------|----------------------|
93
+ | `routes/user.js` | `network/userNetwork.js` |
94
+ | `routes/inventory.js` | `network/inventoryNetwork.js` |
95
+ | `routes/trade.js` | `network/tradeNetwork.js` |
96
+ | `routes/sell.js` | `network/sellNetwork.js` |
97
+ | `routes/insight.js` | `network/insightNetwork.js` |
98
+ | `routes/meta.js` | `network/metaNetwork.js` |
99
+ | `routes/steam.js` | `network/steamNetwork.js` |
100
+ | `routes/stripe.js` | `network/paymentNetwork.js` |
101
+ | `routes/giveaway.js` | `network/giveawayNetwork.js` |
102
+ | `routes/skinCollection.js` | `network/skinCollectionNetwork.js` |
103
+ | `routes/coupons.js` | `network/couponNetwork.js` |
104
+ | `routes/oauth2.js` | `network/oauth2Network.js` |
105
+ | `routes/guessGame.js` | `network/guessGameNetwork.js` |
106
+ | `routes/invest.js` | `network/investNetwork.js` |
107
+
108
+ ---
109
+
110
+ ## 3. Database Schema Changes
111
+
112
+ ### Detection
113
+ - SQL query column list changed
114
+ - Migration file added
115
+ - Repository method modified
116
+
117
+ ### Search Scope (from by-database.md)
118
+
119
+ | Table | Owner (Write) | Readers (Search These) |
120
+ |-------|---------------|------------------------|
121
+ | `item_prices` | pricing-manager | tradeit-backend, tradeit-service |
122
+ | `trades` | tradeit-backend | tradeit-service, tradeit-admin-backend |
123
+ | `users` | tradeit-backend | ALL services |
124
+ | `items_meta` | bymykel-scraper | tradeit-backend, pricing-manager |
125
+ | `pro_players` | pro-settings-scraper | tradeit-backend |
126
+
127
+ ### Search Patterns
128
+ ```bash
129
+ # Column "stable_price" removed
130
+ grep -rn "stable_price" tradeit-backend/server/repository/
131
+ grep -rn "stablePrice" tradeit-backend/server/ # camelCase version
132
+ grep -rn "stablePrice" tradeit/ # frontend usage
133
+ ```
134
+
135
+ ---
136
+
137
+ ## 4. Redis Key Changes
138
+
139
+ ### Detection
140
+ - Redis key pattern changed in `redis/*.js`
141
+ - Key prefix modified
142
+ - TTL changed significantly
143
+
144
+ ### Search Scope
145
+ | Repo | Redis Usage |
146
+ |------|-------------|
147
+ | tradeit-backend | Session, cache, pubsub, queue |
148
+ | tradeit-socket-server | Pubsub, real-time state |
149
+ | pricing-manager | Price cache |
150
+ | tradeit-inventory-server | Inventory cache |
151
+
152
+ ### Common Key Patterns
153
+ ```javascript
154
+ // Inventory cache
155
+ `cinv:${steamId}:${gameId}:compressed`
156
+ `sinv:${steamId}:${gameId}`
157
+
158
+ // User data
159
+ `ud:${steamId}`
160
+ `steamLevel:${steamId}`
161
+
162
+ // Insight cache
163
+ `insight_chart:${gameId}:${slug}`
164
+ `insight_chart_item_details:${gameId}:${itemId}`
165
+ ```
166
+
167
+ ---
168
+
169
+ ## 5. External URL Pattern Changes
170
+
171
+ ### Detection
172
+ - URL template changed (CDN, Steam, etc.)
173
+ - Conditional URL logic removed
174
+ - Domain changed
175
+
176
+ ### Example: imgURL Change (PR #1101)
177
+ ```javascript
178
+ // BEFORE (conditional)
179
+ imgURL: iconUrl
180
+ ? `https://steamcommunity-a.akamaihd.net/economy/image/${iconUrl}/140fx140f`
181
+ : `${process.env.TRADEIT_API_URL}static/img/items-webp-256/${groupId}.webp`
182
+
183
+ // AFTER (always Steam CDN)
184
+ imgURL: `https://steamcommunity-a.akamaihd.net/economy/image/${iconUrl}/256fx256f`
185
+ ```
186
+
187
+ ### Search for URL consumers
188
+ ```bash
189
+ # Find all imgURL usages
190
+ grep -rn "imgURL" tradeit/composables/
191
+ grep -rn "imgURL" tradeit/components/
192
+ grep -rn "\.imgURL" tradeit/
193
+
194
+ # Found 30+ usages in PR #1101 review
195
+ ```
196
+
197
+ ---
198
+
199
+ ## 6. Middleware/Context Changes
200
+
201
+ ### Detection
202
+ - Middleware removed from `index.js`
203
+ - `httpContext.set()` removed
204
+ - Request context field removed
205
+
206
+ ### Search Scope (same repo)
207
+ ```bash
208
+ # Analytics middleware removed
209
+ grep -rn "httpContext.get('analytics')" server/
210
+ grep -rn "analyticsService" server/
211
+ ```
212
+
213
+ ### Common Context Keys
214
+ - `analytics` - Analytics instance
215
+ - `mysqlConnection` - DB connection
216
+ - `requestId` - Request tracking
217
+ - `logger` - Request-scoped logger
218
+
219
+ ---
220
+
221
+ ## 7. Socket Event Changes
222
+
223
+ ### Detection
224
+ - Event name changed in emit/on calls
225
+ - Event payload structure changed
226
+ - Channel/room changed
227
+
228
+ ### Search Scope
229
+ | Change In | Search |
230
+ |-----------|--------|
231
+ | tradeit-backend | tradeit-socket-server, tradeit |
232
+ | tradeit-socket-server | tradeit, tradeit-admin |
233
+
234
+ ### Common Events
235
+ ```javascript
236
+ // Trade events
237
+ 'trade:created', 'trade:updated', 'trade:completed'
238
+
239
+ // Inventory events
240
+ 'inventory:updated', 'inventory:reserved'
241
+
242
+ // User events
243
+ 'user:balance', 'user:notification'
244
+ ```
245
+
246
+ ---
247
+
248
+ ## 8. Enum/Constant Changes
249
+
250
+ ### Detection
251
+ - Value changed in `config/enums.js`
252
+ - Constant renamed
253
+ - New enum value added (usually safe)
254
+
255
+ ### Search Scope
256
+ ```bash
257
+ # CSGO_GAME_ID changed
258
+ grep -rn "CSGO_GAME_ID" tradeit-backend/
259
+ grep -rn "730" tradeit-backend/ # literal value
260
+ grep -rn "CSGO_GAME_ID" tradeit/
261
+ ```
262
+
263
+ ### Critical Enums
264
+ - `CSGO_GAME_ID`, `RUST_GAME_ID`, `DOTA2_GAME_ID`
265
+ - `TradeStatus`, `BotTradeItemStatus`
266
+ - `configurationKeys`
267
+ - `CsgoSlugType`, `InsightRootSlug`
268
+
269
+ ---
270
+
271
+ ## Automated Search Commands
272
+
273
+ ### For PR Review
274
+ ```bash
275
+ # 1. Get changed files
276
+ git diff --name-only base..head
277
+
278
+ # 2. For each changed controller, find response fields
279
+ grep -A5 "res.success" server/controllers/{file}.js
280
+
281
+ # 3. Search frontend for field usage
282
+ for field in $(extract_fields); do
283
+ grep -rn "\.${field}" ../tradeit/
284
+ grep -rn "${field}:" ../tradeit/
285
+ done
286
+
287
+ # 4. Search other backend repos
288
+ for repo in tradeit-service tradeit-admin-backend; do
289
+ grep -rn "{pattern}" ../${repo}/
290
+ done
291
+ ```
292
+
293
+ ### GitHub Search (for remote repos)
294
+ ```bash
295
+ # Search across organization
296
+ gh search code "imgURL" --owner zengamingx --language javascript
297
+
298
+ # Search specific repo
299
+ gh search code "imgURL" --repo zengamingx/tradeit
300
+ ```
301
+
302
+ ---
303
+
304
+ ## Severity Guide
305
+
306
+ | Severity | Meaning | Action |
307
+ |----------|---------|--------|
308
+ | 🔴 CRITICAL | Will crash/break functionality | Block PR, require fix |
309
+ | 🟡 WARNING | May cause issues, needs verification | Request changes, verify |
310
+ | 🟢 SAFE | Low risk, informational | Note in review |
311
+
312
+ ### Auto-Block Triggers
313
+ - Response field removed without frontend update
314
+ - API path changed without network file update
315
+ - Database column removed with active readers
316
+ - Middleware removed with active consumers
317
+
318
+ ---
319
+
320
+ ## Cross-Repo Search Checklist
321
+
322
+ When reviewing a PR, check these boxes:
323
+
324
+ ```markdown
325
+ ## Consumer Search Completed
326
+
327
+ - [ ] Searched tradeit frontend for API field usage
328
+ - [ ] Searched tradeit-admin for admin API usage
329
+ - [ ] Searched tradeit-extension for extension usage
330
+ - [ ] Checked by-database.md for DB table readers
331
+ - [ ] Searched Redis key consumers (if applicable)
332
+ - [ ] Searched socket event subscribers (if applicable)
333
+ - [ ] Verified enum/constant consumers (if applicable)
334
+
335
+ ## Findings
336
+ | Consumer | File | Impact |
337
+ |----------|------|--------|
338
+ | ... | ... | ... |
339
+ ```
@@ -0,0 +1,382 @@
1
+ # Database Checklist
2
+
3
+ Comprehensive review checklist for database-related changes (MySQL, Redis, migrations).
4
+
5
+ ---
6
+
7
+ ## 1. MySQL Query Safety
8
+
9
+ ### CRITICAL - Must Check
10
+
11
+ | Check | Pattern | Why |
12
+ |-------|---------|-----|
13
+ | Named parameters | `:paramName` | Prevents SQL injection, readable |
14
+ | No string concatenation | `WHERE id = ${id}` | SQL injection |
15
+ | Parameterized IN clauses | `WHERE id IN (:ids)` | Injection protection |
16
+ | LIMIT on SELECT | `LIMIT 1000` | Memory protection |
17
+
18
+ ### Detection Patterns
19
+
20
+ ```javascript
21
+ // CRITICAL: SQL injection via concatenation
22
+ await mysql.query(`SELECT * FROM users WHERE id = ${userId}`)
23
+ await mysql.query(`SELECT * FROM items WHERE name LIKE '%${search}%'`)
24
+
25
+ // SECURE: Named parameters
26
+ await mysql.query('SELECT * FROM users WHERE id = :userId', { userId })
27
+ await mysql.query('SELECT * FROM items WHERE name LIKE :search', { search: `%${search}%` })
28
+
29
+ // CRITICAL: Unbounded query
30
+ await mysql.query('SELECT * FROM items WHERE status = :status', { status })
31
+
32
+ // SECURE: With limit
33
+ await mysql.query('SELECT * FROM items WHERE status = :status LIMIT 1000', { status })
34
+
35
+ // WARNING: Dynamic column names (can't parameterize)
36
+ await mysql.query(`SELECT ${columns} FROM items`) // Validate columns first!
37
+
38
+ // SECURE: Whitelist columns
39
+ const allowedColumns = ['id', 'name', 'price']
40
+ const safeColumns = columns.filter(c => allowedColumns.includes(c))
41
+ await mysql.query(`SELECT ${safeColumns.join(',')} FROM items`)
42
+ ```
43
+
44
+ ---
45
+
46
+ ## 2. Transactions
47
+
48
+ ### CRITICAL - Must Check
49
+
50
+ | Check | Pattern | Why |
51
+ |-------|---------|-----|
52
+ | Multi-table ops in transaction | `START TRANSACTION` | Data consistency |
53
+ | ROLLBACK in catch | `catch { ROLLBACK }` | Cleanup on error |
54
+ | Connection released | `finally { release() }` | Connection pool |
55
+ | Deadlock handling | Retry on deadlock | Resilience |
56
+
57
+ ### Detection Patterns
58
+
59
+ ```javascript
60
+ // CRITICAL: Multi-table without transaction
61
+ await mysql.query('INSERT INTO orders ...')
62
+ await mysql.query('UPDATE inventory SET quantity = quantity - 1 ...')
63
+ await mysql.query('INSERT INTO order_items ...')
64
+ // If any fails, data is inconsistent!
65
+
66
+ // SECURE: With transaction
67
+ const connection = await mysql.getConnection()
68
+ try {
69
+ await connection.query('START TRANSACTION')
70
+ await connection.query('INSERT INTO orders ...')
71
+ await connection.query('UPDATE inventory SET quantity = quantity - 1 ...')
72
+ await connection.query('INSERT INTO order_items ...')
73
+ await connection.query('COMMIT')
74
+ } catch (e) {
75
+ await connection.query('ROLLBACK')
76
+ throw e
77
+ } finally {
78
+ connection.release()
79
+ }
80
+
81
+ // WARNING: No deadlock handling
82
+ try {
83
+ await runTransaction()
84
+ } catch (e) {
85
+ throw e // Deadlock causes permanent failure
86
+ }
87
+
88
+ // SECURE: Retry on deadlock
89
+ const MAX_RETRIES = 3
90
+ for (let i = 0; i < MAX_RETRIES; i++) {
91
+ try {
92
+ await runTransaction()
93
+ break
94
+ } catch (e) {
95
+ if (e.code === 'ER_LOCK_DEADLOCK' && i < MAX_RETRIES - 1) {
96
+ await sleep(100 * (i + 1)) // Exponential backoff
97
+ continue
98
+ }
99
+ throw e
100
+ }
101
+ }
102
+ ```
103
+
104
+ ---
105
+
106
+ ## 3. Schema Changes
107
+
108
+ ### CRITICAL - Must Check
109
+
110
+ | Check | Pattern | Why |
111
+ |-------|---------|-----|
112
+ | Column removal has migration | Check readers first | Breaking change |
113
+ | Index added for new WHERE | `CREATE INDEX` | Query performance |
114
+ | NOT NULL has default | `DEFAULT value` | Existing rows |
115
+ | Foreign key has ON DELETE | `ON DELETE CASCADE/SET NULL` | Referential integrity |
116
+
117
+ ### Detection Patterns
118
+
119
+ ```sql
120
+ -- CRITICAL: Removing column without checking readers
121
+ ALTER TABLE items DROP COLUMN stable_price;
122
+ -- Search all repos for 'stable_price' first!
123
+
124
+ -- WARNING: Adding NOT NULL without default
125
+ ALTER TABLE users ADD COLUMN verified BOOLEAN NOT NULL;
126
+ -- Fails if table has existing rows!
127
+
128
+ -- SECURE: With default
129
+ ALTER TABLE users ADD COLUMN verified BOOLEAN NOT NULL DEFAULT FALSE;
130
+
131
+ -- WARNING: Missing index on frequently queried column
132
+ SELECT * FROM items WHERE status = 'active' AND game_id = 730;
133
+ -- If no index on (status, game_id), full table scan!
134
+
135
+ -- SECURE: Add composite index
136
+ CREATE INDEX idx_items_status_game ON items(status, game_id);
137
+
138
+ -- WARNING: Foreign key without ON DELETE
139
+ ALTER TABLE order_items ADD FOREIGN KEY (order_id) REFERENCES orders(id);
140
+ -- What happens when order deleted?
141
+
142
+ -- SECURE: Specify behavior
143
+ ALTER TABLE order_items ADD FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE;
144
+ ```
145
+
146
+ ---
147
+
148
+ ## 4. Query Performance
149
+
150
+ ### WARNING - Should Check
151
+
152
+ | Check | Pattern | Why |
153
+ |-------|---------|-----|
154
+ | No SELECT * | List specific columns | Network, memory |
155
+ | Indexes used | EXPLAIN shows index | Query speed |
156
+ | No N+1 queries | Query in loop | Performance |
157
+ | Pagination for large results | LIMIT + OFFSET | Memory |
158
+
159
+ ### Detection Patterns
160
+
161
+ ```javascript
162
+ // WARNING: SELECT * (fetches all columns)
163
+ await mysql.query('SELECT * FROM items WHERE id = :id', { id })
164
+
165
+ // SECURE: Specific columns
166
+ await mysql.query('SELECT id, name, price FROM items WHERE id = :id', { id })
167
+
168
+ // CRITICAL: N+1 query pattern
169
+ const users = await mysql.query('SELECT * FROM users')
170
+ for (const user of users) {
171
+ const orders = await mysql.query('SELECT * FROM orders WHERE user_id = :userId', { userId: user.id })
172
+ // N+1 queries!
173
+ }
174
+
175
+ // SECURE: JOIN or batch query
176
+ const usersWithOrders = await mysql.query(`
177
+ SELECT u.*, o.* FROM users u
178
+ LEFT JOIN orders o ON o.user_id = u.id
179
+ `)
180
+
181
+ // Or batch:
182
+ const userIds = users.map(u => u.id)
183
+ const orders = await mysql.query('SELECT * FROM orders WHERE user_id IN (:userIds)', { userIds })
184
+
185
+ // WARNING: No pagination
186
+ const items = await mysql.query('SELECT * FROM items') // Could be millions!
187
+
188
+ // SECURE: Paginated
189
+ const items = await mysql.query('SELECT * FROM items LIMIT :limit OFFSET :offset', { limit: 100, offset: page * 100 })
190
+ ```
191
+
192
+ ---
193
+
194
+ ## 5. Redis Operations
195
+
196
+ ### CRITICAL - Must Check
197
+
198
+ | Check | Pattern | Why |
199
+ |-------|---------|-----|
200
+ | TTL on all cache keys | `setEx()` not `set()` | Memory leak |
201
+ | Key naming consistent | `prefix:${id}:suffix` | Maintainability |
202
+ | Large values compressed | JSON.stringify + compress | Memory |
203
+ | Pipeline for batch ops | `multi()...exec()` | Performance |
204
+
205
+ ### Detection Patterns
206
+
207
+ ```javascript
208
+ // CRITICAL: No TTL - memory leak
209
+ await redis.set(`cache:${userId}`, JSON.stringify(data))
210
+
211
+ // SECURE: With TTL
212
+ await redis.setEx(`cache:${userId}`, 3600, JSON.stringify(data))
213
+
214
+ // WARNING: Inconsistent key patterns
215
+ await redis.get(`user_${userId}`) // underscore
216
+ await redis.get(`user:${otherId}`) // colon
217
+ await redis.get(`USER:${anotherId}`) // uppercase
218
+
219
+ // SECURE: Consistent pattern with constants
220
+ const KEYS = {
221
+ user: (id) => `user:${id}`,
222
+ inventory: (steamId, gameId) => `inv:${steamId}:${gameId}`,
223
+ }
224
+ await redis.get(KEYS.user(userId))
225
+
226
+ // WARNING: Multiple individual operations
227
+ for (const key of keys) {
228
+ await redis.get(key) // N round trips!
229
+ }
230
+
231
+ // SECURE: Pipeline
232
+ const pipeline = redis.pipeline()
233
+ for (const key of keys) {
234
+ pipeline.get(key)
235
+ }
236
+ const results = await pipeline.exec()
237
+
238
+ // WARNING: Large value without compression
239
+ const largeData = { items: [...thousandsOfItems] }
240
+ await redis.setEx(key, 3600, JSON.stringify(largeData)) // Could be MBs!
241
+
242
+ // SECURE: Compress large values
243
+ const compressed = await compress(JSON.stringify(largeData))
244
+ await redis.setEx(`${key}:compressed`, 3600, compressed)
245
+ ```
246
+
247
+ ---
248
+
249
+ ## 6. Redis Key Changes (Breaking)
250
+
251
+ ### CRITICAL - Must Check
252
+
253
+ | Check | Pattern | Why |
254
+ |-------|---------|-----|
255
+ | Key pattern change | Search all consumers | Breaking change |
256
+ | Key prefix change | Update all services | Data loss |
257
+ | TTL significantly changed | Verify cache strategy | Stale data |
258
+
259
+ ### Consumer Search Required
260
+
261
+ ```bash
262
+ # Key pattern changed from `user:${id}` to `u:${id}`
263
+ grep -rn "user:" tradeit-backend/
264
+ grep -rn "user:" tradeit-socket-server/
265
+ grep -rn "user:" pricing-manager/
266
+
267
+ # Check by-database.md for Redis consumers
268
+ cat .agents/_indexes/by-database.md | grep "Redis"
269
+ ```
270
+
271
+ ### Common Key Patterns (DO NOT CHANGE without migration)
272
+
273
+ ```javascript
274
+ // User data
275
+ `ud:${steamId}` // User data cache
276
+ `steamLevel:${steamId}` // Steam level cache
277
+
278
+ // Inventory
279
+ `cinv:${steamId}:${gameId}:compressed` // Compressed inventory
280
+ `sinv:${steamId}:${gameId}` // Store inventory
281
+
282
+ // Insight
283
+ `insight_chart:${gameId}:${slug}` // Chart data cache
284
+ `insight_chart_item_details:${gameId}:${itemId}`
285
+
286
+ // Session
287
+ `sess:${sessionId}` // User session
288
+
289
+ // Queue
290
+ `bull:${queueName}:*` // Bull queue keys
291
+ ```
292
+
293
+ ---
294
+
295
+ ## 7. Migration Safety
296
+
297
+ ### CRITICAL - Must Check
298
+
299
+ | Check | Pattern | Why |
300
+ |-------|---------|-----|
301
+ | Backward compatible | Old code still works | Zero-downtime deploy |
302
+ | Reversible | Can rollback | Safety |
303
+ | Tested on copy | Run on staging first | Catch issues |
304
+ | Large table handled | pt-online-schema-change | Lock avoidance |
305
+
306
+ ### Detection Patterns
307
+
308
+ ```sql
309
+ -- CRITICAL: Non-backward compatible change
310
+ ALTER TABLE users RENAME COLUMN email TO email_address;
311
+ -- Old code using 'email' will break!
312
+
313
+ -- SECURE: Add new, migrate, remove old
314
+ ALTER TABLE users ADD COLUMN email_address VARCHAR(255);
315
+ UPDATE users SET email_address = email;
316
+ -- Deploy code that uses both
317
+ -- Later: ALTER TABLE users DROP COLUMN email;
318
+
319
+ -- WARNING: Large table ALTER without pt-osc
320
+ ALTER TABLE items ADD INDEX idx_price (price);
321
+ -- On 10M+ row table, this locks for minutes!
322
+
323
+ -- SECURE: Use pt-online-schema-change
324
+ pt-online-schema-change --alter "ADD INDEX idx_price (price)" D=tradeit,t=items
325
+ ```
326
+
327
+ ---
328
+
329
+ ## 8. Data Integrity
330
+
331
+ ### CRITICAL - Must Check
332
+
333
+ | Check | Pattern | Why |
334
+ |-------|---------|-----|
335
+ | Unique constraints | `UNIQUE INDEX` | Prevent duplicates |
336
+ | Foreign keys | `REFERENCES` | Referential integrity |
337
+ | Check constraints | `CHECK (price >= 0)` | Data validation |
338
+ | NOT NULL where required | `NOT NULL` | Prevent nulls |
339
+
340
+ ---
341
+
342
+ ## Quick Checklist
343
+
344
+ Copy this for PR reviews:
345
+
346
+ ```markdown
347
+ ## Database Review
348
+
349
+ ### MySQL Queries
350
+ - [ ] Named parameters used (not string concatenation)
351
+ - [ ] LIMIT on SELECT queries
352
+ - [ ] No SELECT * (specific columns listed)
353
+ - [ ] Indexes exist for WHERE/JOIN columns
354
+
355
+ ### Transactions
356
+ - [ ] Multi-table operations in transaction
357
+ - [ ] ROLLBACK in catch block
358
+ - [ ] Connection released in finally
359
+ - [ ] Deadlock retry logic (if applicable)
360
+
361
+ ### Schema Changes
362
+ - [ ] Column removal checked against all readers
363
+ - [ ] New columns have defaults (if NOT NULL)
364
+ - [ ] Indexes added for new query patterns
365
+ - [ ] Migration is backward compatible
366
+
367
+ ### Redis
368
+ - [ ] TTL on all cache keys (setEx, not set)
369
+ - [ ] Key naming follows conventions
370
+ - [ ] Large values compressed
371
+ - [ ] Pipeline used for batch operations
372
+
373
+ ### Breaking Changes
374
+ - [ ] No column removed without consumer check
375
+ - [ ] No Redis key pattern changed without migration
376
+ - [ ] Schema change tested on staging
377
+
378
+ ### Consumer Search (if schema changed)
379
+ - [ ] Checked by-database.md for table readers
380
+ - [ ] Searched all repos for column name
381
+ - [ ] Searched all repos for Redis key pattern
382
+ ```