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