Files
goodgo-platform/docs/architecture.md
Ho Ngoc Hai 11f2bf26e6
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
chore: update project documentation, audit reports, and initialize IDE configuration files
2026-04-19 03:12:54 +07:00

246 lines
14 KiB
Markdown

# Kiến Trúc Hệ Thống
## Tổng Quan Hệ Thống
GoodGo Platform AI là một monorepo bao gồm backend NestJS, frontend Next.js, các dịch vụ AI bằng Python, và các máy chủ MCP (Model Context Protocol). Hệ thống được điều phối bằng Turborepo và pnpm workspaces.
```
┌──────────────────────────────────────────┐
│ Client (Browser) │
└──────────────────┬───────────────────────┘
┌──────────────────▼───────────────────────┐
│ Next.js 15 (apps/web) │
│ ┌─────────┐ ┌──────────┐ ┌───────┐ │
│ │ Pages │ │Components│ │Zustand │ │
│ │(App │ │(UI + │ │(State) │ │
│ │ Router) │ │ Domain) │ │ │ │
│ └─────────┘ └──────────┘ └───────┘ │
└──────────────────┬───────────────────────┘
│ REST API
┌──────────────────▼───────────────────────┐
│ NestJS 11 (apps/api) │
│ │
│ ┌────────┐ ┌────────┐ ┌─────────────┐ │
│ │ Auth │ │Listings│ │ Payments │ │
│ ├────────┤ ├────────┤ ├─────────────┤ │
│ │ Search │ │ Admin │ │Subscriptions│ │
│ ├────────┤ ├────────┤ ├─────────────┤ │
│ │Analytics│ │ MCP │ │Notifications│ │
│ ├────────┤ ├────────┤ ├─────────────┤ │
│ │ Agents │ │Inquires│ │ Leads │ │
│ ├────────┤ ├────────┤ ├─────────────┤ │
│ │Reviews │ │ Health │ │ Metrics │ │
│ └────────┘ └────────┘ └─────────────┘ │
└───┬─────┬──────┬─────────┬──────────────┘
│ │ │ │
┌────────────▼┐ ┌─▼────┐ ▼ ┌───▼──────────┐
│ PostgreSQL │ │Redis │ │ │ Typesense │
│ + PostGIS │ │ │ │ │ (Search) │
└─────────────┘ └──────┘ │ └──────────────┘
┌───────────────▼──────────────────────┐
│ MCP Servers (libs/mcp-servers) │
│ ┌──────────┐┌──────────┐┌────────┐ │
│ │ Property ││ Market ││Valua- │ │
│ │ Search ││Analytics ││tion │ │
│ └──────────┘└──────────┘└───┬────┘ │
└──────────────────────────────┼───────┘
┌──────────────────────────────▼───────┐
│ AI Services (libs/ai-services) │
│ FastAPI + XGBoost + Claude API │
│ ┌──────────┐ ┌────────────────┐ │
│ │ AVM │ │ Moderation │ │
│ │(Pricing) │ │ (Claude API) │ │
│ └──────────┘ └────────────────┘ │
└──────────────────────────────────────┘
```
## Kiến Trúc Module
Mỗi module API tuân theo cấu trúc phân lớp theo Domain-Driven Design:
```
modules/{module-name}/
├── presentation/ # Tầng HTTP
│ ├── controllers/ # Xử lý route
│ └── dtos/ # DTO yêu cầu/phản hồi (class-validator)
├── application/ # Điều phối nghiệp vụ
│ ├── commands/ # Thao tác ghi (CQRS)
│ ├── queries/ # Thao tác đọc (CQRS)
│ ├── handlers/ # Handler cho command/query
│ └── services/ # Dịch vụ ứng dụng
├── domain/ # Lõi logic nghiệp vụ
│ ├── entities/ # Entity domain & value object
│ ├── repositories/ # Giao diện repository (trừu tượng hoá)
│ └── events/ # Domain event
├── infrastructure/ # Tích hợp bên ngoài
│ ├── repositories/ # Triển khai repository bằng Prisma
│ └── services/ # Adapter cho dịch vụ ngoài
└── {module-name}.module.ts # Định nghĩa module NestJS
```
### Mẫu CQRS
Nền tảng sử dụng NestJS CQRS (`@nestjs/cqrs`) cho các thao tác phức tạp:
- **Commands** — thay đổi trạng thái (tạo tin đăng, xử lý thanh toán, đăng ký người dùng)
- **Queries** — đọc trạng thái (tìm kiếm bất động sản, lấy phân tích)
- **Events** — giao tiếp liên module (tin đăng được duyệt → đánh chỉ mục vào Typesense, thanh toán hoàn tất → gửi thông báo)
### Module Shared
Module `shared/` cung cấp các mối quan tâm xuyên suốt:
- **Prisma service** — kết nối cơ sở dữ liệu và client
- **Redis service** — bộ nhớ đệm và quản lý phiên
- **Guards** — JWT auth guard, roles guard, throttle guard
- **Pipes** — pipe xác thực toàn cục (chế độ whitelist)
- **Filters** — exception filter cho phản hồi lỗi nhất quán
- **Decorators** — `@CurrentUser()`, `@Roles()`, `@Public()`
## Luồng Dữ Liệu
### Vòng Đời Tin Đăng Bất Động Sản
```
DRAFT → PENDING_REVIEW → ACTIVE → RESERVED → SOLD/RENTED
│ │
▼ │
REJECTED EXPIRED
```
1. **Người bán/Đại lý** tạo tin đăng (trạng thái: `DRAFT`)
2. **Người bán** gửi để duyệt → `PENDING_REVIEW`
3. **Quản trị viên** kiểm duyệt (điểm kiểm duyệt AI hỗ trợ) → `ACTIVE` hoặc `REJECTED`
4. Các tin đăng đang hoạt động được đánh chỉ mục vào Typesense để tìm kiếm
5. **Người mua** gửi yêu cầu → bản ghi `Inquiry` được tạo
6. Quy trình giao dịch: `OFFER_MADE → DEPOSIT_PAID → CONTRACT_SIGNING → COMPLETED`
### Luồng Tìm Kiếm
```
User Query → NestJS Search Module → Typesense
├─ Full-text on title/description
├─ Faceted filters (price, type, bedrooms)
└─ Geo-spatial (lat/long + radius)
```
### Luồng Thanh Toán
```
User → API (create payment) → Provider (VNPay/MoMo/ZaloPay)
[User pays on provider page]
Provider callback → API → Verify signature → Update Payment status
SUCCESS / FAILED
```
### Luồng Định Giá AI
```
API Request → MCP Valuation Server → AI Service (FastAPI)
XGBoost Model
┌─────▼──────┐
│ Estimated │
│ Price + │
│ Confidence │
│ + Factors │
└─────────────┘
```
## Sơ Đồ Cơ Sở Dữ Liệu
### Các Model Cốt Lõi
```
User ──┬── Agent (1:1, for AGENT role users)
├── OAuthAccount (1:N, Google/Zalo)
├── RefreshToken (1:N, token families)
├── Subscription (1:N)
├── SavedSearch (1:N)
└── UsageRecord (1:N)
Property ──┬── PropertyMedia (1:N, images/videos)
├── Listing (1:N)
└── Valuation (1:N)
Listing ──┬── Inquiry (1:N)
├── Lead (1:N)
├── Transaction (1:N)
└── Agent (N:1)
Transaction ── Payment (1:N)
Plan ── Subscription (1:N)
MarketIndex (standalone — city/district/month aggregates)
```
### Các Quyết Định Thiết Kế Chính
- **PostGIS** cho các truy vấn không gian — vị trí bất động sản được lưu dạng hình học `Point`
- **Cột JSON** cho dữ liệu linh hoạt: tiện ích, điểm POI lân cận, dữ liệu KYC, tính năng gói đăng ký
- **Theo dõi token family** để xoay vòng refresh token an toàn (phát hiện tấn công tái sử dụng)
- **Soft status** thay vì soft delete — tin đăng sử dụng quy trình trạng thái, không dùng `deletedAt`
## Máy Chủ MCP
Ba máy chủ Model Context Protocol cung cấp giao diện công cụ cho AI:
| Server | Tools | Data Source |
|--------|-------|-------------|
| **Property Search** | `search_properties`, `compare_properties`, `get_property_details` | Typesense |
| **Market Analytics** | `get_market_report`, `analyze_trends`, `get_price_indices` | PostgreSQL |
| **Valuation** | `estimate_valuation`, `extract_features`, `compare_valuations` | AI Services (FastAPI) |
Các máy chủ MCP được đăng ký qua `McpModule` trong NestJS, quản lý bởi `McpRegistryService`, và được phơi ra qua `McpTransportController` qua HTTP.
## Dịch Vụ AI
Microservice Python FastAPI (`libs/ai-services/`) cung cấp:
| Endpoint | Model | Purpose |
|----------|-------|---------|
| `POST /avm/estimate` | XGBoost | Ước tính giá bất động sản kèm điểm tin cậy |
| `POST /moderation/check` | Claude API | Kiểm duyệt nội dung mô tả tin đăng |
| `GET /health` | — | Kiểm tra tình trạng hoạt động |
- **Underthesea** xử lý phân tách từ và tiền xử lý NLP tiếng Việt
- Mô hình XGBoost sử dụng các đặc trưng được thiết kế (diện tích, vị trí, loại bất động sản, tiện ích)
## Bảo Mật
- **JWT + Refresh Token Rotation** — access token có hiệu lực 15 phút, refresh token 7 ngày với xoay vòng dựa trên token family
- **OAuth** — đăng nhập mạng xã hội qua Google và Zalo
- **Rate Limiting** — mặc định 60 yêu cầu/60 giây, 10 yêu cầu/60 giây cho các endpoint xác thực
- **Helmet** — các header bảo mật HTTP
- **CORS** — các origin được cấu hình linh hoạt qua `CORS_ORIGINS`
- **Input Validation** — class-validator (backend), Zod (frontend)
- **Content Sanitization** — sanitize-html cho nội dung người dùng tạo
- **KYC** — quy trình xác minh đại lý (NONE → PENDING → VERIFIED/REJECTED)
## Giám Sát
- **Prometheus** thu thập dữ liệu từ endpoint `/api/v1/metrics` mỗi 15 giây
- **Grafana** các dashboard được cung cấp tự động từ `monitoring/grafana/dashboards/`
- **Loki + Promtail** tổng hợp log container; có thể xem trong Grafana
- **Pino** ghi log JSON có cấu trúc với cấp độ log có thể cấu hình
- Các chỉ số bao gồm thời gian xử lý yêu cầu HTTP, tỷ lệ lỗi, web vitals, và các chỉ số nghiệp vụ tùy chỉnh
- Thời gian lưu giữ log: 15 ngày (được cấu hình trong `monitoring/loki/loki-config.yml`)
## Hệ Thống Sự Kiện
Nền tảng sử dụng `@nestjs/event-emitter` để kết nối lỏng lẻo giữa các module:
- `listing.published` → Typesense indexer cập nhật chỉ mục tìm kiếm
- `payment.completed` → Dịch vụ thông báo gửi xác nhận
- `inquiry.created` → Kích hoạt thông báo cho đại lý
- `user.registered` → Gửi email chào mừng