# 📚 Mô-đun Inquiries - Tài Liệu Khám Phá Toàn Diện

**Ngày tạo:** 11 tháng 4, 2026  
**Mô-đun:** `apps/api/src/modules/inquiries/`  
**Trạng thái:** ✅ Phân tích Đầy đủ & Kỹ lưỡng

---

## 📖 CÁC TỆP TÀI LIỆU

Bộ khám phá này bao gồm **3 tệp tài liệu toàn diện** được thiết kế cho các trường hợp sử dụng khác nhau:

### 1. **INQUIRIES_MODULE_EXPLORATION.md** (23 KB)
**Mục đích:** Tài liệu tham khảo chuyên sâu  
**Phù hợp nhất:** Hiểu kiến trúc, các mẫu thiết kế và mô tả tệp đầy đủ

Nội dung:
- 📁 Cấu trúc thư mục đầy đủ
- 📄 Danh sách tệp hoàn chỉnh kèm mô tả
- 🏗️ Sơ đồ kiến trúc mô-đun
- 🔑 Phân tích các lớp và trình xử lý chính
- 🎯 Phân tích tầng DDD
- 📊 Tóm tắt tệp kiểm thử
- 🛠️ Phụ thuộc và bảo mật
- 📝 Hợp đồng API

**Đọc khi:** Bạn cần hiểu toàn diện về mô-đun

---

### 2. **INQUIRIES_MODULE_QUICK_REFERENCE.md** (9.3 KB)
**Mục đích:** Tài liệu tra cứu nhanh  
**Phù hợp nhất:** Nắm bắt nhanh, tìm thông tin cụ thể

Nội dung:
- 📊 Tổng quan mô-đun
- 📁 Các tệp theo tầng tổng quan
- 🔄 Sơ đồ luồng yêu cầu
- 🔑 Bảng các lớp chính
- 📝 Các giao diện chính
- 🧪 Thống kê kiểm thử
- 🔐 Ma trận phân quyền
- 🎯 Nguyên tắc DDD
- 📌 Các mẫu phổ biến
- 🔍 Hướng dẫn tìm kiếm theo chủ đề

**Đọc khi:** Bạn cần câu trả lời nhanh hoặc mới làm quen với mô-đun

---

### 3. **INQUIRIES_COMPLETE_FILE_INDEX.md** (23 KB)
**Mục đích:** Tài liệu tham chiếu tệp đầy đủ  
**Phù hợp nhất:** Tìm các tệp cụ thể, hiểu phụ thuộc, lập kế hoạch sửa đổi

Nội dung:
- 📋 Danh sách tệp đầy đủ theo đường dẫn
- 📊 Bảng thống kê tệp
- 🔍 Hướng dẫn khám phá tệp
- 🔗 Đồ thị phụ thuộc
- 📝 Tham chiếu chéo tệp
- 🎯 Điểm vào để sửa đổi
- Số dòng của từng tệp
- Mô tả phương thức chi tiết

**Đọc khi:** Bạn cần chi tiết từng tệp hoặc đang lập kế hoạch thay đổi

---

## 🎯 KHỞI ĐẦU NHANH THEO TRƯỜNG HỢP SỬ DỤNG

### Tôi muốn hiểu kiến trúc tổng thể
→ Bắt đầu với **Quick Reference** → Đi sâu vào **Exploration**

### Tôi mới làm quen với mô-đun này
→ Bắt đầu với **Quick Reference** → Duyệt **File Index** khi cần

### Tôi cần thêm một endpoint mới
→ Xem **File Index** → Mục Entry Points → Làm theo hướng dẫn

### Tôi cần hiểu một tầng cụ thể
→ Tìm kiếm trong **Quick Reference** theo tầng → Đọc chi tiết đầy đủ trong **Exploration**

### Tôi đang tìm một lớp hoặc phương thức cụ thể
→ Dùng **File Index** → Mục File Discovery Guide

### Tôi cần hiểu luồng dữ liệu
→ **Quick Reference** → Mục Request Flows

### Tôi đang sửa lỗi hoặc tái cấu trúc
→ **File Index** → Dependency Graph & Cross-References

---

## 📊 TỔNG QUAN MÔ-ĐUN

```
Location:    apps/api/src/modules/inquiries/
Files:       25 total (19 source + 6 test files)
LOC:         1,212 lines of code
Pattern:     CQRS + DDD (Clean Architecture)
Tests:       24 test cases across 6 suites
Endpoints:   4 HTTP endpoints
```

### Phân Tích Theo Tầng

| Tầng | Tệp | Mục đích |
|------|-----|----------|
| **Presentation** | 5 | Điểm cuối HTTP + xác thực |
| **Application** | 8 | Lệnh/Truy vấn + điều phối |
| **Domain** | 6 | Logic nghiệp vụ + hợp đồng |
| **Infrastructure** | 1 | Lưu trữ Prisma |
| **Module** | 2 | Cấu hình + xuất |

---

## 🗂️ CÂY TỆP

```
inquiries/
├── 📄 index.ts                              [Barrel export]
├── 📄 inquiries.module.ts                   [NestJS Module]
│
├── 📁 presentation/
│   ├── controllers/
│   │   └── inquiries.controller.ts          [4 endpoints]
│   ├── dto/
│   │   ├── create-inquiry.dto.ts            [Input validation]
│   │   └── list-inquiries.dto.ts            [Pagination]
│   └── __tests__/
│       └── inquiries.controller.spec.ts     [6 tests]
│
├── 📁 application/
│   ├── commands/
│   │   ├── create-inquiry/
│   │   │   ├── create-inquiry.command.ts
│   │   │   └── create-inquiry.handler.ts
│   │   └── mark-inquiry-read/
│   │       ├── mark-inquiry-read.command.ts
│   │       └── mark-inquiry-read.handler.ts
│   ├── queries/
│   │   ├── get-inquiries-by-agent/
│   │   │   ├── get-inquiries-by-agent.query.ts
│   │   │   └── get-inquiries-by-agent.handler.ts
│   │   └── get-inquiries-by-listing/
│   │       ├── get-inquiries-by-listing.query.ts
│   │       └── get-inquiries-by-listing.handler.ts
│   └── __tests__/
│       ├── create-inquiry.handler.spec.ts
│       ├── mark-inquiry-read.handler.spec.ts
│       ├── get-inquiries-by-listing.handler.spec.ts
│       └── get-inquiries-by-agent.handler.spec.ts
│
├── 📁 domain/
│   ├── entities/
│   │   └── inquiry.entity.ts                [Aggregate Root]
│   ├── events/
│   │   ├── inquiry-created.event.ts
│   │   └── inquiry-read.event.ts
│   ├── repositories/
│   │   ├── inquiry.repository.ts            [Interface]
│   │   └── inquiry-read.dto.ts              [Read DTO]
│   └── __tests__/
│       └── inquiry-domain.spec.ts           [5 tests]
│
└── 📁 infrastructure/
    └── repositories/
        └── prisma-inquiry.repository.ts     [Implementation]
```

---

## 🔄 LUỒNG YÊU CẦU

### Tạo Yêu Cầu
```
POST /inquiries
→ Controller xác thực JWT
→ CreateInquiryCommand được gửi đi
→ CreateInquiryHandler thực thi:
  • Xác thực listing tồn tại
  • Tạo InquiryEntity
  • Lưu vào repository
  • Phát hành InquiryCreatedEvent
→ Response: { id, listingId, createdAt }
```

### Đánh Dấu Đã Đọc
```
PATCH /inquiries/:id/read (chỉ AGENT)
→ Controller xác thực JWT + vai trò AGENT
→ MarkInquiryReadCommand được gửi đi
→ MarkInquiryReadHandler thực thi:
  • Tải entity yêu cầu
  • Xác minh agent sở hữu listing
  • Cập nhật trạng thái entity
  • Lưu thay đổi
  • Phát hành InquiryReadEvent
→ Response: { success: true }
```

### Liệt Kê Yêu Cầu
```
GET /inquiries/listing/:id or /agent/me
→ Controller xác thực JWT (+ AGENT cho /agent/me)
→ Truy vấn được gửi đi
→ Handler xử lý phân trang
→ Repository thực thi truy vấn phân trang
→ Response: PaginatedResult<InquiryReadDto>
```

---

## 🔑 CÁC KHÁI NIỆM CHÍNH

### DDD (Thiết Kế Hướng Miền)
- **Domain Entity:** `InquiryEntity` đóng gói logic yêu cầu
- **Domain Events:** `InquiryCreatedEvent`, `InquiryReadEvent`
- **Repository Pattern:** Giao diện ở tầng domain, triển khai ở tầng infrastructure
- **Aggregate Root:** InquiryEntity quản lý các chuyển đổi trạng thái

### CQRS (Phân Tách Trách Nhiệm Lệnh - Truy Vấn)
- **Commands:** CreateInquiryCommand, MarkInquiryReadCommand (thao tác ghi)
- **Queries:** GetInquiriesByListingQuery, GetInquiriesByAgentQuery (thao tác đọc)
- **Handlers:** Các lớp riêng biệt cho từng lệnh/truy vấn

### Các Tầng Clean Architecture
1. **Presentation:** Điểm cuối HTTP, DTO, decorator
2. **Application:** Lệnh/Truy vấn, trình xử lý, điều phối
3. **Domain:** Logic nghiệp vụ, entity, sự kiện, giao diện
4. **Infrastructure:** Cơ sở dữ liệu, triển khai lưu trữ

---

## 🧪 ĐỘ PHỦ KIỂM THỬ

**Tổng cộng:** 24 kiểm thử trên 6 bộ kiểm thử

| Bộ kiểm thử | Kiểm thử | Trọng tâm |
|-------------|----------|-----------|
| Domain Entity | 5 | Hành vi aggregate, sự kiện |
| CreateInquiryHandler | 4 | Luồng thành công, xác thực, sự kiện |
| MarkInquiryReadHandler | 5 | Luồng thành công, xác thực, lỗi |
| GetInquiriesByListingHandler | 2 | Phân trang, kết quả rỗng |
| GetInquiriesByAgentHandler | 2 | Kết quả, tra cứu agent |
| InquiriesController | 6 | Tất cả endpoint, giá trị mặc định |

---

## 🔐 Bảo Mật

**Xác thực:** Tất cả endpoint yêu cầu token JWT  
**Phân quyền:** RBAC với vai trò AGENT cho các endpoint nhất định

### Ma Trận Bảo Mật Endpoint

| Endpoint | Xác thực | Vai trò | Kiểm tra thêm |
|----------|----------|---------|---------------|
| POST /inquiries | JWT | Bất kỳ | Listing tồn tại |
| GET /listing/:id | JWT | Bất kỳ | - |
| GET /agent/me | JWT | AGENT | - |
| PATCH /:id/read | JWT | AGENT | Agent sở hữu listing |

---

## 📡 HỢP ĐỒNG API

### POST /inquiries
```
Request:  { listingId: string, message: string, phone?: string }
Response: { id: string, listingId: string, createdAt: string }
Status:   201 | 400 | 401 | 404
```

### GET /inquiries/listing/:listingId
```
Query:    { page?: number, limit?: number }
Response: PaginatedResult<InquiryReadDto>
Status:   200 | 401
```

### GET /inquiries/agent/me
```
Query:    { page?: number, limit?: number }
Response: PaginatedResult<InquiryReadDto>
Status:   200 | 401 | 403
```

### PATCH /inquiries/:id/read
```
Response: { success: boolean }
Status:   200 | 401 | 403 | 404
```

---

## 🚀 BẮT ĐẦU

### Để Hiểu Mã Nguồn
1. Đọc **Quick Reference** (5 phút)
2. Xem lại **Request Flows** (5 phút)
3. Khám phá các tầng cụ thể trong **Exploration** khi cần

### Để Thêm Tính Năng
1. Xem **File Index** → Mục Entry Points (2 phút)
2. Làm theo hướng dẫn sửa đổi (thời gian khác nhau)
3. Kiểm tra các kiểm thử hiện có để học theo mẫu

### Để Gỡ Lỗi
1. Xác định tầng (presentation/application/domain/infrastructure)
2. Tìm tệp trong **File Index**
3. Kiểm tra kiểm thử để biết hành vi mong đợi

---

## 📋 CÁC MẪU PHỔ BIẾN

### Thêm một Command
1. Tạo `application/commands/[name]/[name].command.ts`
2. Tạo `application/commands/[name]/[name].handler.ts`
3. Triển khai `ICommandHandler<YourCommand>`
4. Đăng ký trong mảng CommandHandlers của `inquiries.module.ts`
5. Thêm kiểm thử vào `application/__tests__/`

### Thêm một Query
1. Tạo `application/queries/[name]/[name].query.ts`
2. Tạo `application/queries/[name]/[name].handler.ts`
3. Triển khai `IQueryHandler<YourQuery>`
4. Đăng ký trong mảng QueryHandlers của `inquiries.module.ts`
5. Thêm kiểm thử vào `application/__tests__/`

### Thêm một Endpoint
1. Thêm phương thức vào `InquiriesController`
2. Thêm DTO nếu cần vào `presentation/dto/`
3. Gửi command/query qua bus
4. Thêm kiểm thử vào `presentation/__tests__/`

---

## 🔗 PHỤ THUỘC BÊN NGOÀI

**Cốt lõi:**
- `@nestjs/common` - Framework
- `@nestjs/cqrs` - CQRS bus
- `@prisma/client` - ORM

**Xác thực:**
- `class-validator` - Xác thực DTO
- `class-transformer` - Chuyển đổi kiểu

**Tài liệu:**
- `@nestjs/swagger` - Tài liệu OpenAPI

**Nội bộ:**
- `@modules/shared` - AggregateRoot, exceptions
- `@modules/auth` - JWT guards, decorators

---

## 📈 CHỈ SỐ CHẤT LƯỢNG

| Khía cạnh | Đánh giá | Ghi chú |
|-----------|----------|---------|
| Kiến trúc | ⭐⭐⭐⭐⭐ | DDD + CQRS sạch |
| Tổ chức | ⭐⭐⭐⭐⭐ | Phân tách tầng rõ ràng |
| An toàn kiểu | ⭐⭐⭐⭐⭐ | TypeScript đầy đủ |
| Kiểm thử | ⭐⭐⭐⭐☆ | 24 kiểm thử, chiều sâu tốt |
| Xác thực | ⭐⭐⭐⭐⭐ | RBAC đúng chuẩn |
| Khả năng bảo trì | ⭐⭐⭐⭐⭐ | Dễ mở rộng |

---

## 💡 ĐIỂM NỔI BẬT VỀ KIẾN TRÚC

✅ **Phân tách mối quan tâm** - Mỗi tầng có trách nhiệm đơn lẻ  
✅ **Đảo ngược phụ thuộc** - Phụ thuộc vào trừu tượng, không phải triển khai cụ thể  
✅ **Hướng sự kiện** - Sự kiện miền cho ý nghĩa nghiệp vụ  
✅ **CQRS** - Luồng đọc/ghi tách biệt và có thể tối ưu hóa  
✅ **An toàn kiểu** - TypeScript đầy đủ, không có kiểu `any`  
✅ **Khả năng kiểm thử** - Tất cả tầng có thể kiểm thử độc lập  
✅ **Khả năng mở rộng** - Dễ thêm command/query mới  

---

## 🎓 LỘ TRÌNH HỌC TẬP

**Người mới bắt đầu:** Đọc Quick Reference → Hiểu các tầng → Xem controller  
**Trung cấp:** Nghiên cứu các handler → Xem lại entity → Kiểm tra kiểm thử  
**Nâng cao:** Đi sâu vào event sourcing → Phân trang → Các mẫu tối ưu hóa  

---

## 📞 LIÊN KẾT THAM CHIẾU NHANH

Trong các tệp tài liệu:

**Quick Reference:**
- Các tệp theo tầng
- Luồng yêu cầu
- Ma trận phân quyền
- Điểm vào để thay đổi

**File Index:**
- Mô tả tệp đầy đủ
- Đồ thị phụ thuộc
- Tham chiếu chéo
- Hướng dẫn sửa đổi

**Exploration:**
- Sơ đồ kiến trúc
- Các mẫu thiết kế
- Chi tiết bảo mật
- Phân tích độ phủ kiểm thử

---

## ✨ Bước Tiếp Theo

1. **Đọc Quick Reference** để định hướng
2. **Chọn tệp tài liệu** phù hợp với nhu cầu của bạn
3. **Dùng hướng dẫn khám phá** để tìm thông tin cụ thể
4. **Làm theo hướng dẫn sửa đổi** khi thực hiện thay đổi
5. **Kiểm tra kiểm thử** để biết hành vi mong đợi

---

**Khám phá vui vẻ! 🚀**

Ngày tạo: 11 tháng 4, 2026  
Trạng thái tài liệu: ✅ Hoàn chỉnh
