Quy ước chung
Các quy ước bắt buộc áp dụng cho mọi dự án tại PrimeCommerce.
Quy ước đặt tên
| Đối tượng | Quy ước | Ví dụ |
|---|
| Biến / hàm | camelCase | getUserById |
| Component | PascalCase | UserProfileCard |
| File component | PascalCase | UserProfileCard.tsx |
| File utils/hooks | kebab-case | use-auth.ts, format-date.ts |
| Hằng số | SCREAMING_SNAKE | MAX_RETRY_COUNT |
| Bảng database | snake_case | user_profiles |
| API endpoint | kebab-case | /api/user-profiles |
| Biến môi trường | SCREAMING_SNAKE | DATABASE_URL |
Git Workflow
Branch Strategy — GitHub Flow
main # Production (protected, cần PR + 1 approval + CI pass)
staging # Pre-production (auto-deploy khi push)
feat/* # 1 User Story = 1 branch = 1 PR vào staging
fix/* # Bug fixes → PR vào staging
hotfix/* # Sửa khẩn cấp production (từ main, merge lại main)
chore/* # Deps, config, refactor (không thay đổi business logic)
Đặt tên branch
Format: type/FXX-YY-short-description
feat/F01-01-generate-site
feat/F08-03-bulk-create-products
fix/F01-builder-crash
hotfix/F13-payment-timeout
Yêu cầu PR
- Title theo Conventional Commits
- Description điền đầy đủ theo PR template
- Ít nhất 1 approval từ team member
- Tất cả CI checks pass
- Không còn review comments chưa giải quyết
Commit Convention
Theo chuẩn Conventional Commits: type(scope): description
feat(auth): add Google OAuth login
fix(api): handle null response from payment gateway
chore(deps): upgrade Next.js to 14.2
docs(readme): update local setup instructions
test(user): add unit tests for user service
refactor(db): normalize user address fields
perf(query): add index on orders.created_at
ci(actions): add staging deploy workflow
Types
| Type | Khi nào dùng |
|---|
feat | Tính năng mới |
fix | Sửa bug |
chore | Công việc bảo trì (deps, config) |
docs | Tài liệu |
test | Thêm/sửa tests |
refactor | Tái cấu trúc (không đổi hành vi) |
perf | Tối ưu hiệu năng |
ci | CI/CD |
style | Format code (không đổi logic) |
Quy tắc
- Tối đa 72 ký tự trên dòng subject
- Dùng thì mệnh lệnh: “add”, “fix”, “update” (không phải “added”, “fixes”)
- Tham chiếu ticket:
feat(auth): add Google OAuth login (PROJ-123)
API Design
RESTful Endpoints
GET /api/v1/resources # Lấy danh sách
POST /api/v1/resources # Tạo mới
GET /api/v1/resources/:id # Lấy chi tiết
PATCH /api/v1/resources/:id # Cập nhật một phần
DELETE /api/v1/resources/:id # Xóa
{
"data": {},
"meta": {
"page": 1,
"limit": 20,
"total": 100
},
"error": null
}
HTTP Status Codes
| Code | Ý nghĩa | Khi nào |
|---|
200 | OK | GET, PATCH thành công |
201 | Created | POST thành công |
400 | Bad Request | Input sai format |
401 | Unauthorized | Chưa đăng nhập |
403 | Forbidden | Không có quyền |
404 | Not Found | Resource không tồn tại |
422 | Unprocessable | Validation lỗi |
500 | Server Error | Lỗi server |
GET /api/v1/products?page=1&limit=20
Response meta:
{
"page": 1,
"limit": 20,
"total": 150,
"totalPages": 8
}
Coding Standards
TypeScript / JavaScript
Không sử dụng any trừ khi bắt buộc và có giải thích rõ ràng.
- Dùng
const mặc định, let chỉ khi cần gán lại
- Ưu tiên
async/await hơn .then() chains
- Luôn xử lý lỗi rõ ràng — không silent catch
- Dùng named exports (trừ pages/layouts)
- Co-locate types với nơi sử dụng, chỉ chuyển sang
types/ khi dùng chung
Ví dụ
// Named export, strict types
export const getUserById = async (id: string): Promise<User | null> => {
try {
const user = await prisma.user.findUnique({ where: { id } });
return user;
} catch (error) {
logger.error('Failed to get user', { id, error });
throw new NotFoundException(`User ${id} not found`);
}
};
// Default export, any type, silent catch
export default function getUser(id: any) {
return prisma.user.findUnique({ where: { id } })
.then(u => u)
.catch(() => null); // Silent catch!
}
Môi trường
| Môi trường | Branch | Mục đích |
|---|
local | bất kỳ | Máy developer |
staging | staging | QA testing, PM demo |
production | main | Người dùng thật |
Không bao giờ commit file .env. Dùng .env.example với placeholder values.
Security Checklist
Mỗi tính năng bắt buộc kiểm tra: