chore: update project documentation, audit reports, and initialize IDE configuration files
Some checks failed
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 29s
CI / E2E Tests (push) Has been skipped
CodeQL Analysis / CodeQL (javascript-typescript) (push) Failing after 2m42s
Deploy / Build Web Image (push) Failing after 27s
Deploy / Build AI Services Image (push) Failing after 29s
E2E Tests / Playwright E2E (push) Failing after 43s
Deploy / Build API Image (push) Failing after 1m31s
Security Scanning / Dependency Audit (pnpm) (push) Failing after 6s
Security Scanning / Trivy Scan — API Image (push) Failing after 5m35s
Security Scanning / Trivy Scan — AI Services Image (push) Failing after 3m45s
Deploy / Deploy to Staging (push) Has been skipped
Deploy / Smoke Test Staging (push) Has been skipped
Deploy / Deploy to Production (push) Has been skipped
Deploy / Smoke Test Production (push) Has been skipped
Deploy / Rollback Staging (push) Has been skipped
Deploy / Rollback Production (push) Has been skipped
Security Scanning / Trivy Scan — Web Image (push) Failing after 13m51s
Security Scanning / Trivy Filesystem Scan (push) Failing after 14m46s
Security Scanning / Security Gate (push) Has been cancelled
Some checks failed
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 29s
CI / E2E Tests (push) Has been skipped
CodeQL Analysis / CodeQL (javascript-typescript) (push) Failing after 2m42s
Deploy / Build Web Image (push) Failing after 27s
Deploy / Build AI Services Image (push) Failing after 29s
E2E Tests / Playwright E2E (push) Failing after 43s
Deploy / Build API Image (push) Failing after 1m31s
Security Scanning / Dependency Audit (pnpm) (push) Failing after 6s
Security Scanning / Trivy Scan — API Image (push) Failing after 5m35s
Security Scanning / Trivy Scan — AI Services Image (push) Failing after 3m45s
Deploy / Deploy to Staging (push) Has been skipped
Deploy / Smoke Test Staging (push) Has been skipped
Deploy / Deploy to Production (push) Has been skipped
Deploy / Smoke Test Production (push) Has been skipped
Deploy / Rollback Staging (push) Has been skipped
Deploy / Rollback Production (push) Has been skipped
Security Scanning / Trivy Scan — Web Image (push) Failing after 13m51s
Security Scanning / Trivy Filesystem Scan (push) Failing after 14m46s
Security Scanning / Security Gate (push) Has been cancelled
This commit is contained in:
@@ -1,34 +1,34 @@
|
||||
# Contributing Guide
|
||||
# Hướng Dẫn Đóng Góp
|
||||
|
||||
## Error Handling Convention
|
||||
## Quy Ước Xử Lý Lỗi
|
||||
|
||||
### Overview
|
||||
### Tổng Quan
|
||||
|
||||
All application-layer error handling uses **domain exceptions** from `@modules/shared/domain/domain-exception`. Never import exception classes from `@nestjs/common` in handlers — use the project's own domain exceptions instead.
|
||||
Toàn bộ xử lý lỗi ở tầng ứng dụng sử dụng **domain exceptions** từ `@modules/shared/domain/domain-exception`. Không bao giờ import các lớp exception từ `@nestjs/common` trong handlers — hãy dùng domain exceptions của dự án.
|
||||
|
||||
The `GlobalExceptionFilter` catches all exceptions and normalizes them into a consistent JSON response with structured error codes.
|
||||
`GlobalExceptionFilter` bắt tất cả các exception và chuẩn hóa chúng thành một JSON response nhất quán với error codes có cấu trúc.
|
||||
|
||||
### Domain Exceptions
|
||||
|
||||
| Exception | HTTP Status | When to use |
|
||||
| Exception | HTTP Status | Khi nào dùng |
|
||||
|---|---|---|
|
||||
| `NotFoundException(entity, id?)` | 404 | Entity not found in database |
|
||||
| `ValidationException(message, details?)` | 400 | Invalid input, business rule violation, value object creation failure |
|
||||
| `ConflictException(message)` | 409 | Duplicate resource, idempotency violation |
|
||||
| `UnauthorizedException(message?)` | 401 | Invalid/expired credentials or tokens |
|
||||
| `ForbiddenException(message?)` | 403 | Authenticated but not authorized for the action |
|
||||
| `NotFoundException(entity, id?)` | 404 | Không tìm thấy entity trong database |
|
||||
| `ValidationException(message, details?)` | 400 | Dữ liệu đầu vào không hợp lệ, vi phạm business rule, lỗi tạo value object |
|
||||
| `ConflictException(message)` | 409 | Tài nguyên bị trùng lặp, vi phạm idempotency |
|
||||
| `UnauthorizedException(message?)` | 401 | Thông tin xác thực hoặc token không hợp lệ/đã hết hạn |
|
||||
| `ForbiddenException(message?)` | 403 | Đã xác thực nhưng không được phép thực hiện hành động |
|
||||
|
||||
Import from:
|
||||
Import từ:
|
||||
|
||||
```typescript
|
||||
import { NotFoundException, ValidationException } from '@modules/shared/domain/domain-exception';
|
||||
```
|
||||
|
||||
### Patterns by Layer
|
||||
### Các Mẫu Theo Từng Tầng
|
||||
|
||||
#### Command/Query Handlers
|
||||
|
||||
Handlers throw domain exceptions directly. No try-catch wrapping needed — the `GlobalExceptionFilter` handles uncaught exceptions.
|
||||
Handlers ném domain exceptions trực tiếp. Không cần bọc try-catch — `GlobalExceptionFilter` xử lý các exception chưa được bắt.
|
||||
|
||||
```typescript
|
||||
// Good: domain exception with entity context
|
||||
@@ -50,11 +50,11 @@ if (subscription.status === 'CANCELLED') {
|
||||
|
||||
#### Controllers
|
||||
|
||||
Controllers are thin delegation layers — they dispatch to the command/query bus and return the result. No error handling needed at the controller level.
|
||||
Controllers là các tầng ủy quyền mỏng — chúng dispatch tới command/query bus và trả về kết quả. Không cần xử lý lỗi ở tầng controller.
|
||||
|
||||
#### Domain Services / Value Objects
|
||||
|
||||
Use the `Result<T, E>` pattern from `@modules/shared/domain/result`:
|
||||
Sử dụng mẫu `Result<T, E>` từ `@modules/shared/domain/result`:
|
||||
|
||||
```typescript
|
||||
static create(value: string): Result<Phone, string> {
|
||||
@@ -63,9 +63,9 @@ static create(value: string): Result<Phone, string> {
|
||||
}
|
||||
```
|
||||
|
||||
Handlers consume `Result` by checking `.isErr` and throwing a `ValidationException`.
|
||||
Handlers sử dụng `Result` bằng cách kiểm tra `.isErr` và ném `ValidationException`.
|
||||
|
||||
### What NOT to Do
|
||||
### Những Điều KHÔNG Nên Làm
|
||||
|
||||
```typescript
|
||||
// Bad: NestJS built-in exceptions (missing errorCode in response)
|
||||
@@ -85,8 +85,8 @@ try {
|
||||
// Handlers should unwrap Result and throw on error
|
||||
```
|
||||
|
||||
### Repository Return Types
|
||||
### Kiểu Trả Về Của Repository
|
||||
|
||||
All repository read methods must return explicitly typed DTOs — never `Promise<any>` or `PaginatedResult<any>`. Define read DTOs in the domain layer alongside the repository interface.
|
||||
Tất cả các phương thức đọc của repository phải trả về DTOs được định kiểu rõ ràng — không bao giờ dùng `Promise<any>` hoặc `PaginatedResult<any>`. Định nghĩa read DTOs ở tầng domain cùng với interface của repository.
|
||||
|
||||
See `listing-read.dto.ts` for the canonical example.
|
||||
Xem `listing-read.dto.ts` để tham khảo ví dụ chuẩn.
|
||||
|
||||
Reference in New Issue
Block a user