# Trang Hồ Sơ Công Khai Môi Giới — Hướng Dẫn Triển Khai Đầy Đủ

**Cập nhật lần cuối:** 11 tháng 4, 2026  
**Trạng thái:** 📋 Khám phá hoàn tất — Sẵn sàng triển khai  
**Phạm vi:** Trang hồ sơ công khai `/agents/[id]` cho nền tảng GoodGo

---

## 📚 Mục lục Tài liệu

Gói khám phá này chứa 3 tài liệu toàn diện:

### 1. **AGENT_PROFILE_EXPLORATION.md** (21 KB)
**Phân tích kỹ thuật toàn diện về toàn bộ codebase**

Nội dung:
- ✅ Cấu trúc ứng dụng web & phân tích định tuyến
- ✅ Danh sách code liên quan đến môi giới hiện có
- ✅ Đề xuất thiết kế API endpoint
- ✅ Tổng quan thư viện component giao diện
- ✅ Mẫu styling & cài đặt Tailwind
- ✅ Mẫu quản lý trạng thái & lấy dữ liệu
- ✅ Mẫu SEO & dữ liệu có cấu trúc
- ✅ Định nghĩa kiểu & interface
- ✅ Danh sách kiểm tra triển khai
- ✅ Hướng dẫn tham chiếu các tệp quan trọng

**Đọc tài liệu này trước** để hiểu toàn bộ kiến trúc.

---

### 2. **AGENT_PROFILE_QUICK_REFERENCE.md** (10 KB)
**Hướng dẫn khởi động nhanh cho lập trình viên**

Nội dung:
- ✅ Mẫu URL & định tuyến
- ✅ Đặc tả API backend
- ✅ Sơ đồ kiến trúc frontend
- ✅ Trực quan hóa luồng dữ liệu
- ✅ Hướng dẫn kết hợp component
- ✅ Tham chiếu API endpoint
- ✅ Bản phác thảo giao diện & bố cục
- ✅ Mẫu code sao chép nhanh
- ✅ Tham chiếu SEO & schema
- ✅ Lộ trình triển khai 5 giai đoạn
- ✅ Cấu trúc phản hồi mẫu
- ✅ Danh sách kiểm tra tệp quan trọng

**Dùng tài liệu này trong quá trình phát triển** như tài liệu tham khảo tiện dụng.

---

### 3. **AGENT_PROFILE_CODE_EXAMPLES.md** (20 KB)
**Mẫu code sẵn sàng sử dụng cho tất cả các component**

Nội dung:
- ✅ Query handler backend (mẫu CQRS)
- ✅ Định nghĩa DTO backend
- ✅ Endpoint controller backend
- ✅ Cập nhật interface repository
- ✅ Triển khai Prisma
- ✅ API client frontend (agents-api.ts)
- ✅ Server fetch frontend (agents-server.ts)
- ✅ Server component (page.tsx)
- ✅ Component header môi giới
- ✅ Component phần danh sách bất động sản của môi giới
- ✅ Component phần đánh giá môi giới
- ✅ Mẫu styling Tailwind
- ✅ Danh sách kiểm tra kiểm thử

**Sao chép & dán các mẫu này** vào các tệp thực tế của bạn và tùy chỉnh.

---

## 🎯 Khởi động Nhanh (5 Phút)

1. **Đọc** các phần trong `AGENT_PROFILE_QUICK_REFERENCE.md`:
   - 🎯 Tổng quan Triển khai
   - 📦 Thiết lập Backend
   - 🎨 Kiến trúc Frontend

2. **Xem xét** `AGENT_PROFILE_CODE_EXAMPLES.md`:
   - Cấu trúc tệp backend
   - Cấu trúc tệp frontend

3. **Lên kế hoạch** triển khai theo 5 giai đoạn (xem tài liệu tham chiếu nhanh)

---

## 🏗️ Tóm tắt Kiến trúc

### Backend (NestJS)
```
New Endpoint: GET /api/v1/agents/:agentId/profile
  │
  ├── Query: GetAgentProfileQuery
  ├── Handler: GetAgentProfileHandler
  ├── DTO: AgentPublicProfileDto
  ├── Repository: IAgentRepository.getPublicProfile()
  └── Implementation: PrismaAgentRepository
```

### Frontend (Next.js 15)
```
Route: /agents/[id]
  │
  ├── Page Component: [id]/page.tsx (Server)
  │   ├── Metadata generation (SEO)
  │   └── JSON-LD structured data
  │
  └── Client Component: AgentDetailClient
      ├── AgentHeader (profile info)
      ├── AgentReviewsSection (reviews & ratings)
      └── AgentListingsSection (properties)
```

### Luồng Dữ liệu
```
1. GET /agents/[id]
2. Server fetches agent profile (ISR: 1 hour cache)
3. Generates SEO metadata
4. Renders with JSON-LD structured data
5. Client component fetches:
   - Agent's listings (parallel)
   - Agent's reviews (parallel)
6. Display agent profile with interactive sections
```

---

## 📋 Giai đoạn Triển khai

### Giai đoạn 1: Backend (1-2 giờ)
- [ ] Tạo query handler `get-agent-profile/`
- [ ] Tạo `agent-public-profile.dto.ts`
- [ ] Cập nhật interface `agent.repository.ts`
- [ ] Triển khai `prisma-agent.repository.ts`
- [ ] Thêm endpoint vào `agents.controller.ts`
- [ ] Kiểm thử bằng Postman/curl

### Giai đoạn 2: Thiết lập Frontend (1 giờ)
- [ ] Tạo `lib/agents-api.ts`
- [ ] Tạo `lib/agents-server.ts`
- [ ] Tạo thư mục `/agents/[id]/`
- [ ] Tạo `/agents/[id]/page.tsx` (stub)

### Giai đoạn 3: Các Component Giao diện (2-3 giờ)
- [ ] Tạo thư mục `components/agents/`
- [ ] Tạo `agent-detail-client.tsx`
- [ ] Tạo `agent-header.tsx`
- [ ] Tạo `agent-reviews-section.tsx`
- [ ] Tạo `agent-listings-section.tsx`

### Giai đoạn 4: SEO & Hoàn thiện (1 giờ)
- [ ] Triển khai `generateMetadata()`
- [ ] Thêm schema JSON-LD
- [ ] Kiểm thử responsive trên thiết bị di động
- [ ] Kiểm thử chế độ tối (dark mode)

### Giai đoạn 5: Kiểm thử & QA (1 giờ)
- [ ] Kiểm thử e2e thủ công
- [ ] Xử lý lỗi 404
- [ ] Kiểm tra tái xác thực ISR
- [ ] Phân trang (đánh giá/danh sách)
- [ ] Kiểm tra SEO (Lighthouse)

**Tổng thời gian ước tính:** 6-8 giờ

---

## 🔗 Các API Endpoint Chính

### Backend (Mới)
```http
GET /agents/:agentId/profile
  # Returns: AgentPublicProfileDto
  # Status: 200 (success), 404 (not found)
```

### Backend (Hiện có, Tái sử dụng)
```http
GET /listings?agentId=:id&status=ACTIVE
  # Get agent's active listings

GET /reviews?targetType=AGENT&targetId=:id
  # Get agent reviews with pagination

GET /reviews/stats?targetType=AGENT&targetId=:id
  # Get aggregate rating statistics
```

---

## 🎨 Route Frontend

```
/                                    # Landing page
/agents/[id]                         # Agent profile (MỚI)
/en/agents/[id]                      # English locale (MỚI)
/vi/agents/[id]                      # Vietnamese locale (MỚI)
/listings/[id]                       # Listing detail (HIỆN CÓ)
/search                              # Search page (HIỆN CÓ)
/pricing                             # Pricing page (HIỆN CÓ)
```

---

## 📦 Các Tệp Cần Tạo/Chỉnh sửa

### Backend
| Tệp | Hành động | Dòng |
|------|--------|-------|
| `agents/application/queries/get-agent-profile/get-agent-profile.query.ts` | TẠO MỚI | 5 |
| `agents/application/queries/get-agent-profile/get-agent-profile.handler.ts` | TẠO MỚI | 30 |
| `agents/presentation/dto/agent-public-profile.dto.ts` | TẠO MỚI | 30 |
| `agents/presentation/controllers/agents.controller.ts` | CHỈNH SỬA | +20 |
| `agents/domain/repositories/agent.repository.ts` | CHỈNH SỬA | +1 method |
| `agents/infrastructure/repositories/prisma-agent.repository.ts` | CHỈNH SỬA | +35 |

### Frontend
| Tệp | Hành động | Dòng |
|------|--------|-------|
| `lib/agents-api.ts` | TẠO MỚI | 40 |
| `lib/agents-server.ts` | TẠO MỚI | 15 |
| `app/[locale]/(public)/agents/[id]/page.tsx` | TẠO MỚI | 120 |
| `components/agents/agent-detail-client.tsx` | TẠO MỚI | 30 |
| `components/agents/agent-header.tsx` | TẠO MỚI | 120 |
| `components/agents/agent-listings-section.tsx` | TẠO MỚI | 70 |
| `components/agents/agent-reviews-section.tsx` | TẠO MỚI | 100 |

**Tổng số dòng mới:** ~595  
**Số tệp được tạo:** 10  
**Số tệp được chỉnh sửa:** 3

---

## 🧪 Danh sách Kiểm tra Xác nhận

### Xác nhận API
- [ ] Endpoint trả về 200 cho môi giới hợp lệ
- [ ] Endpoint trả về 404 cho môi giới không hợp lệ
- [ ] Phản hồi bao gồm tất cả các trường bắt buộc
- [ ] Ngày tháng được định dạng theo ISO 8601
- [ ] Số liệu có độ chính xác đúng

### Xác nhận Frontend
- [ ] Trang tải mà không có lỗi
- [ ] Metadata được tạo đúng
- [ ] JSON-LD hợp lệ trên structured.data.org
- [ ] Responsive trên thiết bị di động (320px, 768px, 1024px)
- [ ] Chế độ tối hoạt động đúng
- [ ] Tái xác thực ISR hoạt động

### Xác nhận SEO
- [ ] Thẻ tiêu đề là duy nhất và mô tả đầy đủ
- [ ] Meta description đầy đủ
- [ ] Hình ảnh OG hiển thị đúng
- [ ] URL canonical chính xác
- [ ] Schema breadcrumb hợp lệ
- [ ] Schema LocalBusiness hợp lệ

### Xác nhận Hiệu suất
- [ ] First Contentful Paint < 2 giây
- [ ] Largest Contentful Paint < 2,5 giây
- [ ] Cumulative Layout Shift < 0,1
- [ ] Điểm Lighthouse > 80

---

## 📊 Tham chiếu Cấu trúc Dữ liệu

### Phản hồi Hồ sơ Công khai Môi giới
```typescript
{
  id: string;                      // "clu1x2y3z4a5b6c7d8e9f0"
  fullName: string;                // "Nguyễn Văn A"
  avatarUrl: string | null;        // "https://..."
  licenseNumber: string | null;    // "DA123456"
  agency: string | null;           // "GoodGo Agency"
  qualityScore: number;            // 4.8
  bio: string | null;              // Agent description
  serviceAreas: string[];          // ["quan-1", "quan-7"]
  isVerified: boolean;             // true
  totalListings: number;           // 45
  activeListings: number;          // 32
  avgReviewRating: number;         // 4.7
  totalReviews: number;            // 120
  createdAt: string;               // ISO 8601
  updatedAt: string;               // ISO 8601
}
```

---

## 🔍 Các Quyết định Thiết kế Quan trọng

1. **Định tuyến:** Hồ sơ môi giới nằm dưới nhóm `(public)`, giống như danh sách bất động sản
2. **Mẫu thiết kế:** Tuân theo mẫu trang chi tiết danh sách bất động sản một cách chính xác (phương pháp sao chép/dán)
3. **Lấy dữ liệu:** Phía server với ISR (tái xác thực mỗi 1 giờ)
4. **Trạng thái:** useState phía client cho đánh giá/danh sách (không dùng Zustand)
5. **Component:** Tách thành Page (server) + Client (tương tác)
6. **SEO:** Schema JSON-LD LocalBusiness cho môi giới
7. **Styling:** Tái sử dụng các component giao diện hiện có & token Tailwind
8. **Đánh giá:** Tận dụng các endpoint /reviews hiện có (đã công khai)

---

## 🚀 Bắt đầu

### Bước 1: Đọc Tài liệu
- [ ] Đọc `AGENT_PROFILE_QUICK_REFERENCE.md` (10 phút)
- [ ] Xem lướt `AGENT_PROFILE_EXPLORATION.md` (20 phút)

### Bước 2: Triển khai Backend
- [ ] Sao chép code từ `AGENT_PROFILE_CODE_EXAMPLES.md` (Giai đoạn 1)
- [ ] Điều chỉnh cho phù hợp với codebase của bạn
- [ ] Kiểm thử bằng Postman

### Bước 3: Triển khai Frontend
- [ ] Tạo cấu trúc thư mục
- [ ] Sao chép các component từ mẫu code (Giai đoạn 2-3)
- [ ] Kết nối luồng lấy dữ liệu
- [ ] Thêm metadata SEO

### Bước 4: Kiểm thử
- [ ] Kiểm thử thủ công
- [ ] Kiểm tra Lighthouse
- [ ] Kiểm thử E2E (trang hồ sơ môi giới)

---

## 💡 Mẹo Triển khai

1. **Sao chép cấu trúc trang chi tiết danh sách bất động sản** — Trang môi giới nên tương tự ~90%
2. **Tái sử dụng component PropertyCard** — Để hiển thị danh sách bất động sản của môi giới
3. **Dùng các endpoint đánh giá hiện có** — Đã công khai và không cần xác thực
4. **Tuân theo mẫu i18n** — Tên/tiểu sử môi giới có thể cần dịch
5. **Kiểm thử xử lý 404** — Khi môi giới không tồn tại
6. **Cache hồ sơ môi giới** — ISR 1 giờ phù hợp với mẫu danh sách bất động sản

---

## 📖 Tệp Tham chiếu trong Codebase

### Mẫu để Sao chép
- ✅ `app/[locale]/(public)/listings/[id]/page.tsx` — Cấu trúc trang
- ✅ `components/search/property-card.tsx` — Mẫu card
- ✅ `lib/listings-api.ts` — Mẫu API client
- ✅ `lib/listings-server.ts` — Mẫu server fetch
- ✅ `components/seo/json-ld.tsx` — Mẫu JSON-LD

### Endpoint để Sử dụng
- ✅ `GET /listings?agentId=:id` — Hiện có
- ✅ `GET /reviews?targetType=AGENT` — Hiện có
- ✅ `GET /reviews/stats?targetType=AGENT` — Hiện có

### Component để Tái sử dụng
- ✅ `Card`, `CardContent` — Bố cục
- ✅ `Badge` — Hiển thị trạng thái/thống kê
- ✅ `Button` — Nút CTA
- ✅ `Image` — Ảnh đại diện & ảnh bất động sản
- ✅ `PropertyCard` — Hiển thị danh sách bất động sản

---

## ❓ Câu hỏi Thường gặp

**H: Mất bao lâu để triển khai?**  
A: Tổng cộng 6-8 giờ (1-2 giờ backend, 1 giờ thiết lập, 2-3 giờ giao diện, 1 giờ SEO, 1 giờ kiểm thử)

**H: Tôi có cần tạo endpoint backend mới không?**  
A: Có, 1 endpoint mới: `GET /agents/:agentId/profile`. Các endpoint đánh giá/danh sách đã tồn tại sẵn.

**H: Tôi có thể tái sử dụng các component từ trang danh sách bất động sản không?**  
A: Được! PropertyCard, tạo metadata, cấu trúc JSON-LD đều có thể được điều chỉnh.

**H: Làm thế nào để xử lý phân trang cho danh sách/đánh giá?**  
A: Dùng cách phân trang giống trang chi tiết danh sách bất động sản (`limit`, `offset`, `page`)

**H: Còn về quốc tế hóa (i18n) thì sao?**  
A: fullName/bio của môi giới lấy từ cơ sở dữ liệu; dùng các mẫu i18n hiện có trong codebase

**H: SEO được xử lý như thế nào?**  
A: Tạo metadata phía server + schema JSON-LD LocalBusiness

---

## 📞 Hỗ trợ

Nếu bạn có câu hỏi trong quá trình triển khai:

1. **Kiểm tra tài liệu khám phá** — Hầu hết câu trả lời đều ở đó
2. **Xem lại các mẫu code** — Tất cả mẫu đều được trình bày
3. **Tham khảo các trang hiện có** — Trang chi tiết danh sách bất động sản là tài liệu tham khảo tốt nhất
4. **Tuân theo mẫu CQRS** — Được dùng xuyên suốt trong API

---

## ✅ Danh sách Kiểm tra Hoàn thành

- [ ] Đọc cả 3 tệp tài liệu
- [ ] Hiểu luồng dữ liệu
- [ ] Lên kế hoạch triển khai (5 giai đoạn)
- [ ] Tạo cấu trúc thư mục
- [ ] Triển khai endpoint backend
- [ ] Triển khai API client frontend
- [ ] Tạo page component
- [ ] Tạo các client component
- [ ] Thêm metadata SEO
- [ ] Thêm schema JSON-LD
- [ ] Kiểm thử thủ công
- [ ] Chạy kiểm tra Lighthouse
- [ ] Triển khai & theo dõi

---

**Trạng thái:** 🟢 Sẵn sàng xây dựng!

Chúc bạn triển khai thành công. Hãy tuân theo các mẫu trong codebase và bạn sẽ có một trang hồ sơ môi giới chuyên nghiệp hoạt động trong vòng một ngày.
