codecruise 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 (129) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/bin/codecruise.js +68 -0
  4. package/config/CLAUDE.md +107 -0
  5. package/config/agents/analyst.md +48 -0
  6. package/config/agents/architect-reviewer.md +161 -0
  7. package/config/agents/architect.md +119 -0
  8. package/config/agents/critic.md +63 -0
  9. package/config/agents/developer.md +96 -0
  10. package/config/agents/devops.md +81 -0
  11. package/config/agents/orchestrator.md +91 -0
  12. package/config/agents/planner.md +139 -0
  13. package/config/agents/retro.md +52 -0
  14. package/config/agents/reviewer.md +101 -0
  15. package/config/agents/security-reviewer.md +57 -0
  16. package/config/agents/stack/expo/AGENT.md +473 -0
  17. package/config/agents/stack/expo/rules/critical.md +427 -0
  18. package/config/agents/stack/expo/rules/native.md +455 -0
  19. package/config/agents/stack/expo/rules/navigation.md +445 -0
  20. package/config/agents/stack/expo/rules/performance.md +415 -0
  21. package/config/agents/stack/fastify/AGENT.md +397 -0
  22. package/config/agents/stack/fastify/rules/api-design.md +283 -0
  23. package/config/agents/stack/fastify/rules/critical.md +232 -0
  24. package/config/agents/stack/fastify/rules/queues.md +303 -0
  25. package/config/agents/stack/fastify/rules/security.md +384 -0
  26. package/config/agents/stack/index.yaml +48 -0
  27. package/config/agents/stack/nextjs/AGENT.md +421 -0
  28. package/config/agents/stack/nextjs/rules/components.md +413 -0
  29. package/config/agents/stack/nextjs/rules/critical.md +391 -0
  30. package/config/agents/stack/nextjs/rules/performance.md +403 -0
  31. package/config/agents/stack/nextjs/rules/styling.md +334 -0
  32. package/config/agents/stack/shared-ts/AGENT.md +384 -0
  33. package/config/agents/stack/shared-ts/rules/critical.md +315 -0
  34. package/config/agents/stack/shared-ts/rules/patterns.md +384 -0
  35. package/config/agents/stack/shared-ts/rules/zod.md +427 -0
  36. package/config/agents/tester.md +79 -0
  37. package/config/commands/architect-discuss.md +366 -0
  38. package/config/commands/architect-list.md +160 -0
  39. package/config/commands/architect-review.md +111 -0
  40. package/config/commands/architect.md +118 -0
  41. package/config/commands/compact.md +118 -0
  42. package/config/commands/companion.md +279 -0
  43. package/config/commands/dashboard.md +152 -0
  44. package/config/commands/doctor.md +227 -0
  45. package/config/commands/dogfood-report.md +101 -0
  46. package/config/commands/flags/run-autonomous.md +110 -0
  47. package/config/commands/flags/run-pause.md +80 -0
  48. package/config/commands/ingest.md +173 -0
  49. package/config/commands/init.md +128 -0
  50. package/config/commands/metrics.md +87 -0
  51. package/config/commands/parallel.md +320 -0
  52. package/config/commands/pause.md +55 -0
  53. package/config/commands/plan-review.md +130 -0
  54. package/config/commands/plan.md +216 -0
  55. package/config/commands/production-check.md +308 -0
  56. package/config/commands/refine.md +323 -0
  57. package/config/commands/resume.md +72 -0
  58. package/config/commands/retro.md +121 -0
  59. package/config/commands/retry.md +75 -0
  60. package/config/commands/role.md +310 -0
  61. package/config/commands/run.md +417 -0
  62. package/config/commands/scope.md +85 -0
  63. package/config/commands/setup-permissions.md +104 -0
  64. package/config/commands/skip.md +75 -0
  65. package/config/commands/spec-forge.md +213 -0
  66. package/config/commands/spec-help.md +194 -0
  67. package/config/commands/spec-patch.md +342 -0
  68. package/config/commands/spec-resolve.md +110 -0
  69. package/config/commands/spec-review.md +153 -0
  70. package/config/commands/status.md +114 -0
  71. package/config/commands/sync.md +131 -0
  72. package/config/commands/task.md +138 -0
  73. package/config/commands/verify.md +124 -0
  74. package/config/hooks/README.md +632 -0
  75. package/config/hooks/activity-log.sh +187 -0
  76. package/config/hooks/anti-rationalize.sh +52 -0
  77. package/config/hooks/capture-verification.sh +112 -0
  78. package/config/hooks/collect-metrics.sh +135 -0
  79. package/config/hooks/enforce-file-scope.sh +75 -0
  80. package/config/hooks/enforce-state-machine.sh +161 -0
  81. package/config/hooks/enforce-tdd.sh +180 -0
  82. package/config/hooks/format.sh +40 -0
  83. package/config/hooks/lib/activity-helpers.sh +162 -0
  84. package/config/hooks/lib/read-settings.sh +71 -0
  85. package/config/hooks/load-context-skills.sh +95 -0
  86. package/config/hooks/notify.sh +81 -0
  87. package/config/hooks/pre-commit.sample +35 -0
  88. package/config/hooks/protect-files.sh +63 -0
  89. package/config/hooks/track-agents.sh +41 -0
  90. package/config/hooks/track-commands.sh +37 -0
  91. package/config/hooks/track-enforcement.sh +44 -0
  92. package/config/hooks/track-ooda.sh +77 -0
  93. package/config/hooks/validate-commit-msg.sh +35 -0
  94. package/config/hooks/validate-plan.sh +213 -0
  95. package/config/hooks/verify-criteria.sh +46 -0
  96. package/config/hooks/verify-todo-completion.sh +140 -0
  97. package/config/rules/comments.md +25 -0
  98. package/config/rules/decision-rules.md +308 -0
  99. package/config/rules/hygiene.md +247 -0
  100. package/config/rules/pattern-detection.md +372 -0
  101. package/config/rules/profiles.md +193 -0
  102. package/config/rules/recovery.md +83 -0
  103. package/config/rules/scope-detection.md +213 -0
  104. package/config/rules/standards.md +127 -0
  105. package/config/rules/workflow.md +121 -0
  106. package/config/schemas.md +767 -0
  107. package/config/settings.json +195 -0
  108. package/config/skills/backend/SKILL.md +734 -0
  109. package/config/skills/database/SKILL.md +426 -0
  110. package/config/skills/frontend/SKILL.md +434 -0
  111. package/config/skills/git/SKILL.md +396 -0
  112. package/config/skills/index.yaml +36 -0
  113. package/config/skills/observability/SKILL.md +430 -0
  114. package/config/skills/package-dev/SKILL.md +498 -0
  115. package/config/skills/performance/SKILL.md +378 -0
  116. package/config/skills/resilience/SKILL.md +573 -0
  117. package/config/skills/testing/SKILL.md +398 -0
  118. package/config/skills/testing-patterns/SKILL.md +276 -0
  119. package/config/skills/typescript/SKILL.md +152 -0
  120. package/config/templates/CLAUDE.md +70 -0
  121. package/config/templates/README.md +117 -0
  122. package/config/templates/steering/adr-template.md +102 -0
  123. package/config/templates/steering/product.md +60 -0
  124. package/config/templates/steering/rfc-template.md +159 -0
  125. package/config/templates/steering/structure.md +146 -0
  126. package/config/templates/steering/tech.md +85 -0
  127. package/package.json +40 -0
  128. package/src/install.js +163 -0
  129. package/src/report.js +310 -0
@@ -0,0 +1,426 @@
1
+ ---
2
+ name: db-patterns
3
+ description: Database patterns - N+1 prevention, transactions, cursors, migrations
4
+ keywords: [database, query, transaction, migration, drizzle, prisma, n+1, cursor, pagination]
5
+ ---
6
+
7
+ # Database Standards
8
+
9
+ Query performance, transactions, and migration best practices.
10
+
11
+ ## Query Performance
12
+
13
+ ### N+1 Prevention
14
+
15
+ **N+1 queries are blockers in code review.**
16
+
17
+ ```typescript
18
+ // ❌ N+1 PROBLEM
19
+ const users = await db.user.findMany();
20
+ for (const user of users) {
21
+ const orders = await db.order.findMany({ where: { userId: user.id } });
22
+ // This executes N+1 queries!
23
+ }
24
+
25
+ // ✅ EAGER LOADING (Prisma)
26
+ const users = await db.user.findMany({
27
+ include: {
28
+ orders: true,
29
+ },
30
+ });
31
+
32
+ // ✅ BATCH LOADING (DataLoader pattern)
33
+ const ordersByUserLoader = new DataLoader(async (userIds: string[]) => {
34
+ const orders = await db.order.findMany({
35
+ where: { userId: { in: userIds } },
36
+ });
37
+ return userIds.map(id => orders.filter(o => o.userId === id));
38
+ });
39
+
40
+ // Now fetches in batches
41
+ const users = await db.user.findMany();
42
+ const ordersPerUser = await Promise.all(
43
+ users.map(u => ordersByUserLoader.load(u.id))
44
+ );
45
+ ```
46
+
47
+ ### Index Requirements
48
+
49
+ | Column Type | Index Required |
50
+ |-------------|----------------|
51
+ | Foreign keys | Always |
52
+ | Frequently filtered | Always |
53
+ | Frequently sorted | Always |
54
+ | Unique constraints | Automatic |
55
+ | Full-text search | Specialized (GIN/GIST) |
56
+
57
+ ```sql
58
+ -- Foreign keys
59
+ CREATE INDEX idx_orders_user_id ON orders(user_id);
60
+ CREATE INDEX idx_order_items_order_id ON order_items(order_id);
61
+
62
+ -- Composite for common queries
63
+ CREATE INDEX idx_orders_user_status ON orders(user_id, status);
64
+ CREATE INDEX idx_orders_created_at ON orders(created_at DESC);
65
+
66
+ -- Partial index for common filter
67
+ CREATE INDEX idx_orders_pending ON orders(created_at)
68
+ WHERE status = 'pending';
69
+ ```
70
+
71
+ ### Query Analysis
72
+
73
+ Before deploying any complex query, run EXPLAIN ANALYZE:
74
+
75
+ ```sql
76
+ EXPLAIN ANALYZE
77
+ SELECT o.*, u.email
78
+ FROM orders o
79
+ JOIN users u ON o.user_id = u.id
80
+ WHERE o.status = 'pending'
81
+ AND o.created_at > NOW() - INTERVAL '7 days'
82
+ ORDER BY o.created_at DESC
83
+ LIMIT 100;
84
+ ```
85
+
86
+ **Red flags in execution plan:**
87
+ - Sequential scan on large tables
88
+ - Nested loops with large row counts
89
+ - Sort operations without index
90
+ - Hash joins with memory spills
91
+
92
+ ### Pagination
93
+
94
+ Never use OFFSET for large datasets:
95
+
96
+ ```typescript
97
+ // ❌ OFFSET pagination (slow on large datasets)
98
+ const page2 = await db.order.findMany({
99
+ skip: 1000,
100
+ take: 100,
101
+ });
102
+
103
+ // ✅ CURSOR pagination (constant time)
104
+ const page2 = await db.order.findMany({
105
+ take: 100,
106
+ cursor: { id: lastSeenId },
107
+ skip: 1, // Skip the cursor itself
108
+ orderBy: { createdAt: 'desc' },
109
+ });
110
+ ```
111
+
112
+ ## Transactions
113
+
114
+ ### When to Use
115
+
116
+ - Multi-table mutations that must be atomic
117
+ - Read-then-write patterns (check-then-act)
118
+ - Operations requiring consistent snapshots
119
+ - Financial/billing operations (always)
120
+
121
+ ### Implementation
122
+
123
+ ```typescript
124
+ // Prisma interactive transaction
125
+ async function transferFunds(
126
+ fromAccountId: string,
127
+ toAccountId: string,
128
+ amount: number
129
+ ): Promise<void> {
130
+ await db.$transaction(async (tx) => {
131
+ // Debit source account
132
+ const fromAccount = await tx.account.update({
133
+ where: { id: fromAccountId },
134
+ data: { balance: { decrement: amount } },
135
+ });
136
+
137
+ if (fromAccount.balance < 0) {
138
+ throw new ValidationError('INSUFFICIENT_FUNDS', 'Insufficient balance');
139
+ }
140
+
141
+ // Credit destination account
142
+ await tx.account.update({
143
+ where: { id: toAccountId },
144
+ data: { balance: { increment: amount } },
145
+ });
146
+
147
+ // Record transfer
148
+ await tx.transfer.create({
149
+ data: {
150
+ fromAccountId,
151
+ toAccountId,
152
+ amount,
153
+ status: 'completed',
154
+ },
155
+ });
156
+ });
157
+ }
158
+ ```
159
+
160
+ ### Isolation Levels
161
+
162
+ | Level | Use Case | Trade-off |
163
+ |-------|----------|-----------|
164
+ | Read Committed | Default, most operations | Allows non-repeatable reads |
165
+ | Repeatable Read | Financial reports, analytics | Slightly slower |
166
+ | Serializable | Critical financial ops | Slowest, potential retries |
167
+
168
+ ```typescript
169
+ // Set isolation level for sensitive operations
170
+ await db.$transaction(
171
+ async (tx) => {
172
+ // ... sensitive operations
173
+ },
174
+ {
175
+ isolationLevel: 'Serializable',
176
+ maxWait: 5000,
177
+ timeout: 10000,
178
+ }
179
+ );
180
+ ```
181
+
182
+ ### Deadlock Handling
183
+
184
+ ```typescript
185
+ async function withRetry<T>(
186
+ operation: () => Promise<T>,
187
+ maxRetries = 3
188
+ ): Promise<T> {
189
+ let lastError: Error;
190
+
191
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
192
+ try {
193
+ return await operation();
194
+ } catch (error) {
195
+ lastError = error as Error;
196
+
197
+ // Check if deadlock
198
+ const isDeadlock =
199
+ error instanceof Prisma.PrismaClientKnownRequestError &&
200
+ error.code === 'P2034';
201
+
202
+ if (!isDeadlock || attempt === maxRetries) {
203
+ throw error;
204
+ }
205
+
206
+ // Exponential backoff
207
+ await sleep(Math.pow(2, attempt) * 100 + Math.random() * 100);
208
+ }
209
+ }
210
+
211
+ throw lastError!;
212
+ }
213
+
214
+ // Usage
215
+ await withRetry(() => transferFunds(from, to, amount));
216
+ ```
217
+
218
+ ## Connection Management
219
+
220
+ ### Pool Configuration
221
+
222
+ ```typescript
223
+ // Prisma connection pool (via DATABASE_URL)
224
+ // postgresql://user:pass@host:5432/db?connection_limit=20&pool_timeout=10
225
+
226
+ const poolConfig = {
227
+ connectionLimit: Math.floor(maxConnections / numberOfInstances),
228
+ poolTimeout: 10, // seconds to wait for connection
229
+ idleTimeout: 60, // seconds before idle connection is closed
230
+ };
231
+ ```
232
+
233
+ ### Connection Limits
234
+
235
+ | Environment | Pool Size | Reasoning |
236
+ |-------------|-----------|-----------|
237
+ | Development | 5 | Single instance |
238
+ | Staging | 10 | Limited replicas |
239
+ | Production | 20-50 | Depends on RDS/instance |
240
+
241
+ Formula: `pool_size = (max_connections - reserved) / num_instances`
242
+
243
+ ## Migrations
244
+
245
+ ### Requirements
246
+
247
+ 1. **Idempotent**: Can run multiple times safely
248
+ 2. **Reversible**: Down migration provided
249
+ 3. **Tested**: Verified with production-scale data
250
+ 4. **Documented**: Breaking changes noted
251
+
252
+ ### Migration Template
253
+
254
+ ```typescript
255
+ // migrations/20240115_add_user_preferences.ts
256
+
257
+ export async function up(db: Knex): Promise<void> {
258
+ // Check if already exists (idempotent)
259
+ const hasTable = await db.schema.hasTable('user_preferences');
260
+ if (hasTable) return;
261
+
262
+ await db.schema.createTable('user_preferences', (table) => {
263
+ table.uuid('id').primary().defaultTo(db.raw('gen_random_uuid()'));
264
+ table.uuid('user_id').notNullable().references('users.id').onDelete('CASCADE');
265
+ table.string('theme').defaultTo('light');
266
+ table.boolean('email_notifications').defaultTo(true);
267
+ table.jsonb('settings').defaultTo('{}');
268
+ table.timestamps(true, true);
269
+
270
+ table.unique(['user_id']);
271
+ table.index(['user_id']);
272
+ });
273
+ }
274
+
275
+ export async function down(db: Knex): Promise<void> {
276
+ await db.schema.dropTableIfExists('user_preferences');
277
+ }
278
+ ```
279
+
280
+ ### Breaking Changes
281
+
282
+ For breaking changes, use multi-phase deployment:
283
+
284
+ ```
285
+ Phase 1: Add new column (nullable)
286
+ - Deploy code that writes to both old and new
287
+
288
+ Phase 2: Backfill data
289
+ - Migrate existing data to new column
290
+
291
+ Phase 3: Switch reads
292
+ - Deploy code that reads from new column
293
+
294
+ Phase 4: Remove old column
295
+ - Drop old column after verification
296
+ ```
297
+
298
+ ### Data Migration Example
299
+
300
+ ```typescript
301
+ // Large table migration with batching
302
+ export async function up(db: Knex): Promise<void> {
303
+ const BATCH_SIZE = 1000;
304
+ let processed = 0;
305
+ let hasMore = true;
306
+
307
+ while (hasMore) {
308
+ const result = await db.raw(`
309
+ UPDATE users
310
+ SET email_verified = true
311
+ WHERE id IN (
312
+ SELECT id FROM users
313
+ WHERE email_verified IS NULL
314
+ LIMIT ${BATCH_SIZE}
315
+ )
316
+ RETURNING id
317
+ `);
318
+
319
+ processed += result.rowCount;
320
+ hasMore = result.rowCount === BATCH_SIZE;
321
+
322
+ // Allow other operations between batches
323
+ await sleep(100);
324
+ }
325
+
326
+ console.log(`Migrated ${processed} users`);
327
+ }
328
+ ```
329
+
330
+ ## Soft Deletes
331
+
332
+ ```typescript
333
+ // Model with soft delete
334
+ model User {
335
+ id String @id @default(uuid())
336
+ email String @unique
337
+ deletedAt DateTime? // Soft delete marker
338
+
339
+ @@index([deletedAt])
340
+ }
341
+
342
+ // Middleware to filter soft-deleted records
343
+ prisma.$use(async (params, next) => {
344
+ if (params.model === 'User') {
345
+ if (params.action === 'findMany' || params.action === 'findFirst') {
346
+ params.args.where = {
347
+ ...params.args.where,
348
+ deletedAt: null,
349
+ };
350
+ }
351
+ }
352
+ return next(params);
353
+ });
354
+
355
+ // Soft delete operation
356
+ async function deleteUser(id: string): Promise<void> {
357
+ await db.user.update({
358
+ where: { id },
359
+ data: { deletedAt: new Date() },
360
+ });
361
+ }
362
+
363
+ // Hard delete (when needed)
364
+ async function permanentlyDeleteUser(id: string): Promise<void> {
365
+ await db.user.delete({ where: { id } });
366
+ }
367
+ ```
368
+
369
+ ## Audit Columns
370
+
371
+ All tables should have:
372
+
373
+ ```sql
374
+ CREATE TABLE orders (
375
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
376
+ -- ... business columns
377
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
378
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
379
+ created_by UUID REFERENCES users(id),
380
+ updated_by UUID REFERENCES users(id)
381
+ );
382
+
383
+ -- Auto-update updated_at
384
+ CREATE OR REPLACE FUNCTION update_updated_at()
385
+ RETURNS TRIGGER AS $$
386
+ BEGIN
387
+ NEW.updated_at = NOW();
388
+ RETURN NEW;
389
+ END;
390
+ $$ LANGUAGE plpgsql;
391
+
392
+ CREATE TRIGGER orders_updated_at
393
+ BEFORE UPDATE ON orders
394
+ FOR EACH ROW
395
+ EXECUTE FUNCTION update_updated_at();
396
+ ```
397
+
398
+ ## Query Timeouts
399
+
400
+ ```typescript
401
+ // Set statement timeout
402
+ await db.$executeRaw`SET statement_timeout = '30s'`;
403
+
404
+ // Or per-query with Prisma
405
+ const results = await db.$queryRaw`
406
+ SELECT /*+ MAX_EXECUTION_TIME(30000) */ *
407
+ FROM large_table
408
+ WHERE ...
409
+ `;
410
+ ```
411
+
412
+ ## Quality Checklist
413
+
414
+ - [ ] No N+1 queries
415
+ - [ ] Indexes on all FKs and common filters
416
+ - [ ] Complex queries analyzed with EXPLAIN
417
+ - [ ] Cursor pagination for large datasets
418
+ - [ ] Transactions for multi-step mutations
419
+ - [ ] Deadlock handling implemented
420
+ - [ ] Connection pool sized correctly
421
+ - [ ] Migrations are idempotent
422
+ - [ ] Down migrations provided
423
+ - [ ] Breaking changes use phased rollout
424
+ - [ ] Soft deletes where appropriate
425
+ - [ ] Audit columns on all tables
426
+ - [ ] Query timeouts configured