class-ai-agent 1.2.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 (93) hide show
  1. package/.claude/CLAUDE.md +155 -0
  2. package/.claude/agents/backend.md +395 -0
  3. package/.claude/agents/code-reviewer.md +110 -0
  4. package/.claude/agents/copywriter-seo.md +236 -0
  5. package/.claude/agents/frontend.md +384 -0
  6. package/.claude/agents/project-manager.md +201 -0
  7. package/.claude/agents/qa.md +221 -0
  8. package/.claude/agents/security-auditor.md +143 -0
  9. package/.claude/agents/systems-architect.md +211 -0
  10. package/.claude/agents/test-engineer.md +123 -0
  11. package/.claude/agents/ui-ux-designer.md +210 -0
  12. package/.claude/commands/build.md +132 -0
  13. package/.claude/commands/debug.md +242 -0
  14. package/.claude/commands/deploy.md +40 -0
  15. package/.claude/commands/fix-issue.md +42 -0
  16. package/.claude/commands/plan.md +125 -0
  17. package/.claude/commands/review.md +50 -0
  18. package/.claude/commands/simplify.md +222 -0
  19. package/.claude/commands/spec.md +95 -0
  20. package/.claude/commands/test.md +214 -0
  21. package/.claude/references/accessibility-checklist.md +174 -0
  22. package/.claude/references/performance-checklist.md +150 -0
  23. package/.claude/references/security-checklist.md +94 -0
  24. package/.claude/references/testing-patterns.md +183 -0
  25. package/.claude/rules/api-conventions.md +79 -0
  26. package/.claude/rules/clean-code.md +205 -0
  27. package/.claude/rules/code-style.md +86 -0
  28. package/.claude/rules/database.md +60 -0
  29. package/.claude/rules/error-handling.md +92 -0
  30. package/.claude/rules/git-workflow.md +77 -0
  31. package/.claude/rules/monitoring.md +311 -0
  32. package/.claude/rules/naming-conventions.md +260 -0
  33. package/.claude/rules/project-structure.md +65 -0
  34. package/.claude/rules/security.md +90 -0
  35. package/.claude/rules/system-design.md +162 -0
  36. package/.claude/rules/tech-stack.md +456 -0
  37. package/.claude/rules/testing.md +104 -0
  38. package/.claude/settings.json +14 -0
  39. package/.claude/skills/code-review/SKILL.md +208 -0
  40. package/.claude/skills/deploy/SKILL.md +68 -0
  41. package/.claude/skills/deploy/deploy.md +735 -0
  42. package/.claude/skills/incremental-implementation/SKILL.md +210 -0
  43. package/.claude/skills/security-review/SKILL.md +71 -0
  44. package/.claude/skills/tdd/SKILL.md +217 -0
  45. package/.cursor/CURSOR.md +112 -0
  46. package/.cursor/agents/backend.md +395 -0
  47. package/.cursor/agents/code-reviewer.md +110 -0
  48. package/.cursor/agents/copywriter-seo.md +236 -0
  49. package/.cursor/agents/frontend.md +384 -0
  50. package/.cursor/agents/project-manager.md +201 -0
  51. package/.cursor/agents/qa.md +221 -0
  52. package/.cursor/agents/security-auditor.md +143 -0
  53. package/.cursor/agents/systems-architect.md +211 -0
  54. package/.cursor/agents/test-engineer.md +123 -0
  55. package/.cursor/agents/ui-ux-designer.md +210 -0
  56. package/.cursor/commands/build.md +132 -0
  57. package/.cursor/commands/debug.md +242 -0
  58. package/.cursor/commands/deploy.md +40 -0
  59. package/.cursor/commands/fix-issue.md +42 -0
  60. package/.cursor/commands/plan.md +125 -0
  61. package/.cursor/commands/review.md +50 -0
  62. package/.cursor/commands/simplify.md +222 -0
  63. package/.cursor/commands/spec.md +95 -0
  64. package/.cursor/commands/test.md +214 -0
  65. package/.cursor/references/accessibility-checklist.md +174 -0
  66. package/.cursor/references/performance-checklist.md +150 -0
  67. package/.cursor/references/security-checklist.md +94 -0
  68. package/.cursor/references/testing-patterns.md +183 -0
  69. package/.cursor/rules/api-conventions.mdc +85 -0
  70. package/.cursor/rules/clean-code.mdc +211 -0
  71. package/.cursor/rules/code-style.mdc +92 -0
  72. package/.cursor/rules/cursor-overview.mdc +35 -0
  73. package/.cursor/rules/database.mdc +66 -0
  74. package/.cursor/rules/error-handling.mdc +98 -0
  75. package/.cursor/rules/git-workflow.mdc +83 -0
  76. package/.cursor/rules/monitoring.mdc +317 -0
  77. package/.cursor/rules/naming-conventions.mdc +266 -0
  78. package/.cursor/rules/project-structure.mdc +71 -0
  79. package/.cursor/rules/security.mdc +95 -0
  80. package/.cursor/rules/system-design.mdc +168 -0
  81. package/.cursor/rules/tech-stack.mdc +462 -0
  82. package/.cursor/rules/testing.mdc +110 -0
  83. package/.cursor/settings.json +8 -0
  84. package/.cursor/skills/code-review/SKILL.md +208 -0
  85. package/.cursor/skills/deploy/SKILL.md +68 -0
  86. package/.cursor/skills/deploy/deploy.md +735 -0
  87. package/.cursor/skills/incremental-implementation/SKILL.md +210 -0
  88. package/.cursor/skills/security-review/SKILL.md +71 -0
  89. package/.cursor/skills/tdd/SKILL.md +217 -0
  90. package/AGENTS.md +11 -0
  91. package/README.md +405 -0
  92. package/bin/class-ai-agent.cjs +176 -0
  93. package/package.json +38 -0
@@ -0,0 +1,462 @@
1
+ ---
2
+ description: "Technology Stack — Selection & Standards"
3
+ alwaysApply: false
4
+ globs: "**/*.{ts,tsx,js,jsx,mjs,cjs,json,md,prisma,yml,yaml}"
5
+ ---
6
+
7
+ # Technology Stack — Selection & Standards
8
+
9
+ > This rule defines the **approved tech stack** for all projects. When starting a new project or proposing a new dependency, follow the decision criteria below.
10
+
11
+ ---
12
+
13
+ ## 🗂️ Quick Reference — Approved Stack
14
+
15
+ | Layer | Primary Choice | Alternative | Avoid |
16
+ |-------|---------------|-------------|-------|
17
+ | **Frontend — Landing/SEO** | Next.js 14+ (App Router) | — | CRA (deprecated) |
18
+ | **Frontend — Admin/Dashboard** | React + Vite (SPA) | — | Next.js (overkill for admin) |
19
+ | **UI Components** | shadcn/ui + Radix UI | Chakra UI | MUI (too heavy) |
20
+ | **Styling** | Tailwind CSS | CSS Modules | Styled-components (runtime cost) |
21
+ | **State Management** | Zustand | Redux Toolkit | MobX, Recoil |
22
+ | **Data Fetching** | TanStack Query (React Query) | SWR | Axios alone |
23
+ | **Backend Framework** | Express.js + Node | Fastify | Hapi, Koa |
24
+ | **API Style** | REST (default) | tRPC (fullstack TS) | GraphQL (unless needed) |
25
+ | **Language** | TypeScript (always) | — | Plain JavaScript |
26
+ | **Database** | PostgreSQL | — | MySQL (prefer PG) |
27
+ | **ORM** | Prisma | Drizzle | Sequelize, TypeORM |
28
+ | **Cache** | Redis (ioredis) | Upstash Redis | Memcached |
29
+ | **Queue — Simple jobs** | BullMQ (Redis-backed) | — | — |
30
+ | **Queue — Enterprise/Microservices** | RabbitMQ | Kafka (high-throughput streams) | — |
31
+ | **Auth** | NextAuth.js (Next) / JWT+bcrypt (API) | Lucia Auth | Firebase Auth |
32
+ | **File Storage** | AWS S3 / Cloudflare R2 | Supabase Storage | Local disk (not scalable) |
33
+ | **Email** | Resend | Nodemailer + SMTP | SendGrid (expensive) |
34
+ | **Search** | PostgreSQL FTS (start here) | Meilisearch | Elasticsearch (unless needed) |
35
+ | **Monitoring** | Grafana + Prometheus | Datadog | — |
36
+ | **Logging** | Pino | Winston | console.log (production) |
37
+ | **Testing** | Vitest + Testing Library | Jest | Mocha |
38
+ | **E2E Testing** | Playwright | Cypress | Selenium |
39
+ | **CI/CD** | GitHub Actions | — | Jenkins (legacy) |
40
+ | **Containerization** | Docker + Docker Compose | — | — |
41
+ | **Deployment** | Vercel (frontend) + Railway/Fly.io (backend) | AWS | — |
42
+ | **API Docs** | Swagger / OpenAPI 3.0 | — | Postman collections only |
43
+
44
+ ---
45
+
46
+ ## 🖥️ Frontend — Chọn đúng framework
47
+
48
+ ### Decision Table
49
+
50
+ | Tiêu chí | Next.js 14 (App Router) | React + Vite (SPA) |
51
+ |----------|------------------------|--------------------|
52
+ | **Mục đích** | Landing page, marketing, blog | Admin panel, dashboard, internal tool |
53
+ | **SEO** | ✅ SSR/SSG — Google index tốt | ❌ SPA — khó SEO |
54
+ | **Lưu trữ** | Vercel (tối ưu nhất) | Cloudflare Pages, Netlify, S3 |
55
+ | **Performance** | Server Components — ít JS gửi về client | Client-side rendering |
56
+ | **Auth** | NextAuth.js | JWT stored in cookie/localStorage |
57
+ | **API** | API Routes hoặc Server Actions | Gọi backend REST riêng biệt |
58
+ | **Build complexity** | Cao hơn | Đơn giản hơn |
59
+
60
+ > **Rule**: Một project thường có **cả hai** — Next.js cho public site + React cho admin.
61
+
62
+ ---
63
+
64
+ ### Next.js — Landing Page / SEO Project
65
+
66
+ ```bash
67
+ npx create-next-app@latest my-landing \
68
+ --typescript --tailwind --eslint --app --src-dir --import-alias "@/*"
69
+ ```
70
+
71
+ **Tại sao Next.js cho landing page:**
72
+ - Server-Side Rendering (SSR) → Google crawl được nội dung
73
+ - Static Site Generation (SSG) → build thành HTML tĩnh, lưu CDN, siêu nhanh
74
+ - Image optimization tự động (`next/image`)
75
+ - `<head>` metadata API tích hợp sẵn
76
+ - Incremental Static Regeneration (ISR) → cập nhật nội dung không rebuild toàn bộ
77
+
78
+ ```tsx
79
+ // app/layout.tsx — SEO metadata
80
+ export const metadata: Metadata = {
81
+ title: { default: 'My App', template: '%s | My App' },
82
+ description: 'Mô tả trang chính',
83
+ openGraph: { type: 'website', locale: 'vi_VN', url: 'https://myapp.com' },
84
+ };
85
+ ```
86
+
87
+ **Folder structure (App Router)**
88
+ ```
89
+ src/app/
90
+ ├── (marketing)/ # Public pages (SSG/SSR)
91
+ │ ├── page.tsx # Homepage
92
+ │ ├── about/page.tsx
93
+ │ ├── blog/
94
+ │ │ ├── page.tsx # Blog list (SSG)
95
+ │ │ └── [slug]/page.tsx # Blog post (ISR)
96
+ │ └── pricing/page.tsx
97
+ ├── (auth)/ # Auth pages
98
+ │ ├── login/page.tsx
99
+ │ └── register/page.tsx
100
+ ├── api/v1/ # API Routes
101
+ └── layout.tsx
102
+ ```
103
+
104
+ ---
105
+
106
+ ### React + Vite — Admin / Dashboard Project
107
+
108
+ ```bash
109
+ npx create-vite@latest my-admin -- --template react-ts
110
+ cd my-admin && npm install
111
+ ```
112
+
113
+ **Tại sao React SPA cho admin:**
114
+ - Admin panel không cần SEO (đăng nhập mới vào được)
115
+ - SPA build đơn giản, deploy lên S3/Cloudflare Pages/Nginx
116
+ - Trạng thái phức tạp (table, filter, form) dễ quản lý hơn
117
+ - Hot reload nhanh hơn trong development
118
+
119
+ **Folder structure (Vite SPA)**
120
+ ```
121
+ src/
122
+ ├── pages/ # Các trang (react-router)
123
+ │ ├── Dashboard.tsx
124
+ │ ├── Users/
125
+ │ │ ├── UserList.tsx
126
+ │ │ └── UserDetail.tsx
127
+ │ └── Settings.tsx
128
+ ├── components/
129
+ │ ├── layout/ # Sidebar, Header, Layout
130
+ │ └── ui/ # Shared UI components
131
+ ├── features/ # Feature-based modules
132
+ │ └── users/
133
+ │ ├── api.ts # TanStack Query hooks
134
+ │ ├── store.ts # Zustand slice
135
+ │ └── types.ts
136
+ ├── lib/ # axios instance, utils
137
+ └── main.tsx
138
+ ```
139
+
140
+ **Key Rules cho Admin:**
141
+ - Protected routes với `<AuthGuard>` component
142
+ - Role-based UI: `usePermission()` hook ẩn/hiện features
143
+ - Token refresh tự động trong axios interceptor
144
+
145
+ ---
146
+
147
+ ## 🗄️ Database — PostgreSQL + Prisma
148
+
149
+ ### Why PostgreSQL
150
+ - ACID compliant, battle-tested
151
+ - Excellent JSON support (`jsonb`) — avoids needing MongoDB in most cases
152
+ - Full-text search built-in
153
+ - Row-level security for multi-tenant apps
154
+ - Best ORM support (Prisma, Drizzle)
155
+
156
+ ### Prisma Setup
157
+ ```bash
158
+ npm install prisma @prisma/client
159
+ npx prisma init --datasource-provider postgresql
160
+ ```
161
+
162
+ ### Prisma Schema Conventions
163
+ ```prisma
164
+ // prisma/schema.prisma
165
+
166
+ model User {
167
+ id String @id @default(cuid()) // ✅ cuid() for distributed systems
168
+ email String @unique
169
+ name String?
170
+ role Role @default(USER)
171
+ createdAt DateTime @default(now())
172
+ updatedAt DateTime @updatedAt
173
+ deletedAt DateTime? // soft delete
174
+
175
+ orders Order[]
176
+
177
+ @@map("users") // ✅ snake_case table name
178
+ @@index([email])
179
+ }
180
+
181
+ enum Role {
182
+ USER
183
+ ADMIN
184
+ }
185
+ ```
186
+
187
+ ### Prisma Client — Singleton Pattern
188
+ ```ts
189
+ // src/lib/db.ts
190
+ import { PrismaClient } from '@prisma/client';
191
+
192
+ const globalForPrisma = global as unknown as { prisma: PrismaClient };
193
+
194
+ export const db =
195
+ globalForPrisma.prisma ||
196
+ new PrismaClient({
197
+ log: process.env.NODE_ENV === 'development' ? ['query', 'error'] : ['error'],
198
+ });
199
+
200
+ if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = db;
201
+ ```
202
+
203
+ ### Migration Workflow
204
+ ```bash
205
+ # Development: auto-migrate
206
+ npx prisma migrate dev --name add_user_role
207
+
208
+ # Production: apply pending migrations
209
+ npx prisma migrate deploy
210
+
211
+ # View DB in browser
212
+ npx prisma studio
213
+ ```
214
+
215
+ ### PostgreSQL Best Practices
216
+ - Use `cuid()` or `uuid()` for primary keys (not auto-increment integers for distributed systems)
217
+ - Always add `@@index` on foreign keys and frequently queried columns
218
+ - Use `jsonb` columns for flexible/schema-less data instead of adding MongoDB
219
+ - Enable `pg_trgm` extension for fuzzy search
220
+ - Set `statement_timeout` and `lock_timeout` for long queries
221
+
222
+ ---
223
+
224
+ ## ⚡ Cache — Redis + ioredis
225
+
226
+ ### Why Redis
227
+ - Sub-millisecond latency
228
+ - Supports strings, hashes, lists, sets, sorted sets, streams
229
+ - Built-in TTL, pub/sub, Lua scripts
230
+ - Powers caching + queues (BullMQ) + rate limiting + sessions
231
+
232
+ ### Redis Client Setup
233
+ ```ts
234
+ // src/lib/redis.ts
235
+ import Redis from 'ioredis';
236
+
237
+ const globalForRedis = global as unknown as { redis: Redis };
238
+
239
+ export const redis =
240
+ globalForRedis.redis ||
241
+ new Redis(process.env.REDIS_URL!, {
242
+ maxRetriesPerRequest: 3,
243
+ enableReadyCheck: true,
244
+ lazyConnect: true,
245
+ });
246
+
247
+ if (process.env.NODE_ENV !== 'production') globalForRedis.redis = redis;
248
+ ```
249
+
250
+ ### Cache Helper
251
+ ```ts
252
+ // src/lib/cache.ts
253
+ import { redis } from './redis';
254
+
255
+ export async function getOrSet<T>(
256
+ key: string,
257
+ fetcher: () => Promise<T>,
258
+ ttlSeconds = 3600
259
+ ): Promise<T> {
260
+ const cached = await redis.get(key);
261
+ if (cached) return JSON.parse(cached);
262
+
263
+ const data = await fetcher();
264
+ await redis.setex(key, ttlSeconds, JSON.stringify(data));
265
+ return data;
266
+ }
267
+
268
+ export async function invalidate(pattern: string) {
269
+ const keys = await redis.keys(pattern);
270
+ if (keys.length) await redis.del(...keys);
271
+ }
272
+ ```
273
+
274
+ ### Redis Key Naming → See `naming-conventions.md`
275
+ ```
276
+ myapp:v1:user:123:profile (TTL: 1h)
277
+ myapp:v1:session:abc123 (TTL: 7d)
278
+ myapp:v1:rate_limit:ip:... (TTL: 15m)
279
+ ```
280
+
281
+ ### Queue with BullMQ (Simple — default)
282
+ ```ts
283
+ // src/queues/email-queue.ts
284
+ import { Queue, Worker } from 'bullmq';
285
+ import { redis } from '@/lib/redis';
286
+
287
+ export const emailQueue = new Queue('email', { connection: redis });
288
+ await emailQueue.add('send-welcome', { to: user.email, name: user.name });
289
+ ```
290
+
291
+ ---
292
+
293
+ ## 📨 Queue — Chọn đúng loại
294
+
295
+ ### Decision Table
296
+
297
+ | Tiêu chí | BullMQ | RabbitMQ | Kafka |
298
+ |----------|--------|----------|-------|
299
+ | **Khi dùng** | Jobs đơn giản, retry, schedule | Microservices, routing phức tạp | Event streaming, log, billions messages |
300
+ | **Throughput** | Trung bình | Cao | Cực cao (triệu msg/s) |
301
+ | **Persistence** | Redis TTL | Disk (durable) | Disk (log-based, immutable) |
302
+ | **Setup** | Redis có sẵn | Cài thêm RabbitMQ | Cài thêm Kafka + Zookeeper |
303
+ | **Retry** | ✅ Built-in | ✅ Dead Letter Queue | ✅ Consumer offset |
304
+ | **Ordering** | ❌ Không đảm bảo | ✅ Per-queue | ✅ Per-partition |
305
+ | **Replay** | ❌ | ❌ | ✅ Có thể replay |
306
+ | **Độ phức tạp** | Thấp | Trung bình | Cao |
307
+
308
+ > **Rule**: Mặc định dùng **BullMQ**. Chỉ dùng RabbitMQ khi microservices. Chỉ dùng Kafka khi cần stream lớn hoặc replay.
309
+
310
+ ### BullMQ — Default (Redis-backed)
311
+ ```ts
312
+ // Khi nào: email, notification, PDF, image resize, scheduled tasks
313
+ const emailQueue = new Queue('email', {
314
+ connection: redis,
315
+ defaultJobOptions: { attempts: 3, backoff: { type: 'exponential', delay: 2000 } },
316
+ });
317
+ ```
318
+
319
+ ### RabbitMQ — Microservices
320
+ ```ts
321
+ // Khi nào: nhiều service cần nhận cùng 1 message (pub/sub), routing phức tạp
322
+ import amqplib from 'amqplib';
323
+
324
+ const conn = await amqplib.connect(process.env.RABBITMQ_URL!);
325
+ const channel = await conn.createChannel();
326
+
327
+ // Exchange-based routing
328
+ await channel.assertExchange('order.events', 'topic', { durable: true });
329
+ await channel.publish('order.events', 'order.placed', Buffer.from(JSON.stringify(payload)));
330
+
331
+ // Consumer
332
+ await channel.assertQueue('email-service.order.placed', { durable: true });
333
+ await channel.bindQueue('email-service.order.placed', 'order.events', 'order.placed');
334
+ channel.consume('email-service.order.placed', async (msg) => {
335
+ if (!msg) return;
336
+ const data = JSON.parse(msg.content.toString());
337
+ await sendOrderEmail(data);
338
+ channel.ack(msg);
339
+ });
340
+ ```
341
+
342
+ ### Kafka — High-throughput Streaming
343
+ ```ts
344
+ // Khi nào: analytics events, audit logs, real-time feeds, > 100k msg/s
345
+ import { Kafka } from 'kafkajs';
346
+
347
+ const kafka = new Kafka({ brokers: [process.env.KAFKA_BROKER!] });
348
+
349
+ // Producer
350
+ const producer = kafka.producer();
351
+ await producer.send({
352
+ topic: 'user-events',
353
+ messages: [{ key: userId, value: JSON.stringify({ event: 'page_viewed', page: '/checkout' }) }],
354
+ });
355
+
356
+ // Consumer group
357
+ const consumer = kafka.consumer({ groupId: 'analytics-service' });
358
+ await consumer.subscribe({ topic: 'user-events', fromBeginning: false });
359
+ await consumer.run({
360
+ eachMessage: async ({ message }) => {
361
+ await analyticsService.track(JSON.parse(message.value!.toString()));
362
+ },
363
+ });
364
+ ```
365
+
366
+ ### Queue Naming → See `naming-conventions.md`
367
+ ```
368
+ BullMQ queue names: myapp.email.send
369
+ RabbitMQ exchange: order.events (type: topic)
370
+ RabbitMQ queue: email-service.order.placed
371
+ Kafka topic: user-events, order-events, payment-events
372
+ ```
373
+
374
+
375
+
376
+ ## 📄 Documentation
377
+
378
+ ### API Documentation — OpenAPI / Swagger
379
+ ```bash
380
+ npm install swagger-ui-express @asteasolutions/zod-to-openapi
381
+ ```
382
+
383
+ - Every API endpoint MUST have OpenAPI annotations
384
+ - Auto-generate from code (Zod schemas or JSDoc)
385
+ - Mount at `/api-docs`
386
+ - Keep `openapi.yaml` committed to repo
387
+
388
+ ### Code Documentation
389
+ ```ts
390
+ /**
391
+ * Find a user by their email address.
392
+ * @param email - The user's email (must be lowercase)
393
+ * @returns The user object or null if not found
394
+ * @throws {AppError} If database is unavailable
395
+ */
396
+ async function findUserByEmail(email: string): Promise<User | null> {}
397
+ ```
398
+
399
+ ### README Template (mandatory for every service)
400
+ ```markdown
401
+ # Service Name
402
+
403
+ ## What it does (1-2 sentences)
404
+
405
+ ## Tech Stack
406
+ - Runtime: Node.js 20 + TypeScript
407
+ - Framework: Next.js 14
408
+ - Database: PostgreSQL (Prisma)
409
+ - Cache: Redis
410
+
411
+ ## Quick Start
412
+ \`\`\`bash
413
+ cp .env.example .env
414
+ npm install
415
+ npx prisma migrate dev
416
+ npm run dev
417
+ \`\`\`
418
+
419
+ ## Environment Variables → see .env.example
420
+ ## API Documentation → /api-docs
421
+ ## Architecture → docs/architecture.md
422
+ ```
423
+
424
+ ### Architecture Diagrams (docs/architecture/)
425
+ - Use **Mermaid** for all diagrams (version-controlled, no external tools)
426
+ - Required diagrams: System context, Component diagram, Data flow, DB ERD
427
+
428
+ ```mermaid
429
+ graph LR
430
+ Client --> NextJS
431
+ NextJS --> PostgreSQL
432
+ NextJS --> Redis
433
+ NextJS --> Queue[BullMQ Queue]
434
+ Queue --> Worker[Background Worker]
435
+ ```
436
+
437
+ ---
438
+
439
+ ## ✅ Technology Decision Process
440
+
441
+ When **proposing a new library or technology**, evaluate against these criteria:
442
+
443
+ | Criterion | Questions to ask |
444
+ |-----------|-----------------|
445
+ | **Necessity** | Does an approved alternative already solve this? |
446
+ | **Maintenance** | Stars > 1k? Last commit < 6 months? |
447
+ | **Bundle size** | Check bundlephobia.com — is it worth the KB? |
448
+ | **TypeScript** | Does it have native TS types? |
449
+ | **License** | Is it MIT/Apache? (No GPL in commercial products) |
450
+ | **Security** | `npm audit` — zero high/critical vulnerabilities |
451
+ | **Community** | Active issues/discussions? Stack Overflow answers? |
452
+
453
+ ### Decision Template
454
+ ```markdown
455
+ ## Technology Decision: [Library Name]
456
+
457
+ **Problem**: What problem does this solve?
458
+ **Alternative evaluated**: What from the approved stack was considered?
459
+ **Why chosen**: Specific reason this is better for the use case
460
+ **Risk**: Known downsides or migration cost
461
+ **Decision**: ✅ Adopt / ❌ Reject
462
+ ```
@@ -0,0 +1,110 @@
1
+ ---
2
+ description: "Testing Standards"
3
+ alwaysApply: false
4
+ globs: "**/*.{ts,tsx,js,jsx,mjs,cjs,json,md,prisma,yml,yaml}"
5
+ ---
6
+
7
+ # Testing Standards
8
+
9
+ ## Testing Pyramid
10
+ ```
11
+ [E2E Tests] ← Few, slow, catch integration issues
12
+ [Integration Tests] ← Some, test component interaction
13
+ [Unit Tests] ← Many, fast, test isolated logic
14
+ ```
15
+
16
+ ## Requirements
17
+ - Unit test coverage: **minimum 80%**
18
+ - All new features must have tests
19
+ - All bug fixes must have a regression test
20
+ - Tests run in CI before any merge
21
+
22
+ ## Test File Organization
23
+ ```
24
+ tests/
25
+ ├── unit/
26
+ │ ├── services/user-service.test.js
27
+ │ └── utils/format.test.js
28
+ ├── integration/
29
+ │ ├── routes/users.test.js
30
+ │ └── database/user-repo.test.js
31
+ └── e2e/
32
+ └── auth-flow.test.js
33
+ ```
34
+
35
+ ## Unit Test Example (Jest)
36
+ ```js
37
+ // tests/unit/services/user-service.test.js
38
+ import { UserService } from '../../../src/services/user-service.js';
39
+ import { mockUserRepository } from '../../mocks/user-repository.mock.js';
40
+
41
+ describe('UserService', () => {
42
+ let userService;
43
+ let mockRepo;
44
+
45
+ beforeEach(() => {
46
+ mockRepo = mockUserRepository();
47
+ userService = new UserService(mockRepo);
48
+ });
49
+
50
+ describe('findById', () => {
51
+ it('should return user when found', async () => {
52
+ const mockUser = { id: '1', email: 'test@test.com' };
53
+ mockRepo.findById.mockResolvedValue(mockUser);
54
+
55
+ const result = await userService.findById('1');
56
+
57
+ expect(result).toEqual(mockUser);
58
+ expect(mockRepo.findById).toHaveBeenCalledWith('1');
59
+ });
60
+
61
+ it('should throw AppError when user not found', async () => {
62
+ mockRepo.findById.mockResolvedValue(null);
63
+
64
+ await expect(userService.findById('999'))
65
+ .rejects.toThrow('User not found');
66
+ });
67
+ });
68
+ });
69
+ ```
70
+
71
+ ## Integration Test Example
72
+ ```js
73
+ // tests/integration/routes/users.test.js
74
+ import request from 'supertest';
75
+ import app from '../../../src/index.js';
76
+
77
+ describe('GET /api/users/:id', () => {
78
+ it('should return 200 with user data', async () => {
79
+ const res = await request(app)
80
+ .get('/api/users/1')
81
+ .set('Authorization', `Bearer ${testToken}`);
82
+
83
+ expect(res.status).toBe(200);
84
+ expect(res.body.success).toBe(true);
85
+ expect(res.body.data).toHaveProperty('id');
86
+ });
87
+
88
+ it('should return 404 for unknown user', async () => {
89
+ const res = await request(app)
90
+ .get('/api/users/99999')
91
+ .set('Authorization', `Bearer ${testToken}`);
92
+
93
+ expect(res.status).toBe(404);
94
+ });
95
+ });
96
+ ```
97
+
98
+ ## Test Commands
99
+ ```bash
100
+ npm test # Run all tests
101
+ npm run test:unit # Unit tests only
102
+ npm run test:integration # Integration tests only
103
+ npm run test:coverage # Generate coverage report
104
+ npm run test:watch # Watch mode for development
105
+ ```
106
+
107
+ ## Naming Conventions
108
+ - Test files: `[filename].test.js`
109
+ - `describe` blocks: Match the module/function being tested
110
+ - `it` blocks: `should [expected behavior] when [condition]`
@@ -0,0 +1,8 @@
1
+ {
2
+ "rules_dir": ".cursor/rules",
3
+ "commands_dir": ".cursor/commands",
4
+ "skills_dir": ".cursor/skills",
5
+ "agents_dir": ".cursor/agents",
6
+ "references_dir": ".cursor/references",
7
+ "note": "Parallels .claude/settings.json. Cursor loads .cursor/rules/*.mdc automatically; other paths are for @ mentions and docs."
8
+ }