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,29 +1,29 @@
|
||||
# Agent Public Profile Page — Quick Reference Guide
|
||||
# Trang Hồ Sơ Công Khai Môi Giới — Hướng Dẫn Tham Khảo Nhanh
|
||||
|
||||
## 🎯 Implementation Overview
|
||||
## 🎯 Tổng Quan Triển Khai
|
||||
|
||||
### URL Pattern
|
||||
### Cấu Trúc URL
|
||||
```
|
||||
/agents/[id] # Desktop
|
||||
/agents/[id]?locale=vi # With locale (i18n)
|
||||
/en/agents/[id] # Explicit locale
|
||||
/agents/[id]?locale=vi # Với locale (i18n)
|
||||
/en/agents/[id] # Locale tường minh
|
||||
```
|
||||
|
||||
### Page Location
|
||||
### Vị Trí Trang
|
||||
```
|
||||
apps/web/app/[locale]/(public)/agents/[id]/page.tsx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 Backend Setup (API Changes Required)
|
||||
## 📦 Cấu Hình Backend (Cần Thay Đổi API)
|
||||
|
||||
### New Public Endpoint
|
||||
### Endpoint Công Khai Mới
|
||||
```http
|
||||
GET /agents/:agentId/profile
|
||||
```
|
||||
|
||||
### Response DTO
|
||||
### DTO Phản Hồi
|
||||
```typescript
|
||||
{
|
||||
id: string;
|
||||
@@ -45,7 +45,7 @@ GET /agents/:agentId/profile
|
||||
}
|
||||
```
|
||||
|
||||
### Query Handler Files to Create
|
||||
### Các File Query Handler Cần Tạo
|
||||
```
|
||||
apps/api/src/modules/agents/application/queries/get-agent-profile/
|
||||
├── get-agent-profile.query.ts
|
||||
@@ -57,72 +57,72 @@ apps/api/src/modules/agents/presentation/dto/
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Frontend Architecture
|
||||
## 🎨 Kiến Trúc Frontend
|
||||
|
||||
### Directory Structure to Create
|
||||
### Cấu Trúc Thư Mục Cần Tạo
|
||||
```
|
||||
apps/web/
|
||||
├── app/[locale]/(public)/agents/
|
||||
│ └── [id]/
|
||||
│ ├── page.tsx ← Server component (metadata, ISR)
|
||||
│ └── layout.tsx ← Optional shared layout
|
||||
│ └── layout.tsx ← Layout dùng chung tùy chọn
|
||||
│
|
||||
├── components/agents/
|
||||
│ ├── agent-detail-client.tsx ← Main interactive component
|
||||
│ ├── agent-header.tsx ← Profile info section
|
||||
│ ├── agent-listings-section.tsx ← Grid of listings
|
||||
│ └── agent-reviews-section.tsx ← Reviews with stars
|
||||
│ ├── agent-detail-client.tsx ← Component tương tác chính
|
||||
│ ├── agent-header.tsx ← Phần thông tin hồ sơ
|
||||
│ ├── agent-listings-section.tsx ← Lưới danh sách bất động sản
|
||||
│ └── agent-reviews-section.tsx ← Đánh giá với sao
|
||||
│
|
||||
└── lib/
|
||||
├── agents-api.ts ← API client
|
||||
└── agents-server.ts ← Server-side ISR fetch
|
||||
└── agents-server.ts ← Fetch phía server (ISR)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Data Flow
|
||||
## 🔄 Luồng Dữ Liệu
|
||||
|
||||
```
|
||||
1. Browser requests: /agents/[id]
|
||||
1. Trình duyệt yêu cầu: /agents/[id]
|
||||
↓
|
||||
2. Next.js generates metadata (SEO)
|
||||
2. Next.js tạo metadata (SEO)
|
||||
- Title: "Agent Name — Real Estate Agent at GoodGo"
|
||||
- Description: Bio + stats
|
||||
- Description: Bio + thống kê
|
||||
- Image: Avatar
|
||||
- Canonical URL
|
||||
↓
|
||||
3. Server-side fetch agent profile data
|
||||
3. Fetch dữ liệu hồ sơ môi giới phía server
|
||||
- GET /api/v1/agents/:id/profile (ISR: revalidate 3600s)
|
||||
↓
|
||||
4. Render Server Component with metadata + JSON-LD
|
||||
4. Render Server Component với metadata + JSON-LD
|
||||
↓
|
||||
5. Pass data to Client Component for interactivity
|
||||
- Fetch reviews in parallel
|
||||
- Fetch listings in parallel
|
||||
5. Truyền dữ liệu sang Client Component để tương tác
|
||||
- Fetch đánh giá song song
|
||||
- Fetch danh sách bất động sản song song
|
||||
↓
|
||||
6. Client renders:
|
||||
- Agent header (avatar, name, stats, badges)
|
||||
- Reviews section (star ratings, comment cards)
|
||||
- Listings section (reuse PropertyCard component)
|
||||
6. Client render:
|
||||
- Header môi giới (avatar, tên, thống kê, huy hiệu)
|
||||
- Phần đánh giá (xếp hạng sao, thẻ bình luận)
|
||||
- Phần danh sách bất động sản (tái sử dụng component PropertyCard)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎭 Component Composition
|
||||
## 🎭 Kết Hợp Component
|
||||
|
||||
### Server Component (page.tsx)
|
||||
```typescript
|
||||
export async function generateMetadata({ params }): Promise<Metadata> {
|
||||
// 1. Fetch agent using agents-server.ts
|
||||
// 2. Build SEO metadata
|
||||
// 3. Return title, description, OG, canonical
|
||||
// 1. Fetch môi giới dùng agents-server.ts
|
||||
// 2. Xây dựng metadata SEO
|
||||
// 3. Trả về title, description, OG, canonical
|
||||
}
|
||||
|
||||
export default async function AgentProfilePage({ params }) {
|
||||
// 1. Fetch agent profile (with ISR)
|
||||
// 2. Generate JSON-LD (LocalBusiness schema)
|
||||
// 3. Render <JsonLd> for structured data
|
||||
// 4. Pass agent to client component
|
||||
// 1. Fetch hồ sơ môi giới (với ISR)
|
||||
// 2. Tạo JSON-LD (schema LocalBusiness)
|
||||
// 3. Render <JsonLd> cho dữ liệu có cấu trúc
|
||||
// 4. Truyền agent sang client component
|
||||
return <>
|
||||
<JsonLd data={agentJsonLd} />
|
||||
<AgentDetailClient agent={agent} />
|
||||
@@ -140,8 +140,8 @@ export function AgentDetailClient({ agent }: Props) {
|
||||
const [reviewStats, setReviewStats] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
// Fetch agent's active listings
|
||||
// Fetch reviews & stats
|
||||
// Fetch danh sách bất động sản đang hoạt động của môi giới
|
||||
// Fetch đánh giá & thống kê
|
||||
}, [agent.id]);
|
||||
|
||||
return <>
|
||||
@@ -154,79 +154,79 @@ export function AgentDetailClient({ agent }: Props) {
|
||||
|
||||
---
|
||||
|
||||
## 🔗 API Calls Used
|
||||
## 🔗 Các API Call Được Sử Dụng
|
||||
|
||||
### Existing Public Endpoints (No Auth Required)
|
||||
### Endpoint Công Khai Hiện Có (Không Cần Xác Thực)
|
||||
```http
|
||||
# Get agent profile (NEW - to be created)
|
||||
# Lấy hồ sơ môi giới (MỚI - cần tạo)
|
||||
GET /api/v1/agents/:agentId/profile
|
||||
|
||||
# Get agent's listings (EXISTING)
|
||||
# Lấy danh sách bất động sản của môi giới (ĐÃ CÓ)
|
||||
GET /api/v1/listings?agentId=:agentId&status=ACTIVE
|
||||
|
||||
# Get agent reviews (EXISTING)
|
||||
# Lấy đánh giá môi giới (ĐÃ CÓ)
|
||||
GET /api/v1/reviews?targetType=AGENT&targetId=:agentId&limit=20
|
||||
|
||||
# Get agent review stats (EXISTING)
|
||||
# Lấy thống kê đánh giá môi giới (ĐÃ CÓ)
|
||||
GET /api/v1/reviews/stats?targetType=AGENT&targetId=:agentId
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 UI Sections & Reusable Components
|
||||
## 🎨 Các Phần UI & Component Tái Sử Dụng
|
||||
|
||||
### 1. Agent Header Section
|
||||
### 1. Phần Header Môi Giới
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ [Avatar] Name │
|
||||
│ License: ABC123 │
|
||||
│ Agency: XYZ Agency │
|
||||
│ ✓ Verified │
|
||||
│ [Avatar] Tên │
|
||||
│ Giấy phép: ABC123 │
|
||||
│ Công ty: XYZ Agency │
|
||||
│ ✓ Đã Xác Minh │
|
||||
│ │
|
||||
│ ⭐ 4.5 (120 reviews) │
|
||||
│ 📍 Serves: Quan 1, Quan 7, ... │
|
||||
│ 🏠 45 active listings │
|
||||
│ ⭐ 4.5 (120 đánh giá) │
|
||||
│ 📍 Phục vụ: Quận 1, Quận 7, ...│
|
||||
│ 🏠 45 tin đăng đang hoạt động │
|
||||
└─────────────────────────────────┘
|
||||
|
||||
Components: Card, Badge, Image, Text
|
||||
Styling: Tailwind (p-6, flex, gap-4)
|
||||
```
|
||||
|
||||
### 2. Reviews Section
|
||||
### 2. Phần Đánh Giá
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ Customer Reviews (120 total) │
|
||||
│ Đánh Giá Khách Hàng (120 tổng) │
|
||||
├─────────────────────────────────┤
|
||||
│ [Review Card] │
|
||||
│ ⭐⭐⭐⭐⭐ John Doe │ 2 days ago │
|
||||
│ "Great agent, very professional" │
|
||||
│ [Thẻ Đánh Giá] │
|
||||
│ ⭐⭐⭐⭐⭐ John Doe │ 2 ngày trước│
|
||||
│ "Môi giới tuyệt vời, rất chuyên nghiệp" │
|
||||
├─────────────────────────────────┤
|
||||
│ [Review Card] │
|
||||
│ ⭐⭐⭐⭐ Jane Smith │ 1 week ago │
|
||||
│ "Good communication" │
|
||||
│ [Thẻ Đánh Giá] │
|
||||
│ ⭐⭐⭐⭐ Jane Smith │ 1 tuần trước│
|
||||
│ "Giao tiếp tốt" │
|
||||
└─────────────────────────────────┘
|
||||
|
||||
Components: Card, Badge (rating), Avatar
|
||||
Reuse: PropertyCard padding/spacing pattern
|
||||
Components: Card, Badge (xếp hạng), Avatar
|
||||
Tái sử dụng: Kiểu padding/spacing của PropertyCard
|
||||
```
|
||||
|
||||
### 3. Listings Section
|
||||
### 3. Phần Danh Sách Bất Động Sản
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ Active Listings (45 total) │
|
||||
│ Tin Đăng Đang Hoạt Động (45) │
|
||||
├─────────────────────────────────┤
|
||||
│ [PropertyCard] [PropertyCard] │
|
||||
│ [PropertyCard] [PropertyCard] │
|
||||
│ [PropertyCard] [PropertyCard] │
|
||||
└─────────────────────────────────┘
|
||||
|
||||
Components: PropertyCard (reuse from search/property-card.tsx)
|
||||
Components: PropertyCard (tái sử dụng từ search/property-card.tsx)
|
||||
Grid: grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Copy-Paste Templates
|
||||
## 🎯 Mẫu Copy-Paste
|
||||
|
||||
### agents-api.ts
|
||||
```typescript
|
||||
@@ -263,7 +263,7 @@ const API_BASE_URL = process.env['NEXT_PUBLIC_API_URL'] || 'http://localhost:300
|
||||
export async function fetchAgentById(id: string) {
|
||||
try {
|
||||
const res = await fetch(`${API_BASE_URL}/agents/${id}/profile`, {
|
||||
next: { revalidate: 3600 } // ISR: revalidate every 1 hour
|
||||
next: { revalidate: 3600 } // ISR: revalidate mỗi 1 giờ
|
||||
});
|
||||
if (!res.ok) return null;
|
||||
return res.json();
|
||||
@@ -275,17 +275,17 @@ export async function fetchAgentById(id: string) {
|
||||
|
||||
---
|
||||
|
||||
## 🔍 SEO & Structured Data
|
||||
## 🔍 SEO & Dữ Liệu Có Cấu Trúc
|
||||
|
||||
### Metadata Hints
|
||||
### Gợi Ý Metadata
|
||||
```typescript
|
||||
title: `${agent.fullName} — Real Estate Agent at GoodGo`
|
||||
description: `${agent.bio}. Quality Score: ${agent.qualityScore}. ${agent.activeListings} active listings. ⭐ ${agent.avgReviewRating} (${agent.totalReviews} reviews)`
|
||||
|
||||
// OG Image: Use avatar or placeholder
|
||||
// OG Image: Dùng avatar hoặc ảnh thay thế
|
||||
```
|
||||
|
||||
### JSON-LD Schema
|
||||
### Schema JSON-LD
|
||||
```json
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
@@ -306,48 +306,48 @@ description: `${agent.bio}. Quality Score: ${agent.qualityScore}. ${agent.active
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Implementation Phases
|
||||
## 🚀 Các Giai Đoạn Triển Khai
|
||||
|
||||
### Phase 1: Backend (1-2 hours)
|
||||
- [ ] Create GetAgentProfileQuery
|
||||
- [ ] Create GetAgentProfileHandler
|
||||
- [ ] Create AgentPublicProfileDto
|
||||
- [ ] Add endpoint to AgentsController
|
||||
- [ ] Update AgentRepository interface
|
||||
- [ ] Implement in PrismaAgentRepository
|
||||
- [ ] Test with Postman/curl
|
||||
### Giai Đoạn 1: Backend (1-2 giờ)
|
||||
- [ ] Tạo GetAgentProfileQuery
|
||||
- [ ] Tạo GetAgentProfileHandler
|
||||
- [ ] Tạo AgentPublicProfileDto
|
||||
- [ ] Thêm endpoint vào AgentsController
|
||||
- [ ] Cập nhật interface AgentRepository
|
||||
- [ ] Triển khai trong PrismaAgentRepository
|
||||
- [ ] Kiểm tra với Postman/curl
|
||||
|
||||
### Phase 2: Frontend Setup (1 hour)
|
||||
- [ ] Create agents-api.ts
|
||||
- [ ] Create agents-server.ts
|
||||
- [ ] Create agents folder structure
|
||||
- [ ] Create [id]/page.tsx (stub)
|
||||
- [ ] Import types from agents-api.ts
|
||||
### Giai Đoạn 2: Cài Đặt Frontend (1 giờ)
|
||||
- [ ] Tạo agents-api.ts
|
||||
- [ ] Tạo agents-server.ts
|
||||
- [ ] Tạo cấu trúc thư mục agents
|
||||
- [ ] Tạo [id]/page.tsx (stub)
|
||||
- [ ] Import kiểu từ agents-api.ts
|
||||
|
||||
### Phase 3: UI Components (2-3 hours)
|
||||
- [ ] Create AgentHeader component
|
||||
- [ ] Create AgentReviewsSection component
|
||||
- [ ] Create AgentListingsSection component
|
||||
- [ ] Create RatingStars/ReviewCard components
|
||||
- [ ] Wire up data fetching
|
||||
### Giai Đoạn 3: Các Component UI (2-3 giờ)
|
||||
- [ ] Tạo component AgentHeader
|
||||
- [ ] Tạo component AgentReviewsSection
|
||||
- [ ] Tạo component AgentListingsSection
|
||||
- [ ] Tạo các component RatingStars/ReviewCard
|
||||
- [ ] Kết nối việc fetch dữ liệu
|
||||
|
||||
### Phase 4: SEO & Polish (1 hour)
|
||||
- [ ] Add generateMetadata()
|
||||
- [ ] Generate JSON-LD schemas
|
||||
- [ ] Test OG preview
|
||||
- [ ] Mobile responsive check
|
||||
- [ ] Dark mode testing
|
||||
### Giai Đoạn 4: SEO & Hoàn Thiện (1 giờ)
|
||||
- [ ] Thêm generateMetadata()
|
||||
- [ ] Tạo schema JSON-LD
|
||||
- [ ] Kiểm tra xem trước OG
|
||||
- [ ] Kiểm tra responsive trên di động
|
||||
- [ ] Kiểm tra chế độ tối
|
||||
|
||||
### Phase 5: Testing (1 hour)
|
||||
- [ ] Manual e2e test
|
||||
- [ ] Check 404 handling
|
||||
- [ ] Verify ISR revalidation
|
||||
- [ ] Test pagination (listings/reviews)
|
||||
- [ ] SEO audit (Lighthouse)
|
||||
### Giai Đoạn 5: Kiểm Thử (1 giờ)
|
||||
- [ ] Kiểm thử e2e thủ công
|
||||
- [ ] Kiểm tra xử lý lỗi 404
|
||||
- [ ] Xác minh việc revalidate ISR
|
||||
- [ ] Kiểm tra phân trang (danh sách/đánh giá)
|
||||
- [ ] Kiểm tra SEO (Lighthouse)
|
||||
|
||||
---
|
||||
|
||||
## 📊 Example Response Structure
|
||||
## 📊 Ví Dụ Cấu Trúc Phản Hồi
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -371,10 +371,10 @@ description: `${agent.bio}. Quality Score: ${agent.qualityScore}. ${agent.active
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Key Files Reference
|
||||
## 🎯 Tham Khảo Các File Chính
|
||||
|
||||
| Phase | Files to Create/Modify |
|
||||
|-------|------------------------|
|
||||
| Giai Đoạn | File Cần Tạo/Chỉnh Sửa |
|
||||
|-----------|------------------------|
|
||||
| Backend | `agents/application/queries/get-agent-profile/*` |
|
||||
| Backend | `agents/presentation/controllers/agents.controller.ts` |
|
||||
| Backend | `agents/presentation/dto/agent-public-profile.dto.ts` |
|
||||
@@ -385,4 +385,3 @@ description: `${agent.bio}. Quality Score: ${agent.qualityScore}. ${agent.active
|
||||
| Frontend | `components/agents/agent-header.tsx` |
|
||||
| Frontend | `components/agents/agent-reviews-section.tsx` |
|
||||
| Frontend | `components/agents/agent-listings-section.tsx` |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user