agent-workflow-kit-cli 1.3.1 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/add.js +1 -1
- package/dist/cli/commands/doctor.js +8 -1
- package/dist/cli/index.js +2 -2
- package/dist/core/analyzer.js +146 -1
- package/dist/core/awos/intelligence.js +30 -6
- package/dist/core/detector.js +32 -4
- package/package.json +1 -1
- package/templates/dotnet/AGENTS.md.hbs +53 -0
- package/templates/dotnet/rules/api-structure.md +43 -0
- package/templates/dotnet/rules/csharp-style.md +33 -0
- package/templates/dotnet/rules/dependency-injection.md +54 -0
- package/templates/dotnet/rules/error-handling-validation.md +86 -0
- package/templates/dotnet/skills/dotnet-controller/SKILL.md +24 -0
- package/templates/express/AGENTS.md.hbs +41 -0
- package/templates/express/rules/error-handling.md +88 -0
- package/templates/express/rules/express-style.md +39 -0
- package/templates/express/rules/router-controller.md +27 -0
- package/templates/express/skills/express-endpoint/SKILL.md +24 -0
- package/templates/nestjs/AGENTS.md.hbs +38 -0
- package/templates/nestjs/rules/module-architecture.md +35 -0
- package/templates/nestjs/rules/nestjs-style.md +41 -0
- package/templates/nestjs/rules/validation-errors.md +46 -0
- package/templates/nestjs/skills/nestjs-module/SKILL.md +25 -0
- package/templates/next-js/AGENTS.md.hbs +41 -0
- package/templates/next-js/rules/data-fetching-mutations.md +36 -0
- package/templates/next-js/rules/next-style.md +32 -0
- package/templates/next-js/rules/seo-metadata.md +50 -0
- package/templates/next-js/rules/server-client-components.md +27 -0
- package/templates/next-js/skills/next-feature/SKILL.md +26 -0
- package/templates/react-ts/AGENTS.md.hbs +109 -32
- package/templates/react-ts/rules/data-fetching.md +45 -0
- package/templates/react-ts/rules/forms-validation.md +55 -0
- package/templates/react-ts/rules/premium-ui.md +45 -0
- package/templates/react-ts/rules/react-style.md +38 -26
- package/templates/react-ts/rules/routing-splitting.md +21 -0
- package/templates/react-ts/rules/seo-accessibility.md +34 -0
- package/templates/react-ts/skills/react-feature/SKILL.md +5 -5
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
## 🗺️ Hướng Dẫn Phát Triển Express.js (Node.js Backend)
|
|
2
|
+
|
|
3
|
+
### 🔄 Vòng Đời Phát Triển Tác Nhân (Agent Development Lifecycle)
|
|
4
|
+
Tác nhân AI phải thực hiện tất cả các nhiệm vụ Express.js theo quy trình 5 bước sau:
|
|
5
|
+
1. **Thiết kế & Lập trình:** Phân tách mã nguồn theo cấu trúc 3 lớp rõ ràng (3-Tier Architecture). Tuyệt đối cấm viết mã nguồn lộn xộn (Spaghetti Code).
|
|
6
|
+
2. **Kiểm thử Toàn diện:** Viết unit test cho các Service sử dụng Jest và kiểm thử tích hợp API sử dụng Supertest.
|
|
7
|
+
3. **Chất lượng Mã nguồn:** Chạy các lệnh kiểm tra lỗi cú pháp và kiểu dữ liệu:
|
|
8
|
+
- Kiểm tra Lint: `{{runCommand}} lint`
|
|
9
|
+
- Kiểm tra Kiểu dữ liệu: `{{runCommand}} typecheck`
|
|
10
|
+
- Chạy Kiểm thử: `{{runCommand}} test` (hoặc `{{runCommand}} test -- --run` cho môi trường CI/CD)
|
|
11
|
+
- Chạy Build thử nghiệm: `{{runCommand}} build`
|
|
12
|
+
4. **Quản lý Thư viện:** Cài đặt các thư viện mới bằng lệnh: `{{packageManager}} add [tên_thư_viện]`. Tuyệt đối cấm sửa thủ công file lock `{{lockFile}}`.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
### 🏗️ Kiến Trúc Hệ Thống Bản Mẫu (Template Blueprint)
|
|
17
|
+
Vui lòng tham khảo các tài liệu quy tắc chi tiết dưới đây:
|
|
18
|
+
- Quy ước viết mã sạch, định nghĩa kiểu dữ liệu tường minh bằng TypeScript trong môi trường Express: `@express-style.md`
|
|
19
|
+
- Phân định ranh giới trách nhiệm: Router nhận diện đường dẫn $\rightarrow$ Controller điều phối $\rightarrow$ Service xử lý core logic: `@router-controller.md`
|
|
20
|
+
- Chiến lược xử lý lỗi bất đồng bộ (Async Error Catching) và cơ chế vận hành Middleware xử lý lỗi tập trung: `@error-handling.md`
|
|
21
|
+
- Workflow chuẩn hóa giúp sinh mới một cụm API Endpoint an toàn, đầy đủ từ Router, Controller đến Validator: `@SKILL.md`
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
### 🏛️ Quy Tắc Phát Triển Nghiêm Ngặt
|
|
26
|
+
|
|
27
|
+
#### 1. Phân Tách Lớp Tuyệt Đối (Strict Layer Separation)
|
|
28
|
+
Tác nhân phải tuân thủ nghiêm ngặt chuỗi truyền dẫn dữ liệu:
|
|
29
|
+
$$\text{Client} \longrightarrow \text{Router} \longrightarrow \text{Middleware} \longrightarrow \text{Controller} \longrightarrow \text{Service} \longrightarrow \text{Model/Database}$$
|
|
30
|
+
- **Router:** Tuyệt đối không chứa logic xử lý, chỉ ánh xạ HTTP Method + Path và liên kết middleware xác thực/kiểm duyệt.
|
|
31
|
+
- **Controller:** Chỉ bóc tách dữ liệu từ `req` (req.body, req.query, req.params), gọi lớp Service xử lý, nhận kết quả và trả về thông qua `res.status().json()`. Không làm việc trực tiếp với cơ sở dữ liệu.
|
|
32
|
+
- **Service:** Nơi chứa logic nghiệp vụ, tính toán thuật toán, tương tác với lớp DB Model. Tuyệt đối không được tiếp xúc hay phụ thuộc vào các đối tượng `req` hay `res` của Express để đảm bảo tính độc lập khi viết Unit Test.
|
|
33
|
+
|
|
34
|
+
#### 2. Bẫy Lỗi Bất Đồng Bộ (Async Error Handling)
|
|
35
|
+
- **Không dùng try/catch thủ công tại Controller:** Việc viết try/catch ở mọi hàm trong tất cả các controller gây loãng mã nguồn.
|
|
36
|
+
- **Sử dụng Wrapper Tự động:** Toàn bộ các hàm controller bất đồng bộ phải được bọc bằng một hàm tiện ích tự động bắt lỗi (như `express-async-handler`) để tự động chuyển tiếp tất cả các ngoại lệ phát sinh sang cấu phần `next()`.
|
|
37
|
+
- **Middleware xử lý lỗi tập trung (Global Error Handler):** Bắt buộc phải khai báo middleware xử lý lỗi có đủ 4 tham số ở cuối tệp cấu hình server (sau khi khai báo tất cả các routes) để định dạng lại toàn bộ phản hồi lỗi.
|
|
38
|
+
|
|
39
|
+
#### 3. Kiểm Thử Dữ Liệu Tự Động Với Zod Middleware
|
|
40
|
+
- **Cấm Validate thủ công bằng câu lệnh điều kiện:** Không viết các đoạn code `if (!req.body.email)`.
|
|
41
|
+
- **Xây dựng Middleware Validate Schema:** Phát triển một middleware dùng chung nhận vào một Schema của Zod để tự động kiểm duyệt toàn bộ dữ liệu đầu vào (body, query, params) trước khi cho phép dữ liệu đi sâu vào tầng Controller.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Bẫy Lỗi Bất Đồng Bộ & Xác Thực Dữ Liệu Tự Động (Zod Middleware)
|
|
2
|
+
|
|
3
|
+
Tài liệu này quy định chiến lược xử lý lỗi bất đồng bộ (Async Error Catching), cấu hình Middleware xử lý lỗi tập trung, và tự động kiểm tra dữ liệu bằng Zod.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🚨 Bẫy Lỗi Bất Đồng Bộ (Async Error Handling Architecture)
|
|
8
|
+
- **Không dùng try/catch thủ công tại Controller:** Việc viết try/catch ở mọi hàm trong tất cả các controller gây loãng mã nguồn.
|
|
9
|
+
- **Sử dụng Wrapper Tự động:** Toàn bộ các hàm controller bất đồng bộ phải được bọc bằng một hàm tiện ích tự động bắt lỗi (như `asyncHandler`) để tự động chuyển tiếp tất cả các ngoại lệ phát sinh sang cấu phần `next()`.
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { Request, Response, NextFunction } from 'express';
|
|
13
|
+
|
|
14
|
+
// Hàm Wrapper bắt lỗi bất đồng bộ tự động
|
|
15
|
+
export const asyncHandler = (fn: Function) => (req: Request, res: Response, next: NextFunction) => {
|
|
16
|
+
Promise.resolve(fn(req, res, next)).catch(next);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Cách triển khai thực tế tại Controller
|
|
20
|
+
export const getUserProfile = asyncHandler(async (req: Request, res: Response) => {
|
|
21
|
+
const userId = req.user.id;
|
|
22
|
+
const profile = await userService.getProfile(userId); // Nếu ném lỗi bên trong service, asyncHandler sẽ tự catch
|
|
23
|
+
return res.status(200).json({ success: true, data: profile });
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 🔌 Middleware Xử Lý Lỗi Tập Trung (Global Error Handler)
|
|
30
|
+
- **Khai báo bộ lọc:** Bắt buộc phải khai báo một middleware xử lý lỗi có đủ 4 tham số ở cuối tệp cấu hình server (sau khi khai báo tất cả các routes) để định dạng lại toàn bộ phản hồi lỗi trước khi trả về cho Client.
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
// Trong file app.ts hoặc server.ts
|
|
34
|
+
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
|
|
35
|
+
const statusCode = err.statusCode || 500;
|
|
36
|
+
const message = err.message || 'Internal Server Error';
|
|
37
|
+
|
|
38
|
+
res.status(statusCode).json({
|
|
39
|
+
success: false,
|
|
40
|
+
status: statusCode,
|
|
41
|
+
message: message,
|
|
42
|
+
stack: process.env.NODE_ENV === 'development' ? err.stack : undefined,
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 🛡️ Kiểm Thử Dữ Liệu Tự Động Với Zod Middleware
|
|
50
|
+
- **Cấm Validate thủ công bằng câu lệnh điều kiện:** Không viết các đoạn code `if (!req.body.email)`.
|
|
51
|
+
- **Xây dựng Middleware Validate Schema:** Phát triển một middleware dùng chung nhận vào một Schema của Zod để tự động kiểm duyệt toàn bộ dữ liệu đầu vào (`body`, `query`, `params`) trước khi cho phép dữ liệu đi sâu vào tầng Controller.
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { AnyZodObject, ZodError } from 'zod';
|
|
55
|
+
import { Request, Response, NextFunction } from 'express';
|
|
56
|
+
|
|
57
|
+
export const validateSchema = (schema: AnyZodObject) => {
|
|
58
|
+
return async (req: Request, res: Response, next: NextFunction): Promise<any> => {
|
|
59
|
+
try {
|
|
60
|
+
// Xác thực đồng thời cả body, query, và params thông qua cấu trúc schema của Zod
|
|
61
|
+
const parsed = await schema.parseAsync({
|
|
62
|
+
body: req.body,
|
|
63
|
+
query: req.query,
|
|
64
|
+
params: req.params,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Gán lại dữ liệu đã được parse sạch (và ép kiểu nếu có) vào hệ thống request
|
|
68
|
+
req.body = parsed.body;
|
|
69
|
+
req.query = parsed.query;
|
|
70
|
+
req.params = parsed.params;
|
|
71
|
+
|
|
72
|
+
return next();
|
|
73
|
+
} catch (error) {
|
|
74
|
+
if (error instanceof ZodError) {
|
|
75
|
+
return res.status(400).json({
|
|
76
|
+
success: false,
|
|
77
|
+
message: 'Dữ liệu đầu vào không hợp lệ',
|
|
78
|
+
errors: error.errors.map((err) => ({
|
|
79
|
+
field: err.path.join('.'),
|
|
80
|
+
message: err.message,
|
|
81
|
+
})),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return next(error);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Quy Ước Đặt Tên & Coding Style cho Express.js
|
|
2
|
+
|
|
3
|
+
Tài liệu này hướng dẫn coding style sạch, định nghĩa kiểu dữ liệu tường minh bằng TypeScript trong môi trường Express.js.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🏷️ Quy Ước Đặt Tên (Naming Conventions)
|
|
8
|
+
|
|
9
|
+
### Thư mục Phân lớp (Architecture Folders)
|
|
10
|
+
Mã nguồn phải được tách biệt hoàn toàn theo kiến trúc 3 lớp (3-Tier Architecture):
|
|
11
|
+
```bash
|
|
12
|
+
src/
|
|
13
|
+
├── config/ # Cấu hình biến môi trường, kết nối Database
|
|
14
|
+
├── middlewares/ # Các hàm Middleware (Auth, Log, Validation)
|
|
15
|
+
├── models/ # Schema cơ sở dữ liệu (Mongoose, Sequelize ORM, Prisma)
|
|
16
|
+
├── routes/ # Định tuyến HTTP, cấu hình gắn kết middleware đầu vào
|
|
17
|
+
├── controllers/ # Điều phối Request, định dạng Response đầu ra
|
|
18
|
+
├── services/ # Chứa 100% logic nghiệp vụ xử lý dữ liệu và tính toán
|
|
19
|
+
├── utils/ # Các hàm bổ trợ dùng chung
|
|
20
|
+
└── app.ts # File khởi tạo cấu hình Express App
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Quy ước Tên Tệp tin (File Naming)
|
|
24
|
+
- **Tính đồng nhất:** Toàn bộ dự án phải chọn và tuân thủ duy nhất định dạng `kebab-case.ts`.
|
|
25
|
+
- **Hậu tố định danh:** Tên file phải đi kèm vai trò kiến trúc của nó làm hậu tố:
|
|
26
|
+
- Controller: `user-controller.ts`
|
|
27
|
+
- Service: `user-service.ts`
|
|
28
|
+
- Route: `user-route.ts`
|
|
29
|
+
- Middleware: `auth-middleware.ts`, `validate-middleware.ts`
|
|
30
|
+
- Model: `user-model.ts`
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 📦 Định Nghĩa Kiểu Dữ Liệu & Quy Chuẩn TypeScript
|
|
35
|
+
- **Khai báo kiểu dữ liệu tường minh:** Không dùng kiểu ngầm định. Luôn định nghĩa rõ ràng kiểu cho tham số `req`, `res`, và `next` lấy từ thư viện `express`:
|
|
36
|
+
```typescript
|
|
37
|
+
import { Request, Response, NextFunction } from 'express';
|
|
38
|
+
```
|
|
39
|
+
- **Không lạm dụng `any`:** Định nghĩa đầy đủ các interface hoặc type cho các cấu trúc dữ liệu gửi lên và trả về cho Client.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Phân Tách Lớp Trách Nhiệm (Router vs Controller vs Service)
|
|
2
|
+
|
|
3
|
+
Tài liệu này đặc tả ranh giới trách nhiệm giữa các lớp trong Express.js: Router nhận diện đường dẫn $\rightarrow$ Controller điều phối $\rightarrow$ Service xử lý core logic.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🏛️ Chuỗi Truyền Dẫn Dữ Liệu
|
|
8
|
+
Mã nguồn dự án phải tuân thủ nghiêm ngặt mô hình luồng dữ liệu 3 lớp:
|
|
9
|
+
$$\text{Client} \longrightarrow \text{Router} \longrightarrow \text{Middleware} \longrightarrow \text{Controller} \longrightarrow \text{Service} \longrightarrow \text{Model/Database}$$
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 🚦 Trách Nhiệm Chi Tiết Của Từng Lớp
|
|
14
|
+
|
|
15
|
+
### 1. Lớp Định Tuyến (Router Layer - `routes/`)
|
|
16
|
+
- **Vai trò:** Chỉ làm nhiệm vụ map HTTP Method + Path, liên kết các middleware xác thực (Auth) hoặc kiểm duyệt định dạng đầu vào (Zod validate schema).
|
|
17
|
+
- **Quy tắc:** Tuyệt đối không chứa bất kỳ logic xử lý nghiệp vụ hay điều phối dữ liệu nào. Chỉ định hướng luồng sang Controller tương ứng.
|
|
18
|
+
|
|
19
|
+
### 2. Lớp Điều Phối (Controller Layer - `controllers/`)
|
|
20
|
+
- **Vai trò:** Làm nhiệm vụ bóc tách dữ liệu đầu vào từ đối tượng `req` (req.body, req.query, req.params, req.user), chuyển tiếp các tham số đó sang tầng Service, nhận kết quả và trả về cho Client bằng lệnh `res.status().json()`.
|
|
21
|
+
- **Quy tắc:**
|
|
22
|
+
- Không truy vấn cơ sở dữ liệu hoặc làm việc trực tiếp với ORM Models trong Controller.
|
|
23
|
+
- Không bắt lỗi try/catch thủ công (sử dụng asyncHandler để ủy thác cho bộ bắt lỗi toàn cục).
|
|
24
|
+
|
|
25
|
+
### 3. Lớp Nghiệp Vụ (Service Layer - `services/`)
|
|
26
|
+
- **Vai trò:** Chứa 100% logic nghiệp vụ xử lý dữ liệu, thực hiện tính toán thuật toán, tương tác với Database thông qua ORM Models.
|
|
27
|
+
- **Quy tắc:** Tuyệt đối không được tiếp xúc hay phụ thuộc vào các đối tượng `req`, `res`, hay `next` của Express. Lớp Service phải độc lập hoàn toàn với framework để dễ dàng viết các bài kiểm thử Unit Test.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: express-endpoint
|
|
3
|
+
description: Sinh hoặc mở rộng một API Endpoint Express.js + TypeScript an toàn, đầy đủ từ Router, Controller đến Validator
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Tuân thủ quy trình này để tạo mới một API Endpoint Express.js hoặc mở rộng tuyến định tuyến hiện có.
|
|
7
|
+
|
|
8
|
+
Đầu vào (Inputs):
|
|
9
|
+
- endpointName: Tên của API Endpoint cần tạo (ví dụ: `user-profile`)
|
|
10
|
+
- routePath: Đường dẫn tuyến HTTP của API (ví dụ: `/api/v1/users/profile`)
|
|
11
|
+
- httpMethod: Phương thức HTTP (GET, POST, PUT, DELETE)
|
|
12
|
+
- targetPath: Thư mục gốc chứa mã nguồn của mô-đun để đặt tệp tin
|
|
13
|
+
|
|
14
|
+
Các bước thực hiện (Steps):
|
|
15
|
+
1. Định nghĩa Zod Validation Schema dưới thư mục `middlewares/` hoặc bên cạnh controller để kiểm duyệt các trường dữ liệu đầu vào.
|
|
16
|
+
2. Xây dựng hàm Service tương ứng bên dưới thư mục `services/` để đảm nhiệm 100% logic xử lý nghiệp vụ, truy vấn dữ liệu ORM.
|
|
17
|
+
3. Triển khai Controller điều phối trong thư mục `controllers/` sử dụng tiện ích bọc `asyncHandler` để giải phóng việc try/catch thủ công, nhận tham số từ request và gửi phản hồi dạng JSON sạch.
|
|
18
|
+
4. Đăng ký Controller và gắn middleware `validateSchema(zodSchema)` vào file định tuyến Route tương ứng bên dưới thư mục `routes/`.
|
|
19
|
+
5. Bổ sung các test suite kiểm thử đơn vị cho Service và kiểm thử tích hợp (E2E) qua Supertest.
|
|
20
|
+
6. Chạy kiểm tra lỗi cục bộ:
|
|
21
|
+
- `{{runCommand}} lint`
|
|
22
|
+
- `{{runCommand}} typecheck`
|
|
23
|
+
- `{{runCommand}} test`
|
|
24
|
+
- `{{runCommand}} build`
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
## 🗺️ Hướng Dẫn Phát Triển NestJS (Node.js Backend)
|
|
2
|
+
|
|
3
|
+
### 🔄 Vòng Đời Phát Triển Tác Nhân (Agent Development Lifecycle)
|
|
4
|
+
Tác nhân AI phải thực hiện tất cả các nhiệm vụ NestJS theo quy trình 5 bước sau:
|
|
5
|
+
1. **Thiết kế & Lập trình:** Triển khai các lớp nghiệp vụ tuân thủ cấu trúc Module-driven. Giữ Controller mỏng, đặt 100% logic nghiệp vụ trong Service.
|
|
6
|
+
2. **Kiểm thử Toàn diện:** Viết unit test cho các Service sử dụng Jest Mocking (`.spec.ts`) và viết kiểm thử tích hợp đầu cuối (E2E) sử dụng Supertest.
|
|
7
|
+
3. **Chất lượng Mã nguồn:** Chạy các lệnh kiểm tra lỗi cú pháp và kiểu dữ liệu:
|
|
8
|
+
- Kiểm tra Lint: `{{runCommand}} lint`
|
|
9
|
+
- Kiểm tra Kiểu dữ liệu: `{{runCommand}} typecheck`
|
|
10
|
+
- Chạy Kiểm thử: `{{runCommand}} test` (hoặc `{{runCommand}} test -- --run` cho môi trường CI/CD)
|
|
11
|
+
- Chạy Build thử nghiệm: `{{runCommand}} build`
|
|
12
|
+
4. **Quản lý Thư viện:** Cài đặt các thư viện mới bằng lệnh: `{{packageManager}} add [tên_thư_viện]`. Tuyệt đối cấm sửa thủ công file lock `{{lockFile}}`.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
### 🏗️ Kiến Trúc Hệ Thống Bản Mẫu (Template Blueprint)
|
|
17
|
+
Vui lòng tham khảo các tài liệu quy tắc chi tiết dưới đây:
|
|
18
|
+
- Hướng dẫn coding style chuẩn TypeScript, quy tắc căn lề, sắp xếp decorator và tổ chức mã nguồn sạch: `@nestjs-style.md`
|
|
19
|
+
- Quy định chặt chẽ về ranh giới Module, cơ chế cô lập mã nguồn, Encapsulation và chia sẻ tài nguyên: `@module-architecture.md`
|
|
20
|
+
- Cấu hình Class Validator, chuyển đổi dữ liệu thông qua ValidationPipe và xử lý lỗi tập trung bằng Exceptions Filters: `@validation-errors.md`
|
|
21
|
+
- Quy trình tự động sinh trọn bộ cấu phần gồm Module, Controller, Service, DTO, Entity theo đúng chuẩn hệ thống: `@SKILL.md`
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
### 🏛️ Quy Tắc Phát Triển Nghiêm Ngặt
|
|
26
|
+
|
|
27
|
+
#### 1. Tiêm Phụ Thuộc (Dependency Injection)
|
|
28
|
+
- **Cấm tiêm thuộc tính (Property Injection):** Tuyệt đối không dùng `@Inject()` trực tiếp trên thuộc tính của Class trừ trường hợp tiêm các token tùy biến (Custom Tokens).
|
|
29
|
+
- **Bắt buộc tiêm qua Hàm Khởi Tạo (Constructor Injection):** Sử dụng cơ chế tự động phân giải phụ thuộc của NestJS qua từ khóa `private readonly`.
|
|
30
|
+
|
|
31
|
+
#### 2. Kiểm Thử Dữ Liệu Đầu Vào (Validation & Transformation)
|
|
32
|
+
- **Định hình DTO nghiêm ngặt:** Toàn bộ dữ liệu đầu vào của HTTP Request (`@Body()`, `@Query()`, `@Param()`) phải được đặc tả qua các lớp DTO sử dụng decorator từ `class-validator`.
|
|
33
|
+
- **Kích hoạt ống lọc toàn cục (Global Validation Pipe):** Khai báo tại file `main.ts` để tự động lọc bỏ các thuộc tính không nằm trong danh sách trắng (whitelist) và tự động ép kiểu dữ liệu (transform).
|
|
34
|
+
|
|
35
|
+
#### 3. Quản Lý Ngoại Lệ Toàn Cục (Unified Exception Handling)
|
|
36
|
+
- **Cấm trả về lỗi hệ thống thô:** Tuyệt đối không để lộ lỗi thô (chẳng hạn như lỗi từ DB) ra ngoài client với mã lỗi 500.
|
|
37
|
+
- **Sử dụng HttpExceptions tích hợp:** Bắt buộc phải bắt lỗi (try/catch) ở tầng Service và ánh xạ sang các Http Exception tường minh của NestJS (`NotFoundException`, `BadRequestException`, `ForbiddenException`).
|
|
38
|
+
- **Tập trung hóa bằng Exception Filter:** Xây dựng một Filter toàn cục để cấu trúc lại định dạng JSON trả về cho Client một cách đồng nhất.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Kiến Trúc Mô-đun & Cơ Chế Tiêm Phụ Thuộc (DI)
|
|
2
|
+
|
|
3
|
+
Tài liệu này quy định ranh giới Module, cơ chế cô lập mã nguồn, Encapsulation và cách tiêm phụ thuộc chuẩn trong NestJS.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 💉 Tiêm Phụ Thuộc (Dependency Injection)
|
|
8
|
+
- **Cấm tiêm thuộc tính (Property Injection):** Tuyệt đối không dùng `@Inject()` trực tiếp trên thuộc tính của Class trừ trường hợp tiêm các token tùy biến (Custom Tokens). Việc tiêm thuộc tính làm giảm khả năng kiểm thử (mocking) và làm loãng mã nguồn.
|
|
9
|
+
- **Bắt buộc tiêm qua Hàm Khởi Tạo (Constructor Injection):** Sử dụng cơ chế tự động phân giải phụ thuộc của NestJS qua từ khóa `private readonly` trong constructor.
|
|
10
|
+
|
|
11
|
+
* **Không hợp lệ (❌ Cấm viết):**
|
|
12
|
+
```typescript
|
|
13
|
+
@Injectable()
|
|
14
|
+
export class AuthService {
|
|
15
|
+
@Inject(UsersService)
|
|
16
|
+
private readonly usersService: UsersService;
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
* **Hợp lệ (✔️ Khuyến khích):**
|
|
20
|
+
```typescript
|
|
21
|
+
@Injectable()
|
|
22
|
+
export class AuthService {
|
|
23
|
+
constructor(private readonly usersService: UsersService) {}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 🏗️ Ranh Giới Mô-đun & Encapsulation
|
|
30
|
+
- **Cô lập theo mặc định (Encapsulation by Default):** Các Provider (Services, Repositories) bên trong một Module mặc định là private. Các module khác không thể truy cập nếu không được export công khai.
|
|
31
|
+
- **Chia sẻ tài nguyên qua Module:** Khi Module B muốn sử dụng Service của Module A:
|
|
32
|
+
1. Thêm Service đó vào mảng `exports` trong `@Module()` của Module A.
|
|
33
|
+
2. Import Module A vào mảng `imports` của Module B.
|
|
34
|
+
* Nghiêm cấm import trực tiếp Service của Module A vào danh sách `providers` của Module B.
|
|
35
|
+
- **Mô-đun Toàn cục (Global Modules):** Hạn chế sử dụng `@Global()` ngoại trừ các mô-đun hạ tầng chung cực kỳ ổn định (như cơ sở dữ liệu hoặc cấu hình hệ thống).
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Quy Ước Đặt Tên & Coding Style cho NestJS
|
|
2
|
+
|
|
3
|
+
Tài liệu này hướng dẫn coding style chuẩn TypeScript, quy tắc đặt tên tệp tin và lớp trong NestJS.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🏷️ Quy Ước Đặt Tên (Naming Conventions)
|
|
8
|
+
|
|
9
|
+
### Kỹ thuật Đặt Tên Tệp (Dot Notation)
|
|
10
|
+
Tất cả các tệp tin trong NestJS phải tuân thủ nghiêm ngặt định dạng cấu trúc: `<tên-đối-tượng>.<loại-cấu-phần>.ts`.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# Thư mục module luôn dùng số nhiều hoặc số ít đồng nhất (Ví dụ: auth, users, products)
|
|
14
|
+
src/users/
|
|
15
|
+
├── users.module.ts
|
|
16
|
+
├── users.controller.ts
|
|
17
|
+
├── users.service.ts
|
|
18
|
+
├── dto/
|
|
19
|
+
│ ├── create-user-request.dto.ts
|
|
20
|
+
│ └── update-user-response.dto.ts
|
|
21
|
+
├── entities/
|
|
22
|
+
│ └── user.entity.ts
|
|
23
|
+
├── guards/
|
|
24
|
+
│ └── roles.guard.ts
|
|
25
|
+
└── interceptors/
|
|
26
|
+
└── logging.interceptor.ts
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Quy ước đặt tên Lớp (Class Naming)
|
|
30
|
+
Tên lớp phải được viết theo định dạng PascalCase và kết thúc bằng tên cụ thể của loại cấu phần đó:
|
|
31
|
+
- **Controller:** `src/auth/auth.controller.ts` $\rightarrow$ `export class AuthController {}`
|
|
32
|
+
- **Service:** `src/auth/auth.service.ts` $\rightarrow$ `export class AuthService {}`
|
|
33
|
+
- **Module:** `src/auth/auth.module.ts` $\rightarrow$ `export class AuthModule {}`
|
|
34
|
+
- **DTO:** `src/auth/dto/login.dto.ts` $\rightarrow$ `export class LoginRequestDto {}`
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 📦 TypeScript & Sắp Xếp Decorator
|
|
39
|
+
- **Sắp xếp Decorator:** Nhóm và sắp xếp các decorator một cách khoa học. Các decorator định nghĩa phương thức HTTP (`@Get()`, `@Post()`) nằm trên cùng, tiếp theo là cấu hình bảo mật hoặc kiểm duyệt đầu vào (`@UseGuards()`, `@UseInterceptors()`).
|
|
40
|
+
- **Kiểu trả về tường minh:** Khai báo kiểu trả về rõ ràng cho tất cả các phương thức trong Controller và Service để bảo đảm tính chặt chẽ của kiểu dữ liệu.
|
|
41
|
+
- **Nghiêm cấm kiểu dữ liệu `any`:** Luôn khai báo class hoặc interface tương ứng cho các tham số và kết quả xử lý.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Xác Thực Dữ Liệu & Quản Lý Lỗi Tập Trung
|
|
2
|
+
|
|
3
|
+
Tài liệu này quy định việc sử dụng Class Validator, thiết lập ValidationPipe toàn cục và xử lý lỗi tập trung qua Exceptions Filters trong NestJS.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🛡️ Kiểm Thử Dữ Liệu Đầu Vào (Validation & Transformation)
|
|
8
|
+
- **Định hình DTO nghiêm ngặt:** Toàn bộ dữ liệu đầu vào của HTTP Request (`@Body()`, `@Query()`, `@Param()`) phải được đặc tả qua các lớp DTO sử dụng decorator từ `class-validator` (như `@IsString()`, `@IsEmail()`, `@IsInt()`).
|
|
9
|
+
- **Kích hoạt ống lọc toàn cục (Global Validation Pipe):** Khai báo tại file `main.ts` để tự động lọc bỏ các thuộc tính không nằm trong danh sách trắng (whitelist) và tự động ép kiểu dữ liệu (transform).
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
// Trong file main.ts
|
|
13
|
+
app.useGlobalPipes(
|
|
14
|
+
new ValidationPipe({
|
|
15
|
+
whitelist: true, // Tự động loại bỏ các thuộc tính không khai báo trong DTO
|
|
16
|
+
forbidNonWhitelisted: true, // Ném lỗi 400 nếu client gửi thuộc tính thừa
|
|
17
|
+
transform: true, // Tự động chuyển đổi kiểu dữ liệu (string sang number, object sang DTO class)
|
|
18
|
+
}),
|
|
19
|
+
);
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 🚨 Quản Lý Ngoại Lệ Toàn Cục (Unified Exception Handling)
|
|
25
|
+
- **Cấm trả về lỗi hệ thống thô:** Tuyệt đối không để lộ lỗi thô (chẳng hạn như lỗi từ DB, lỗi kết nối dịch vụ) ra ngoài client với mã lỗi 500.
|
|
26
|
+
- **Sử dụng HttpExceptions tích hợp:** Bắt buộc phải bắt lỗi (try/catch) ở tầng Service và ánh xạ sang các Http Exception tường minh của NestJS (`NotFoundException`, `BadRequestException`, `ForbiddenException`, v.v.).
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
try {
|
|
30
|
+
return await this.courseRepo.findOneOrFail(id);
|
|
31
|
+
} catch (error) {
|
|
32
|
+
throw new NotFoundException("Khóa học không tồn tại trên hệ thống.");
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
- **Tập trung hóa bằng Exception Filter:** Xây dựng một Filter toàn cục để cấu trúc lại định dạng JSON trả về cho Client một cách đồng nhất. Phản hồi lỗi hệ thống mong muốn phải có cấu trúc:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"success": false,
|
|
41
|
+
"statusCode": 404,
|
|
42
|
+
"timestamp": "2026-06-13T06:48:24.000Z",
|
|
43
|
+
"path": "/api/v1/courses/999",
|
|
44
|
+
"message": "Khóa học không tồn tại trên hệ thống."
|
|
45
|
+
}
|
|
46
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nestjs-module
|
|
3
|
+
description: Tự động sinh trọn bộ cấu phần gồm Module, Controller, Service, DTO, Entity theo đúng chuẩn hệ thống NestJS
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Tuân thủ quy trình này để tạo mới một Module NestJS hoặc mở rộng một mô-đun hiện có.
|
|
7
|
+
|
|
8
|
+
Đầu vào (Inputs):
|
|
9
|
+
- moduleName: Tên của mô-đun cần tạo (ví dụ: `products`)
|
|
10
|
+
- targetPath: Thư mục đích đặt mã nguồn bên dưới `src/`
|
|
11
|
+
- functionality: Tóm tắt yêu cầu nghiệp vụ và các endpoints cần cung cấp
|
|
12
|
+
|
|
13
|
+
Các bước thực hiện (Steps):
|
|
14
|
+
1. Tạo thư mục mô-đun `<moduleName>/` bên dưới thư mục `src/` (ví dụ: `src/products`).
|
|
15
|
+
2. Định nghĩa Entity model trong thư mục `<moduleName>/entities/`.
|
|
16
|
+
3. Định nghĩa các Request/Response DTO trong thư mục `<moduleName>/dto/`. Thêm các decorator validation tương ứng.
|
|
17
|
+
4. Xây dựng lớp Service trong `<moduleName>/` kế thừa DI của NestJS. Đặt toàn bộ business logic và bắt lỗi để ném ra các HttpException tường minh ở đây.
|
|
18
|
+
5. Xây dựng Controller trong `<moduleName>/` để ánh xạ các yêu cầu HTTP, kiểm tra phân quyền (Guards) và trả về kết quả JSON phù hợp.
|
|
19
|
+
6. Đăng ký Controller và Service vào file định nghĩa mô-đun `<moduleName>.module.ts`, export Service nếu các module khác cần sử dụng.
|
|
20
|
+
7. Viết unit test cho Service (`.spec.ts`) và cấu hình kịch bản kiểm thử tích hợp (E2E) sử dụng Supertest.
|
|
21
|
+
8. Chạy kiểm tra lỗi cục bộ:
|
|
22
|
+
- `{{runCommand}} lint`
|
|
23
|
+
- `{{runCommand}} typecheck`
|
|
24
|
+
- `{{runCommand}} test`
|
|
25
|
+
- `{{runCommand}} build`
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
## 🗺️ Hướng Dẫn Phát Triển Next.js (App Router)
|
|
2
|
+
|
|
3
|
+
### 🔄 Vòng Đời Phát Triển Tác Nhân (Agent Development Lifecycle)
|
|
4
|
+
Tác nhân AI phải thực hiện tất cả các nhiệm vụ Next.js theo quy trình 5 bước sau:
|
|
5
|
+
1. **Thiết kế & Lập trình:** Xây dựng page và component tuân thủ cấu trúc App Router. Mặc định sử dụng React Server Components (RSC).
|
|
6
|
+
2. **Kiểm thử Toàn diện:** Viết unit test cho các tiện ích xử lý nghiệp vụ và kiểm thử hành vi giao diện bằng Jest/Vitest.
|
|
7
|
+
3. **Chất lượng Mã nguồn:** Chạy các lệnh kiểm tra lỗi cú pháp và kiểu dữ liệu:
|
|
8
|
+
- Kiểm tra Lint: `{{runCommand}} lint`
|
|
9
|
+
- Kiểm tra Kiểu dữ liệu: `{{runCommand}} typecheck`
|
|
10
|
+
- Chạy Kiểm thử: `{{runCommand}} test` (hoặc `{{runCommand}} test -- --run` cho môi trường CI/CD)
|
|
11
|
+
- Chạy Build thử nghiệm: `{{runCommand}} build`
|
|
12
|
+
4. **Quản lý Thư viện:** Cài đặt các thư viện mới bằng lệnh: `{{packageManager}} add [tên_thư_viện]`. Tuyệt đối cấm sửa thủ công file lock `{{lockFile}}`.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
### 🏗️ Kiến Trúc Hệ Thống Bản Mẫu (Template Blueprint)
|
|
17
|
+
Vui lòng tham khảo các tài liệu quy tắc chi tiết dưới đây:
|
|
18
|
+
- Quy ước viết mã, định dạng file, cấu trúc import tự động và quy tắc tổ chức folder: `@next-style.md`
|
|
19
|
+
- Phân định ranh giới kiến trúc giữa React Server Components (RSC) và React Client Components (RCC): `@server-client-components.md`
|
|
20
|
+
- Tiêu chuẩn hóa việc gọi API tại tầng Server, quản lý cơ chế Caching, Revalidation và triển khai Server Actions bảo mật: `@data-fetching-mutations.md`
|
|
21
|
+
- Quy định bắt buộc về Semantic HTML5 và tích hợp Dynamic Metadata API: `@seo-metadata.md`
|
|
22
|
+
- Quy trình từng bước giúp khởi tạo một Page hoặc Route mới không lỗi: `@SKILL.md`
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
### 🏛️ Quy Tắc Phát Triển Nghiêm Ngặt
|
|
27
|
+
|
|
28
|
+
#### 1. Kiến Trúc Thành Phần (Rendering Paradigm)
|
|
29
|
+
- **Mặc định là Server Components:** Tất cả các component trong thư mục `app/` mặc định phải là React Server Components (RSC).
|
|
30
|
+
- **Cách ly Client Components (RCC):** Chỉ gắn directive `"use client"` ở lớp component lá (Leaf Components) cần tương tác (như xử lý Form, Nút bấm bắt sự kiện onClick, sử dụng useState, useEffect, hoặc các Hook trình duyệt).
|
|
31
|
+
|
|
32
|
+
#### 2. Fetching Dữ Liệu & Server Actions
|
|
33
|
+
- **Gọi dữ liệu tại gốc:** Thực hiện `fetch()` trực tiếp bên trong các async Server Components để tận dụng tối đa cơ chế tối ưu hóa request và bảo mật mã nguồn API token tại Server.
|
|
34
|
+
- **Quản lý bộ nhớ đệm (Caching & Revalidation):** Nghiêm cấm sử dụng fetch thô không có cấu hình kiểm soát vòng đời dữ liệu.
|
|
35
|
+
- **Đột biến dữ liệu (Mutations via Server Actions):** Toàn bộ các tương tác POST, PUT, DELETE phải qua Server Actions (`"use server"`).
|
|
36
|
+
- **Trải nghiệm người dùng mượt mà:** Sử dụng hook `useActionState` (hoặc `useFormState`) để quản lý trạng thái phản hồi của form từ server và bọc các tác vụ mutate trong `useTransition` nhằm duy trì giao diện không bị đóng băng.
|
|
37
|
+
|
|
38
|
+
#### 3. Tối Ưu Hóa Hiệu Năng & SEO
|
|
39
|
+
- **Tối ưu hình ảnh:** Tuyệt đối không dùng thẻ `<img>` thô. Bắt buộc sử dụng `<Image />` từ `next/image` với đầy đủ thuộc tính `sizes` và cấu hình `priority` cho các hình ảnh xuất hiện ở nấc màn hình đầu tiên (Above the fold).
|
|
40
|
+
- **Tối ưu điều hướng:** Dùng `<Link />` từ `next/link` để kích hoạt cơ chế pre-fetching tài nguyên ngầm khi link xuất hiện trong viewport.
|
|
41
|
+
- **Cấu hình Metadata động:** Khai báo cấu hình SEO thông qua hàm `generateMetadata` đối với các route động để tối ưu hóa SEO tối đa cho hệ thống tìm kiếm.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Gọi Dữ Liệu & Đột Biến Dữ Liệu (Data Fetching & Mutations)
|
|
2
|
+
|
|
3
|
+
Tài liệu này quy định tiêu chuẩn gọi API, quản lý bộ nhớ đệm (caching) và thay đổi dữ liệu sử dụng Next.js Server Actions.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🔌 Gọi Dữ Liệu Tại Gốc (Data Fetching at the Source)
|
|
8
|
+
- **Thực hiện trong RSC:** Gọi dữ liệu `fetch()` trực tiếp bên trong các async Server Components (`RSC`). Điều này giúp bảo mật API endpoint, token xác thực và giảm thiểu độ trễ mạng bằng cách gộp xử lý trên server.
|
|
9
|
+
- **Quy tắc:** Không sử dụng các client-side fetch wrapper tùy tiện trong các server pages. Hãy sử dụng cú pháp async/await tiêu chuẩn.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 💾 Quản Lý Bộ Nhớ Đệm (Caching & Revalidation)
|
|
14
|
+
- **Cấm Fetch Thô:** Nghiêm cấm sử dụng fetch() thô mà không có cấu hình kiểm soát vòng đời dữ liệu hoặc chiến lược revalidate rõ ràng.
|
|
15
|
+
|
|
16
|
+
* **Không hợp lệ (❌ Nghiêm cấm):**
|
|
17
|
+
```typescript
|
|
18
|
+
// Fetch dữ liệu tĩnh vô thời hạn mà không có chiến lược revalidate rõ ràng
|
|
19
|
+
const res = await fetch('https://api.skillverse.vn/v1/courses');
|
|
20
|
+
```
|
|
21
|
+
* **Hợp lệ (✔️ Khuyến khích):**
|
|
22
|
+
```typescript
|
|
23
|
+
// Cấu hình ISR (Incremental Static Regeneration) rõ ràng với cache tag
|
|
24
|
+
const res = await fetch('https://api.skillverse.vn/v1/courses', {
|
|
25
|
+
next: { revalidate: 3600, tags: ['courses'] }
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
- **Làm mới bộ nhớ đệm:** Sử dụng `revalidatePath` hoặc `revalidateTag` bên trong các Server Actions để xóa các bản ghi cũ trong cache và bắt buộc Next.js cập nhật lại dữ liệu mới.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## ⚡ Đột Biến Dữ Liệu (Mutations via Server Actions)
|
|
33
|
+
- **Sử dụng Server Actions:** Toàn bộ các tương tác POST, PUT, DELETE, PATCH phải qua Server Actions được đánh dấu bằng directive `"use server"` ở đầu hàm hoặc đầu file chứa hành động.
|
|
34
|
+
- **Trải nghiệm người dùng mượt mà:**
|
|
35
|
+
- Sử dụng hook `useActionState` (hoặc `useFormState` trong các phiên bản trước React 19) để quản lý trạng thái phản hồi của form từ server và kiểm soát trạng thái đang xử lý (`isPending`).
|
|
36
|
+
- Bọc các tác vụ mutate trong `useTransition` nhằm duy trì giao diện người dùng mượt mà, không bị đóng băng trong quá trình xử lý ngầm.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Quy Ước Đặt Tên & Coding Style cho Next.js (App Router)
|
|
2
|
+
|
|
3
|
+
Tài liệu này đặc tả quy ước đặt tên file, thư mục, cấu trúc import và tổ chức folder trong các dự án Next.js App Router.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🏷️ Quy Ước Đặt Tên (Naming Conventions)
|
|
8
|
+
|
|
9
|
+
| Đối Tượng | Quy Chuẩn Đặt Tên | Ví Dụ Minh Họa |
|
|
10
|
+
| :--- | :--- | :--- |
|
|
11
|
+
| **Thư mục Route (`app/`)** | lowercase hoặc kebab-case | `app/dashboard/`, `app/user-profile/` |
|
|
12
|
+
| **Route Nhóm (Route Groups)** | Bọc trong dấu ngoặc đơn `(group-name)` | `app/(auth)/login/`, `app/(dashboard)/layout.tsx` |
|
|
13
|
+
| **Route Động (Dynamic Routes)** | Bọc trong dấu ngoặc vuông `[paramName]` | `app/blog/[id]/page.tsx`, `app/shop/[...slug]/page.tsx` |
|
|
14
|
+
| **Tệp Giao Diện Đặc Trưng** | Định dạng chuẩn Next.js (lowercase.tsx) | `page.tsx`, `layout.tsx`, `loading.tsx`, `error.tsx` |
|
|
15
|
+
| **Route Handlers** | Định dạng file API endpoint của Next.js | `route.ts` |
|
|
16
|
+
| **Component UI Phụ Trợ** | PascalCase.tsx | `Button.tsx`, `ProductCard.tsx`, `SidebarSkeleton.tsx` |
|
|
17
|
+
| **Custom Hooks** | camelCase bắt đầu bằng tiền tố `use` | `useAuth.ts`, `useLocalStorage.ts` |
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 📦 Imports & Aliasing
|
|
22
|
+
- **Absolute Imports:** Luôn luôn sử dụng absolute imports với alias `@/` trỏ tới thư mục `src/` hoặc root (ví dụ: `import { Button } from "@/components/ui/Button"`). Nghiêm cấm sử dụng relative imports với nhiều tầng nhảy thư mục sâu (ví dụ: `../../../../Button`).
|
|
23
|
+
- **CSS / Styles Imports:** Đặt các styles toàn cục trong một file duy nhất (như `globals.css` hoặc `index.css`) được import trong file `layout.tsx` gốc. Không import file CSS tùy tiện trong các component con.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 📁 Tổ Chức Thư Mục (Folder Organization)
|
|
28
|
+
- Giữ các thư mục bên trong `app/` dành riêng cho việc khai báo routing và giao diện trang tương ứng.
|
|
29
|
+
- Đặt các component nghiệp vụ, hook, service và type bên trong thư mục `src/features/` hoặc `src/components/` bên ngoài thư mục `app/`. Mỗi feature (ví dụ: `billing`) nên đóng gói các tài nguyên liên quan:
|
|
30
|
+
- `src/features/billing/components/BillingForm.tsx`
|
|
31
|
+
- `src/features/billing/hooks/useBilling.ts`
|
|
32
|
+
- Xuất bản public APIs của feature qua một file `index.ts` sạch sẽ.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Tối Ưu Hóa SEO & Cấu Trúc Semantic HTML
|
|
2
|
+
|
|
3
|
+
Tài liệu này quy định việc sử dụng cấu trúc thẻ Semantic, tối ưu hóa điều hướng hình ảnh và tích hợp Metadata API của Next.js để đạt thứ hạng SEO tốt nhất.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🔍 Tích Hợp Metadata API Của Next.js
|
|
8
|
+
- **Metadata Tĩnh:** Khai báo đối tượng `metadata` tĩnh trong các layouts hoặc pages không có biến số động:
|
|
9
|
+
```typescript
|
|
10
|
+
export const metadata = {
|
|
11
|
+
title: 'Dashboard | Skillverse Platform',
|
|
12
|
+
description: 'Trang tổng quan quản lý khóa học',
|
|
13
|
+
};
|
|
14
|
+
```
|
|
15
|
+
- **Metadata Động:** Đối với các route động (như trang chi tiết bài viết, khóa học), khai báo cấu hình SEO thông qua hàm `generateMetadata` đối với các route động để tối ưu hóa SEO tối đa cho hệ thống tìm kiếm:
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { Metadata } from 'next';
|
|
19
|
+
|
|
20
|
+
type Props = { params: Promise<{ id: string }> };
|
|
21
|
+
|
|
22
|
+
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
|
23
|
+
const id = (await params).id;
|
|
24
|
+
const course = await getCourseDetail(id);
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
title: `${course.title} | Skillverse Platform`,
|
|
28
|
+
description: course.shortDescription,
|
|
29
|
+
openGraph: { images: [course.thumbnailUrl] }
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 🎨 Cấu Trúc Semantic HTML5
|
|
37
|
+
- **Thẻ cấu trúc:** Bắt buộc xây dựng bố cục trang bằng các thẻ HTML5 ngữ nghĩa thay vì lạm dụng các thẻ `<div>` vô nghĩa:
|
|
38
|
+
- `<header>`: Thanh tiêu đề hoặc thanh đầu trang chính.
|
|
39
|
+
- `<nav>`: Danh mục liên kết điều hướng cốt lõi.
|
|
40
|
+
- `<main>`: Bao bọc duy nhất phần nội dung cốt lõi của trang.
|
|
41
|
+
- `<section>`: Phân đoạn chủ đề nội dung tổng quát.
|
|
42
|
+
- `<article>`: Các thành phần độc lập (bài viết blog, phần tử thẻ card sản phẩm).
|
|
43
|
+
- `<footer>`: Chứa thông tin bản quyền và liên kết chân trang.
|
|
44
|
+
- **Tiêu đề h-tags:** Đảm bảo thứ tự logic của các thẻ tiêu đề (từ `<h1>` đến `<h6>`). Đảm bảo có duy nhất một thẻ `<h1>` trên mỗi trang.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## ⚡ Tối Ưu Hóa Hình Ảnh & Điều Hướng
|
|
49
|
+
- **Tối ưu hình ảnh:** Tuyệt đối không dùng thẻ `<img>` thô. Bắt buộc sử dụng `<Image />` từ `next/image` với đầy đủ thuộc tính `sizes` và cấu hình `priority` cho các hình ảnh xuất hiện ở nấc màn hình đầu tiên (Above the fold).
|
|
50
|
+
- **Tối ưu điều hướng:** Dùng `<Link />` từ `next/link` để kích hoạt cơ chế pre-fetching tài nguyên ngầm khi link xuất hiện trong viewport, giúp chuyển trang tức thì.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# React Server Components (RSC) vs React Client Components (RCC)
|
|
2
|
+
|
|
3
|
+
Tài liệu này quy định ranh giới kiến trúc và quy tắc phân loại component trong ứng dụng Next.js sử dụng App Router.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🏛️ React Server Components (RSC)
|
|
8
|
+
- **Mặc định:** Tất cả các page, layout và component được tạo bên trong thư mục routing `app/` mặc định phải là React Server Components (RSC).
|
|
9
|
+
- **Lợi ích của RSC:**
|
|
10
|
+
- Gọi dữ liệu (data fetching) trực tiếp sử dụng async/await.
|
|
11
|
+
- Sử dụng an toàn các thư viện phía server (truy vấn DB, đọc file, import khóa bảo mật).
|
|
12
|
+
- Giảm dung lượng bundle size gửi xuống client do mã nguồn RSC chỉ biên dịch và chạy trên server.
|
|
13
|
+
- **Quy tắc:**
|
|
14
|
+
- Thực hiện toàn bộ việc nạp dữ liệu và cấu trúc khung trang bên trong các RSC.
|
|
15
|
+
- Không thêm `"use client"` vào các layout hoặc page entry points trừ khi bắt buộc.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 💻 React Client Components (RCC)
|
|
20
|
+
- **Định nghĩa:** Các component chạy trên trình duyệt để hỗ trợ tương tác và cập nhật trạng thái động từ người dùng.
|
|
21
|
+
- **Dấu hiệu nhận biết RCC:** Chỉ gắn directive `"use client"` ở lớp component lá (Leaf Components) khi component:
|
|
22
|
+
- Sử dụng các Hook vòng đời và trạng thái của React (`useState`, `useReducer`, `useEffect`, `useLayoutEffect`).
|
|
23
|
+
- Gọi các API đặc trưng của trình duyệt (`window`, `localStorage`, custom viewport hooks).
|
|
24
|
+
- Đăng ký các callback lắng nghe sự kiện DOM (như `onClick`, `onChange`, `onSubmit`).
|
|
25
|
+
- **Phân tách ranh giới RCC:**
|
|
26
|
+
- Giữ RCC ở cấp lá (Leaf Components) cuối cùng của cây dựng hình để tối ưu hiệu năng.
|
|
27
|
+
- *Ví dụ:* Nếu trang danh sách sản phẩm (RSC) có thanh tìm kiếm (RCC), hãy tách thanh tìm kiếm thành một component riêng (`<SearchBar />` có `"use client"`) và import vào trang cha chạy ở phía server.
|