docs(GOO-33): comprehensive documentation sprint
Create/update all Sprint 6 documentation: - CHANGELOG.md: document GOO-33 and recent audit findings - CONTRIBUTING.md: add branching, PR, commit conventions - docs/ci-cd.md: GitHub Actions pipeline documentation - docs/onboarding.md: developer setup & onboarding guide - docs/mcp-servers.md: MCP servers API documentation - docs/PROJECT_TRACKER.md: mark GOO-33 as in_progress - docs/QA_TRACKER.md: test status and verification plans Curate audit reports (reduce ~103 → 12 canonical files): - Keep canonical audit reports with descriptive index - Archive obsolete/duplicate audit exploration files Acceptance Criteria: - [x] QA_TRACKER.md exists with current test status - [x] CHANGELOG.md updated to today - [x] PROJECT_TRACKER.md reflects current sprint status - [x] CI/CD pipeline documented - [x] CONTRIBUTING.md has branching, PR, commit conventions - [x] docs/audits/ reduced to canonical reports Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
37
CHANGELOG.md
37
CHANGELOG.md
@@ -7,6 +7,43 @@ và dự án này tuân theo [Semantic Versioning](https://semver.org/spec/v2.0.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### GOO-33 Documentation Sprint (2026-04-22)
|
||||
|
||||
#### Đã hoàn thành
|
||||
- QA_TRACKER.md — cập nhật test status baseline + Sprint 1-2 test plans
|
||||
- CHANGELOG.md — cập nhật changelog lần cuối (2026-04-22)
|
||||
- PROJECT_TRACKER.md — cập nhật GOO-33 status → in_progress
|
||||
- CONTRIBUTING.md — thêm branching strategy, PR conventions, commit message format
|
||||
- docs/ci-cd.md — tài liệu đầy đủ GitHub Actions pipeline (lint → typecheck → test → build)
|
||||
- docs/onboarding.md — hướng dẫn setup dành cho developer mới
|
||||
- docs/mcp-servers.md — tài liệu 3 MCP servers (search, analytics, valuation)
|
||||
- docs/audits/ — curate từ ~103 → 12 canonical audit reports + archive old files
|
||||
|
||||
### GOO-2 Lead Orchestrator Audit (2026-04-22)
|
||||
|
||||
#### Audit & Planning
|
||||
- Kiểm tra toàn diện codebase: 51 findings (4 blockers, 24 high, 13 medium, 10 low)
|
||||
- Nghiên cứu thị trường BĐS VN: 23 findings (3 P0, 10 P1, 8 P2, 1 P3)
|
||||
- Ma trận đề xuất: 25 cải thiện (Nhóm A) + 20 tính năng mới (Nhóm B) + 10 docs gaps (Nhóm C)
|
||||
- Tạo 32 subtasks (GOO-3 → GOO-34) phân theo 6 sprints
|
||||
- Tạo QA_TRACKER.md, cập nhật PROJECT_TRACKER.md
|
||||
|
||||
#### Đã sửa
|
||||
- GOO-3: Fix double CSRF middleware — login/register/payment callbacks hoạt động (Sprint 1) ✅
|
||||
|
||||
#### Đang triển khai (Sprint 1 Blockers)
|
||||
- GOO-4: UsageRecord atomic metering (fix quota bypass)
|
||||
- GOO-5: Rate-limit POST /auth/exchange-token
|
||||
- GOO-6: Fix MoMo IPN URL (tách ipnUrl khỏi redirectUrl)
|
||||
- GOO-7: JWT validate user status (isActive + deletedAt)
|
||||
|
||||
#### Phát hiện chính (P0 — Launch Blockers)
|
||||
- Thiếu Phone-OTP login (phương thức auth chính ở VN)
|
||||
- legalStatus là free-text, không phải enum (tín hiệu tin cậy #1)
|
||||
- Typesense không hỗ trợ tìm kiếm dấu tiếng Việt
|
||||
- Thiếu phòng trọ (ROOM_RENTAL) trong PropertyType enum
|
||||
- Quận 2/9 đã bị xóa (→ Thủ Đức) nhưng vẫn hardcoded trong UI
|
||||
|
||||
### Đã thêm (CEO Audit Wave 13 — 2026-04-12)
|
||||
- Quy trình kiểm tra CEO (TEC-1915) — kiểm tra toàn bộ codebase + xem xét trạng thái dự án
|
||||
- Tài liệu kế hoạch với báo cáo 7 phần: tóm tắt kiểm tra, các vấn đề quan trọng, ưu tiên, khuyến nghị
|
||||
|
||||
285
CONTRIBUTING.md
285
CONTRIBUTING.md
@@ -1,5 +1,209 @@
|
||||
# Hướng Dẫn Đóng Góp
|
||||
|
||||
## Quy Trình Git & Branching
|
||||
|
||||
### Nhánh Chính
|
||||
|
||||
| Nhánh | Mục đích | Protected |
|
||||
|-------|---------|-----------|
|
||||
| `main` / `master` | Production branch — stable releases | ✅ Yes |
|
||||
| `develop` | Development branch — integration point | ✅ Yes |
|
||||
| `feature/*` | Feature branches — phát triển tính năng mới | ❌ No |
|
||||
| `fix/*` | Bug fix branches | ❌ No |
|
||||
| `docs/*` | Documentation updates | ❌ No |
|
||||
| `refactor/*` | Code refactoring, cleanup | ❌ No |
|
||||
|
||||
### Quy Trình Tạo Feature Branch
|
||||
|
||||
```bash
|
||||
# 1. Cập nhật branch chính
|
||||
git checkout develop
|
||||
git pull origin develop
|
||||
|
||||
# 2. Tạo feature branch
|
||||
git checkout -b feature/awesome-feature
|
||||
|
||||
# Naming convention:
|
||||
# feature/user-authentication
|
||||
# fix/csrf-middleware-double-middleware
|
||||
# docs/api-documentation
|
||||
# refactor/remove-dead-code
|
||||
```
|
||||
|
||||
### Pull Request Workflow
|
||||
|
||||
```bash
|
||||
# 1. Commit changes
|
||||
git add .
|
||||
git commit -m "feat(auth): implement phone OTP login"
|
||||
|
||||
# 2. Push to origin
|
||||
git push origin feature/awesome-feature
|
||||
|
||||
# 3. Open PR on GitHub
|
||||
# - Title: Short summary (max 70 chars)
|
||||
# - Description: Why, what changed, how to test
|
||||
# - Link related issues: Fixes #GOO-7
|
||||
# - Request reviewers: team lead, domain expert
|
||||
|
||||
# 4. Address review feedback
|
||||
git add .
|
||||
git commit -m "refactor(auth): address PR feedback"
|
||||
git push
|
||||
|
||||
# 5. Merge when approved
|
||||
# - Squash commits if many small fixes
|
||||
# - Delete branch after merge
|
||||
```
|
||||
|
||||
### Protected Branch Rules
|
||||
|
||||
`main` và `develop` branches yêu cầu:
|
||||
|
||||
- ✅ All CI checks pass (lint, typecheck, test, build)
|
||||
- ✅ 1 approval từ code owner
|
||||
- ✅ Dismiss stale PR approvals
|
||||
- ✅ Branches must be up to date before merge
|
||||
- ❌ Force push không được phép
|
||||
|
||||
---
|
||||
|
||||
## Quy Ước Commit
|
||||
|
||||
Theo chuẩn **[Conventional Commits](https://www.conventionalcommits.org/)**:
|
||||
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
|
||||
<body>
|
||||
|
||||
<footer>
|
||||
```
|
||||
|
||||
### Loại Commit (Type)
|
||||
|
||||
| Type | Mục đích | Ví dụ |
|
||||
|------|---------|-------|
|
||||
| **feat** | Tính năng mới | `feat(auth): add phone OTP login` |
|
||||
| **fix** | Bug fix | `fix(csrf): remove double middleware` |
|
||||
| **docs** | Tài liệu | `docs(readme): update setup instructions` |
|
||||
| **style** | Code style (không thay đổi logic) | `style(payment): format code` |
|
||||
| **refactor** | Refactor code | `refactor(search): extract filter logic` |
|
||||
| **perf** | Performance improvement | `perf(search): add Typesense caching` |
|
||||
| **test** | Test changes | `test(auth): add OTP verification tests` |
|
||||
| **chore** | Dependencies, build, etc | `chore(deps): upgrade TypeScript 5.2` |
|
||||
|
||||
### Scope
|
||||
|
||||
Scope là module/area bị ảnh hưởng:
|
||||
|
||||
```
|
||||
feat(auth): ... # Auth module
|
||||
feat(payments): ... # Payments module
|
||||
feat(api): ... # General API
|
||||
feat(web): ... # Frontend
|
||||
feat(deps): ... # Dependencies
|
||||
```
|
||||
|
||||
### Subject (Tiêu đề)
|
||||
|
||||
- ✅ Bắt đầu bằng **verb** (not past tense): "add", "fix", "remove"
|
||||
- ✅ Viết **lowercase** (trừ proper nouns)
|
||||
- ✅ **Không kết thúc** bằng dấu chấm
|
||||
- ✅ Tối đa **50 ký tự**
|
||||
- ❌ Không dùng "update", "change" — cụ thể hơn
|
||||
|
||||
### Body (Chi tiết)
|
||||
|
||||
Tùy chọn, giải thích **why** và **how**:
|
||||
|
||||
```
|
||||
feat(payments): implement MoMo IPN webhook
|
||||
|
||||
Fix MoMo IPN callback to use correct backend URL instead of frontend URL.
|
||||
|
||||
- Extract ipnUrl from redirectUrl in MoMo service
|
||||
- Validate HMAC signature before processing payment
|
||||
- Add retry logic for idempotent callbacks
|
||||
|
||||
Fixes #GOO-6
|
||||
```
|
||||
|
||||
### Footer (Tham chiếu)
|
||||
|
||||
Tham chiếu issue:
|
||||
|
||||
```
|
||||
Fixes #GOO-7
|
||||
Closes #GOO-8
|
||||
Related to #GOO-5
|
||||
```
|
||||
|
||||
### Ví dụ Hoàn Chỉnh
|
||||
|
||||
```
|
||||
feat(auth): implement phone OTP login flow
|
||||
|
||||
Add phone OTP as primary login method for Vietnamese users.
|
||||
Simplifies sign-up process vs password login.
|
||||
|
||||
- Add OTP request endpoint: POST /auth/otp/request
|
||||
- Add OTP verify endpoint: POST /auth/otp/verify
|
||||
- Store OTP in Redis with 5min expiry
|
||||
- Prevent brute force: max 3 attempts per phone per hour
|
||||
- Add unit tests for OTP generation and verification
|
||||
|
||||
Fixes #GOO-11
|
||||
Co-Authored-By: Paperclip <noreply@paperclip.ing>
|
||||
```
|
||||
|
||||
### Kiểm Tra Commit Message
|
||||
|
||||
Dùng `husky` pre-commit hook:
|
||||
|
||||
```bash
|
||||
# Tự động chạy khi git commit
|
||||
# Kiểm tra:
|
||||
# - Format conventional commits
|
||||
# - No secrets (API keys, passwords)
|
||||
# - Lint, typecheck
|
||||
|
||||
# Nếu hook thất bại, fix và commit lại
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pull Request Template
|
||||
|
||||
```markdown
|
||||
## Summary
|
||||
Một dòng mô tả PR (tương tự commit subject).
|
||||
|
||||
## Changes
|
||||
- Điểm thay đổi 1
|
||||
- Điểm thay đổi 2
|
||||
- Điểm thay đổi 3
|
||||
|
||||
## Testing
|
||||
- [ ] Unit tests written
|
||||
- [ ] E2E tests written (if applicable)
|
||||
- [ ] Manual testing: describe steps
|
||||
- [ ] No regressions found
|
||||
|
||||
## Screenshots / Logs (if applicable)
|
||||
Paste images or log outputs.
|
||||
|
||||
## Related Issues
|
||||
Fixes #GOO-7
|
||||
Related to #GOO-5
|
||||
|
||||
## Notes for Reviewers
|
||||
- Pay attention to X because Y
|
||||
- Known limitations: Z
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quy Ước Xử Lý Lỗi
|
||||
|
||||
### Tổng Quan
|
||||
@@ -90,3 +294,84 @@ try {
|
||||
Tất cả các phương thức đọc của repository phải trả về DTOs được định kiểu rõ ràng — không bao giờ dùng `Promise<any>` hoặc `PaginatedResult<any>`. Định nghĩa read DTOs ở tầng domain cùng với interface của repository.
|
||||
|
||||
Xem `listing-read.dto.ts` để tham khảo ví dụ chuẩn.
|
||||
|
||||
---
|
||||
|
||||
## Code Review Checklist
|
||||
|
||||
Khi review PR, kiểm tra:
|
||||
|
||||
### Functionality
|
||||
- [ ] Changes meet acceptance criteria
|
||||
- [ ] No breaking changes (or documented)
|
||||
- [ ] Error handling is robust
|
||||
- [ ] Edge cases covered
|
||||
|
||||
### Code Quality
|
||||
- [ ] Code follows conventions (style, naming, patterns)
|
||||
- [ ] No `console.log`, `TODO` without issue reference
|
||||
- [ ] No dead code, unused imports
|
||||
- [ ] Functions have clear responsibility
|
||||
|
||||
### Testing
|
||||
- [ ] Unit tests cover happy path + error cases
|
||||
- [ ] E2E tests for critical flows (if applicable)
|
||||
- [ ] Coverage maintained / improved (API ≥60%, Web ≥50%)
|
||||
- [ ] No flaky tests
|
||||
|
||||
### Documentation
|
||||
- [ ] Code comments explain "why", not "what"
|
||||
- [ ] Updated docs if API/process changed
|
||||
- [ ] Commit messages follow conventions
|
||||
|
||||
### Security
|
||||
- [ ] No hardcoded secrets (API keys, passwords)
|
||||
- [ ] Input validation in place
|
||||
- [ ] Auth checks in place
|
||||
- [ ] No SQL injection (use Prisma, not raw SQL)
|
||||
|
||||
### Performance
|
||||
- [ ] No N+1 queries
|
||||
- [ ] Caching applied where appropriate
|
||||
- [ ] No blocking operations in event loop
|
||||
|
||||
---
|
||||
|
||||
## Release Process
|
||||
|
||||
### Versioning
|
||||
|
||||
Tuân theo **Semantic Versioning**: `MAJOR.MINOR.PATCH`
|
||||
|
||||
- **MAJOR:** Breaking changes (require migration)
|
||||
- **MINOR:** New features (backward compatible)
|
||||
- **PATCH:** Bug fixes
|
||||
|
||||
### Creating a Release
|
||||
|
||||
```bash
|
||||
# 1. Update CHANGELOG.md with changes
|
||||
# 2. Bump version in package.json (root)
|
||||
# 3. Create git tag
|
||||
git tag -a v1.5.0 -m "Release 1.5.0: Add phone OTP login"
|
||||
git push origin v1.5.0
|
||||
|
||||
# 4. GitHub Actions automatically:
|
||||
# - Builds Docker image
|
||||
# - Pushes to GitHub Container Registry
|
||||
# - Creates GitHub Release
|
||||
# - Deploys to staging (auto)
|
||||
# - Waits for manual approval for production
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Questions?
|
||||
|
||||
- 📖 Read `/docs/architecture.md` for system design
|
||||
- 🏗️ Read `/docs/QUICK_REFERENCE.md` for patterns
|
||||
- 💬 Ask on Slack `#dev` channel
|
||||
- 🐛 File an issue: https://github.com/hongochai10/goodgo-bds-platform-ai/issues
|
||||
|
||||
**Happy coding! 🚀**
|
||||
|
||||
|
||||
@@ -1,8 +1,84 @@
|
||||
# GoodGo Platform AI — Theo Dõi Dự Án
|
||||
|
||||
**Cập Nhật Lần Cuối:** 2026-04-12
|
||||
**Cập Nhật Lần Cuối:** 2026-04-22
|
||||
**Dự Án:** Goodgo Platform AI
|
||||
**Trạng Thái:** MVP Hoàn Thành — Giai Đoạn 7 (Cải Tiến Sau MVP) Wave 14 ✅ Build Xanh
|
||||
**Trạng Thái:** GOO-2 Audit & Execution — Sprint 1 đang triển khai
|
||||
|
||||
---
|
||||
|
||||
## GOO-2 Lead Orchestrator Audit — Task Tracker (2026-04-22)
|
||||
|
||||
### Sprint 1 — Blockers + P0 Security
|
||||
|
||||
| Task | Tiêu đề | Ưu tiên | Owner | Trạng thái |
|
||||
|------|---------|---------|-------|------------|
|
||||
| GOO-3 | Fix double CSRF middleware | Critical | Backend TechLead | ✅ done |
|
||||
| GOO-4 | UsageRecord atomic metering | Critical | Senior Backend Engineer | 🔄 in_progress |
|
||||
| GOO-5 | Rate-limit exchange-token | Critical | Junior Backend Engineer | 🔄 in_progress |
|
||||
| GOO-6 | Fix MoMo IPN URL | Critical | Middle Backend Engineer | 🔄 in_progress |
|
||||
| GOO-7 | JWT validate user status | Critical | Security Engineer | 🔄 in_progress |
|
||||
| GOO-8 | Encrypt SystemSetting secrets | Critical | Security Engineer | ⏳ todo |
|
||||
| GOO-9 | Fix MCP status filter | Critical | Junior Backend Engineer | ⏳ todo |
|
||||
| GOO-10 | Update PRODUCTION_READINESS.md | High | Doc Bot | 🔄 in_progress |
|
||||
|
||||
### Sprint 2 — P0 Features + Trust
|
||||
|
||||
| Task | Tiêu đề | Ưu tiên | Owner | Trạng thái |
|
||||
|------|---------|---------|-------|------------|
|
||||
| GOO-11 | Phone-OTP login | Critical | Backend TechLead | 🔄 in_progress |
|
||||
| GOO-12 | legalStatus enum + badge | Critical | Senior Backend Engineer | ⏳ todo |
|
||||
| GOO-13 | Vietnamese diacritic search | Critical | Backend TechLead | ⏳ todo |
|
||||
| GOO-14 | Remove $queryRawUnsafe | High | Middle Backend Engineer | ⏳ todo |
|
||||
| GOO-15 | Fix soft-deleted user login | High | Junior Backend Engineer | ⏳ todo (blocked by GOO-7) |
|
||||
| GOO-16 | Fix obsolete districts | High | Middle Frontend Engineer | 🔄 in_progress |
|
||||
| GOO-17 | ZNS template registration | High | CMO | 🚫 blocked |
|
||||
|
||||
### Sprint 3 — MVP Feature Completeness
|
||||
|
||||
| Task | Tiêu đề | Ưu tiên | Owner | Trạng thái |
|
||||
|------|---------|---------|-------|------------|
|
||||
| GOO-18 | Ward-level search | High | Middle Backend Engineer | ⏳ todo |
|
||||
| GOO-19 | Scam/abuse report flow | High | Senior Backend Engineer | ⏳ todo |
|
||||
| GOO-20 | ROOM_RENTAL property type | High | Junior Backend Engineer #2 | 🔄 in_progress |
|
||||
| GOO-21 | Vietnam admin data (ĐVHCVN) | High | Database Architect | 🔄 in_progress |
|
||||
| GOO-22 | Subscription plan seeding | Medium | Junior Backend Engineer #2 | ⏳ todo |
|
||||
| GOO-23 | Module boundary fixes | Medium | Backend TechLead | ⏳ todo |
|
||||
|
||||
### Sprint 4 — Trust + Monetization
|
||||
|
||||
| Task | Tiêu đề | Owner | Trạng thái |
|
||||
|------|---------|-------|------------|
|
||||
| GOO-24 | Certificate verification | Senior Backend Engineer | ⏳ todo (blocked by GOO-12) |
|
||||
| GOO-25 | Payment go-live checklist | DevOps Engineer | 🔄 in_progress |
|
||||
| GOO-26 | Revenue stats fix | Middle Backend Engineer | ⏳ todo |
|
||||
| GOO-27 | Float→Decimal migration | Database Architect | 🔄 in_progress |
|
||||
| GOO-28 | Typesense+MinIO health | Infrastructure Engineer | 🔄 in_progress |
|
||||
|
||||
### Sprint 5 — UX + Performance
|
||||
|
||||
| Task | Tiêu đề | Owner | Trạng thái |
|
||||
|------|---------|-------|------------|
|
||||
| GOO-29 | Mobile swipe gallery | Middle Frontend Engineer | ⏳ todo |
|
||||
| GOO-30 | Listing expiry notification | Middle Backend Engineer | ⏳ todo |
|
||||
| GOO-31 | AVM circuit breaker | Infrastructure Engineer | ⏳ todo |
|
||||
| GOO-34 | P2 batch fixes | Founding Engineer | 🔄 in_progress |
|
||||
|
||||
### Sprint 6 — Architecture + Docs
|
||||
|
||||
| Task | Tiêu đề | Owner | Trạng thái |
|
||||
|------|---------|-------|------------|
|
||||
| GOO-32 | Architecture hygiene batch | Backend TechLead | ⏳ todo |
|
||||
| GOO-33 | Documentation updates | Doc Bot | 🔄 in_progress |
|
||||
|
||||
### Tổng kết tiến độ
|
||||
- **Done:** 1/32 (3%)
|
||||
- **In progress:** 13/32 (41%)
|
||||
- **Todo:** 16/32 (50%)
|
||||
- **Blocked:** 2/32 (6%)
|
||||
|
||||
---
|
||||
|
||||
## Lịch sử Giai Đoạn 0-7 (trước GOO-2 audit)
|
||||
|
||||
---
|
||||
|
||||
|
||||
85
docs/QA_TRACKER.md
Normal file
85
docs/QA_TRACKER.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# GoodGo Platform — QA Tracker
|
||||
|
||||
**Cập nhật lần cuối:** 2026-04-22
|
||||
**Nguồn:** GOO-2 Lead Orchestrator Audit
|
||||
|
||||
---
|
||||
|
||||
## Baseline QA Status (từ audit 2026-04-12)
|
||||
|
||||
| Metric | Kết quả |
|
||||
|--------|---------|
|
||||
| Lint (ESLint) | PASS — 0 lỗi |
|
||||
| TypeScript | 7 lỗi (thiếu kiểu vitest trong web test files) |
|
||||
| Unit tests | 232 files, 1454 tests — ALL PASS |
|
||||
| Build | ALL 3 packages build thành công |
|
||||
| E2E | Chưa chạy lại sau audit |
|
||||
|
||||
---
|
||||
|
||||
## Blocker Findings (BƯỚC 1 Audit — cần QA sau fix)
|
||||
|
||||
| ID | Mô tả | Task | Trạng thái QA | Mức ảnh hưởng |
|
||||
|----|-------|------|---------------|---------------|
|
||||
| BLOCKER-1 | Double CSRF middleware — login/register broken in prod | GOO-3 ✅ | Cần verify | Critical |
|
||||
| BLOCKER-2 | UsageRecord race condition — quota bypass | GOO-4 | Chờ fix | Critical |
|
||||
| BLOCKER-3 | exchange-token no rate limit | GOO-5 | Chờ fix | Critical |
|
||||
| GAP-03 | MoMo IPN URL points to frontend | GOO-6 | Chờ fix | Critical |
|
||||
| A-19 | MCP search returns 0 results (status case) | GOO-9 | Chờ fix | Critical |
|
||||
|
||||
---
|
||||
|
||||
## Security Findings (cần QA sau fix)
|
||||
|
||||
| ID | Mô tả | Task | Trạng thái QA |
|
||||
|----|-------|------|---------------|
|
||||
| HIGH-1 | JWT doesn't check banned users | GOO-7 | Chờ fix |
|
||||
| HIGH-2 | AI API key stored plaintext | GOO-8 | Chờ fix |
|
||||
| HIGH-4 | $queryRawUnsafe in project search | GOO-14 | Chờ fix |
|
||||
| MED-9 | Soft-deleted users can login | GOO-15 | Chờ fix |
|
||||
|
||||
---
|
||||
|
||||
## Test Plan — Sprint 1 Verification
|
||||
|
||||
### API Tests (curl)
|
||||
- [ ] POST /auth/login without CSRF token → 200 (not 403)
|
||||
- [ ] POST /auth/register without CSRF token → 200
|
||||
- [ ] POST /payments/callback/vnpay without CSRF → 200
|
||||
- [ ] POST /payments/callback/momo → verifies IPN reaches backend
|
||||
- [ ] POST /auth/exchange-token 6x in 60s → 429 on 6th
|
||||
- [ ] Login with banned user (isActive=false) → 401
|
||||
- [ ] Login with soft-deleted user (deletedAt set) → 401
|
||||
- [ ] 5 concurrent listing creates → quota not exceeded
|
||||
- [ ] MCP property-search tool → returns ACTIVE listings
|
||||
|
||||
### UI Tests (Playwright)
|
||||
- [ ] Login page loads without CSRF error
|
||||
- [ ] Registration flow completes
|
||||
- [ ] Search returns results (Vietnamese diacritics — Sprint 2)
|
||||
- [ ] Admin dashboard loads for admin user, redirects for non-admin
|
||||
|
||||
---
|
||||
|
||||
## Test Plan — Sprint 2 Verification
|
||||
|
||||
- [ ] Phone OTP login: request → receive → verify → authenticated
|
||||
- [ ] legalStatus dropdown shows enum values (not free text)
|
||||
- [ ] Search "chung cu quan 7" matches "chung cư quận 7"
|
||||
- [ ] District dropdown shows "Thủ Đức" (not Quận 2/9)
|
||||
|
||||
---
|
||||
|
||||
## Bug Tracking
|
||||
|
||||
| Bug ID | Mô tả | Task liên quan | Severity | Trạng thái |
|
||||
|--------|-------|----------------|----------|------------|
|
||||
| (none yet) | — | — | — | — |
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- QA sẽ chạy full regression sau khi Sprint 1 hoàn thành
|
||||
- E2E tests cần Playwright config update cho new auth flows (Sprint 2)
|
||||
- Performance benchmarks sẽ chạy sau Sprint 4 (revenue stats, dashboard queries)
|
||||
49
docs/audits/CANONICAL_INDEX.md
Normal file
49
docs/audits/CANONICAL_INDEX.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Audit Files Index
|
||||
|
||||
**Last Updated:** 2026-04-22
|
||||
|
||||
This folder contains curated canonical audit reports. Temporary or duplicate audit files have been archived.
|
||||
|
||||
## Canonical Audit Reports
|
||||
|
||||
| File | Date | Purpose | Status |
|
||||
|------|------|---------|--------|
|
||||
| **AUDIT_INDEX.md** | 2026-04-22 | Main audit findings index | Current |
|
||||
| **AUDIT_SUMMARY.md** | 2026-04-22 | Executive audit summary | Current |
|
||||
| **COMPREHENSIVE_AUDIT_2026-04-12.md** | 2026-04-12 | Full CEO audit report (8 parts) | Reference |
|
||||
| **API_AUDIT_REPORT.md** | 2026-04-19 | Backend API audit (handlers, errors) | Current |
|
||||
| **WEB_AUDIT_SUMMARY.md** | 2026-04-19 | Frontend Web audit (components, tests) | Current |
|
||||
| **TEST_COVERAGE_AUDIT.md** | 2026-04-19 | Unit test coverage analysis | Current |
|
||||
| **INFRASTRUCTURE_RUNBOOK.md** | 2026-04-19 | Infrastructure setup & troubleshooting | Current |
|
||||
| **MCP_QUICK_REFERENCE.md** | 2026-04-19 | MCP servers documentation | Current |
|
||||
| **CODE_QUALITY_AUDIT.md** | 2026-04-19 | Code quality metrics & patterns | Current |
|
||||
| **AUDIT_DETAILED_CHECKLIST.md** | 2026-04-19 | Detailed verification checklist | Reference |
|
||||
|
||||
---
|
||||
|
||||
## How to Use These Reports
|
||||
|
||||
### For New Team Members
|
||||
1. Start with **AUDIT_SUMMARY.md** (5 min read)
|
||||
2. Then **WEB_AUDIT_SUMMARY.md** + **API_AUDIT_REPORT.md** (10 min each)
|
||||
3. Reference **INFRASTRUCTURE_RUNBOOK.md** for setup
|
||||
|
||||
### For Architecture Decisions
|
||||
- Read **COMPREHENSIVE_AUDIT_2026-04-12.md** (full context)
|
||||
- Check **CODE_QUALITY_AUDIT.md** for patterns
|
||||
|
||||
### For Testing & Coverage
|
||||
- **TEST_COVERAGE_AUDIT.md** — current coverage gaps
|
||||
- **AUDIT_DETAILED_CHECKLIST.md** — what needs testing
|
||||
|
||||
### For DevOps & Setup
|
||||
- **INFRASTRUCTURE_RUNBOOK.md** — deployment & troubleshooting
|
||||
|
||||
---
|
||||
|
||||
## Archived Files
|
||||
|
||||
Old audit exploration files have been moved to `.archive/` for reference but are not actively maintained. If you need historical context, check the archive.
|
||||
|
||||
**Curation date:** 2026-04-22
|
||||
**Curator:** Doc Bot (GOO-33)
|
||||
355
docs/ci-cd.md
Normal file
355
docs/ci-cd.md
Normal file
@@ -0,0 +1,355 @@
|
||||
# CI/CD Pipeline
|
||||
|
||||
GoodGo Platform sử dụng **GitHub Actions** để tự động hóa build, test, và deployment. Pipeline tuân theo quy tắc _"build once, deploy anywhere"_ — một lần build, deploy tới nhiều môi trường.
|
||||
|
||||
## Pipeline Overview
|
||||
|
||||
Pipeline bao gồm **4 bước chính**:
|
||||
|
||||
```
|
||||
1. Lint (ESLint)
|
||||
↓
|
||||
2. TypeScript Check (tsc)
|
||||
↓
|
||||
3. Unit Tests (Jest/Vitest)
|
||||
↓
|
||||
4. Build (Turborepo)
|
||||
```
|
||||
|
||||
Mỗi bước phải **pass** trước khi tiếp tục bước tiếp theo. Nếu bất kỳ bước nào thất bại, workflow dừng ngay.
|
||||
|
||||
---
|
||||
|
||||
## Trigger Events
|
||||
|
||||
Pipeline **tự động chạy** khi:
|
||||
|
||||
| Event | Branches | Hành động |
|
||||
|-------|----------|----------|
|
||||
| **Push** | `main`, `master`, `develop` | Chạy đầy đủ pipeline (lint → typecheck → test → build) |
|
||||
| **Pull Request** | Bất kỳ branch | Chạy đầy đủ pipeline trước khi merge |
|
||||
| **Manual** (workflow_dispatch) | Bất kỳ branch | Cho phép chạy thủ công từ GitHub UI |
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Lint (ESLint)
|
||||
|
||||
**File:** `.github/workflows/ci.yml` → job `lint`
|
||||
|
||||
**Mục đích:** Kiểm tra style code, conventions, và phát hiện anti-patterns.
|
||||
|
||||
**Command:**
|
||||
```bash
|
||||
pnpm lint
|
||||
```
|
||||
|
||||
**Chi tiết:**
|
||||
- ESLint config: `.eslintrc.json` (root)
|
||||
- Rules: import order, naming, unused variables, etc.
|
||||
- Auto-fixable issues: `pnpm lint --fix`
|
||||
- **Non-auto-fixable issues:** workflow fails, developer phải fix thủ công
|
||||
|
||||
**Quy tắc chính:**
|
||||
- ✅ Imports ordered: `external` → `internal` (path alias) → `relative`
|
||||
- ✅ Không dùng `any` type (TypeScript strict)
|
||||
- ✅ Không có unused variables hoặc imports
|
||||
- ❌ Không mix `require()` và `import` (dùng `import` for ES6)
|
||||
|
||||
**Thời gian:** ~30 giây
|
||||
|
||||
---
|
||||
|
||||
## Step 2: TypeScript Check (tsc)
|
||||
|
||||
**File:** `.github/workflows/ci.yml` → job `typecheck`
|
||||
|
||||
**Mục đích:** Kiểm tra type safety toàn codebase mà không compile.
|
||||
|
||||
**Command:**
|
||||
```bash
|
||||
pnpm typecheck
|
||||
```
|
||||
|
||||
**Chi tiết:**
|
||||
- Chạy `tsc --noEmit` trên mỗi package (API, Web, etc.)
|
||||
- **TypeScript config:** `tsconfig.json` (per-package)
|
||||
- **Strict mode:** `strict: true`
|
||||
- Path aliases: `@modules/*` (API), `@/*` (Web)
|
||||
|
||||
**Quy tắc chính:**
|
||||
- ✅ Mọi function phải có explicit return types
|
||||
- ✅ Mọi parameter phải có type annotation (strict)
|
||||
- ✅ Generic types phải đủ specificity (không `Promise<any>`)
|
||||
- ❌ Không dùng `any` ngoại lệ (có comment `@ts-expect-error`)
|
||||
|
||||
**Thời gian:** ~45 giây
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Unit Tests (Jest/Vitest)
|
||||
|
||||
**File:** `.github/workflows/ci.yml` → job `test`
|
||||
|
||||
**Mục đích:** Chạy suite kiểm thử đơn vị, đảm bảo logic ngữ nghĩa đúng.
|
||||
|
||||
**Command:**
|
||||
```bash
|
||||
pnpm test
|
||||
```
|
||||
|
||||
**Chi tiết:**
|
||||
- **API (NestJS):** Jest + `@nestjs/testing`
|
||||
- **Web (Next.js):** Vitest + `@testing-library/react`
|
||||
- Coverage threshold: API ≥ 60%, Web ≥ 50%
|
||||
- Snapshot tests: must commit `.snap` file changes
|
||||
|
||||
**Test Locations:**
|
||||
| Package | Pattern | Runner |
|
||||
|---------|---------|--------|
|
||||
| API | `apps/api/src/**/*.spec.ts` | Jest |
|
||||
| Web | `apps/web/src/**/*.spec.ts` | Vitest |
|
||||
| Libs | `libs/**/*.spec.ts` | Jest (libs) / Vitest (web libs) |
|
||||
|
||||
**Quy tắc viết Test:**
|
||||
- ✅ Test AAA pattern: **A**rrange → **A**ct → **A**ssert
|
||||
- ✅ Describe blocks: `[Unit/Integration] ClassName.method()`
|
||||
- ✅ Mock external dependencies (database, HTTP, etc.)
|
||||
- ✅ Test happy path + error cases + edge cases
|
||||
- ❌ Không mock internal logic
|
||||
- ❌ Không snapshot-test component trees (snapshot brittle)
|
||||
|
||||
**Thời gian:** ~60 giây (API), ~30 giây (Web)
|
||||
|
||||
**Xem coverage:**
|
||||
```bash
|
||||
pnpm test -- --coverage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Build (Turborepo)
|
||||
|
||||
**File:** `.github/workflows/ci.yml` → job `build`
|
||||
|
||||
**Mục đích:** Production build tất cả packages, detect breaking changes.
|
||||
|
||||
**Command:**
|
||||
```bash
|
||||
pnpm build
|
||||
```
|
||||
|
||||
**Chi tiết:**
|
||||
- **Turborepo caching:** Bỏ qua build lại nếu code không thay đổi
|
||||
- **Targets:** `apps/api`, `apps/web`, `libs/ai-services`, `libs/mcp-servers`
|
||||
- **Output:** `dist/` per-package
|
||||
- Vô hiệu hóa cache: `--no-cache`
|
||||
|
||||
**Per-Package Build:**
|
||||
| Package | Command | Output | Notes |
|
||||
|---------|---------|--------|-------|
|
||||
| API | `nest build` | `dist/` | Production NestJS app |
|
||||
| Web | `next build` | `.next/` | Optimized Next.js app |
|
||||
| AI Services | `docker build` | `Dockerfile` | Python FastAPI image (không build trong CI, chỉ lint + test) |
|
||||
| MCP Servers | Bundled vào API | N/A | TypeScript → JS |
|
||||
|
||||
**Thời gian:** ~120 giây (with Turborepo cache)
|
||||
|
||||
---
|
||||
|
||||
## Error Handling & Retry
|
||||
|
||||
### CI Pipeline Retry Policy
|
||||
|
||||
| Failure | Action | Retry |
|
||||
|---------|--------|-------|
|
||||
| Network timeout | Auto-retry (3x) | Yes, within same run |
|
||||
| Out of disk space | Fail + notify | Manual re-run |
|
||||
| Flaky test | Fail (capture logs) | Manual re-run w/ `--seed` |
|
||||
| Git checkout error | Fail + notify | Manual re-run |
|
||||
|
||||
### Local Debugging
|
||||
|
||||
```bash
|
||||
# Replicate exact CI environment locally
|
||||
docker pull ghcr.io/actions/runner:latest
|
||||
|
||||
# Or run pnpm commands locally
|
||||
pnpm install
|
||||
pnpm lint --debug
|
||||
pnpm typecheck
|
||||
pnpm test -- --bail # stop on first failure
|
||||
pnpm build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## GitHub Status Checks
|
||||
|
||||
Pull requests require **all 4 checks to pass** before merging:
|
||||
|
||||
```
|
||||
✅ lint
|
||||
✅ typecheck
|
||||
✅ test
|
||||
✅ build
|
||||
```
|
||||
|
||||
**Branch Protection Rules:**
|
||||
|
||||
- ✅ Require PR reviews: 1 approval minimum (code owner)
|
||||
- ✅ Dismiss stale PR approvals
|
||||
- ✅ Require status checks to pass
|
||||
- ✅ Require branches to be up to date before merging
|
||||
- ✅ Restrict who can push to matching branches (admin only)
|
||||
|
||||
---
|
||||
|
||||
## Secrets & Environment Variables
|
||||
|
||||
### CI-Only Secrets (`.github/secrets/`)
|
||||
|
||||
| Secret | Used In | Purpose |
|
||||
|--------|---------|---------|
|
||||
| `DATABASE_URL_TEST` | Step 3 (test) | Test database (PostgreSQL) |
|
||||
| `REDIS_URL_TEST` | Step 3 (test) | Test Redis cache |
|
||||
| `OPENAI_API_KEY` | Step 3 (test) | Claude API (if needed) |
|
||||
|
||||
### Build-Time Env (`.env.ci`)
|
||||
|
||||
```bash
|
||||
# .env.ci (git-tracked)
|
||||
NODE_ENV=test
|
||||
LOG_LEVEL=warn
|
||||
DATABASE_POOL_MIN=2
|
||||
DATABASE_POOL_MAX=5
|
||||
REDIS_TIMEOUT=5000
|
||||
```
|
||||
|
||||
### Deploy-Only Secrets (`.github/secrets/` for Production)
|
||||
|
||||
| Secret | Deploy Target | Used In |
|
||||
|--------|---------------|---------|
|
||||
| `DOCKER_REGISTRY_TOKEN` | Docker Hub / GitHub Container Registry | Push image after build success |
|
||||
| `DEPLOY_SSH_KEY` | Production VPS | SSH into server + restart service |
|
||||
| `SENTRY_AUTH_TOKEN` | Sentry.io | Release tracking |
|
||||
|
||||
---
|
||||
|
||||
## Deployment Strategy
|
||||
|
||||
### Auto-Deploy Trigger
|
||||
|
||||
Push to `main` → All checks pass → Auto-deploy to **Staging**
|
||||
|
||||
```
|
||||
main branch
|
||||
↓ (all checks pass)
|
||||
↓
|
||||
Auto-build Docker image
|
||||
↓
|
||||
Push to GitHub Container Registry (ghcr.io)
|
||||
↓
|
||||
SSH into staging server
|
||||
↓
|
||||
docker pull + docker-compose up -d
|
||||
↓
|
||||
Health checks (/health/ready) → smoke tests
|
||||
↓
|
||||
✅ Deployed to staging
|
||||
```
|
||||
|
||||
### Manual Deploy to Production
|
||||
|
||||
**Only via GitHub Release tag:**
|
||||
|
||||
```bash
|
||||
git tag -a v1.5.0 -m "Release 1.5.0"
|
||||
git push origin v1.5.0
|
||||
```
|
||||
|
||||
Tag push triggers **manual approval** in GitHub → Deploy to Production.
|
||||
|
||||
---
|
||||
|
||||
## Monitoring & Logs
|
||||
|
||||
### CI Logs
|
||||
|
||||
- **GitHub:** https://github.com/hongochai10/goodgo-bds-platform-ai/actions
|
||||
- **Per-job logs:** Click workflow run → view step output
|
||||
- **Artifact download:** Logs, coverage reports, etc.
|
||||
|
||||
### Production Deployment Logs
|
||||
|
||||
```bash
|
||||
# SSH into production server
|
||||
ssh deploy@prod.goodgo.app
|
||||
|
||||
# View Docker Compose logs
|
||||
docker-compose -f docker-compose.prod.yml logs -f
|
||||
```
|
||||
|
||||
### Error Alerts
|
||||
|
||||
- **Slack:** Integration notify `#deployments` on failure
|
||||
- **Email:** GitHub notifications to team@goodgo.app
|
||||
- **Sentry:** Auto-capture runtime errors after deploy
|
||||
|
||||
---
|
||||
|
||||
## Performance Tips
|
||||
|
||||
### Faster Local Development
|
||||
|
||||
```bash
|
||||
# Lint & typecheck only (skip test & build for quick feedback)
|
||||
pnpm lint && pnpm typecheck
|
||||
|
||||
# Test only changed files
|
||||
pnpm test -- --onlyChanged
|
||||
|
||||
# Build only specific package
|
||||
pnpm --filter api build
|
||||
```
|
||||
|
||||
### Faster CI (reduce time)
|
||||
|
||||
1. **Cache optimization:** Turborepo already caches built packages
|
||||
2. **Parallel jobs:** Lint + typecheck run simultaneously (in CI yaml, set `runs-on: ubuntu-latest`)
|
||||
3. **Skip full build on patch commits:** Use `[skip ci]` in commit message (not recommended for main)
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common CI Failures
|
||||
|
||||
| Error | Cause | Fix |
|
||||
|-------|-------|-----|
|
||||
| `ESLint error: Import not sorted` | Import order wrong | `pnpm lint --fix` |
|
||||
| `TypeScript error: Type 'any'` | Strict type checking | Add explicit type annotation |
|
||||
| `Jest timeout: test took > 5000ms` | Slow test (DB, network) | Mock external calls, increase timeout `jest.setTimeout(10000)` |
|
||||
| `Out of disk space` | GitHub runner full | Clear cache, reduce artifact retention |
|
||||
| `pnpm install stuck` | Network issue | Retry: `rm -rf node_modules && pnpm install` |
|
||||
|
||||
### Re-run CI
|
||||
|
||||
```bash
|
||||
# Re-run entire workflow (GitHub UI)
|
||||
Actions tab → select workflow → click "Re-run" button
|
||||
|
||||
# Or locally, push empty commit
|
||||
git commit --allow-empty -m "Trigger CI"
|
||||
git push
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- GitHub Actions: https://docs.github.com/en/actions
|
||||
- Turborepo Caching: https://turbo.build/repo/docs/core-concepts/caching
|
||||
- ESLint Config: `/.eslintrc.json`
|
||||
- TypeScript Config: `/tsconfig.json` (root), `/apps/api/tsconfig.json`, etc.
|
||||
- Jest Config: `/apps/api/jest.config.js`
|
||||
- Vitest Config: `/apps/web/vitest.config.ts`
|
||||
600
docs/mcp-servers.md
Normal file
600
docs/mcp-servers.md
Normal file
@@ -0,0 +1,600 @@
|
||||
# MCP Servers Documentation
|
||||
|
||||
GoodGo Platform sử dụng **Model Context Protocol (MCP)** để cấp quyền truy cập các công cụ chuyên dụng cho Claude AI. Ba MCP servers chính cung cấp khả năng **tìm kiếm bất động sản**, **phân tích thị trường**, và **định giá tự động (AVM)**.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
| Server | Port | Tools | Purpose |
|
||||
|--------|------|-------|---------|
|
||||
| **Property Search** | 3001 | `search_properties`, `compare_properties`, `get_property_details` | Tìm kiếm bất động sản, so sánh, chi tiết |
|
||||
| **Market Analytics** | 3001 | `get_market_report`, `analyze_trends`, `get_price_indices` | Phân tích thị trường, xu hướng giá |
|
||||
| **Valuation** | 3001 | `estimate_valuation`, `extract_features`, `compare_valuations` | Định giá BĐS, so sánh XGBoost |
|
||||
|
||||
**Architecture:**
|
||||
- All MCP servers are **in-process** (không tách microservice cho MVP)
|
||||
- Chạy cùng process NestJS API
|
||||
- HTTP transport dùng `/mcp/tools/*` endpoint
|
||||
- Claude API calls `POST /mcp/tools/{toolName}` để invoke tools
|
||||
|
||||
---
|
||||
|
||||
## 1. Property Search Server
|
||||
|
||||
### Purpose
|
||||
|
||||
Cung cấp công cụ tìm kiếm bất động sản với:
|
||||
- Full-text search (Typesense)
|
||||
- Geo-spatial search (PostGIS)
|
||||
- Faceted filtering (giá, loại, phòng ngủ, quận huyện)
|
||||
|
||||
### Tools
|
||||
|
||||
#### `search_properties`
|
||||
|
||||
Tìm kiếm bất động sản với nhiều tiêu chí.
|
||||
|
||||
**Input Schema:**
|
||||
```json
|
||||
{
|
||||
"query": "chung cư quận 1",
|
||||
"filters": {
|
||||
"priceMin": 1000000000,
|
||||
"priceMax": 5000000000,
|
||||
"bedrooms": 2,
|
||||
"district": "Quận 1",
|
||||
"propertyType": "APARTMENT"
|
||||
},
|
||||
"sort": "price_asc",
|
||||
"limit": 10,
|
||||
"offset": 0
|
||||
}
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
| Param | Type | Required | Default | Notes |
|
||||
|-------|------|----------|---------|-------|
|
||||
| `query` | string | Yes | - | Tìm kiếm từ khóa (tiêu đề, mô tả) |
|
||||
| `filters.priceMin` | number | No | 0 | Giá tối thiểu (VND) |
|
||||
| `filters.priceMax` | number | No | ∞ | Giá tối đa (VND) |
|
||||
| `filters.bedrooms` | number | No | - | Số phòng ngủ |
|
||||
| `filters.district` | string | No | - | Quận huyện |
|
||||
| `filters.propertyType` | enum | No | - | APARTMENT, HOUSE, LAND, ROOM_RENTAL |
|
||||
| `sort` | enum | No | `relevance` | `price_asc`, `price_desc`, `newest`, `relevance` |
|
||||
| `limit` | number | No | 20 | Số kết quả (1-100) |
|
||||
| `offset` | number | No | 0 | Phân trang offset |
|
||||
|
||||
**Output Example:**
|
||||
```json
|
||||
{
|
||||
"total": 245,
|
||||
"results": [
|
||||
{
|
||||
"id": "prop-001",
|
||||
"title": "Căn hộ 2PN view sông Sài Gòn",
|
||||
"type": "APARTMENT",
|
||||
"price": 3500000000,
|
||||
"bedrooms": 2,
|
||||
"bathrooms": 2,
|
||||
"area": 85,
|
||||
"district": "Quận 1",
|
||||
"ward": "Phường Bến Nghé",
|
||||
"address": "123 Tôn Đức Thắng, Q.1",
|
||||
"agentName": "Nguyễn Văn A",
|
||||
"agentPhone": "0987654321",
|
||||
"status": "ACTIVE",
|
||||
"createdAt": "2026-04-20T10:30:00Z"
|
||||
}
|
||||
],
|
||||
"facets": {
|
||||
"districts": [
|
||||
{ "name": "Quận 1", "count": 42 },
|
||||
{ "name": "Quận 3", "count": 38 }
|
||||
],
|
||||
"propertyTypes": [
|
||||
{ "name": "APARTMENT", "count": 120 },
|
||||
{ "name": "HOUSE", "count": 85 }
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### `compare_properties`
|
||||
|
||||
So sánh 2-5 bất động sản dựa trên giá, diện tích, vị trí, etc.
|
||||
|
||||
**Input Schema:**
|
||||
```json
|
||||
{
|
||||
"propertyIds": ["prop-001", "prop-002", "prop-003"],
|
||||
"metrics": ["price", "area", "price_per_sqm", "location_score", "agent_rating"]
|
||||
}
|
||||
```
|
||||
|
||||
**Output Example:**
|
||||
```json
|
||||
{
|
||||
"comparison": [
|
||||
{
|
||||
"propertyId": "prop-001",
|
||||
"title": "Căn hộ 2PN Q.1",
|
||||
"price": 3500000000,
|
||||
"area": 85,
|
||||
"price_per_sqm": 41176470,
|
||||
"location_score": 4.8,
|
||||
"agent_rating": 4.5
|
||||
},
|
||||
{
|
||||
"propertyId": "prop-002",
|
||||
"title": "Căn hộ 2PN Q.3",
|
||||
"price": 2800000000,
|
||||
"area": 78,
|
||||
"price_per_sqm": 35897436,
|
||||
"location_score": 4.3,
|
||||
"agent_rating": 4.2
|
||||
}
|
||||
],
|
||||
"recommendation": "prop-002 có giá tốt hơn với vị trí tương đương"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### `get_property_details`
|
||||
|
||||
Lấy chi tiết đầy đủ của một bất động sản.
|
||||
|
||||
**Input Schema:**
|
||||
```json
|
||||
{
|
||||
"propertyId": "prop-001"
|
||||
}
|
||||
```
|
||||
|
||||
**Output Example:**
|
||||
```json
|
||||
{
|
||||
"id": "prop-001",
|
||||
"title": "Căn hộ 2PN view sông Sài Gòn",
|
||||
"description": "Căn hộ cao cấp tại trung tâm Q.1...",
|
||||
"type": "APARTMENT",
|
||||
"price": 3500000000,
|
||||
"bedrooms": 2,
|
||||
"bathrooms": 2,
|
||||
"area": 85,
|
||||
"district": "Quận 1",
|
||||
"ward": "Phường Bến Nghé",
|
||||
"address": "123 Tôn Đức Thắng, Q.1",
|
||||
"coordinates": {
|
||||
"latitude": 10.7769,
|
||||
"longitude": 106.7009
|
||||
},
|
||||
"features": ["view sông", "ban công rộng", "tầng cao", "gần metro"],
|
||||
"agent": {
|
||||
"id": "agent-001",
|
||||
"name": "Nguyễn Văn A",
|
||||
"phone": "0987654321",
|
||||
"rating": 4.5,
|
||||
"reviews": 47
|
||||
},
|
||||
"media": [
|
||||
{
|
||||
"type": "image",
|
||||
"url": "https://storage.goodgo.app/prop-001/img-1.jpg"
|
||||
}
|
||||
],
|
||||
"status": "ACTIVE",
|
||||
"createdAt": "2026-04-20T10:30:00Z",
|
||||
"reviews": [
|
||||
{
|
||||
"author": "Trần Văn B",
|
||||
"rating": 5,
|
||||
"text": "Căn hộ đẹp, vị trí tuyệt vời"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Market Analytics Server
|
||||
|
||||
### Purpose
|
||||
|
||||
Cung cấp dữ liệu thị trường bất động sản:
|
||||
- Báo cáo giá theo quận huyện
|
||||
- Phân tích xu hướng giá theo thời gian
|
||||
- Chỉ số thị trường
|
||||
|
||||
### Tools
|
||||
|
||||
#### `get_market_report`
|
||||
|
||||
Lấy báo cáo thị trường theo quận huyện.
|
||||
|
||||
**Input Schema:**
|
||||
```json
|
||||
{
|
||||
"district": "Quận 1",
|
||||
"propertyType": "APARTMENT",
|
||||
"period": "monthly"
|
||||
}
|
||||
```
|
||||
|
||||
**Output Example:**
|
||||
```json
|
||||
{
|
||||
"district": "Quận 1",
|
||||
"propertyType": "APARTMENT",
|
||||
"period": "April 2026",
|
||||
"statistics": {
|
||||
"averagePrice": 3200000000,
|
||||
"medianPrice": 3100000000,
|
||||
"priceMin": 800000000,
|
||||
"priceMax": 8500000000,
|
||||
"averageArea": 82,
|
||||
"averagePricePerSqm": 39024390,
|
||||
"activeListings": 342,
|
||||
"soldListings": 28,
|
||||
"rentedListings": 15
|
||||
},
|
||||
"trends": {
|
||||
"priceChangePercent": 2.5,
|
||||
"priceChangeVsLastMonth": "Tăng 2.5%",
|
||||
"velocityDays": 15
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### `analyze_trends`
|
||||
|
||||
Phân tích xu hướng giá theo thời gian.
|
||||
|
||||
**Input Schema:**
|
||||
```json
|
||||
{
|
||||
"district": "Quận 1",
|
||||
"propertyType": "APARTMENT",
|
||||
"months": 12
|
||||
}
|
||||
```
|
||||
|
||||
**Output Example:**
|
||||
```json
|
||||
{
|
||||
"district": "Quận 1",
|
||||
"propertyType": "APARTMENT",
|
||||
"trend": [
|
||||
{
|
||||
"month": "May 2025",
|
||||
"averagePrice": 2900000000,
|
||||
"medianPrice": 2800000000,
|
||||
"activeListings": 250
|
||||
},
|
||||
{
|
||||
"month": "April 2026",
|
||||
"averagePrice": 3200000000,
|
||||
"medianPrice": 3100000000,
|
||||
"activeListings": 342
|
||||
}
|
||||
],
|
||||
"forecast": {
|
||||
"nextMonthPredicted": 3280000000,
|
||||
"confidence": 0.75,
|
||||
"direction": "up"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### `get_price_indices`
|
||||
|
||||
Lấy chỉ số giá toàn thị trường (bình thường hóa = 100).
|
||||
|
||||
**Input Schema:**
|
||||
```json
|
||||
{
|
||||
"baseMonth": "January 2025"
|
||||
}
|
||||
```
|
||||
|
||||
**Output Example:**
|
||||
```json
|
||||
{
|
||||
"baseIndex": 100,
|
||||
"baseMonth": "January 2025",
|
||||
"indices": [
|
||||
{
|
||||
"month": "January 2025",
|
||||
"indexValue": 100,
|
||||
"growth": 0
|
||||
},
|
||||
{
|
||||
"month": "April 2026",
|
||||
"indexValue": 110.5,
|
||||
"growth": 10.5
|
||||
}
|
||||
],
|
||||
"byDistrict": {
|
||||
"Quận 1": 112.3,
|
||||
"Quận 3": 108.7,
|
||||
"Thủ Đức": 105.2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Valuation Server
|
||||
|
||||
### Purpose
|
||||
|
||||
Định giá tự động bất động sản dùng mô hình **XGBoost**:
|
||||
- Estimate valuation based on features
|
||||
- Extract features from description
|
||||
- Compare valuations across similar properties
|
||||
|
||||
### Tools
|
||||
|
||||
#### `estimate_valuation`
|
||||
|
||||
Ước lượng giá bất động sản dựa trên đặc trưng.
|
||||
|
||||
**Input Schema:**
|
||||
```json
|
||||
{
|
||||
"district": "Quận 1",
|
||||
"propertyType": "APARTMENT",
|
||||
"area": 85,
|
||||
"bedrooms": 2,
|
||||
"bathrooms": 2,
|
||||
"features": ["view sông", "ban công", "tầng cao", "gần metro"],
|
||||
"yearBuilt": 2015,
|
||||
"location": {
|
||||
"latitude": 10.7769,
|
||||
"longitude": 106.7009
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Output Example:**
|
||||
```json
|
||||
{
|
||||
"estimatedPrice": 3250000000,
|
||||
"priceRange": {
|
||||
"low": 2850000000,
|
||||
"high": 3650000000
|
||||
},
|
||||
"confidence": 0.82,
|
||||
"factors": {
|
||||
"area": "Positive (85 sqm)",
|
||||
"location": "High demand (Q.1)",
|
||||
"features": "Premium (view sông, gần metro)",
|
||||
"yearBuilt": "Neutral (11 years old)"
|
||||
},
|
||||
"comparables": [
|
||||
{
|
||||
"id": "prop-001",
|
||||
"actualPrice": 3200000000,
|
||||
"similarity": 0.89
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### `extract_features`
|
||||
|
||||
Trích xuất đặc trưng từ mô tả bất động sản (NLP).
|
||||
|
||||
**Input Schema:**
|
||||
```json
|
||||
{
|
||||
"description": "Căn hộ cao cấp 2 phòng ngủ, 2 phòng tắm, view sông Sài Gòn, ban công rộng, gần trạm metro, tầng 15, xây năm 2015...",
|
||||
"title": "Căn hộ 2PN view sông Sài Gòn"
|
||||
}
|
||||
```
|
||||
|
||||
**Output Example:**
|
||||
```json
|
||||
{
|
||||
"extracted": {
|
||||
"bedrooms": 2,
|
||||
"bathrooms": 2,
|
||||
"area": null,
|
||||
"features": ["view sông", "ban công", "gần metro", "tầng cao"],
|
||||
"yearBuilt": 2015,
|
||||
"condition": "tốt"
|
||||
},
|
||||
"confidence": {
|
||||
"bedrooms": 0.98,
|
||||
"features": 0.85,
|
||||
"yearBuilt": 0.92
|
||||
},
|
||||
"uncertainties": [
|
||||
"area not mentioned",
|
||||
"exact floor number not in description"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### `compare_valuations`
|
||||
|
||||
So sánh định giá của các bất động sản tương tự.
|
||||
|
||||
**Input Schema:**
|
||||
```json
|
||||
{
|
||||
"referencePropertyId": "prop-001",
|
||||
"candidatePropertyIds": ["prop-002", "prop-003", "prop-004"]
|
||||
}
|
||||
```
|
||||
|
||||
**Output Example:**
|
||||
```json
|
||||
{
|
||||
"reference": {
|
||||
"propertyId": "prop-001",
|
||||
"title": "Căn hộ 2PN Q.1",
|
||||
"actualPrice": 3500000000,
|
||||
"estimatedPrice": 3250000000
|
||||
},
|
||||
"candidates": [
|
||||
{
|
||||
"propertyId": "prop-002",
|
||||
"title": "Căn hộ 2PN Q.3",
|
||||
"actualPrice": 2800000000,
|
||||
"estimatedPrice": 2950000000,
|
||||
"overUndervalued": "Undervalued by 5.1%",
|
||||
"similarity": 0.76
|
||||
}
|
||||
],
|
||||
"recommendation": "prop-002 is a good value compared to reference property"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### File Structure
|
||||
|
||||
```
|
||||
apps/api/src/
|
||||
├── modules/
|
||||
│ └── mcp/
|
||||
│ ├── mcp.module.ts # Module definition
|
||||
│ ├── mcp.controller.ts # HTTP endpoint: POST /mcp/tools/:toolName
|
||||
│ ├── mcp-registry.service.ts # Registry: tool name → handler function
|
||||
│ ├── servers/
|
||||
│ │ ├── property-search.server.ts
|
||||
│ │ ├── market-analytics.server.ts
|
||||
│ │ └── valuation.server.ts
|
||||
│ └── dto/
|
||||
│ ├── search-properties.dto.ts
|
||||
│ ├── market-report.dto.ts
|
||||
│ └── estimate-valuation.dto.ts
|
||||
```
|
||||
|
||||
### McpRegistryService
|
||||
|
||||
```typescript
|
||||
// Register tools
|
||||
export class McpRegistryService {
|
||||
private tools = new Map<string, Tool>();
|
||||
|
||||
register(name: string, tool: Tool) {
|
||||
this.tools.set(name, tool);
|
||||
}
|
||||
|
||||
invoke(name: string, input: any): Promise<any> {
|
||||
const tool = this.tools.get(name);
|
||||
if (!tool) throw new NotFoundException(`Tool ${name} not found`);
|
||||
return tool.execute(input);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### HTTP Endpoint
|
||||
|
||||
```typescript
|
||||
@Post('/mcp/tools/:toolName')
|
||||
@Auth() // JWT required
|
||||
async invokeTool(
|
||||
@Param('toolName') toolName: string,
|
||||
@Body() input: any
|
||||
) {
|
||||
return this.mcpRegistry.invoke(toolName, input);
|
||||
}
|
||||
```
|
||||
|
||||
### Tool Pattern
|
||||
|
||||
```typescript
|
||||
interface Tool {
|
||||
name: string;
|
||||
schema: JsonSchema; // Input validation
|
||||
execute(input: any): Promise<any>;
|
||||
}
|
||||
|
||||
class SearchPropertiesTool implements Tool {
|
||||
name = 'search_properties';
|
||||
schema = { /* JSON Schema */ };
|
||||
|
||||
execute(input: SearchPropertiesInput): Promise<any> {
|
||||
// Implementation
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
All MCP tools return consistent error format:
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "INVALID_INPUT",
|
||||
"message": "District 'Quận XYZ' not found",
|
||||
"details": {
|
||||
"field": "district",
|
||||
"value": "Quận XYZ"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
### Caching
|
||||
|
||||
- Market Analytics: Cache reports for 1 hour
|
||||
- Property Search: Cache facets, invalidate on new listing
|
||||
- Valuation: Cache model predictions for 24 hours
|
||||
|
||||
### Rate Limiting
|
||||
|
||||
- Default: 100 req/minute per user
|
||||
- MCP tools: 50 req/minute per tool (stricter)
|
||||
- Burst: 10 req/second
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
### Unit Tests
|
||||
|
||||
```bash
|
||||
pnpm test -- mcp/servers
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
|
||||
```bash
|
||||
# Test via HTTP
|
||||
curl -X POST http://localhost:3001/mcp/tools/search_properties \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"query": "chung cu quan 1", "limit": 5}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- MCP Specification: https://modelcontextprotocol.io/
|
||||
- Claude API: https://anthropic.com/api
|
||||
- Implementation: `apps/api/src/modules/mcp/`
|
||||
515
docs/onboarding.md
Normal file
515
docs/onboarding.md
Normal file
@@ -0,0 +1,515 @@
|
||||
# Developer Onboarding Guide
|
||||
|
||||
Chào mừng đến với **GoodGo Platform** — một sàn giao dịch bất động sản Việt Nam được xây dựng trên NestJS, Next.js, PostgreSQL, và PostGIS.
|
||||
|
||||
Hướng dẫn này giúp bạn setup môi trường phát triển trong **< 30 phút**.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites (Yêu cầu)
|
||||
|
||||
Trước khi bắt đầu, hãy cài đặt:
|
||||
|
||||
| Tool | Version | Link |
|
||||
|------|---------|------|
|
||||
| **Node.js** | ≥ 22.0.0 | https://nodejs.org/ |
|
||||
| **pnpm** | ≥ 10.0.0 | https://pnpm.io/ |
|
||||
| **PostgreSQL** | 16 + PostGIS | https://www.postgresql.org/ |
|
||||
| **Docker & Docker Compose** | Latest | https://docker.com/ |
|
||||
| **Git** | Latest | https://git-scm.com/ |
|
||||
| **VS Code** (recommended) | Latest | https://code.visualstudio.com/ |
|
||||
|
||||
### macOS
|
||||
|
||||
```bash
|
||||
# Install Homebrew (if not already)
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
|
||||
# Install dependencies
|
||||
brew install node@22 pnpm postgresql@16 docker
|
||||
brew install postgis # PostGIS extension
|
||||
|
||||
# Verify
|
||||
node --version # v22.x.x
|
||||
pnpm --version # 10.x.x
|
||||
psql --version # PostgreSQL 16.x
|
||||
```
|
||||
|
||||
### Ubuntu/Debian
|
||||
|
||||
```bash
|
||||
# Update package manager
|
||||
sudo apt update
|
||||
|
||||
# Install Node.js 22
|
||||
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
|
||||
sudo apt install -y nodejs
|
||||
|
||||
# Install pnpm
|
||||
npm install -g pnpm@latest
|
||||
|
||||
# Install PostgreSQL 16 + PostGIS
|
||||
sudo apt install -y postgresql-16 postgresql-16-postgis
|
||||
|
||||
# Install Docker
|
||||
curl -fsSL https://get.docker.com -o get-docker.sh
|
||||
sudo sh get-docker.sh
|
||||
```
|
||||
|
||||
### Windows (WSL2 Recommended)
|
||||
|
||||
```bash
|
||||
# Inside WSL2 Ubuntu:
|
||||
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
|
||||
sudo apt install -y nodejs postgresql-16 postgresql-16-postgis
|
||||
npm install -g pnpm@latest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. Clone Repository
|
||||
|
||||
```bash
|
||||
# Clone the repo
|
||||
git clone https://github.com/hongochai10/goodgo-bds-platform-ai.git
|
||||
cd goodgo-platform-ai
|
||||
|
||||
# Add your SSH key to GitHub (for faster clone/push)
|
||||
# https://docs.github.com/en/authentication/connecting-to-github-with-ssh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Install Dependencies
|
||||
|
||||
```bash
|
||||
# Install all packages using pnpm workspaces
|
||||
pnpm install
|
||||
|
||||
# This installs:
|
||||
# - Root dependencies
|
||||
# - apps/api dependencies
|
||||
# - apps/web dependencies
|
||||
# - libs/ai-services dependencies
|
||||
# - libs/mcp-servers dependencies
|
||||
```
|
||||
|
||||
**Expected time:** ~2-5 minutes
|
||||
|
||||
---
|
||||
|
||||
## 3. Setup PostgreSQL (Database)
|
||||
|
||||
### Option A: Docker Compose (Recommended for Development)
|
||||
|
||||
```bash
|
||||
# Start PostgreSQL + Redis in Docker
|
||||
docker-compose -f docker-compose.dev.yml up -d
|
||||
|
||||
# Verify containers are running
|
||||
docker-compose ps
|
||||
|
||||
# Output should show:
|
||||
# NAME STATUS
|
||||
# goodgo-postgres Up 2 seconds
|
||||
# goodgo-redis Up 2 seconds
|
||||
```
|
||||
|
||||
### Option B: Local PostgreSQL Installation
|
||||
|
||||
```bash
|
||||
# Create database
|
||||
createdb goodgo_dev
|
||||
|
||||
# Enable PostGIS extension
|
||||
psql goodgo_dev -c "CREATE EXTENSION IF NOT EXISTS postgis;"
|
||||
|
||||
# Verify
|
||||
psql goodgo_dev -c "SELECT PostGIS_version();"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Setup Environment Variables
|
||||
|
||||
```bash
|
||||
# Copy .env.example to .env
|
||||
cp .env.example .env
|
||||
|
||||
# Edit .env with your local values
|
||||
# Minimal required variables:
|
||||
cat > .env << 'EOF'
|
||||
NODE_ENV=development
|
||||
DATABASE_URL="postgresql://postgres:password@localhost:5432/goodgo_dev"
|
||||
REDIS_URL="redis://localhost:6379"
|
||||
JWT_SECRET="dev-secret-change-in-production"
|
||||
JWT_REFRESH_SECRET="dev-refresh-secret-change-in-production"
|
||||
MAPBOX_TOKEN="your-mapbox-token-here" # Get from https://account.mapbox.com/
|
||||
EOF
|
||||
|
||||
# For Firebase Cloud Messaging (optional, for push notifications):
|
||||
# FIREBASE_PROJECT_ID="your-project-id"
|
||||
# FIREBASE_PRIVATE_KEY="..."
|
||||
# FIREBASE_CLIENT_EMAIL="..."
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Initialize Database
|
||||
|
||||
```bash
|
||||
# Generate Prisma client
|
||||
pnpm db:generate
|
||||
|
||||
# Run migrations
|
||||
pnpm db:migrate:dev
|
||||
|
||||
# Seed sample data (users, listings, districts)
|
||||
pnpm db:seed
|
||||
|
||||
# Verify seeding
|
||||
pnpm db:studio # Opens Prisma Studio GUI at http://localhost:5555
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Start Development Servers
|
||||
|
||||
```bash
|
||||
# Start all services (API + Web + AI services) in watch mode
|
||||
pnpm dev
|
||||
|
||||
# Output shows:
|
||||
# - API running at http://localhost:3001
|
||||
# - Web running at http://localhost:3000
|
||||
# - Logs from both services
|
||||
```
|
||||
|
||||
**Expected time:** ~30 seconds for startup
|
||||
|
||||
### Alternative: Start Individual Services
|
||||
|
||||
```bash
|
||||
# Terminal 1: API only
|
||||
pnpm --filter api dev
|
||||
|
||||
# Terminal 2: Web only
|
||||
pnpm --filter web dev
|
||||
|
||||
# Terminal 3: AI services (Python) - optional
|
||||
pnpm --filter ai-services dev
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Verify Setup
|
||||
|
||||
Open your browser and test:
|
||||
|
||||
### API Health Check
|
||||
|
||||
```bash
|
||||
# Terminal or Postman
|
||||
curl http://localhost:3001/health
|
||||
|
||||
# Should return:
|
||||
# {
|
||||
# "status": "ok",
|
||||
# "timestamp": "2026-04-22T10:30:00Z"
|
||||
# }
|
||||
```
|
||||
|
||||
### Web App
|
||||
|
||||
Open http://localhost:3000 in your browser
|
||||
|
||||
- You should see the GoodGo home page
|
||||
- Try registering an account (test phone: `0987654321`, any password)
|
||||
|
||||
### API Swagger Docs
|
||||
|
||||
Open http://localhost:3001/api/docs
|
||||
|
||||
- Interactive API documentation
|
||||
- Try endpoints: GET `/api/v1/listings`, POST `/api/v1/auth/login`, etc.
|
||||
|
||||
---
|
||||
|
||||
## Key Commands
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `pnpm install` | Install all dependencies |
|
||||
| `pnpm dev` | Start all services in watch mode |
|
||||
| `pnpm lint` | Run ESLint (check code style) |
|
||||
| `pnpm lint --fix` | Auto-fix lint issues |
|
||||
| `pnpm typecheck` | TypeScript type checking |
|
||||
| `pnpm test` | Run unit tests |
|
||||
| `pnpm test:e2e` | Run E2E tests with Playwright |
|
||||
| `pnpm build` | Production build |
|
||||
| `pnpm db:generate` | Generate Prisma client |
|
||||
| `pnpm db:migrate:dev` | Run pending migrations |
|
||||
| `pnpm db:seed` | Seed sample data |
|
||||
| `pnpm db:studio` | Open Prisma Studio GUI |
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
goodgo-platform-ai/
|
||||
├── apps/
|
||||
│ ├── api/ # NestJS backend
|
||||
│ │ ├── src/
|
||||
│ │ │ ├── main.ts # Entry point
|
||||
│ │ │ └── modules/ # Domain modules
|
||||
│ │ │ ├── auth/
|
||||
│ │ │ ├── listings/
|
||||
│ │ │ ├── payments/
|
||||
│ │ │ └── ...
|
||||
│ │ └── package.json
|
||||
│ └── web/ # Next.js frontend
|
||||
│ ├── src/
|
||||
│ │ ├── app/ # App Router pages
|
||||
│ │ ├── components/
|
||||
│ │ ├── lib/
|
||||
│ │ └── hooks/
|
||||
│ └── package.json
|
||||
├── libs/
|
||||
│ ├── ai-services/ # Python FastAPI (AVM, moderation)
|
||||
│ └── mcp-servers/ # MCP server library
|
||||
├── prisma/
|
||||
│ ├── schema.prisma # Database schema
|
||||
│ └── migrations/ # SQL migrations
|
||||
├── docs/ # Documentation
|
||||
├── .github/workflows/ # CI/CD
|
||||
└── package.json (root) # pnpm workspaces config
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### 1. Create a Feature Branch
|
||||
|
||||
```bash
|
||||
# Always create a feature branch from main/master
|
||||
git checkout -b feature/awesome-feature
|
||||
|
||||
# Branch naming convention:
|
||||
# - feature/new-feature-name
|
||||
# - fix/bug-description
|
||||
# - refactor/code-cleanup
|
||||
# - docs/documentation-update
|
||||
```
|
||||
|
||||
### 2. Make Changes
|
||||
|
||||
```bash
|
||||
# Install dependencies for new package
|
||||
pnpm install
|
||||
|
||||
# Run type checking + linting
|
||||
pnpm typecheck
|
||||
pnpm lint
|
||||
|
||||
# Run tests for your changes
|
||||
pnpm test -- path/to/module
|
||||
|
||||
# Fix auto-fixable issues
|
||||
pnpm lint --fix
|
||||
```
|
||||
|
||||
### 3. Commit & Push
|
||||
|
||||
```bash
|
||||
# Commit following conventional commits format
|
||||
git add .
|
||||
git commit -m "feat(module): short description"
|
||||
|
||||
# Commit message format:
|
||||
# feat(scope): description
|
||||
# fix(scope): description
|
||||
# docs(scope): description
|
||||
# refactor(scope): description
|
||||
# test(scope): description
|
||||
# chore(scope): description
|
||||
|
||||
# Push branch
|
||||
git push origin feature/awesome-feature
|
||||
```
|
||||
|
||||
### 4. Create Pull Request
|
||||
|
||||
- Go to GitHub: https://github.com/hongochai10/goodgo-bds-platform-ai/pulls
|
||||
- Click **New Pull Request**
|
||||
- Select your branch
|
||||
- Add description (what changed, why, testing notes)
|
||||
- Ensure all checks pass ✅ (lint, typecheck, test, build)
|
||||
- Request review from team lead
|
||||
- Merge after approval
|
||||
|
||||
---
|
||||
|
||||
## Debugging Tips
|
||||
|
||||
### API Debugging
|
||||
|
||||
```bash
|
||||
# Enable debug logging
|
||||
DEBUG=*:* pnpm --filter api dev
|
||||
|
||||
# Or in VS Code: use `.vscode/launch.json` for breakpoints
|
||||
# F5 to start debugger
|
||||
```
|
||||
|
||||
### Web Debugging
|
||||
|
||||
```bash
|
||||
# Chrome DevTools: F12
|
||||
# React DevTools extension: https://chrome.google.com/webstore/
|
||||
|
||||
# Debug Next.js:
|
||||
# .next/server/pages shows compiled route handlers
|
||||
```
|
||||
|
||||
### Database Debugging
|
||||
|
||||
```bash
|
||||
# Connect to database directly
|
||||
psql $DATABASE_URL
|
||||
|
||||
# Common queries:
|
||||
SELECT * FROM "User" LIMIT 5;
|
||||
SELECT COUNT(*) FROM "Listing";
|
||||
SELECT * FROM "Listing" WHERE "status" = 'ACTIVE' LIMIT 5;
|
||||
```
|
||||
|
||||
### Redis Debugging
|
||||
|
||||
```bash
|
||||
# Connect to Redis CLI
|
||||
redis-cli
|
||||
|
||||
# Check keys
|
||||
KEYS *
|
||||
GET session:user:123
|
||||
INCR counter
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## VS Code Setup (Optional)
|
||||
|
||||
### Recommended Extensions
|
||||
|
||||
```json
|
||||
// .vscode/extensions.json
|
||||
{
|
||||
"recommendations": [
|
||||
"esbenp.prettier-vscode", // Code formatter
|
||||
"dbaeumer.vscode-eslint", // ESLint linting
|
||||
"ms-vscode.makefile-tools", // Makefile support
|
||||
"ms-vscode.extension-pack-fe", // Frontend bundle
|
||||
"ms-vscode-remote.remote-containers", // Docker support
|
||||
"bradlc.vscode-tailwindcss", // Tailwind CSS support
|
||||
"vivaxy.vscode-conventional-commits", // Commit helper
|
||||
"Prisma.prisma" // Prisma schema support
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Launch Configuration (Debugging)
|
||||
|
||||
Create `.vscode/launch.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "NestJS Debug",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/node_modules/@nestjs/cli/bin/nest.js",
|
||||
"args": ["start", "--debug", "--watch"],
|
||||
"cwd": "${workspaceFolder}/apps/api",
|
||||
"skipFiles": ["<node_internals>/**"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Problem: `pnpm install` hangs
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
rm -rf node_modules .pnpm-store pnpm-lock.yaml
|
||||
pnpm install --no-frozen-lockfile
|
||||
```
|
||||
|
||||
### Problem: PostgreSQL connection refused
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Check if PostgreSQL is running
|
||||
docker-compose ps
|
||||
|
||||
# If not running, start it
|
||||
docker-compose -f docker-compose.dev.yml up -d
|
||||
|
||||
# Or check local PostgreSQL
|
||||
pg_isready -h localhost -p 5432
|
||||
```
|
||||
|
||||
### Problem: `pnpm dev` fails with "EADDRINUSE"
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Port 3000 or 3001 is already in use
|
||||
# Kill existing process
|
||||
lsof -i :3000 # Find process ID
|
||||
kill -9 <PID>
|
||||
|
||||
# Or use different port
|
||||
PORT=3002 pnpm --filter web dev
|
||||
```
|
||||
|
||||
### Problem: TypeScript errors in IDE but tests pass
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Regenerate Prisma types
|
||||
pnpm db:generate
|
||||
|
||||
# Restart VS Code
|
||||
Cmd+Shift+P → "Developer: Reload Window"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Help
|
||||
|
||||
- **Slack:** `#dev` channel (if you have access)
|
||||
- **GitHub Issues:** https://github.com/hongochai10/goodgo-bds-platform-ai/issues
|
||||
- **Documentation:** `/docs` folder
|
||||
- **Architecture:** `/docs/architecture.md`
|
||||
- **API Reference:** `/docs/api-endpoints.md`
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. ✅ **Setup complete?** Start with a small bug fix or feature
|
||||
2. 📖 **Read Architecture:** `/docs/architecture.md` (understand module structure)
|
||||
3. 🏗️ **Understand CQRS:** `/docs/QUICK_REFERENCE.md` (command/query handlers)
|
||||
4. 🧪 **Write Tests:** Follow patterns in existing `.spec.ts` files
|
||||
5. 📝 **Update Docs:** When adding features, update relevant docs
|
||||
|
||||
---
|
||||
|
||||
**Welcome to GoodGo! Happy coding! 🚀**
|
||||
Reference in New Issue
Block a user