Files
goodgo-platform/docs/load-testing/K6_LOAD_TESTING_GUIDE.md
Ho Ngoc Hai d8b409a9ab
Some checks failed
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 18s
CI / E2E Tests (push) Has been skipped
CodeQL Analysis / CodeQL (javascript-typescript) (push) Failing after 2m15s
Deploy / Build API Image (push) Failing after 28s
Deploy / Build Web Image (push) Failing after 16s
Deploy / Build AI Services Image (push) Failing after 17s
E2E Tests / Playwright E2E (push) Failing after 31s
Security Scanning / Dependency Audit (pnpm) (push) Failing after 3s
Security Scanning / Trivy Scan — API Image (push) Failing after 1m46s
Security Scanning / Trivy Scan — Web Image (push) Failing after 1m7s
Security Scanning / Trivy Scan — AI Services Image (push) Failing after 53s
Security Scanning / Trivy Filesystem Scan (push) Failing after 35s
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
Security Scanning / Security Gate (push) Failing after 0s
Deploy / Rollback Staging (push) Has been skipped
Deploy / Rollback Production (push) Has been skipped
docs: dịch 22 file Markdown còn lại sang tiếng Việt có dấu (TEC-2881)
Hoàn tất đợt cuối của nhiệm vụ chuyển toàn bộ tài liệu sang tiếng Việt.
Đã dịch 22 file `.md` còn sót (~9.7k dòng) — gồm RUNBOOK, audits,
docs/architecture, docs/load-testing, libs READMEs và các quick references.
Giữ nguyên code blocks, đường dẫn, identifier kỹ thuật, URL và biến môi trường.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-19 03:26:14 +07:00

805 lines
22 KiB
Markdown

# GoodGo Platform API — Hướng Dẫn K6 Load Testing
## 🎯 Tóm Tắt Nhanh
**Base URL**: `http://localhost:3001/api/v1`
**Phiên bản Node**: >= 22.0.0
**Testing Framework**: Playwright (E2E), Vitest (Unit)
**Chưa có thiết lập K6 hoặc load testing nào tồn tại**
---
## 📋 Cấu Trúc Dự Án
### Thư Mục Gốc
```
goodgo-platform/
├── apps/api # NestJS backend (port 3001)
├── apps/web # Next.js 15 frontend (port 3000)
├── libs/mcp-servers # MCP tool server library
├── prisma/ # Database schema & migrations
├── e2e/ # Playwright E2E tests (api + web)
├── turbo.json # Turborepo config
├── package.json # Root workspace scripts
├── .env.example # Environment variables template
└── playwright.config.ts # Playwright configuration
```
### Các Script Chính (package.json)
```bash
pnpm dev # Start all apps (API :3001, Web :3000)
pnpm test # Unit tests via Vitest (API only)
pnpm test:e2e # Playwright E2E tests
pnpm test:e2e:api # API E2E tests only
pnpm test:e2e:web # Web E2E tests only
pnpm build # Production build
pnpm lint # ESLint
pnpm typecheck # TypeScript checking
```
---
## 🏗️ Cấu Trúc Module API
### Kiến Trúc Cơ Sở API: `apps/api/src/modules/`
Mỗi module tuân theo các tầng DDD: `domain/``application/``infrastructure/``presentation/`
```
modules/
├── auth/ # Authentication & JWT
├── listings/ # Property listings CRUD
├── payments/ # Payment processing (VNPay, MoMo, ZaloPay)
├── search/ # Full-text & geo search (Typesense)
├── subscriptions/ # Plans, quotas, usage tracking
├── admin/ # Moderation, KYC, user management
├── analytics/ # Market data, heatmaps, price trends
├── reviews/ # User reviews
├── notifications/ # Email, push (FCM), in-app
├── metrics/ # Prometheus metrics
├── health/ # Health checks
├── shared/ # Domain primitives, guards, pipes, logging
└── mcp/ # MCP tool server endpoints
```
---
## 🔐 MODULE AUTH
### Controllers & Endpoints
#### File: `apps/api/src/modules/auth/presentation/controllers/auth.controller.ts`
| Method | Endpoint | Rate Limit | Auth | Mô tả |
|--------|----------|-----------|------|-------------|
| POST | `/auth/register` | 5/giờ | Không | Đăng ký người dùng mới |
| POST | `/auth/login` | 5/giờ | LocalAuth | Đăng nhập bằng số điện thoại + mật khẩu |
| POST | `/auth/refresh` | 5/giờ | Không | Làm mới access token |
| POST | `/auth/logout` | Không giới hạn | Không | Xóa cookie xác thực |
| POST | `/auth/exchange-token` | Không giới hạn | Không | Đổi OAuth token lấy cookie |
| GET | `/auth/profile` | Không giới hạn | JWT | Lấy hồ sơ người dùng hiện tại |
| GET | `/auth/profile/agent` | Không giới hạn | JWT | Lấy hồ sơ agent của người dùng |
| PATCH | `/auth/kyc` | Không giới hạn | JWT+Admin | Xác minh KYC người dùng (chỉ admin) |
### DTOs
#### LoginDto
```typescript
{
phone: string // Required, example: "0901234567"
password: string // Required, example: "P@ssw0rd!"
}
```
#### RegisterDto
```typescript
{
phone: string // Required, example: "0901234567"
password: string // Required, min 8 chars, example: "P@ssw0rd!"
fullName: string // Required, example: "Nguyen Van A"
email?: string // Optional, valid email format
}
```
#### RefreshTokenDto
```typescript
{
refreshToken?: string // Optional if using cookie
}
```
#### VerifyKycDto
```typescript
{
userId: string
kycStatus: string
kycData?: object
}
```
### Cookies & Xác Thực
**Access Token**:
- Cookie: `access_token`
- Max Age: 15 phút (900s)
- HttpOnly: true
- Secure: true (chỉ production)
- SameSite: strict
- Path: /
**Refresh Token**:
- Cookie: `refresh_token`
- Max Age: 30 ngày
- HttpOnly: true
- Secure: true (chỉ production)
- SameSite: strict
- Path: `/auth`
**Chỉ Báo Phiên**:
- Cookie: `goodgo_authenticated` = "1"
- HttpOnly: false (frontend nhìn thấy được)
### Hỗ Trợ OAuth
- Google OAuth 2.0
- Zalo OAuth (nền tảng Việt Nam)
- Environment: `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`, `ZALO_APP_ID`, `ZALO_APP_SECRET`
---
## 🏠 MODULE LISTINGS
### Controllers & Endpoints
#### File: `apps/api/src/modules/listings/presentation/controllers/listings.controller.ts`
| Method | Endpoint | Auth | Quota | Mô tả |
|--------|----------|------|-------|-------------|
| POST | `/listings` | JWT | Có | Tạo listing mới |
| GET | `/listings` | Không | Không | Tìm kiếm/lọc listing (công khai) |
| GET | `/listings/:id` | Không | Không | Lấy chi tiết listing |
| GET | `/listings/pending` | JWT+Admin | Không | Lấy listing đang chờ kiểm duyệt |
| PATCH | `/listings/:id/status` | JWT | Không | Cập nhật trạng thái listing |
| POST | `/listings/:id/media` | JWT | Không | Tải lên ảnh/video |
| PATCH | `/listings/:id/moderate` | JWT+Admin | Không | Kiểm duyệt listing (admin) |
### DTOs
#### CreateListingDto
```typescript
{
transactionType: 'SALE' | 'RENT',
priceVND: bigint | string,
propertyType: 'APARTMENT' | 'HOUSE' | 'LAND' | etc.,
title: string, // Min 5 chars
description: string, // Min 10 chars
address: string,
ward: string,
district: string,
city: string,
latitude: number, // -90 to 90
longitude: number, // -180 to 180
areaM2: number, // Total area
usableAreaM2?: number,
bedrooms?: number,
bathrooms?: number,
floors?: number, // For houses
floor?: number, // For apartments
totalFloors?: number,
direction?: 'EAST' | 'WEST' | 'NORTH' | 'SOUTH' | etc.,
yearBuilt?: number,
legalStatus?: string,
amenities?: string[], // e.g., ['Hồ bơi', 'Gym']
nearbyPOIs?: object, // e.g., { schools: [], hospitals: [] }
metroDistanceM?: number,
projectName?: string,
agentId?: string,
rentPriceMonthly?: bigint | string,
commissionPct?: number,
}
```
#### SearchListingsDto
```typescript
{
status?: 'ACTIVE' | 'INACTIVE' | 'ARCHIVED',
transactionType?: 'SALE' | 'RENT',
propertyType?: 'APARTMENT' | 'HOUSE' | 'LAND' | etc.,
city?: string,
district?: string,
minPrice?: bigint | string,
maxPrice?: bigint | string,
minArea?: number,
maxArea?: number,
bedrooms?: number,
page?: number, // Default: 1
limit?: number, // Default: 20, Max: 100
}
```
#### UpdateListingStatusDto
```typescript
{
status: string,
moderationNotes?: string,
}
```
#### ModerateListingDto
```typescript
{
action: 'APPROVE' | 'REJECT',
moderationScore?: number,
notes?: string,
}
```
### Cấu Trúc Phản Hồi
#### ListingDetailData
Chứa thông tin đầy đủ về listing bao gồm:
- id, title, description
- propertyType, transactionType
- address, latitude, longitude, ward, district, city
- priceVND, rentPriceMonthly
- areaM2, usableAreaM2, bedrooms, bathrooms, floors
- amenities, nearbyPOIs
- legalStatus, yearBuilt, direction
- mediaUrls (ảnh/video)
- agentInfo
- createdAt, updatedAt
#### PaginatedResult<ListingSearchItem>
```typescript
{
items: ListingSearchItem[],
total: number,
page: number,
limit: number,
totalPages: number,
}
```
---
## 💳 MODULE PAYMENTS
### Controllers & Endpoints
#### File: `apps/api/src/modules/payments/presentation/controllers/payments.controller.ts`
| Method | Endpoint | Auth | Rate Limit | Mô tả |
|--------|----------|------|-----------|-------------|
| POST | `/payments` | JWT | Không | Tạo thanh toán |
| GET | `/payments` | JWT | Không | Liệt kê giao dịch của người dùng |
| GET | `/payments/:id` | JWT | Không | Lấy trạng thái thanh toán |
| POST | `/payments/callback/:provider` | Không | 20/phút | Xử lý callback thanh toán (webhook) |
| POST | `/payments/:id/refund` | JWT+Admin | Không | Hoàn tiền (admin) |
### DTOs
#### CreatePaymentDto
```typescript
{
provider: 'VNPAY' | 'MOMO' | 'ZALOPAY',
type: 'LISTING_FEE' | 'SUBSCRIPTION' | 'AGENT_COMMISSION',
amountVND: number, // 1 to 100,000,000,000
description: string, // Payment description
returnUrl: string, // URL (must be valid)
transactionId?: string, // External ID
idempotencyKey?: string, // For idempotency
}
```
#### ListTransactionsDto
```typescript
{
status?: string,
limit?: number,
offset?: number,
}
```
#### RefundPaymentDto
```typescript
{
reason: string,
}
```
### Nhà Cung Cấp Thanh Toán
- **VNPay** (Chính cho Việt Nam)
- Environment: `VNPAY_TMN_CODE`, `VNPAY_HASH_SECRET`
- Sandbox: `https://sandbox.vnpayment.vn/paymentv2/vpcpay.html`
- API: `https://sandbox.vnpayment.vn/merchant_webapi/api/transaction`
- **MoMo** (Ví di động)
- Environment: `MOMO_PARTNER_CODE`, `MOMO_ACCESS_KEY`, `MOMO_SECRET_KEY`
- Endpoint: `https://test-payment.momo.vn/v2/gateway/api`
- **ZaloPay** (Tích hợp Zalo)
- Environment: `ZALOPAY_APP_ID`, `ZALOPAY_KEY1`, `ZALOPAY_KEY2`
- Endpoint: `https://sb-openapi.zalopay.vn/v2`
### Xử Lý Callback
**Mẫu URL Webhook**: `/payments/callback/{provider}`
Hỗ trợ cả:
- Query parameters (VNPay)
- Request body (MoMo, ZaloPay)
- Xử lý dữ liệu hợp nhất nội bộ
---
## 🔍 MODULE SEARCH
### Controllers & Endpoints
#### File: `apps/api/src/modules/search/presentation/controllers/search.controller.ts`
| Method | Endpoint | Auth | Mô tả |
|--------|----------|------|-------------|
| GET | `/search` | Không | Tìm kiếm full-text (công khai) |
| GET | `/search/geo` | Không | Tìm kiếm theo bán kính địa lý (công khai) |
| POST | `/search/reindex` | JWT+Admin | Lập chỉ mục lại tất cả bất động sản (admin) |
### DTOs
#### SearchPropertiesDto (Tìm kiếm full-text)
```typescript
{
q?: string, // Free-text query, e.g., 'chung cu quan 7'
propertyType?: string, // Filter by type
transactionType?: string, // 'sale' or 'rent'
priceMin?: number, // Min price in VND
priceMax?: number, // Max price in VND
areaMin?: number, // Min area in m²
areaMax?: number, // Max area in m²
bedrooms?: number, // Number of bedrooms
district?: string, // District name
city?: string, // City name
sortBy?: 'price_asc' | 'price_desc' | 'date_desc' | 'relevance',
page?: number, // 1-based, default: 1
perPage?: number, // Default: 20, Max: 100
}
```
#### GeoSearchDto (Tìm kiếm địa lý)
```typescript
{
lat: number, // Latitude, -90 to 90
lng: number, // Longitude, -180 to 180
radiusKm: number, // Radius, 0.1 to 100
propertyType?: string,
transactionType?: string,
priceMin?: number,
priceMax?: number,
sortBy?: 'distance' | 'price_asc' | 'price_desc' | 'date_desc',
page?: number, // Default: 1
perPage?: number, // Default: 20, Max: 100
}
```
### Search Engine
Tích hợp **Typesense** cho tìm kiếm full-text & faceted nhanh
- Environment: `TYPESENSE_HOST`, `TYPESENSE_PORT`, `TYPESENSE_API_KEY`
- Mặc định: `http://localhost:8108`
### Cấu Trúc Phản Hồi
#### SearchResult
```typescript
{
results: SearchHit[],
facets?: {
propertyType?: { value: string; count: number }[],
district?: { value: string; count: number }[],
transactionType?: { value: string; count: number }[],
},
total: number,
page: number,
perPage: number,
totalPages: number,
}
```
---
## 🗄️ Database & Environment
### PostgreSQL với PostGIS
```
DB_HOST=localhost
DB_PORT=5432
DB_NAME=goodgo
DB_USER=goodgo
DB_PASSWORD=<change_me>
DATABASE_URL=postgresql://goodgo:password@localhost:5432/goodgo?schema=public
```
### Redis Cache
```
REDIS_URL=redis://localhost:6379
```
### Các Biến Môi Trường Chính
```bash
# JWT Secrets (REQUIRED)
JWT_SECRET=<openssl rand -base64 48>
JWT_REFRESH_SECRET=<openssl rand -base64 48>
JWT_EXPIRES_IN=15m
JWT_REFRESH_EXPIRES_IN=7d
# CORS
CORS_ORIGINS=http://localhost:3000,http://localhost:3001
# Node Environment
NODE_ENV=development|test|production
PORT=3001 # API port
# OAuth
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
ZALO_APP_ID=
ZALO_APP_SECRET=
# Typesense Search
TYPESENSE_HOST=localhost
TYPESENSE_PORT=8108
TYPESENSE_API_KEY=
# MinIO/S3 Storage
MINIO_ENDPOINT=localhost
MINIO_PORT=9000
MINIO_ACCESS_KEY=
MINIO_SECRET_KEY=
MINIO_BUCKET=goodgo-media
# Payment Gateways
VNPAY_TMN_CODE=
VNPAY_HASH_SECRET=
MOMO_PARTNER_CODE=
ZALOPAY_APP_ID=
# Logging
LOG_LEVEL=info
```
---
## 🧪 Thiết Lập Test Hiện Có
### Cấu Hình Playwright
**File**: `playwright.config.ts`
```typescript
testDir: './e2e'
globalSetup: './e2e/global-setup.ts'
globalTeardown: './e2e/global-teardown.ts'
Projects:
- "api": Tests NestJS API (port 3001)
baseURL: http://localhost:3001/api/v1
- "web": Tests Next.js frontend (port 3000)
baseURL: http://localhost:3000
```
### Các Script Playwright
```bash
pnpm test:e2e # Run all E2E tests
pnpm test:e2e:api # API tests only
pnpm test:e2e:web # Web tests only
pnpm test:e2e:report # Show HTML report
```
### Database Test
- CI sử dụng database `goodgo_test`
- Local sử dụng `.env.test` cho URL database test
- Migration & seed chạy trong `global-setup.ts`
- Dọn dẹp trong `global-teardown.ts`
### Ví Dụ E2E Test
**File**: `e2e/api/auth-register.spec.ts`
```typescript
import { test, expect } from '@playwright/test';
import { createTestUser } from '../fixtures';
test.describe('POST /auth/register', () => {
test('registers a new user and returns token pair', async ({ request }) => {
const user = createTestUser();
const res = await request.post('/auth/register', { data: user });
expect(res.status()).toBe(201);
const body = await res.json();
expect(body).toHaveProperty('accessToken');
expect(body).toHaveProperty('refreshToken');
});
});
```
### Unit Tests (Vitest)
```bash
pnpm test # Run unit tests (API only)
pnpm test:integration # Integration tests
```
---
## 🔄 Thiết Lập CI/CD
### Workflow GitHub Actions
#### `ci.yml` - Lint → Typecheck → Test → Build
- Chạy khi: `push main``pull_request`
- Services: PostgreSQL 16 + PostGIS
- Các bước: lint → typecheck → test → build
#### `e2e.yml` - Playwright E2E Tests
- Chạy khi: `push main``pull_request`
- Services:
- PostgreSQL 16 + PostGIS
- Redis 7
- Typesense 27.1
- MinIO (lưu trữ tương thích S3)
- Artifacts: HTML report + traces
#### `security.yml` - Bảo Mật Mã Nguồn
- Quét dependency
- Phân tích SAST
#### `deploy.yml` - Triển Khai Production
- Build Docker
- Push registry
- Điều phối triển khai
---
## 📊 Mẫu Kiến Trúc
### Mẫu CQRS NestJS
Mỗi module sử dụng:
- **Commands** (Thao tác ghi)
- `CommandBus.execute(command)`
- Đặt trong `application/commands/`
- Handlers trong `application/commands/{command}/`
- **Queries** (Thao tác đọc)
- `QueryBus.execute(query)`
- Đặt trong `application/queries/`
- Handlers trong `application/queries/{query}/`
Ví dụ:
```typescript
// In controller
const result = await this.commandBus.execute(
new CreateListingCommand(userId, ...)
);
const profile = await this.queryBus.execute(
new GetProfileQuery(userId)
);
```
### Guards & Interceptors
- `JwtAuthGuard` - Xác thực JWT token
- `LocalAuthGuard` - Xác thực email/mật khẩu
- `RolesGuard` - Kiểm soát truy cập dựa trên vai trò
- `QuotaGuard` - Thi hành hạn ngạch subscription
- `FileValidationPipe` - Xác thực file upload
---
## 🚀 Khởi Động API
### Phát Triển Cục Bộ
```bash
# Install dependencies
pnpm install
# Generate Prisma client
pnpm db:generate
# Run migrations
pnpm db:migrate:dev
# Seed data (users, listings, etc.)
pnpm db:seed
# Start API (and Web)
pnpm dev
# API will be available at:
# http://localhost:3001/api/v1
# Swagger UI: http://localhost:3001/api/v1/docs
```
### Với Docker
```bash
docker-compose up
# Services: PostgreSQL, Redis, Typesense, MinIO, API, Web
```
---
## 🎯 Khuyến Nghị K6 Load Testing
### Các Endpoint Chính Cần Test
1. **Authentication** (Ưu tiên cao)
- Register: `POST /auth/register`
- Login: `POST /auth/login`
- Refresh: `POST /auth/refresh`
- Profile: `GET /auth/profile` (đã xác thực)
2. **Listings** (Ưu tiên cao)
- Create: `POST /listings` (giới hạn quota)
- Search: `GET /listings` (công khai, lưu lượng cao)
- Detail: `GET /listings/:id` (công khai, lưu lượng cao)
3. **Search** (Ưu tiên cao)
- Full-text: `GET /search?q=...` (công khai, lưu lượng cao)
- Geo: `GET /search/geo?lat=...&lng=...` (công khai, lưu lượng cao)
4. **Payments** (Ưu tiên trung bình)
- Create: `POST /payments` (đã xác thực)
- List: `GET /payments` (đã xác thực)
- Webhook: `POST /payments/callback/:provider` (không giới hạn throttle)
5. **Endpoint Admin** (Ưu tiên trung bình, hạn chế)
- Kiểm duyệt listing: `PATCH /listings/:id/moderate`
- Liệt kê pending: `GET /listings/pending`
- Xác minh KYC: `PATCH /auth/kyc`
- Reindex: `POST /search/reindex`
### Cấu Trúc Script K6
```javascript
import http from 'k6/http';
import { check, group, sleep } from 'k6';
const BASE_URL = 'http://localhost:3001/api/v1';
// Stage-based load: ramp up → sustained → ramp down
export const options = {
stages: [
{ duration: '2m', target: 100 }, // Ramp up
{ duration: '5m', target: 100 }, // Sustained
{ duration: '2m', target: 0 }, // Ramp down
],
thresholds: {
http_req_duration: ['p(95)<500', 'p(99)<1000'],
http_req_failed: ['rate<0.1'],
},
};
export default function() {
// Test scenarios here
}
```
### Mẹo Tạo Dữ Liệu
- Sử dụng test fixture user từ Playwright tests
- Tận dụng dữ liệu Prisma seed (quận, loại bất động sản)
- Tạo các truy vấn tìm kiếm thực tế
- Test với các tọa độ địa lý khác nhau (TP.HCM: ~10.77°N, 106.70°E)
---
## 📁 Tham Khảo Nhanh Vị Trí File
```
apps/api/
├── src/
│ ├── main.ts # API entry point (port 3001)
│ ├── app.module.ts # Root module
│ └── modules/
│ ├── auth/
│ │ ├── presentation/controllers/auth.controller.ts
│ │ ├── presentation/dto/
│ │ │ ├── login.dto.ts
│ │ │ ├── register.dto.ts
│ │ │ ├── refresh-token.dto.ts
│ │ │ └── verify-kyc.dto.ts
│ │ ├── application/commands/
│ │ ├── application/queries/
│ │ ├── infrastructure/services/token.service.ts
│ │ └── domain/
│ ├── listings/
│ │ ├── presentation/controllers/listings.controller.ts
│ │ ├── presentation/dto/
│ │ │ ├── create-listing.dto.ts
│ │ │ ├── search-listings.dto.ts
│ │ │ ├── update-listing-status.dto.ts
│ │ │ └── moderate-listing.dto.ts
│ │ └── ...
│ ├── payments/
│ │ ├── presentation/controllers/payments.controller.ts
│ │ ├── presentation/dto/
│ │ │ ├── create-payment.dto.ts
│ │ │ ├── list-transactions.dto.ts
│ │ │ └── refund-payment.dto.ts
│ │ └── ...
│ ├── search/
│ │ ├── presentation/controllers/search.controller.ts
│ │ ├── presentation/dto/
│ │ │ ├── search-properties.dto.ts
│ │ │ └── geo-search.dto.ts
│ │ └── ...
│ └── ...
└── package.json # Dependencies, scripts
e2e/
├── api/ # Playwright API tests
│ ├── auth-register.spec.ts
│ ├── auth-refresh.spec.ts
│ └── ...
├── web/ # Playwright web tests
├── fixtures.ts # Test data generators
├── global-setup.ts # DB setup before tests
└── global-teardown.ts # DB cleanup after tests
playwright.config.ts # Playwright config
.github/workflows/
├── ci.yml # Lint → typecheck → test → build
├── e2e.yml # Playwright E2E
├── security.yml # Security scanning
└── deploy.yml # Production deployment
.env.example # Environment variable template
.env.test # Test database connection
```
---
## 🔗 Liên Kết & Tham Khảo Hữu Ích
- **API Swagger Docs**: `http://localhost:3001/api/v1/docs`
- **Tài Liệu Gốc Dự Án**: `CLAUDE.md`
- **Phân Tích Hiện Có**: `CODEBASE_ANALYSIS.md`, `EXPLORATION_REPORT.md`
- **Tài Liệu Frontend**: `docs/audits/FRONTEND_EXPLORATION.md`
---
## ✅ Tóm Tắt Triển Khai K6
**Chưa có thiết lập K6 nào** — bạn có một khởi đầu hoàn toàn mới!
**Các endpoint chính** được xác định trên các module:
- Auth (register, login, refresh, profile)
- Listings (create, search, detail, moderate)
- Search (full-text, geo)
- Payments (create, callback, list, refund)
- Admin (moderate, KYC, reindex)
**Rate limit** cần xem xét:
- Auth: 5/giờ mỗi endpoint
- Payments callback: 20/phút
- Khác: Không giới hạn (trừ quota guard cho thao tác create)
**Hạ tầng sẵn sàng**:
- Turbo monorepo cho quản lý dependency
- PostgreSQL + PostGIS cho dữ liệu không gian
- Typesense cho lập chỉ mục tìm kiếm
- Redis cho caching
- MinIO cho lưu trữ media
- Endpoint Prometheus metrics
**Tests có thể được tích hợp** vào CI/CD pipeline qua `.github/workflows/` (đề xuất: `load-test.yml` mới)