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,18 +1,18 @@
|
||||
# Inquiries Module - Quick Reference
|
||||
# Module Yêu Cầu - Tài Liệu Tham Khảo Nhanh
|
||||
|
||||
## 📊 Module at a Glance
|
||||
## 📊 Tổng Quan Module
|
||||
|
||||
**Path:** `apps/api/src/modules/inquiries/`
|
||||
**Pattern:** CQRS + DDD
|
||||
**Total Files:** 25
|
||||
**Total LOC:** 1,212
|
||||
**Test Coverage:** 6 suites, 24 tests
|
||||
**Đường dẫn:** `apps/api/src/modules/inquiries/`
|
||||
**Kiến trúc:** CQRS + DDD
|
||||
**Tổng số tệp:** 25
|
||||
**Tổng số dòng mã:** 1,212
|
||||
**Độ phủ kiểm thử:** 6 bộ kiểm thử, 24 bài kiểm thử
|
||||
|
||||
---
|
||||
|
||||
## 📁 FILES BY LAYER
|
||||
## 📁 CÁC TỆP THEO TẦNG
|
||||
|
||||
### PRESENTATION (5 files)
|
||||
### TRÌNH BÀY (5 tệp)
|
||||
```
|
||||
presentation/
|
||||
├── controllers/inquiries.controller.ts [4 endpoints]
|
||||
@@ -21,7 +21,7 @@ presentation/
|
||||
└── __tests__/inquiries.controller.spec.ts [6 tests]
|
||||
```
|
||||
|
||||
### APPLICATION (8 files)
|
||||
### ỨNG DỤNG (8 tệp)
|
||||
```
|
||||
application/
|
||||
├── commands/create-inquiry/
|
||||
@@ -39,7 +39,7 @@ application/
|
||||
└── __tests__/ [4 test files, 13 tests]
|
||||
```
|
||||
|
||||
### DOMAIN (6 files)
|
||||
### MIỀN (6 tệp)
|
||||
```
|
||||
domain/
|
||||
├── entities/inquiry.entity.ts [Aggregate Root]
|
||||
@@ -52,14 +52,14 @@ domain/
|
||||
└── __tests__/inquiry-domain.spec.ts [5 tests]
|
||||
```
|
||||
|
||||
### INFRASTRUCTURE (1 file)
|
||||
### HẠ TẦNG (1 tệp)
|
||||
```
|
||||
infrastructure/
|
||||
└── repositories/
|
||||
└── prisma-inquiry.repository.ts [6 methods]
|
||||
```
|
||||
|
||||
### MODULE (2 files)
|
||||
### MODULE (2 tệp)
|
||||
```
|
||||
inquiries.module.ts [NestJS Module]
|
||||
index.ts [Barrel export]
|
||||
@@ -67,9 +67,9 @@ index.ts [Barrel export]
|
||||
|
||||
---
|
||||
|
||||
## 🔄 REQUEST FLOWS
|
||||
## 🔄 LUỒNG YÊU CẦU
|
||||
|
||||
### CREATE INQUIRY
|
||||
### TẠO YÊU CẦU
|
||||
```
|
||||
POST /inquiries { listingId, message, phone? }
|
||||
↓
|
||||
@@ -86,7 +86,7 @@ CreateInquiryHandler
|
||||
Response: { id, listingId, createdAt }
|
||||
```
|
||||
|
||||
### MARK AS READ
|
||||
### ĐÁNH DẤU ĐÃ ĐỌC
|
||||
```
|
||||
PATCH /inquiries/:id/read (AGENT only)
|
||||
↓
|
||||
@@ -104,7 +104,7 @@ MarkInquiryReadHandler
|
||||
Response: { success: true }
|
||||
```
|
||||
|
||||
### LIST BY LISTING
|
||||
### DANH SÁCH THEO TIN ĐĂNG
|
||||
```
|
||||
GET /inquiries/listing/:listingId?page=1&limit=20
|
||||
↓
|
||||
@@ -119,7 +119,7 @@ PrismaInquiryRepository.findByListing()
|
||||
Response: PaginatedResult<InquiryReadDto>
|
||||
```
|
||||
|
||||
### LIST BY AGENT
|
||||
### DANH SÁCH THEO MÔI GIỚI
|
||||
```
|
||||
GET /inquiries/agent/me?page=1&limit=20 (AGENT only)
|
||||
↓
|
||||
@@ -138,21 +138,21 @@ Response: PaginatedResult<InquiryReadDto>
|
||||
|
||||
---
|
||||
|
||||
## 🔑 KEY CLASSES
|
||||
## 🔑 CÁC LỚP CHÍNH
|
||||
|
||||
| Class | Location | Purpose |
|
||||
|-------|----------|---------|
|
||||
| **InquiryEntity** | domain/entities/ | Aggregate root with business logic |
|
||||
| **CreateInquiryHandler** | application/commands/create-inquiry/ | Executes create command |
|
||||
| **MarkInquiryReadHandler** | application/commands/mark-inquiry-read/ | Executes mark read command |
|
||||
| **GetInquiriesByListingHandler** | application/queries/get-inquiries-by-listing/ | Resolves listing inquiries |
|
||||
| **GetInquiriesByAgentHandler** | application/queries/get-inquiries-by-agent/ | Resolves agent inquiries |
|
||||
| **PrismaInquiryRepository** | infrastructure/repositories/ | Implements persistence |
|
||||
| **InquiriesController** | presentation/controllers/ | HTTP endpoints |
|
||||
| Lớp | Vị trí | Mục đích |
|
||||
|-----|--------|----------|
|
||||
| **InquiryEntity** | domain/entities/ | Gốc tổng hợp với logic nghiệp vụ |
|
||||
| **CreateInquiryHandler** | application/commands/create-inquiry/ | Thực thi lệnh tạo mới |
|
||||
| **MarkInquiryReadHandler** | application/commands/mark-inquiry-read/ | Thực thi lệnh đánh dấu đã đọc |
|
||||
| **GetInquiriesByListingHandler** | application/queries/get-inquiries-by-listing/ | Phân giải yêu cầu theo tin đăng |
|
||||
| **GetInquiriesByAgentHandler** | application/queries/get-inquiries-by-agent/ | Phân giải yêu cầu theo môi giới |
|
||||
| **PrismaInquiryRepository** | infrastructure/repositories/ | Triển khai lưu trữ dữ liệu |
|
||||
| **InquiriesController** | presentation/controllers/ | Các endpoint HTTP |
|
||||
|
||||
---
|
||||
|
||||
## 📝 KEY INTERFACES
|
||||
## 📝 CÁC GIAO DIỆN CHÍNH
|
||||
|
||||
```typescript
|
||||
// Domain interface (repository contract)
|
||||
@@ -191,37 +191,37 @@ interface PaginatedResult<T> {
|
||||
|
||||
---
|
||||
|
||||
## 🧪 TEST FILES AT A GLANCE
|
||||
## 🧪 CÁC TỆP KIỂM THỬ TỔNG QUAN
|
||||
|
||||
| Test File | Tests | Focus |
|
||||
|-----------|-------|-------|
|
||||
| `domain/__tests__/inquiry-domain.spec.ts` | 5 | Entity creation, events |
|
||||
| `application/__tests__/create-inquiry.handler.spec.ts` | 4 | Handler success, validation |
|
||||
| `application/__tests__/mark-inquiry-read.handler.spec.ts` | 5 | Handler success, auth checks |
|
||||
| `application/__tests__/get-inquiries-by-listing.handler.spec.ts` | 2 | Query results, empty state |
|
||||
| `application/__tests__/get-inquiries-by-agent.handler.spec.ts` | 2 | Query results, agent lookup |
|
||||
| `presentation/__tests__/inquiries.controller.spec.ts` | 6 | All endpoints, defaults |
|
||||
| **TOTAL** | **24** | **Comprehensive coverage** |
|
||||
| Tệp kiểm thử | Số bài | Nội dung |
|
||||
|--------------|--------|----------|
|
||||
| `domain/__tests__/inquiry-domain.spec.ts` | 5 | Tạo thực thể, sự kiện |
|
||||
| `application/__tests__/create-inquiry.handler.spec.ts` | 4 | Thành công của handler, kiểm tra đầu vào |
|
||||
| `application/__tests__/mark-inquiry-read.handler.spec.ts` | 5 | Thành công của handler, kiểm tra xác thực |
|
||||
| `application/__tests__/get-inquiries-by-listing.handler.spec.ts` | 2 | Kết quả truy vấn, trạng thái rỗng |
|
||||
| `application/__tests__/get-inquiries-by-agent.handler.spec.ts` | 2 | Kết quả truy vấn, tra cứu môi giới |
|
||||
| `presentation/__tests__/inquiries.controller.spec.ts` | 6 | Tất cả endpoint, giá trị mặc định |
|
||||
| **TỔNG** | **24** | **Độ phủ toàn diện** |
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Authorization Matrix
|
||||
## 🔐 Ma Trận Phân Quyền
|
||||
|
||||
| Endpoint | Auth | Role | Query |
|
||||
|----------|------|------|-------|
|
||||
| `POST /inquiries` | JWT | Any | - |
|
||||
| `GET /listing/:id` | JWT | Any | page, limit |
|
||||
| Endpoint | Xác thực | Vai trò | Truy vấn |
|
||||
|----------|----------|---------|----------|
|
||||
| `POST /inquiries` | JWT | Bất kỳ | - |
|
||||
| `GET /listing/:id` | JWT | Bất kỳ | page, limit |
|
||||
| `GET /agent/me` | JWT | AGENT | page, limit |
|
||||
| `PATCH /:id/read` | JWT | AGENT | - |
|
||||
|
||||
**Permission Checks:**
|
||||
- MarkInquiryReadHandler: Verifies user is agent, agent owns listing
|
||||
**Kiểm tra quyền:**
|
||||
- MarkInquiryReadHandler: Xác minh người dùng là môi giới, môi giới sở hữu tin đăng
|
||||
|
||||
---
|
||||
|
||||
## 🎯 DDD PRINCIPLES
|
||||
## 🎯 NGUYÊN TẮC DDD
|
||||
|
||||
### Domain Entity Encapsulation
|
||||
### Đóng Gói Thực Thể Miền
|
||||
```typescript
|
||||
// Factory method (controlled creation)
|
||||
static createNew(id, listingId, userId, message, phone): InquiryEntity
|
||||
@@ -234,43 +234,43 @@ markAsRead(): void
|
||||
→ Emits InquiryReadEvent
|
||||
```
|
||||
|
||||
### Repository Pattern
|
||||
- **Interface in Domain** → `IInquiryRepository`
|
||||
- **Implementation in Infrastructure** → `PrismaInquiryRepository`
|
||||
- **Dependency Injection** → `INQUIRY_REPOSITORY` symbol
|
||||
### Mẫu Repository
|
||||
- **Giao diện trong Miền** → `IInquiryRepository`
|
||||
- **Triển khai trong Hạ tầng** → `PrismaInquiryRepository`
|
||||
- **Tiêm phụ thuộc** → ký hiệu `INQUIRY_REPOSITORY`
|
||||
|
||||
### Separate Read/Write Models
|
||||
- **Write Model:** `InquiryEntity` (aggregate)
|
||||
- **Read Model:** `InquiryReadDto` (query DTO)
|
||||
### Mô Hình Đọc/Ghi Tách Biệt
|
||||
- **Mô hình Ghi:** `InquiryEntity` (tổng hợp)
|
||||
- **Mô hình Đọc:** `InquiryReadDto` (DTO truy vấn)
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Domain Events
|
||||
## 🔄 Sự Kiện Miền
|
||||
|
||||
| Event | When | Data |
|
||||
|-------|------|------|
|
||||
| **InquiryCreatedEvent** | Inquiry created | aggregateId, listingId, userId |
|
||||
| **InquiryReadEvent** | Marked as read | aggregateId, listingId, userId |
|
||||
| Sự kiện | Thời điểm | Dữ liệu |
|
||||
|---------|-----------|---------|
|
||||
| **InquiryCreatedEvent** | Yêu cầu được tạo | aggregateId, listingId, userId |
|
||||
| **InquiryReadEvent** | Được đánh dấu đã đọc | aggregateId, listingId, userId |
|
||||
|
||||
---
|
||||
|
||||
## 💾 Database Operations
|
||||
## 💾 Thao Tác Cơ Sở Dữ Liệu
|
||||
|
||||
**Prisma Models Used:**
|
||||
- `inquiry` - Main entity
|
||||
- `listing` - For foreign key & agent lookup
|
||||
- `property` - For listing title
|
||||
- `user` - For buyer name & phone
|
||||
**Các Prisma Model được sử dụng:**
|
||||
- `inquiry` - Thực thể chính
|
||||
- `listing` - Cho khóa ngoại & tra cứu môi giới
|
||||
- `property` - Cho tiêu đề tin đăng
|
||||
- `user` - Cho tên & số điện thoại người mua
|
||||
|
||||
**Key Queries:**
|
||||
- `inquiry.create()` - New inquiry
|
||||
- `inquiry.update()` - Mark read
|
||||
- `inquiry.findMany()` - Pagination
|
||||
- `inquiry.count()` - Total count
|
||||
**Các Truy Vấn Chính:**
|
||||
- `inquiry.create()` - Tạo yêu cầu mới
|
||||
- `inquiry.update()` - Đánh dấu đã đọc
|
||||
- `inquiry.findMany()` - Phân trang
|
||||
- `inquiry.count()` - Đếm tổng số
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Entry Points
|
||||
## 🚀 Điểm Vào
|
||||
|
||||
```typescript
|
||||
// Module export
|
||||
@@ -286,35 +286,35 @@ import { InquiriesModule } from '@modules/inquiries'
|
||||
|
||||
---
|
||||
|
||||
## 🎓 Architecture Summary
|
||||
## 🎓 Tóm Tắt Kiến Trúc
|
||||
|
||||
```
|
||||
CLEAN ARCHITECTURE with CQRS + DDD
|
||||
KIẾN TRÚC SẠCH với CQRS + DDD
|
||||
|
||||
Presentation Layer (Controllers + DTOs)
|
||||
Tầng Trình Bày (Controllers + DTOs)
|
||||
↓
|
||||
Application Layer (CQRS Handlers)
|
||||
Tầng Ứng Dụng (CQRS Handlers)
|
||||
↓
|
||||
Domain Layer (Entities + Events + Interfaces)
|
||||
Tầng Miền (Entities + Events + Interfaces)
|
||||
↓
|
||||
Infrastructure Layer (Prisma Repository)
|
||||
Tầng Hạ Tầng (Prisma Repository)
|
||||
↓
|
||||
Database
|
||||
Cơ Sở Dữ Liệu
|
||||
```
|
||||
|
||||
**Key Characteristics:**
|
||||
✅ Dependency Inversion - Domain defines contracts
|
||||
✅ Separation of Concerns - Each layer has clear responsibility
|
||||
✅ Testability - Mock implementations at each layer
|
||||
✅ Event-Driven - Domain events for audit & integration
|
||||
✅ CQRS - Separate commands & queries for scalability
|
||||
✅ Type Safety - Full TypeScript with strict interfaces
|
||||
**Đặc Điểm Chính:**
|
||||
✅ Đảo Ngược Phụ Thuộc - Miền định nghĩa các hợp đồng
|
||||
✅ Phân Tách Mối Quan Tâm - Mỗi tầng có trách nhiệm rõ ràng
|
||||
✅ Khả Năng Kiểm Thử - Triển khai giả lập tại mỗi tầng
|
||||
✅ Hướng Sự Kiện - Sự kiện miền cho kiểm toán & tích hợp
|
||||
✅ CQRS - Tách biệt lệnh & truy vấn để mở rộng quy mô
|
||||
✅ An Toàn Kiểu - TypeScript đầy đủ với giao diện nghiêm ngặt
|
||||
|
||||
---
|
||||
|
||||
## 📌 Common Patterns
|
||||
## 📌 Các Mẫu Thường Dùng
|
||||
|
||||
**Command Pattern:**
|
||||
**Mẫu Command:**
|
||||
```typescript
|
||||
// Send command
|
||||
commandBus.execute(new CreateInquiryCommand(...))
|
||||
@@ -323,7 +323,7 @@ commandBus.execute(new CreateInquiryCommand(...))
|
||||
class CreateInquiryHandler { ... }
|
||||
```
|
||||
|
||||
**Query Pattern:**
|
||||
**Mẫu Query:**
|
||||
```typescript
|
||||
// Send query
|
||||
queryBus.execute(new GetInquiriesByListingQuery(...))
|
||||
@@ -332,7 +332,7 @@ queryBus.execute(new GetInquiriesByListingQuery(...))
|
||||
class GetInquiriesByListingHandler { ... }
|
||||
```
|
||||
|
||||
**Dependency Injection Pattern:**
|
||||
**Mẫu Tiêm Phụ Thuộc:**
|
||||
```typescript
|
||||
@Injectable()
|
||||
export class Handler {
|
||||
@@ -345,19 +345,19 @@ export class Handler {
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Where to Look For...
|
||||
## 🔍 Nơi Tìm Kiếm...
|
||||
|
||||
| Need | File |
|
||||
|------|------|
|
||||
| Add new endpoint | `presentation/controllers/inquiries.controller.ts` |
|
||||
| Add command | `application/commands/[name]/[name].command.ts` + `[name].handler.ts` |
|
||||
| Add query | `application/queries/[name]/[name].query.ts` + `[name].handler.ts` |
|
||||
| Business logic | `domain/entities/inquiry.entity.ts` |
|
||||
| New domain event | `domain/events/[name].event.ts` |
|
||||
| Database queries | `infrastructure/repositories/prisma-inquiry.repository.ts` |
|
||||
| Input validation | `presentation/dto/*.ts` |
|
||||
| Write tests | `[layer]/__tests__/*` |
|
||||
| Nhu cầu | Tệp |
|
||||
|---------|-----|
|
||||
| Thêm endpoint mới | `presentation/controllers/inquiries.controller.ts` |
|
||||
| Thêm command | `application/commands/[name]/[name].command.ts` + `[name].handler.ts` |
|
||||
| Thêm query | `application/queries/[name]/[name].query.ts` + `[name].handler.ts` |
|
||||
| Logic nghiệp vụ | `domain/entities/inquiry.entity.ts` |
|
||||
| Sự kiện miền mới | `domain/events/[name].event.ts` |
|
||||
| Truy vấn cơ sở dữ liệu | `infrastructure/repositories/prisma-inquiry.repository.ts` |
|
||||
| Kiểm tra đầu vào | `presentation/dto/*.ts` |
|
||||
| Viết kiểm thử | `[layer]/__tests__/*` |
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** April 11, 2026
|
||||
**Cập Nhật Lần Cuối:** 11 tháng 4, 2026
|
||||
|
||||
Reference in New Issue
Block a user