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

This commit is contained in:
Ho Ngoc Hai
2026-04-19 03:12:54 +07:00
parent 3be106074d
commit 11f2bf26e6
101 changed files with 21312 additions and 20672 deletions

View File

@@ -1,13 +1,13 @@
# GoodGo Platform AI - Technical Reference & Deep Dive
**For Developers & Architects**
# GoodGo Platform AI - Tài Liệu Kỹ Thuật Tham Chiếu & Phân Tích Chuyên Sâu
**Dành cho Nhà Phát Triển & Kiến Trúc Sư**
---
## BACKEND MODULE HIERARCHY
## PHÂN CẤP MODULE BACKEND
### Core Module Dependencies
### Phụ Thuộc Module Cốt Lõi
```
SharedModule (lowest level)
SharedModule (cấp thấp nhất)
├── Infrastructure Services
├── Middleware & Guards
├── Decorators & Utilities
@@ -32,258 +32,258 @@ SharedModule (lowest level)
---
## DOMAIN MODELS - RELATIONSHIPS
## MÔ HÌNH MIỀN - MỐI QUAN HỆ
### User Role Hierarchy
### Phân Cấp Vai Trò Người Dùng
```
User (root entity)
├── Role: BUYER → Can browse, search, inquire, purchase
├── Role: SELLER → Can create listings, receive inquiries, sell
├── Role: AGENT → Extends Seller + lead management
└── Role: ADMIN → All permissions + moderation
User (thực thể gốc)
├── Role: BUYER → Có thể duyệt, tìm kiếm, hỏi thăm, mua
├── Role: SELLER → Có thể tạo tin đăng, nhận hỏi thăm, bán
├── Role: AGENT → Mở rộng từ Seller + quản lý khách hàng tiềm năng
└── Role: ADMIN → Toàn bộ quyền hạn + kiểm duyệt
```
### Listing Workflow
### Luồng Xử Lý Tin Đăng
```
User (SELLER)
creates
tạo
Property + PropertyMedia
associated with
Listing (status: DRAFT → PUBLISHED → SOLD → ARCHIVED)
receives
Inquiry (from BUYER/AGENT)
↓ converts to
Transaction (buyer-seller exchange)
followed by
Review + UsageRecord (analytics)
liên kết với
Listing (trạng thái: DRAFT → PUBLISHED → SOLD → ARCHIVED)
nhận
Inquiry (từ BUYER/AGENT)
↓ chuyển đổi thành
Transaction (giao dịch người mua - người bán)
tiếp theo là
Review + UsageRecord (phân tích)
```
### Payment Flow
### Luồng Thanh Toán
```
User (Subscription Start)
User (Bắt đầu Đăng ký)
Plan (monthly/yearly pricing)
Plan (giá hàng tháng/hàng năm)
Subscription (active/cancelled/expired)
Subscription (đang hoạt động/đã hủy/đã hết hạn)
Payment (processed via VNPay)
├── Idempotency Key (prevents duplicates)
Payment (xử lý qua VNPay)
├── Idempotency Key (ngăn trùng lặp)
└── Status Tracking
UsageRecord (track consumed resources)
UsageRecord (theo dõi tài nguyên đã dùng)
```
---
## AUTHENTICATION FLOW
## LUỒNG XÁC THỰC
### JWT Token Lifecycle
### Vòng Đời Token JWT
```
1. User Login (email + password OR OAuth)
└→ Verify credentials (bcrypt hash)
1. Đăng nhập Người dùng (email + mật khẩu HOẶC OAuth)
└→ Xác minh thông tin đăng nhập (bcrypt hash)
2. Generate Tokens
├→ AccessToken (15 min, bearer auth)
└→ RefreshToken (7 days, stored in DB)
└→ Token Family (refresh rotation)
2. Tạo Token
├→ AccessToken (15 phút, bearer auth)
└→ RefreshToken (7 ngày, lưu trong DB)
└→ Token Family (luân phiên refresh)
3. Return to Client
└→ Set Secure HTTP-Only Cookie (refresh token)
3. Trả về Client
└→ Đặt Cookie HTTP-Only Bảo mật (refresh token)
4. API Access
4. Truy cập API
├→ Authorization: Bearer <accessToken>
├→ Guard validates JWT signature
└→ Inject user context into request
├→ Guard xác thực chữ ký JWT
└→ Đưa ngữ cảnh người dùng vào request
5. Token Refresh
├→ Client sends refresh token
├→ Verify token family (revocation check)
├→ Rotate token (issue new family)
└→ Return new access token
5. Làm mới Token
├→ Client gửi refresh token
├→ Xác minh token family (kiểm tra thu hồi)
├→ Luân phiên token (cấp family mới)
└→ Trả về access token mới
```
---
## DATABASE SCHEMA - KEY INDEXES
## SCHEMA CƠ SỞ DỮ LIỆU - CHỈ MỤC QUAN TRỌNG
### Query Optimization Strategy
### Chiến Lược Tối Ưu Hóa Truy Vấn
```
User Table:
├── idx_user_role (BUYER/SELLER/AGENT/ADMIN filtering)
├── idx_user_kyc_status (compliance checks)
├── idx_user_active (active user queries)
├── idx_user_deleted_at (soft delete filtering)
└── idx_role_active_created (complex queries: role + active + order by)
Bảng User:
├── idx_user_role (lọc BUYER/SELLER/AGENT/ADMIN)
├── idx_user_kyc_status (kiểm tra tuân thủ)
├── idx_user_active (truy vấn người dùng hoạt động)
├── idx_user_deleted_at (lọc xóa mềm)
└── idx_role_active_created (truy vấn phức tạp: vai trò + hoạt động + sắp xếp theo)
Listing Table:
├── idx_listing_status (published, archived, sold filtering)
├── idx_listing_user_created (user's listings ordered)
└── idx_listing_location_geo (PostGIS spatial queries)
Bảng Listing:
├── idx_listing_status (lọc đã đăng, đã lưu trữ, đã bán)
├── idx_listing_user_created (tin đăng của người dùng theo thứ tự)
└── idx_listing_location_geo (truy vấn không gian PostGIS)
Payment Table:
├── idx_payment_user_status (user's payment history)
├── idx_payment_idempotency (duplicate prevention)
└── idx_payment_external_ref (payment gateway reconciliation)
Bảng Payment:
├── idx_payment_user_status (lịch sử thanh toán của người dùng)
├── idx_payment_idempotency (ngăn trùng lặp)
└── idx_payment_external_ref (đối soát cổng thanh toán)
Search Optimization:
└── Typesense (full-text + geo-search, delegated from DB)
Tối Ưu Hóa Tìm Kiếm:
└── Typesense (tìm kiếm toàn văn bản + địa lý, ủy thác từ DB)
```
---
## SECURITY LAYERS - DETAILED
## CÁC LỚP BẢO MẬT - CHI TIẾT
### Layer 1: Network Level
### Lớp 1: Cấp Mạng
```
HTTP Request
Helmet (Express middleware)
├── Content-Security-Policy
│ └── Blocks inline scripts, restricts origins
│ └── Chặn script nội tuyến, hạn chế nguồn gốc
├── X-Frame-Options: DENY
│ └── Prevents clickjacking
│ └── Ngăn chặn clickjacking
├── Strict-Transport-Security (HSTS)
│ └── Forces HTTPS for 31536000 seconds
│ └── Bắt buộc HTTPS trong 31536000 giây
├── X-Content-Type-Options: nosniff
│ └── Prevents MIME-sniffing
│ └── Ngăn chặn MIME-sniffing
└── Referrer-Policy: strict-origin-when-cross-origin
└── Controls referrer leaks
└── Kiểm soát rò rỉ referrer
```
### Layer 2: Application Level
### Lớp 2: Cấp Ứng Dụng
```
Request Processing
Xử Lý Request
1. CORS Validation
└── Whitelist check (process.env.CORS_ORIGINS)
1. Xác Thực CORS
└── Kiểm tra danh sách trắng (process.env.CORS_ORIGINS)
2. CSRF Protection
├── Read (GET): Set __Host-X-CSRF-Token cookie
└── Write (POST/PUT/PATCH/DELETE):
├── Verify X-CSRF-Token header
└── Validate cookie matches header (double-submit)
2. Bảo Vệ CSRF
├── Đọc (GET): Đặt cookie __Host-X-CSRF-Token
└── Ghi (POST/PUT/PATCH/DELETE):
├── Xác minh header X-CSRF-Token
└── Xác nhận cookie khớp header (double-submit)
3. Input Sanitization
├── Remove XSS vectors (sanitize-html)
├── Whitelist validation (class-validator)
└── Type coercion (class-transformer)
3. Làm Sạch Đầu Vào
├── Loại bỏ vector XSS (sanitize-html)
├── Xác thực danh sách trắng (class-validator)
└── Ép kiểu dữ liệu (class-transformer)
4. Rate Limiting
├── Global: 60 req/min per IP
├── Auth: 10 req/min per IP (login brute-force protection)
└── Payments: 20 req/min per IP (webhook replay protection)
4. Giới Hạn Tốc Độ
├── Toàn cầu: 60 req/phút mỗi IP
├── Xác thực: 10 req/phút mỗi IP (bảo vệ brute-force đăng nhập)
└── Thanh toán: 20 req/phút mỗi IP (bảo vệ phát lại webhook)
```
### Layer 3: Data Level
### Lớp 3: Cấp Dữ Liệu
```
Field Encryption (PII Protection)
Mã Hóa Trường (Bảo Vệ PII)
├── FieldEncryptionService
│ ├── AES-256-GCM encryption
│ ├── Field-level (can query by hash)
│ └── Key derivation from master secret
├── Email: Encrypted + hashed (both in DB)
├── Phone: Encrypted + hashed (both in DB)
└── KYC Data: Encrypted JSON storage
│ ├── Mã hóa AES-256-GCM
│ ├── Cấp trường (có thể truy vấn bằng hash)
│ └── Dẫn xuất khóa từ bí mật chính
├── Email: Đã mã hóa + đã băm (cả hai trong DB)
├── Điện thoại: Đã mã hóa + đã băm (cả hai trong DB)
└── Dữ liệu KYC: Lưu trữ JSON đã mã hóa
Audit Trail
├── AdminAuditLog captures:
│ ├── User ID (who)
│ ├── Action (what)
│ ├── Target entity (where)
│ ├── Changes (before/after)
│ └── Timestamp (when)
└── Queryable for compliance
Nhật Ký Kiểm Toán
├── AdminAuditLog ghi lại:
│ ├── User ID (ai)
│ ├── Action ()
│ ├── Target entity (ở đâu)
│ ├── Changes (trước/sau)
│ └── Timestamp (khi nào)
└── Có thể truy vấn để tuân thủ
```
### Layer 4: Authorization
### Lớp 4: Phân Quyền
```
Route Handler
@UseGuards(JwtGuard, RoleGuard)
├── Extract JWT from Authorization header
├── Validate signature (HS256)
├── Check token expiration
├── Inject user context (request.user)
└── Verify role (BUYER/SELLER/AGENT/ADMIN)
└── Reject if insufficient permissions
├── Trích xuất JWT từ header Authorization
├── Xác thực chữ ký (HS256)
├── Kiểm tra hạn sử dụng token
├── Đưa ngữ cảnh người dùng vào (request.user)
└── Xác minh vai trò (BUYER/SELLER/AGENT/ADMIN)
└── Từ chối nếu không đủ quyền
```
---
## CQRS PATTERN IMPLEMENTATION
## TRIỂN KHAI MẪU CQRS
### Command Pattern (State Changes)
### Mẫu Lệnh (Thay Đổi Trạng Thái)
```
CreateListingCommand
├── Input: CreateListingDTO
├── Handler: CreateListingCommandHandler
│ ├── Validate inputs
│ ├── Check user permissions
│ ├── Create Property entity
│ ├── Create Listing entity
│ ├── Emit ListingCreatedEvent
│ └── Update search index
│ ├── Xác thực đầu vào
│ ├── Kiểm tra quyền người dùng
│ ├── Tạo thực thể Property
│ ├── Tạo thực thể Listing
│ ├── Phát ListingCreatedEvent
│ └── Cập nhật chỉ mục tìm kiếm
└── Output: CreatedListingDTO
Flow:
Luồng:
Controller → Command → CommandHandler → Domain → Event → Repository → Cache invalidate
```
### Query Pattern (Read-only)
### Mẫu Truy Vấn (Chỉ Đọc)
```
GetListingQuery
├── Input: ListingId
├── Handler: GetListingQueryHandler
│ ├── Check cache (Redis)
│ ├── If hit: return cached
│ └── If miss:
│ ├── Query database
│ ├── Cache result (TTL-based)
│ └── Return to client
│ ├── Kiểm tra cache (Redis)
│ ├── Nếu trúng cache: trả về kết quả đã cache
│ └── Nếu không trúng:
│ ├── Truy vấn cơ sở dữ liệu
│ ├── Cache kết quả (dựa trên TTL)
│ └── Trả về cho client
└── Output: ListingDTO
Flow:
Luồng:
Controller → Query → QueryHandler → Repository → Cache store → Response
```
---
## CACHING STRATEGY
## CHIẾN LƯỢC CACHE
### Multi-Level Caching
### Cache Nhiều Cấp
```
Level 1: Browser Cache
├── Static assets (CSS, JS)
├── Max-Age: 31536000 (1 year)
Cấp 1: Cache Trình Duyệt
├── Tài nguyên tĩnh (CSS, JS)
├── Max-Age: 31536000 (1 năm)
└── Immutable: true
Level 2: CDN Cache (if deployed)
├── JSON responses
├── Max-Age: 300 (5 min)
└── Surrogate-Key invalidation
Cấp 2: Cache CDN (nếu đã triển khai)
├── Phản hồi JSON
├── Max-Age: 300 (5 phút)
└── Vô hiệu hóa Surrogate-Key
Level 3: Application Cache (Redis)
├── User objects (TTL: 1 hour)
├── Listing details (TTL: 30 min)
├── Search results (TTL: 5 min)
└── Rate limit counters (TTL: per window)
Cấp 3: Cache Ứng Dụng (Redis)
├── Đối tượng User (TTL: 1 giờ)
├── Chi tiết Listing (TTL: 30 phút)
├── Kết quả tìm kiếm (TTL: 5 phút)
└── Bộ đếm giới hạn tốc độ (TTL: theo cửa sổ)
Cache Invalidation Triggers:
├── Event-based: ListingUpdatedEvent → invalidate key
├── Time-based: TTL expiration
├── Manual: Cache.delete(key) on batch operations
└── Circuit breaker: If Redis down, bypass to DB
Kích Hoạt Vô Hiệu Hóa Cache:
├── Dựa trên sự kiện: ListingUpdatedEvent → vô hiệu hóa key
├── Dựa trên thời gian: hết hạn TTL
├── Thủ công: Cache.delete(key) trên các thao tác theo lô
└── Circuit breaker: Nếu Redis down, bỏ qua sang DB
```
---
## ERROR HANDLING & OBSERVABILITY
## XỬ LÝ LỖI & QUAN SÁT HỆ THỐNG
### Exception Hierarchy
### Phân Cấp Ngoại Lệ
```
GlobalExceptionFilter (catches all)
GlobalExceptionFilter (bắt tất cả)
├→ HttpException (known errors)
├→ HttpException (lỗi đã biết)
│ ├── BadRequestException (400)
│ ├── UnauthorizedException (401)
│ ├── ForbiddenException (403)
@@ -291,46 +291,46 @@ GlobalExceptionFilter (catches all)
│ ├── ConflictException (409)
│ └── InternalServerErrorException (500)
└→ Unknown Error
└→ Lỗi Không Xác Định
└→ Sentry.captureException(error)
├── Capture stack trace
├── Attach request context
├── Tag by module/operation
└── Alert ops team (if severity > WARN)
├── Ghi lại stack trace
├── Đính kèm ngữ cảnh request
├── Gắn thẻ theo module/thao tác
└── Cảnh báo đội vận hành (nếu mức độ nghiêm trọng > WARN)
Structured Logging (Pino)
├── JSON format for log aggregation
├── Context injection (request ID, user ID)
├── Log levels: trace, debug, info, warn, error, fatal
└── Destination: stdout (collected by Loki/Promtail)
Ghi Log Có Cấu Trúc (Pino)
├── Định dạng JSON để tổng hợp log
├── Đưa ngữ cảnh vào (request ID, user ID)
├── Cấp độ log: trace, debug, info, warn, error, fatal
└── Đích: stdout (thu thập bởi Loki/Promtail)
```
### Monitoring Points
### Điểm Giám Sát
```
Metrics (Prometheus)
├── HTTP request latency
├── Database query time
├── Cache hit/miss ratio
├── Error rate by endpoint
├── Queue depth (background jobs)
└── Payment processing success rate
Chỉ Số (Prometheus)
├── Độ trễ HTTP request
├── Thời gian truy vấn cơ sở dữ liệu
├── Tỷ lệ trúng/trượt cache
├── Tỷ lệ lỗi theo endpoint
├── Độ sâu hàng đợi (công việc nền)
└── Tỷ lệ thành công xử lý thanh toán
Logs (Loki)
├── Searchable by timestamp, level, service, user
├── Retention: 30 days
└── Queries: error trends, user activity, audit trail
Log (Loki)
├── Có thể tìm kiếm theo timestamp, cấp độ, dịch vụ, người dùng
├── Lưu trữ: 30 ngày
└── Truy vấn: xu hướng lỗi, hoạt động người dùng, nhật ký kiểm toán
Traces (Sentry)
├── Request waterfall
├── Database call chains
└── Error context snapshot
Trace (Sentry)
├── Luồng waterfall request
├── Chuỗi gọi cơ sở dữ liệu
└── Snapshot ngữ cảnh lỗi
```
---
## BACKGROUND JOBS & EVENTS
## CÔNG VIỆC NỀN & SỰ KIỆN
### Event System
### Hệ Thống Sự Kiện
```
Domain Event
├── ListingCreatedEvent
@@ -340,27 +340,27 @@ Domain Event
EventEmitter.emit()
Event Subscribers (consume in order)
Event Subscribers (xử lý theo thứ tự)
├── ListingCreatedEventSubscriber
│ └→ Index in Typesense
│ └→ Lập chỉ mục trong Typesense
├── PaymentProcessedEventSubscriber
│ └→ Send email receipt
│ └→ Gửi email biên lai
├── NotificationScheduledEventSubscriber
│ └→ Queue FCM push
│ └→ Xếp hàng FCM push
└── UserDeletedEventSubscriber
└→ Archive data + audit trail
└→ Lưu trữ dữ liệu + nhật ký kiểm toán
Error Handling:
├── Retry policy (3 retries, exponential backoff)
├── Dead letter queue (failed events)
└── Monitoring alert (critical events failed)
Xử Lý Lỗi:
├── Chính sách thử lại (3 lần, exponential backoff)
├── Dead letter queue (sự kiện thất bại)
└── Cảnh báo giám sát (sự kiện quan trọng thất bại)
```
---
## FRONTEND STATE MANAGEMENT
## QUẢN LÝ TRẠNG THÁI FRONTEND
### Zustand Store Pattern
### Mẫu Zustand Store
```
// auth-store.ts
const useAuthStore = create((set) => ({
@@ -374,227 +374,226 @@ const useAuthStore = create((set) => ({
}
}))
// Component Usage
// Cách Dùng Trong Component
const { user, setUser } = useAuthStore()
// Persistence (automatic)
├── localStorage (client-side)
├── Hydration on page load
└── Sync across tabs (storage event)
// Lưu Trữ Bền Vững (tự động)
├── localStorage (phía client)
├── Hydration khi tải trang
└── Đồng bộ giữa các tab (storage event)
```
### React Query Integration
### Tích Hợp React Query
```
// Hook Pattern
// Mẫu Hook
const useListings = (filters) => {
return useQuery({
queryKey: ['listings', filters],
queryFn: () => listingsApi.search(filters),
staleTime: 5 * 60 * 1000, // 5 min
gcTime: 10 * 60 * 1000, // 10 min (old: cacheTime)
staleTime: 5 * 60 * 1000, // 5 phút
gcTime: 10 * 60 * 1000, // 10 phút (cũ: cacheTime)
retry: 3,
retryDelay: exponentialBackoff,
})
}
// Features
├── Automatic caching by queryKey
├── Background refetching
├── Optimistic updates
├── Pagination support
└── Dependency tracking
// Tính Năng
├── Cache tự động theo queryKey
├── Tải lại nền
├── Cập nhật lạc quan
├── Hỗ trợ phân trang
└── Theo dõi phụ thuộc
```
---
## DEPLOYMENT ARCHITECTURE
## KIẾN TRÚC TRIỂN KHAI
### Local Development
### Phát Triển Cục Bộ
```
docker-compose.yml
├── PostgreSQL (5432)
├── Redis (6379)
├── Typesense (8108)
├── MinIO (9000)
└── PgBouncer (6432 - optional)
└── PgBouncer (6432 - tùy chọn)
API Server: http://localhost:3001/api/v1
Web Server: http://localhost:3000
Swagger Docs: http://localhost:3001/api/v1/docs
```
### Production Deployment
### Triển Khai Sản Xuất
```
Kubernetes Cluster
├── API Pod (NestJS)
│ ├── Port: 3001
│ ├── Resources: 2 CPU, 2GB RAM
│ ├── Replicas: 3+ (autoscaling)
│ ├── Tài nguyên: 2 CPU, 2GB RAM
│ ├── Replicas: 3+ (tự động mở rộng)
│ ├── Probes: liveness + readiness
│ └── Limits: enforce resource quotas
│ └── Limits: thực thi hạn mức tài nguyên
├── Web Pod (Next.js)
│ ├── Port: 3000
│ ├── Replicas: 2+
│ └── CDN: CloudFront/Cloudflare
├── PostgreSQL (managed RDS or Kubernetes StatefulSet)
├── Redis (managed ElastiCache or Kubernetes)
└── Typesense (managed or self-hosted cluster)
├── PostgreSQL (RDS được quản lý hoặc Kubernetes StatefulSet)
├── Redis (ElastiCache được quản lý hoặc Kubernetes)
└── Typesense (được quản lý hoặc cluster tự lưu trữ)
Ingress → Load Balancer → Service → Pods
```
---
## CI/CD PIPELINE
## PIPELINE CI/CD
### Automated Stages
### Các Giai Đoạn Tự Động
```
1. Code Push to master/PR
└→ GitHub Actions triggered
1. Đẩy Code lên master/PR
└→ Kích hoạt GitHub Actions
2. Lint Stage (2 min)
├── ESLint check
└── Prettier validation
2. Giai Đoạn Lint (2 phút)
├── Kiểm tra ESLint
└── Xác thực Prettier
3. Type Check Stage (3 min)
└── TypeScript compilation (no emit)
3. Giai Đoạn Kiểm Tra Kiểu (3 phút)
└── Biên dịch TypeScript (không emit)
4. Unit Test Stage (5 min)
4. Giai Đoạn Kiểm Thử Đơn Vị (5 phút)
├── Backend: Vitest (pnpm test)
└── Frontend: Vitest + RTL
5. Integration Test Stage (8 min)
├── Test database setup
└── Vitest integration config
5. Giai Đoạn Kiểm Thử Tích Hợp (8 phút)
├── Thiết lập cơ sở dữ liệu kiểm thử
└── Cấu hình tích hợp Vitest
6. Build Stage (10 min)
├── NestJS build (tsc + webpack)
├── Next.js build (.next folder)
└── Artifact storage
6. Giai Đoạn Build (10 phút)
├── Build NestJS (tsc + webpack)
├── Build Next.js (thư mục .next)
└── Lưu trữ artifact
7. E2E Test Stage (15 min) - if CI passes
├── Service startup (Postgres, Redis, Typesense)
├── Database migration
├── Seed data
├── Playwright tests (Chromium)
└── Report generation
7. Giai Đoạn Kiểm Thử E2E (15 phút) - nếu CI vượt qua
├── Khởi động dịch vụ (Postgres, Redis, Typesense)
├── Migration cơ sở dữ liệu
├── Dữ liệu seed
├── Kiểm thử Playwright (Chromium)
└── Tạo báo cáo
8. Deploy Stage (5 min) - if all pass
├── Docker image build
├── Registry push
└── Kubernetes rollout
8. Giai Đoạn Triển Khai (5 phút) - nếu tất cả vượt qua
├── Build Docker image
├── Đẩy lên Registry
└── Triển khai Kubernetes
Total: ~50 min (sequential) or ~15 min (parallel)
Tổng cộng: ~50 phút (tuần tự) hoặc ~15 phút (song song)
```
---
## PERFORMANCE TUNING CHECKLIST
## DANH SÁCH KIỂM TRA TINH CHỈNH HIỆU SUẤT
### Database
- [ ] Query analysis (EXPLAIN ANALYZE)
- [ ] Missing indexes (pg_stat_statements)
- [ ] Connection pooling tuned (PgBouncer)
- [ ] Replication lag monitored
- [ ] Backup tested (recovery time < 1 hour)
### Cơ Sở Dữ Liệu
- [ ] Phân tích truy vấn (EXPLAIN ANALYZE)
- [ ] Thiếu chỉ mục (pg_stat_statements)
- [ ] Tinh chỉnh connection pooling (PgBouncer)
- [ ] Giám sát độ trễ nhân rộng
- [ ] Kiểm tra sao lưu (thời gian phục hồi < 1 giờ)
### Application
- [ ] Memory usage profiled (Node.js heap)
- [ ] CPU throttling identified
- [ ] Garbage collection tuned (heap snapshots)
- [ ] Logging overhead measured
- [ ] Dependency versions updated
### Ứng Dụng
- [ ] Lập hồ sơ sử dụng bộ nhớ (Node.js heap)
- [ ] Xác định giới hạn CPU
- [ ] Tinh chỉnh garbage collection (heap snapshots)
- [ ] Đo lường chi phí ghi log
- [ ] Cập nhật phiên bản phụ thuộc
### Frontend
- [ ] Bundle size analyzed (webpack analyzer)
- [ ] Code splitting implemented (routes)
- [ ] Images optimized (Next.js Image)
- [ ] Critical CSS inlined
- [ ] Web vitals tracked (LCP, FID, CLS)
- [ ] Phân tích kích thước bundle (webpack analyzer)
- [ ] Triển khai code splitting (routes)
- [ ] Tối ưu hóa hình ảnh (Next.js Image)
- [ ] Nội tuyến CSS quan trọng
- [ ] Theo dõi web vitals (LCP, FID, CLS)
### Infrastructure
- [ ] Load balancer health checks tuned
- [ ] Autoscaling policies tested
- [ ] Cache hit rates > 80%
- [ ] Network latency acceptable (< 100ms)
- [ ] Monitoring alert thresholds realistic
### Hạ Tầng
- [ ] Tinh chỉnh kiểm tra sức khỏe load balancer
- [ ] Kiểm tra chính sách tự động mở rộng
- [ ] Tỷ lệ trúng cache > 80%
- [ ] Độ trễ mạng chấp nhận được (< 100ms)
- [ ] Ngưỡng cảnh báo giám sát thực tế
---
## TROUBLESHOOTING GUIDE
## HƯỚNG DẪN KHẮC PHỤC SỰ CỐ
### "Database Connection Timeout"
```
Diagnosis:
1. Check if PostgreSQL container is running: docker-compose ps
2. Verify DATABASE_URL in .env
3. Check PgBouncer if production: psql -h localhost -p 6432 -U pgbouncer
4. Look for connection limit reached: SELECT count(*) FROM pg_stat_activity
Chẩn Đoán:
1. Kiểm tra container PostgreSQL có đang chạy: docker-compose ps
2. Xác minh DATABASE_URL trong .env
3. Kiểm tra PgBouncer nếu production: psql -h localhost -p 6432 -U pgbouncer
4. Tìm kiếm giới hạn kết nối đạt: SELECT count(*) FROM pg_stat_activity
Fix:
├── Restart: docker-compose restart postgres
├── Increase PgBouncer pool: PGBOUNCER_POOL_SIZE=30
└── Check slow queries: pg_stat_statements
Khắc Phục:
├── Khởi động lại: docker-compose restart postgres
├── Tăng pool PgBouncer: PGBOUNCER_POOL_SIZE=30
└── Kiểm tra truy vấn chậm: pg_stat_statements
```
### "Redis Connection Refused"
```
Diagnosis:
1. Check Redis container: docker-compose ps redis
2. Verify REDIS_URL in .env
3. Check port: redis-cli -p 6379 ping
4. Check memory: redis-cli INFO memory
Chẩn Đoán:
1. Kiểm tra container Redis: docker-compose ps redis
2. Xác minh REDIS_URL trong .env
3. Kiểm tra port: redis-cli -p 6379 ping
4. Kiểm tra bộ nhớ: redis-cli INFO memory
Fix:
├── Restart: docker-compose restart redis
├── Flush if needed: redis-cli FLUSHALL (dev only!)
└── Monitor: redis-cli --stat
Khắc Phục:
├── Khởi động lại: docker-compose restart redis
├── Xóa nếu cần: redis-cli FLUSHALL (chỉ môi trường dev!)
└── Giám sát: redis-cli --stat
```
### "Typesense Index Not Found"
```
Diagnosis:
1. Check Typesense container: docker-compose ps typesense
2. Verify TYPESENSE_API_KEY in .env
3. List indexes: curl http://localhost:8108/collections -H "X-TYPESENSE-API-KEY: <key>"
4. Check sync job logs
Chẩn Đoán:
1. Kiểm tra container Typesense: docker-compose ps typesense
2. Xác minh TYPESENSE_API_KEY trong .env
3. Lit kê chỉ mục: curl http://localhost:8108/collections -H "X-TYPESENSE-API-KEY: <key>"
4. Kiểm tra log công việc đồng bộ
Fix:
├── Re-seed: pnpm db:seed
├── Reindex: DELETE /listings index, then rebuild
└── Monitor: Typesense dashboard http://localhost:8108/dashboard
Khắc Phục:
├── Seed lại: pnpm db:seed
├── Lập chỉ mục lại: XÓA chỉ mục /listings, sau đó xây dựng lại
└── Giám sát: Typesense dashboard http://localhost:8108/dashboard
```
### "Tests Failing with 'Port Already in Use'"
```
Diagnosis:
1. Check running processes: lsof -i :3001 (macOS) or netstat -ano (Windows)
2. Docker containers: docker ps
Chẩn Đoán:
1. Kiểm tra tiến trình đang chạy: lsof -i :3001 (macOS) hoặc netstat -ano (Windows)
2. Container Docker: docker ps
Fix:
├── Kill process: kill -9 <PID>
├── Stop containers: docker-compose down
├── Update port in .env.test
└── Ensure cleanup in global-teardown.ts
Khắc Phục:
├── Hủy tiến trình: kill -9 <PID>
├── Dừng container: docker-compose down
├── Cập nhật port trong .env.test
└── Đảm bảo dọn dẹp trong global-teardown.ts
```
---
## SECURITY CHECKLIST - PRE-DEPLOYMENT
- [ ] JWT secrets rotated and unique
- [ ] CORS_ORIGINS finalized (no localhost in prod)
- [ ] Database credentials strong (> 16 chars, random)
- [ ] MinIO/AWS S3 credentials secure (IAM policy restricted)
- [ ] OAuth client secrets masked
- [ ] SSL certificate installed (HTTPS)
- [ ] HSTS preload submitted
- [ ] Security headers tested (securityheaders.com)
- [ ] OWASP Top 10 reviewed
- [ ] Penetration test scheduled
- [ ] Rate limits tuned (no bypass possible)
- [ ] Audit logging verified
- [ ] Backup encryption enabled
- [ ] Incident response plan documented
- [ ] On-call rotation configured
## DANH SÁCH KIỂM TRA BẢO MẬT - TRƯỚC KHI TRIỂN KHAI
- [ ] Bí mật JWT đã được xoay vòng và duy nhất
- [ ] CORS_ORIGINS đã được hoàn thiện (không có localhost trong production)
- [ ] Thông tin đăng nhập cơ sở dữ liệu mạnh (> 16 ký tự, ngẫu nhiên)
- [ ] Thông tin đăng nhập MinIO/AWS S3 an toàn (chính sách IAM bị hạn chế)
- [ ] Bí mật OAuth client đã được che giấu
- [ ] Chứng chỉ SSL đã được cài đặt (HTTPS)
- [ ] HSTS preload đã được gửi
- [ ] Headers bảo mật đã được kiểm tra (securityheaders.com)
- [ ] OWASP Top 10 đã được xem xét
- [ ] Kiểm tra thâm nhập đã được lên lịch
- [ ] Giới hạn tốc độ đã được tinh chỉnh (không thể bỏ qua)
- [ ] Ghi log kiểm toán đã được xác minh
- [ ] Mã hóa sao lưu đã được bật
- [ ] Kế hoạch ứng phó sự cố đã được lập tài liệu
- [ ] Lịch trực đã được cấu hình