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