chore: organize docs — move 37 files from root into docs/ subfolders
Root now contains only essential files: README.md, CLAUDE.md, CHANGELOG.md, CONTRIBUTING.md Reorganized into: docs/audits/ — all audit reports & checklists (71 files) docs/architecture/ — codebase overview, implementation plan docs/guides/ — auth guide, implementation checklist docs/load-testing/ — k6 load test guides & endpoints docs/security/ — payment & security reviews Also removed 5 untracked debug/investigation files and cleaned up playwright-report/ & test-results/ artifacts. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
This commit is contained in:
237
docs/architecture/ARCHITECTURE_SUMMARY.txt
Normal file
237
docs/architecture/ARCHITECTURE_SUMMARY.txt
Normal file
@@ -0,0 +1,237 @@
|
||||
╔════════════════════════════════════════════════════════════════════════════════╗
|
||||
║ GoodGo Platform — Architecture & Implementation Status ║
|
||||
║ MVP Complete — Phase 7 Wave 14 ✅ ║
|
||||
╚════════════════════════════════════════════════════════════════════════════════╝
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ TECHNOLOGY STACK │
|
||||
├─────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ Frontend │ Next.js 15 + React 18 + Tailwind CSS + Shadcn/ui │
|
||||
│ Backend │ NestJS 11 + TypeScript 6 (DDD/CQRS architecture) │
|
||||
│ Database │ PostgreSQL 16 + PostGIS (geospatial queries) │
|
||||
│ Cache │ Redis 5.4 (ioredis client) │
|
||||
│ Search │ Typesense 3.0 (full-text + filters) │
|
||||
│ File Storage │ AWS S3 (pre-signed URLs) │
|
||||
│ Payments │ VNPay, MoMo, ZaloPay (webhook callbacks) │
|
||||
│ Auth │ JWT + OAuth2 (Google, Zalo) + TOTP/MFA │
|
||||
│ Notifications │ Email (Nodemailer), SMS, FCM, Zalo OA │
|
||||
│ Monitoring │ Prometheus + Grafana + Sentry + Pino logs │
|
||||
│ Testing │ Playwright (E2E), Vitest (unit), K6 (load) │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ API LAYER — 18 MODULES (NestJS Monorepo) │
|
||||
├─────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ AUTHENTICATION BUSINESS LOGIC MONETIZATION OPERATIONS │
|
||||
│ ├── Auth Module ├── Listings ├── Payments ├── Admin │
|
||||
│ │ (JWT/OAuth/MFA) │ (CRUD/Media) │ (3 gateways) │ (Moderation) │
|
||||
│ ├── RefreshToken ├── Search ├── Subscriptions├── Notifications │
|
||||
│ ├── OAuthAccount │ (Typesense) │ (4 plans) ├── Metrics │
|
||||
│ └── MfaChallenge ├── Inquiries └── Orders ├── Health │
|
||||
│ │ (CRM) ├── MCP Server │
|
||||
│ ├── Leads └── Shared (DI/ │
|
||||
│ │ (Agent CRM) Encryption) │
|
||||
│ ├── Agents │
|
||||
│ │ (Profiles) │
|
||||
│ ├── Analytics │
|
||||
│ │ (AI Valuation) │
|
||||
│ └── Reviews │
|
||||
│ (User ratings) │
|
||||
│ │
|
||||
│ SHARED LAYER │
|
||||
│ ├── Domain Primitives ├── Infrastructure ├── Utilities │
|
||||
│ │ (Result, Exception, │ (Logger, Redis, │ (Encryption, PII │
|
||||
│ │ ValueObject) │ Prisma, EventBus) │ Masking, Validation) │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ DATABASE MODEL — 31 Entities (PostgreSQL 16 + PostGIS) │
|
||||
├─────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ AUTH (5) LISTINGS (4) TRANSACTIONS (4) ANALYTICS (2) │
|
||||
│ • User • Property • Transaction • Valuation │
|
||||
│ • RefreshToken • PropertyMedia • Inquiry • MarketIndex │
|
||||
│ • OAuthAccount • Listing • Lead │
|
||||
│ • Agent • SavedSearch • Review │
|
||||
│ • MfaChallenge │
|
||||
│ │
|
||||
│ PAYMENTS (2) ORDERS (3) OPERATIONS (6) │
|
||||
│ • Payment • Order • NotificationLog │
|
||||
│ • Plan • Escrow • NotificationPreference │
|
||||
│ • Subscription • AdminAuditLog │
|
||||
│ • UsageRecord │
|
||||
│ │
|
||||
│ INDEXES: 30+ single/compound indexes for query optimization │
|
||||
│ ENUMS: UserRole, PropertyType, TransactionType, PaymentProvider, etc. │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ FRONTEND LAYER — Next.js 15 (TypeScript + React) │
|
||||
├─────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ROUTE GROUPS (App Router with [locale] i18n) │
|
||||
│ ├── (public) Landing, Search, Browse Listings │
|
||||
│ ├── (auth) Login, Register, OAuth Callback │
|
||||
│ ├── (dashboard) Seller Dashboard, Listing Management │
|
||||
│ └── (admin) Admin Panel (Moderation, KYC, Users) │
|
||||
│ │
|
||||
│ COMPONENTS (16 directories) │
|
||||
│ ├── auth/ Login forms, OAuth buttons │
|
||||
│ ├── listings/ List view, detail, create, edit forms │
|
||||
│ ├── search/ Filters, saved searches, alerts │
|
||||
│ ├── agents/ Agent profiles, quality ratings │
|
||||
│ ├── inquiries/ Message threads, notifications │
|
||||
│ ├── leads/ Lead management UI, scoring │
|
||||
│ ├── charts/ Market analytics (Recharts) │
|
||||
│ ├── map/ Mapbox integration │
|
||||
│ ├── subscription/ Plan selection, billing UI │
|
||||
│ ├── valuation/ AI price estimates │
|
||||
│ ├── comparison/ Property comparison tool │
|
||||
│ └── ui/ Shadcn/ui base components │
|
||||
│ │
|
||||
│ LIBRARIES │
|
||||
│ ├── API Clients (6) Listings, Search, Payments, Analytics, etc. │
|
||||
│ ├── Stores (2) Auth store, Comparison store (Zustand) │
|
||||
│ ├── Hooks (8) useListings, usePayments, useSavedSearches, etc. │
|
||||
│ ├── Validations Zod schemas for forms │
|
||||
│ └── Utils Currency formatting, blur hashes, Web Vitals │
|
||||
│ │
|
||||
│ i18n: Vietnamese + English (next-intl) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ TESTING & QUALITY ASSURANCE │
|
||||
├─────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ UNIT TESTS (Vitest) │
|
||||
│ • Payment gateway services (VNPay, MoMo, ZaloPay) │
|
||||
│ • Value objects (Money, PlatformFee) │
|
||||
│ • Stores and utilities (Auth store, Currency, etc.) │
|
||||
│ │
|
||||
│ E2E TESTS (Playwright) │
|
||||
│ • Web: 15 scenarios (auth, listings, search, admin, responsive) │
|
||||
│ • API: 16 scenarios (auth, payments, subscriptions, etc.) │
|
||||
│ • Load: K6 scripts (baseline benchmarks, concurrency up to 1000 VU) │
|
||||
│ │
|
||||
│ TOTAL: 242 test files across unit + integration + E2E │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ OBSERVABILITY & MONITORING │
|
||||
├─────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ METRICS LOGS TRACING ALERTS │
|
||||
│ • Prometheus • Pino (structured) • Sentry • AlertManager │
|
||||
│ • Grafana dashboards • Loki (aggregated) • Error tracking • Configured │
|
||||
│ • Custom counters • Promtail • Performance RUM │ │
|
||||
│ • HTTP latency │ │ │ │
|
||||
│ │ │ │ │
|
||||
│ CONTAINERS: Docker Compose (dev), Kubernetes (prod) │
|
||||
│ CONNECTION POOLING: PgBouncer for PostgreSQL │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ IMPLEMENTATION PROGRESS — PHASE 7 MVP ✅ │
|
||||
├─────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Phase 0: Foundation (P0) ✅ COMPLETE │
|
||||
│ ✓ Monorepo (Turborepo), Docker, Prisma, CI/CD │
|
||||
│ │
|
||||
│ Phase 1: Core Auth & Listings (P1) ✅ COMPLETE │
|
||||
│ ✓ JWT + OAuth, MFA/TOTP, Listings CRUD, Search (Typesense), Security │
|
||||
│ │
|
||||
│ Phase 2: Monetization & Operations (P2) ✅ COMPLETE │
|
||||
│ ✓ Payments (3 gateways), Subscriptions (4 tiers), Notifications, Admin │
|
||||
│ │
|
||||
│ Phase 3: AI & Advanced (P3) ✅ COMPLETE │
|
||||
│ ✓ Analytics, AI/ML services, MCP Integration, Monitoring │
|
||||
│ │
|
||||
│ Phase 4: Production Hardening (P0/P1) ✅ COMPLETE │
|
||||
│ ✓ JWT secrets, deployment pipeline, HMAC signing, CSRF, DB indexes │
|
||||
│ │
|
||||
│ Phase 5: Quality & Polish (P2) ✅ COMPLETE │
|
||||
│ ✓ Redis caching, error boundaries, Swagger docs, README/deployment │
|
||||
│ │
|
||||
│ Phase 6: MVP Completion & Audits (P0-P2) ✅ COMPLETE │
|
||||
│ ✓ Untracked files, i18n consolidation, Agent portal, AI integration, tests │
|
||||
│ │
|
||||
│ Phase 7: Post-MVP Improvements (P0-P2) 🔄 IN PROGRESS (Wave 14) │
|
||||
│ ✓ Waves 1-4: Critical bug fixes, production readiness, UI polish │
|
||||
│ ✓ Wave 5: Security audit, npm vulnerabilities, test coverage increase │
|
||||
│ ✓ Wave 6: Code hygiene, ESLint fixes, file commits │
|
||||
│ 🔄 Remaining: │
|
||||
│ - TEC-1650: Listing detail error handling (404 vs 500) │
|
||||
│ - TEC-1652: Full E2E test suite validation │
|
||||
│ - TEC-1657: Comprehensive audit logging │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ KEY METRICS & STATISTICS │
|
||||
├─────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Codebase Size: ~50,000+ LOC (excluding node_modules) │
|
||||
│ Backend Files: ~845 TypeScript files (18 modules + shared) │
|
||||
│ Frontend Files: ~245 TypeScript/TSX files (components + libs) │
|
||||
│ Database Models: 31 entities (fully normalized, 30+ indexes) │
|
||||
│ Migrations: 7+ applied to PostgreSQL 16 │
|
||||
│ API Endpoints: 100+ documented (Swagger/OpenAPI) │
|
||||
│ E2E Tests: 31 scenarios (web + API + load) │
|
||||
│ Unit Tests: 200+ test specs │
|
||||
│ Dependencies: 600+ npm packages (managed by pnpm) │
|
||||
│ │
|
||||
│ Deployment: Docker + Docker Compose + Kubernetes ready │
|
||||
│ Scalability: Connection pooling, caching, resilient services │
|
||||
│ Security: JWT, MFA, field encryption, rate limiting, CSRF, PII mask│
|
||||
│ Monitoring: Prometheus, Grafana, Sentry, structured logging │
|
||||
│ Performance: Baseline established, K6 load tests defined │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ DOCUMENTATION │
|
||||
├─────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Root Level: │
|
||||
│ • PROJECT_TRACKER.md Phase & issue tracking (7 phases, 40+ issues)
|
||||
│ • IMPLEMENTATION_PLAN.md Feature roadmap with status │
|
||||
│ • CODEBASE_OVERVIEW.md This comprehensive guide │
|
||||
│ │
|
||||
│ Technical (/docs/): │
|
||||
│ • architecture.md DDD layers, CQRS patterns │
|
||||
│ • api-endpoints.md Swagger-generated endpoint reference │
|
||||
│ • api-error-codes.md Structured error taxonomy │
|
||||
│ • deployment.md Docker, K8s, CI/CD procedures │
|
||||
│ • dev-environment.md Local setup guide │
|
||||
│ • RUNBOOK.md Operations & troubleshooting │
|
||||
│ • PRODUCTION_READINESS.md Security, compliance checklist │
|
||||
│ │
|
||||
│ Audits (/docs/audits/): │
|
||||
│ • 80+ audit files documenting features & bug fixes │
|
||||
│ • Pricing audit, checkout flow, KYC, payment gateway tests │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
HOW FAR ALONG IS THIS PROJECT?
|
||||
|
||||
✅ PRODUCTION READY — MVP is feature-complete and battle-tested
|
||||
|
||||
The GoodGo platform is a fully-fledged, enterprise-grade real estate marketplace
|
||||
with comprehensive monetization, advanced search, AI/ML integration, and
|
||||
operational tooling. All critical features are implemented, tested, and
|
||||
documented. The remaining work (Phase 7 Wave 14) focuses on edge case handling
|
||||
and final validation before full production deployment.
|
||||
|
||||
IMMEDIATE NEXT STEPS:
|
||||
|
||||
1. Review PROJECT_TRACKER.md for remaining 3 issues in Wave 14
|
||||
2. Run `pnpm test:e2e` to validate all E2E scenarios
|
||||
3. Deploy with `docker-compose.prod.yml` or Kubernetes manifests
|
||||
4. Monitor with Grafana dashboards and Sentry
|
||||
|
||||
═══════════════════════════════════════════════════════════════════════════════════
|
||||
412
docs/architecture/CODEBASE_OVERVIEW.md
Normal file
412
docs/architecture/CODEBASE_OVERVIEW.md
Normal file
@@ -0,0 +1,412 @@
|
||||
# GoodGo Platform — Comprehensive Codebase Overview
|
||||
|
||||
**Generated:** April 12, 2026
|
||||
**Project Status:** MVP Complete — Phase 7 Wave 14 ✅ Build Green
|
||||
|
||||
---
|
||||
|
||||
## 1. TOP-LEVEL DIRECTORY STRUCTURE
|
||||
|
||||
```
|
||||
goodgo-platform-ai/
|
||||
├── apps/ # Monorepo applications
|
||||
│ ├── api/ # NestJS backend
|
||||
│ └── web/ # Next.js frontend
|
||||
├── libs/ # Shared libraries
|
||||
│ ├── mcp-servers/ # MCP server implementations
|
||||
│ └── ai-services/ # AI/ML services (Python FastAPI)
|
||||
├── prisma/ # Database schema & migrations
|
||||
│ ├── schema.prisma # Complete data model
|
||||
│ └── migrations/ # 7+ migration files
|
||||
├── docs/ # Technical documentation
|
||||
├── e2e/ # End-to-end tests (Playwright)
|
||||
├── monitoring/ # Observability stack
|
||||
│ ├── grafana/ # Dashboards
|
||||
│ ├── loki/ # Log aggregation
|
||||
│ ├── alertmanager/ # Alerts
|
||||
│ └── promtail/ # Log forwarding
|
||||
├── load-tests/ # K6 performance tests
|
||||
├── scripts/ # DevOps & automation
|
||||
├── infra/ # Infrastructure config
|
||||
│ └── pgbouncer/ # DB connection pooling
|
||||
├── .github/workflows/ # CI/CD pipelines
|
||||
├── docker-compose.yml # Local development
|
||||
├── docker-compose.prod.yml # Production stack
|
||||
├── PROJECT_TRACKER.md # Issue & phase tracking
|
||||
├── IMPLEMENTATION_PLAN.md # Feature roadmap
|
||||
└── package.json # Monorepo config (pnpm workspaces)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. API MODULES (`apps/api/src/modules/`) — 18 MODULES
|
||||
|
||||
### Core Authentication & Authorization
|
||||
- **auth/** — JWT, OAuth (Google/Zalo), MFA, TOTP backup codes
|
||||
- Subdirs: application, domain, infrastructure, presentation, __tests__
|
||||
- Key: JWT guards, passport strategies, role-based access
|
||||
|
||||
### Listings & Properties
|
||||
- **listings/** — CRUD, status management, media, AI price estimates
|
||||
- Moderation scoring, featured listings, expiration logic
|
||||
- Media upload with pre-signed URLs (AWS S3)
|
||||
|
||||
### Search & Discovery
|
||||
- **search/** — Typesense integration (full-text), geospatial (PostGIS)
|
||||
- Resilient repository with fallback to PostgreSQL
|
||||
- Filters: location, price, property type, bedrooms
|
||||
|
||||
### Transactions & Inquiries
|
||||
- **inquiries/** — Buyer-to-seller messages for specific listings
|
||||
- **leads/** — Agent CRM (lead scoring, status tracking, notes)
|
||||
|
||||
### Monetization
|
||||
- **payments/** — VNPay, MoMo, ZaloPay, Bank Transfer
|
||||
- Idempotency keys, webhook callbacks, refund handling
|
||||
- 4 payment types: subscription, listing fee, deposit, featured
|
||||
|
||||
- **subscriptions/** — Plans (FREE, AGENT_PRO, INVESTOR, ENTERPRISE)
|
||||
- Usage tracking, quota management, billing cycles
|
||||
|
||||
### Operations
|
||||
- **agents/** — Agent profiles, quality scores, service areas, verification
|
||||
- **admin/** — User bans, KYC approval, listing moderation, audit logs
|
||||
- **notifications/** — Email, SMS, Push (FCM), Zalo OA
|
||||
- Preferences per user/channel, template system
|
||||
|
||||
### Analytics & Intelligence
|
||||
- **analytics/** — Market reports, price index by district/city/type
|
||||
- Valuation engine integration (AI/ML service)
|
||||
|
||||
### Infrastructure & System
|
||||
- **health/** — Liveness/readiness probes, Kubernetes hooks
|
||||
- **metrics/** — Prometheus metrics, HTTP latency, error rates
|
||||
- **mcp/** — Model Context Protocol server for AI tools
|
||||
- **shared/** — Domain primitives, encryption, logging, error handling
|
||||
|
||||
**Code Metrics:**
|
||||
- ~845 TypeScript files
|
||||
- Layered DDD architecture: presentation → application → domain → infrastructure
|
||||
- Uses NestJS modules, CQRS pattern for complex operations
|
||||
|
||||
---
|
||||
|
||||
## 3. FRONTEND STRUCTURE (`apps/web/`)
|
||||
|
||||
### Root Layout
|
||||
- **app/layout.tsx** — Root wrapper
|
||||
- **app/[locale]/** — i18n routing (Vietnamese + English)
|
||||
|
||||
### Page Groups (Route Groups with Shared Layouts)
|
||||
- **(public)/** — Landing, listings, search (no auth required)
|
||||
- **(auth)/** — Login, register, OAuth callbacks
|
||||
- **(dashboard)/** — Seller/agent dashboard
|
||||
- **(admin)/** — Admin moderation, KYC review, user management
|
||||
|
||||
### Components (`components/`)
|
||||
```
|
||||
├── agents/ — Agent profiles, cards
|
||||
├── auth/ — Login forms, OAuth buttons
|
||||
├── charts/ — Market analytics, performance graphs (Recharts)
|
||||
├── comparison/ — Property comparison tool
|
||||
├── inquiries/ — Message threads
|
||||
├── leads/ — Lead management UI
|
||||
├── listings/ — List, create, edit, detail views
|
||||
├── map/ — Mapbox integration
|
||||
├── search/ — Filters, saved searches
|
||||
├── subscription/ — Plan selection, billing
|
||||
├── valuation/ — AI price estimates
|
||||
├── ui/ — Shadcn/ui components (button, card, modal, etc.)
|
||||
└── providers/ — Context providers (auth, query, etc.)
|
||||
```
|
||||
|
||||
### Libraries (`lib/`)
|
||||
```
|
||||
├── *-api.ts — React Query API clients (6 main ones)
|
||||
├── *-store.ts — Zustand state stores (auth, comparison)
|
||||
├── hooks/ — Custom React hooks (8 hooks)
|
||||
├── validations/ — Zod schemas (listing, auth, search)
|
||||
├── currency.ts — VND formatting & exchange rates
|
||||
├── image-blur.ts — Blur hash for image placeholders
|
||||
└── web-vitals.ts — Core Web Vitals tracking
|
||||
```
|
||||
|
||||
### i18n (`i18n/`)
|
||||
- Vietnamese & English message files
|
||||
- next-intl integration
|
||||
|
||||
**Frontend Metrics:**
|
||||
- ~245 TypeScript/TSX files
|
||||
- Built on: Next.js 15, React 18, Tailwind CSS, Shadcn/ui
|
||||
- State: Zustand + React Query
|
||||
- Forms: React Hook Form + Zod validation
|
||||
|
||||
---
|
||||
|
||||
## 4. PRISMA SCHEMA — DATA MODEL
|
||||
|
||||
**Database:** PostgreSQL 16 + PostGIS extension
|
||||
|
||||
### Total Models: 31
|
||||
|
||||
#### Authentication (5)
|
||||
| Model | Purpose |
|
||||
|-------|---------|
|
||||
| User | Main user profile + KYC status, MFA fields |
|
||||
| RefreshToken | JWT refresh token chain management |
|
||||
| OAuthAccount | Google/Zalo OAuth linkage |
|
||||
| Agent | Seller/Agent extended profile |
|
||||
| MfaChallenge | TOTP/backup code verification tracking |
|
||||
|
||||
#### Listings & Properties (4)
|
||||
| Model | Purpose |
|
||||
|-------|---------|
|
||||
| Property | Physical property details + geolocation |
|
||||
| PropertyMedia | Images/videos per property |
|
||||
| Listing | Listing instance (sale/rent) + status |
|
||||
| SavedSearch | User's saved search preferences |
|
||||
|
||||
#### Transactions (4)
|
||||
| Model | Purpose |
|
||||
|-------|---------|
|
||||
| Transaction | Buyer-seller transaction flow (inquiry → completed) |
|
||||
| Inquiry | Buyer questions on specific listings |
|
||||
| Lead | Agent CRM lead records |
|
||||
| Review | User reviews of agents/transactions |
|
||||
|
||||
#### Payments (2)
|
||||
| Model | Purpose |
|
||||
|-------|---------|
|
||||
| Payment | Payment records (all providers) |
|
||||
| Plan | Subscription tier definitions |
|
||||
|
||||
#### Orders & Escrow (3)
|
||||
| Model | Purpose |
|
||||
|-------|---------|
|
||||
| Order | Auction settlement order |
|
||||
| Escrow | Escrow holding for transactions |
|
||||
| Subscription | User's active subscription |
|
||||
|
||||
#### Analytics (2)
|
||||
| Model | Purpose |
|
||||
|-------|---------|
|
||||
| Valuation | AI-generated property valuations |
|
||||
| MarketIndex | Market statistics per district/city |
|
||||
|
||||
#### Operations (6)
|
||||
| Model | Purpose |
|
||||
|-------|---------|
|
||||
| NotificationLog | Sent notification records |
|
||||
| NotificationPreference | User notification opt-in/out |
|
||||
| AdminAuditLog | Admin action audit trail |
|
||||
| UsageRecord | Subscription usage tracking |
|
||||
|
||||
**Index Strategy:**
|
||||
- Single-column indexes on foreign keys, status fields, dates
|
||||
- Compound indexes for common query patterns (e.g., `[role, isActive, createdAt DESC]`)
|
||||
- GIST index on PostGIS location geometry
|
||||
|
||||
**Key Enums:**
|
||||
- UserRole: BUYER, SELLER, AGENT, ADMIN
|
||||
- PropertyType: APARTMENT, VILLA, TOWNHOUSE, LAND, OFFICE, SHOPHOUSE
|
||||
- TransactionType: SALE, RENT
|
||||
- PaymentProvider: VNPAY, MOMO, ZALOPAY, BANK_TRANSFER
|
||||
- PaymentStatus: PENDING, PROCESSING, COMPLETED, FAILED, REFUNDED
|
||||
|
||||
---
|
||||
|
||||
## 5. DOCUMENTATION & TRACKING
|
||||
|
||||
### Root-Level Planning Docs
|
||||
- **PROJECT_TRACKER.md** — 7 phases, 40+ issues, current status (Phase 7 Wave 14)
|
||||
- **IMPLEMENTATION_PLAN.md** — Feature roadmap with priority/status
|
||||
- **COMPREHENSIVE_AUDIT_2026-04-12.md** — Full system audit with implementation notes
|
||||
|
||||
### Technical Docs (`docs/`)
|
||||
- **architecture.md** — DDD layering, CQRS, module boundaries
|
||||
- **api-endpoints.md** — Swagger-generated endpoint reference
|
||||
- **api-error-codes.md** — Structured error code taxonomy
|
||||
- **deployment.md** — Docker, K8s, CI/CD pipeline steps
|
||||
- **RUNBOOK.md** — Operational procedures, troubleshooting
|
||||
- **PRODUCTION_READINESS.md** — Security, compliance, performance checklist
|
||||
|
||||
### Audit Directory (`docs/audits/`)
|
||||
- 80+ audit files documenting feature implementations
|
||||
- Pricing audit, checkout flow, KYC, payment gateway testing
|
||||
|
||||
---
|
||||
|
||||
## 6. DEPENDENCIES & TOOLING
|
||||
|
||||
### Monorepo Setup
|
||||
- **pnpm** v10.27.0 (workspace) — faster, strict peer deps
|
||||
- **Turbo** v2.9.4 — task orchestration & caching
|
||||
- **Node** ≥22.0.0
|
||||
|
||||
### Backend (NestJS)
|
||||
```
|
||||
Core: @nestjs/core ^11.0, @nestjs/common ^11.0
|
||||
DB: @prisma/client ^7.7, pg ^8.20
|
||||
Auth: @nestjs/jwt, @nestjs/passport, passport-jwt, passport-google-oauth20
|
||||
Cache: ioredis ^5.4
|
||||
Search: typesense ^3.0.5
|
||||
File Upload: @aws-sdk/client-s3, @aws-sdk/s3-request-presigner
|
||||
Payments: (custom integrations for VNPay, MoMo, ZaloPay)
|
||||
Monitoring: @sentry/nestjs, pino, prom-client
|
||||
Email: nodemailer
|
||||
2FA: otplib, qrcode
|
||||
```
|
||||
|
||||
### Frontend (Next.js)
|
||||
```
|
||||
Core: next ^15.5, react ^18.3, react-dom ^18.3
|
||||
Forms: react-hook-form ^7.72, @hookform/resolvers
|
||||
Validation: zod ^4.3
|
||||
State: zustand ^5.0, @tanstack/react-query ^5.96
|
||||
UI: tailwindcss ^3.4, lucide-react ^1.7, recharts ^3.8
|
||||
i18n: next-intl ^4.9
|
||||
Maps: mapbox-gl ^3.21
|
||||
Monitoring: @sentry/nextjs
|
||||
```
|
||||
|
||||
### Testing & Quality
|
||||
```
|
||||
Test: vitest ^4.1.3, @playwright/test ^1.59
|
||||
Lint: eslint ^9.39, prettier ^3.8, typescript-eslint
|
||||
Dependencies: dependency-cruiser (architecture validation)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. TEST COVERAGE & QUALITY
|
||||
|
||||
### Test Files: 242 total
|
||||
|
||||
#### API Tests
|
||||
- **Unit tests:** Payment gateways (VNPay, MoMo, ZaloPay), Money value objects, Platform fee logic
|
||||
- **Integration tests:** Auth flows, health checks, notifications
|
||||
- Located in `__tests__` subdirs within each module
|
||||
|
||||
#### Frontend Tests
|
||||
- **Unit tests:** Auth store, comparison store, currency formatting, validations
|
||||
- **E2E tests (Playwright):** 15+ web tests, 16+ API tests
|
||||
|
||||
#### E2E Test Coverage
|
||||
**Web Tests (15):**
|
||||
- auth-login, auth-register, auth-oauth-callback
|
||||
- homepage, navigation, responsive
|
||||
- create-listing, listing-detail
|
||||
- search, analytics
|
||||
- admin dashboard, KYC, moderation, users
|
||||
- dashboard
|
||||
|
||||
**API Tests (16):**
|
||||
- auth (login, register, profile, refresh, KYC)
|
||||
- listings, listing media, moderation
|
||||
- search
|
||||
- payments, payment callbacks
|
||||
- subscriptions
|
||||
- inquiries
|
||||
- mcp, admin
|
||||
|
||||
**Load Tests (K6):**
|
||||
- Baseline benchmarks for search, listings, auth endpoints
|
||||
- Concurrency testing up to 1000 virtual users
|
||||
|
||||
---
|
||||
|
||||
## 8. IMPLEMENTATION STATUS
|
||||
|
||||
### ✅ COMPLETE (Phase 7 MVP)
|
||||
1. **Foundation** — Monorepo, Docker, Prisma schema, CI/CD
|
||||
2. **Auth** — JWT, OAuth, MFA/TOTP, session management
|
||||
3. **Listings** — Full CRUD, media upload, status workflow
|
||||
4. **Search** — Typesense + PostGIS geo-search
|
||||
5. **Payments** — 3 VN payment gateways, webhook handling
|
||||
6. **Subscriptions** — 4 tiers, quota tracking
|
||||
7. **Notifications** — Email, SMS, Push, Zalo OA
|
||||
8. **Admin Panel** — Moderation, user management, audit logs
|
||||
9. **Agents** — Portal, inquiries, lead CRM, quality metrics
|
||||
10. **Analytics** — Market reports, AI valuation service
|
||||
11. **Security** — Rate limiting, CSRF, field encryption, PII masking
|
||||
12. **Monitoring** — Prometheus, Grafana, Sentry, log aggregation
|
||||
13. **Testing** — Unit tests, E2E tests (Playwright), load tests (K6)
|
||||
|
||||
### 🔄 IN PROGRESS / REMAINING
|
||||
- Per Wave 14:
|
||||
- TEC-1650: Listing detail non-existent ID error handling
|
||||
- TEC-1652: Full E2E test suite validation
|
||||
- TEC-1657: Comprehensive audit logging
|
||||
|
||||
### Database Migrations
|
||||
- 7+ migrations applied
|
||||
- Connection pooling (PgBouncer)
|
||||
- PostGIS extension enabled
|
||||
|
||||
---
|
||||
|
||||
## 9. PROJECT MATURITY INDICATORS
|
||||
|
||||
| Dimension | Status | Evidence |
|
||||
|-----------|--------|----------|
|
||||
| **Architecture** | Production-Ready | DDD, CQRS, layered modules, clear boundaries |
|
||||
| **Code Quality** | High | 242 tests, ESLint enforcement, module cruiser |
|
||||
| **Security** | Hardened | JWT, MFA, encryption, rate limiting, CSRF, PII masking |
|
||||
| **Documentation** | Comprehensive | 80+ audit files, runbooks, error codes, architecture |
|
||||
| **Performance** | Optimized | Redis caching, Typesense search, query optimization, load tests |
|
||||
| **Monitoring** | Complete | Prometheus, Grafana, Sentry, structured logging |
|
||||
| **DevOps** | Mature | Docker, Kubernetes config, CI/CD pipelines, smoke tests |
|
||||
| **Scaling** | Prepared | Connection pooling, caching layer, resilient services |
|
||||
|
||||
---
|
||||
|
||||
## 10. KEY STATISTICS
|
||||
|
||||
```
|
||||
Backend Files: ~845 TypeScript files
|
||||
Frontend Files: ~245 TypeScript/TSX files
|
||||
Total Test Files: 242 (unit + E2E + load)
|
||||
API Modules: 18 feature modules + 1 shared
|
||||
Database Models: 31 (fully normalized)
|
||||
Migrations: 7+ applied to PostgreSQL 16
|
||||
API Endpoints: 100+ documented
|
||||
E2E Test Cases: 31 (web + API)
|
||||
Load Test Scenarios: 5+ K6 scripts
|
||||
Documentation: 80+ audit files + runbooks
|
||||
Lines of Code: ~50,000+ (excluding node_modules)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. TECH STACK SUMMARY
|
||||
|
||||
| Layer | Technology |
|
||||
|-------|-----------|
|
||||
| **Frontend** | Next.js 15, React 18, Tailwind CSS, Shadcn/ui |
|
||||
| **Backend** | NestJS 11, TypeScript 6 |
|
||||
| **Database** | PostgreSQL 16 + PostGIS |
|
||||
| **Cache** | Redis (ioredis) |
|
||||
| **Search** | Typesense 3.0 |
|
||||
| **File Storage** | AWS S3 |
|
||||
| **Payments** | VNPay, MoMo, ZaloPay |
|
||||
| **Auth** | JWT + OAuth2 (Google, Zalo) |
|
||||
| **Notifications** | Email (Nodemailer), SMS, FCM, Zalo OA |
|
||||
| **Monitoring** | Prometheus, Grafana, Sentry |
|
||||
| **Logs** | Pino + Loki |
|
||||
| **Testing** | Playwright (E2E), Vitest (unit), K6 (load) |
|
||||
| **Package Manager** | pnpm 10.27 |
|
||||
| **Orchestration** | Turbo |
|
||||
| **Containerization** | Docker + Docker Compose |
|
||||
| **i18n** | next-intl (Vietnamese + English) |
|
||||
|
||||
---
|
||||
|
||||
## 12. NEXT STEPS FOR DEVELOPERS
|
||||
|
||||
1. **Local Setup:** `docker-compose up` → database + API + frontend
|
||||
2. **Run Tests:** `pnpm test` (unit), `pnpm test:e2e` (E2E)
|
||||
3. **Check Status:** Review PROJECT_TRACKER.md for ongoing issues
|
||||
4. **Architecture:** Read docs/architecture.md for module boundaries
|
||||
5. **API:** Browse docs/api-endpoints.md (Swagger-generated)
|
||||
6. **Deploy:** Follow docs/deployment.md for production setup
|
||||
|
||||
648
docs/architecture/FILE_MAPPING_GUIDE.md
Normal file
648
docs/architecture/FILE_MAPPING_GUIDE.md
Normal file
@@ -0,0 +1,648 @@
|
||||
# GoodGo Frontend: File-by-File i18n & A11y Implementation Guide
|
||||
|
||||
## 📋 Complete File Mapping
|
||||
|
||||
### PHASE 1: INFRASTRUCTURE SETUP
|
||||
|
||||
#### 1. `middleware.ts` (CRITICAL)
|
||||
**Current:** Auth routing only
|
||||
**Changes:**
|
||||
- Add locale detection from URL pathname
|
||||
- Add cookie-based locale storage
|
||||
- Redirect `/en/*` and `/vi/*` paths appropriately
|
||||
- Add Accept-Language header fallback
|
||||
|
||||
**Pseudo-code:**
|
||||
```typescript
|
||||
export function middleware(request: NextRequest) {
|
||||
const pathname = request.nextUrl.pathname;
|
||||
|
||||
// Extract locale from URL: /en/*, /vi/*, or default
|
||||
const locale = extractLocale(pathname) || getPreferredLocale(request);
|
||||
|
||||
// ... existing auth logic ...
|
||||
|
||||
// If no locale prefix, add it
|
||||
if (!locale) {
|
||||
return NextResponse.redirect(new URL(`/${locale}${pathname}`, request.url));
|
||||
}
|
||||
|
||||
// Set locale cookie for client-side
|
||||
response.cookies.set('goodgo_locale', locale);
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. `app/layout.tsx` (CRITICAL)
|
||||
**Current:** Thai providers, hardcoded Vietnamese metadata
|
||||
**Changes:**
|
||||
- Change `lang="vi"` to dynamic locale
|
||||
- Update metadata to be i18n-aware
|
||||
- Wrap with `NextIntlClientProvider` from next-intl
|
||||
- Keep existing providers (ThemeProvider, QueryProvider, AuthProvider)
|
||||
|
||||
**Key changes:**
|
||||
```typescript
|
||||
import { getLocale, getTranslations } from 'next-intl/server';
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
const locale = getLocale();
|
||||
const t = getTranslations();
|
||||
|
||||
return {
|
||||
title: t('common.site_name'),
|
||||
description: t('common.site_description'),
|
||||
openGraph: {
|
||||
locale: locale === 'en' ? 'en_US' : 'vi_VN',
|
||||
...
|
||||
}
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. `i18n/config.ts` (NEW)
|
||||
**Create new file** with i18n configuration:
|
||||
```typescript
|
||||
export const locales = ['en', 'vi'] as const;
|
||||
export const defaultLocale = 'vi';
|
||||
|
||||
export const timeZone = 'Asia/Ho_Chi_Minh';
|
||||
```
|
||||
|
||||
#### 4. `public/locales/en.json` (NEW - LARGE FILE)
|
||||
**Structure:**
|
||||
```json
|
||||
{
|
||||
"common": {
|
||||
"site_name": "GoodGo",
|
||||
"site_description": "Smart real estate platform in Vietnam",
|
||||
"home": "Home",
|
||||
"search": "Search",
|
||||
"dashboard": "Dashboard",
|
||||
"logout": "Logout",
|
||||
"loading": "Loading...",
|
||||
"error": "An error occurred",
|
||||
"try_again": "Try again"
|
||||
},
|
||||
"auth": {
|
||||
"login": "Login",
|
||||
"register": "Register",
|
||||
"phone": "Phone number",
|
||||
"password": "Password",
|
||||
"confirm_password": "Confirm password",
|
||||
"no_account": "Don't have an account?",
|
||||
"sign_up": "Sign up",
|
||||
"sign_in": "Sign in",
|
||||
"oauth_failed": "Social login failed. Please try again.",
|
||||
"access_denied": "You denied access. Please try again.",
|
||||
"invalid_request": "Invalid login request. Please try again.",
|
||||
"server_error": "Server error. Please try again later.",
|
||||
"show_password": "Show",
|
||||
"hide_password": "Hide"
|
||||
},
|
||||
"property": {
|
||||
"apartment": "Apartment",
|
||||
"house": "House",
|
||||
"villa": "Villa",
|
||||
"land": "Land",
|
||||
"office": "Office",
|
||||
"shophouse": "Shophouse",
|
||||
"price": "Price",
|
||||
"area": "Area",
|
||||
"bedrooms": "Bedrooms",
|
||||
"bathrooms": "Bathrooms",
|
||||
"direction": "Direction"
|
||||
},
|
||||
"transaction": {
|
||||
"sale": "Sale",
|
||||
"rent": "Rent",
|
||||
"buy": "Buy",
|
||||
"lease": "Lease"
|
||||
},
|
||||
"direction": {
|
||||
"north": "North",
|
||||
"south": "South",
|
||||
"east": "East",
|
||||
"west": "West",
|
||||
"northeast": "Northeast",
|
||||
"northwest": "Northwest",
|
||||
"southeast": "Southeast",
|
||||
"southwest": "Southwest"
|
||||
},
|
||||
"status": {
|
||||
"draft": "Draft",
|
||||
"pending_review": "Pending review",
|
||||
"active": "Active",
|
||||
"reserved": "Reserved",
|
||||
"sold": "Sold",
|
||||
"rented": "Rented",
|
||||
"expired": "Expired",
|
||||
"rejected": "Rejected"
|
||||
},
|
||||
"validation": {
|
||||
"required": "This field is required",
|
||||
"min_length": "Minimum {count} characters",
|
||||
"invalid_phone": "Invalid phone number",
|
||||
"invalid_email": "Invalid email",
|
||||
"passwords_match": "Passwords must match"
|
||||
},
|
||||
"navigation": {
|
||||
"home": "Home",
|
||||
"search": "Search",
|
||||
"create_listing": "Create listing",
|
||||
"my_listings": "My listings",
|
||||
"analytics": "Analytics",
|
||||
"valuation": "Valuation",
|
||||
"profile": "Profile",
|
||||
"subscription": "Subscription",
|
||||
"payments": "Payments",
|
||||
"admin_dashboard": "Admin",
|
||||
"admin_users": "Users",
|
||||
"admin_kyc": "KYC",
|
||||
"admin_moderation": "Moderation"
|
||||
},
|
||||
"landing": {
|
||||
"hero_title": "Find your perfect real estate",
|
||||
"hero_subtitle": "Smart real estate platform in Vietnam",
|
||||
"search_placeholder": "Enter area, project, or keyword...",
|
||||
"featured_listings": "Featured listings",
|
||||
"districts": "Popular districts",
|
||||
"stats_title": "GoodGo in numbers",
|
||||
"stats_listings": "Listings",
|
||||
"stats_users": "Users",
|
||||
"stats_transactions": "Successful transactions",
|
||||
"stats_cities": "Cities",
|
||||
"cta_title": "Have a property to list?",
|
||||
"cta_subtitle": "List for free today, reach thousands of potential buyers",
|
||||
"cta_register": "Sign up free",
|
||||
"cta_search": "Search now"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 5. `public/locales/vi.json` (NEW - LARGE FILE)
|
||||
Same structure as en.json but with Vietnamese translations.
|
||||
|
||||
---
|
||||
|
||||
### PHASE 2: CORE COMPONENT UPDATES
|
||||
|
||||
#### Files Requiring Translation Hook Integration
|
||||
|
||||
##### Layout Files
|
||||
|
||||
1. **`app/(public)/layout.tsx`**
|
||||
```typescript
|
||||
// Current: Hardcoded nav items
|
||||
const navItems = [
|
||||
{ href: '/', label: 'Trang chủ' },
|
||||
{ href: '/search', label: 'Tìm kiếm' },
|
||||
];
|
||||
|
||||
// After i18n:
|
||||
export default function PublicLayout() {
|
||||
const t = useTranslations('navigation');
|
||||
const navItems = [
|
||||
{ href: '/', label: t('home') },
|
||||
{ href: '/search', label: t('search') },
|
||||
];
|
||||
|
||||
// Also update footer content
|
||||
}
|
||||
```
|
||||
|
||||
2. **`app/(dashboard)/layout.tsx`**
|
||||
```typescript
|
||||
// Update all 8 nav items to use t('navigation.item_name')
|
||||
// Update theme toggle aria-label
|
||||
const toggleLabel = theme === 'light'
|
||||
? t('common.toggle_dark_mode')
|
||||
: t('common.toggle_light_mode');
|
||||
```
|
||||
|
||||
3. **`app/(auth)/layout.tsx`**
|
||||
Update any error messages or labels to use translations.
|
||||
|
||||
##### Page Files
|
||||
|
||||
1. **`app/(public)/page.tsx` (LARGE FILE)**
|
||||
**Areas to update:**
|
||||
- Hero section (title, subtitle)
|
||||
- Search form (placeholder)
|
||||
- Property type badges
|
||||
- Price ranges
|
||||
- City options
|
||||
- Section headings
|
||||
- Stats labels
|
||||
- CTA buttons
|
||||
|
||||
```typescript
|
||||
export default function LandingPage() {
|
||||
const t = useTranslations();
|
||||
|
||||
const PROPERTY_TYPES_LABELS = PROPERTY_TYPES.map(pt => ({
|
||||
value: pt.value,
|
||||
label: t(`property.${pt.value.toLowerCase()}`),
|
||||
}));
|
||||
|
||||
// Update all hardcoded strings:
|
||||
// Hero title: t('landing.hero_title')
|
||||
// Hero subtitle: t('landing.hero_subtitle')
|
||||
// Search placeholder: t('landing.search_placeholder')
|
||||
// etc.
|
||||
}
|
||||
```
|
||||
|
||||
2. **`app/(auth)/login/page.tsx`**
|
||||
```typescript
|
||||
// Update all form labels to use t()
|
||||
const phoneLabel = t('auth.phone');
|
||||
const passwordLabel = t('auth.password');
|
||||
const loginButton = t('auth.sign_in');
|
||||
|
||||
// OAuth error messages - move to translations
|
||||
const OAUTH_ERROR_MESSAGES = {
|
||||
oauth_failed: t('auth.oauth_failed'),
|
||||
access_denied: t('auth.access_denied'),
|
||||
// ... etc
|
||||
};
|
||||
```
|
||||
|
||||
3. **`app/(auth)/register/page.tsx`**
|
||||
Same pattern as login page.
|
||||
|
||||
4. **`app/(dashboard)/dashboard/page.tsx`** and all other dashboard pages
|
||||
Update section titles, empty states, button labels.
|
||||
|
||||
##### Search & Listing Pages
|
||||
|
||||
1. **`app/(public)/search/page.tsx`**
|
||||
Update search results headings, empty states, filter labels.
|
||||
|
||||
2. **`app/(public)/listings/[id]/page.tsx`**
|
||||
Update property detail labels.
|
||||
|
||||
3. **`app/(dashboard)/listings/page.tsx`**
|
||||
Update table headers, status labels, action labels.
|
||||
|
||||
4. **`app/(dashboard)/listings/new/page.tsx`**
|
||||
Uses listing-form-steps component (see below).
|
||||
|
||||
---
|
||||
|
||||
#### Component Files
|
||||
|
||||
##### Critical Components (Do First)
|
||||
|
||||
1. **`components/search/filter-bar.tsx` (HIGH PRIORITY)**
|
||||
```typescript
|
||||
// Current: Hardcoded arrays
|
||||
const CITIES = ['Hồ Chí Minh', 'Hà Nội', 'Đà Nẵng', ...];
|
||||
const PRICE_RANGES = [
|
||||
{ label: 'Dưới 1 tỷ', ... },
|
||||
{ label: '1 - 3 tỷ', ... },
|
||||
];
|
||||
|
||||
// After i18n:
|
||||
const CITIES = t('locations.cities').split(',');
|
||||
const PRICE_RANGES = [
|
||||
{ label: t('search.price_under_1b'), ... },
|
||||
{ label: t('search.price_1_3b'), ... },
|
||||
];
|
||||
```
|
||||
|
||||
2. **`components/listings/listing-form-steps.tsx` (HIGH PRIORITY - LARGE FILE)**
|
||||
This multi-step form has many labels to translate:
|
||||
- Step 1: Transaction type, property type, title, description
|
||||
- Step 2: Address fields, location
|
||||
- Step 3: Area, rooms, bathrooms, direction, year built, etc.
|
||||
- Step 4: Pricing
|
||||
|
||||
All field labels should use `t('form.field_name')` pattern.
|
||||
|
||||
3. **`components/auth/oauth-buttons.tsx`**
|
||||
```typescript
|
||||
// Update button text
|
||||
<Button>
|
||||
{t('auth.google')} // Currently hardcoded "Google"
|
||||
</Button>
|
||||
<Button>
|
||||
{t('auth.zalo')} // Currently hardcoded "Zalo"
|
||||
</Button>
|
||||
```
|
||||
|
||||
##### Medium Priority Components
|
||||
|
||||
1. **`components/search/property-card.tsx`**
|
||||
```typescript
|
||||
// Update PROPERTY_TYPE_LABELS to use translations
|
||||
const t = useTranslations();
|
||||
const PROPERTY_TYPE_LABELS = {
|
||||
APARTMENT: t('property.apartment'),
|
||||
HOUSE: t('property.house'),
|
||||
// ... etc
|
||||
};
|
||||
|
||||
// Update aria-labels to use translations
|
||||
aria-label={t('property.card_label', {
|
||||
title: listing.property.title,
|
||||
type: propertyTypeLabel,
|
||||
price: formatPrice(listing.priceVND)
|
||||
})}
|
||||
```
|
||||
|
||||
2. **`components/listings/listing-status-badge.tsx`**
|
||||
```typescript
|
||||
// Update status labels
|
||||
const LISTING_STATUSES = {
|
||||
DRAFT: { label: t('status.draft'), variant: 'secondary' },
|
||||
ACTIVE: { label: t('status.active'), variant: 'success' },
|
||||
// ... etc
|
||||
};
|
||||
```
|
||||
|
||||
3. **`components/valuation/valuation-form.tsx`**
|
||||
Update form labels and buttons.
|
||||
|
||||
4. **`components/listings/image-upload.tsx`**
|
||||
Update button text and error messages.
|
||||
|
||||
5. **All `components/ui/*.tsx` files with text**
|
||||
- Button: any default text
|
||||
- Dialog: Close button aria-label
|
||||
- Input: placeholder attrs if hardcoded
|
||||
- Label: any default text
|
||||
- Others: similar
|
||||
|
||||
---
|
||||
|
||||
### PHASE 3: VALIDATION & ERROR MESSAGES
|
||||
|
||||
#### 1. `lib/validations/auth.ts`
|
||||
```typescript
|
||||
// Current:
|
||||
const loginSchema = z.object({
|
||||
phone: z.string().min(1, 'Vui lòng nhập số điện thoại'),
|
||||
password: z.string().min(1, 'Vui lòng nhập mật khẩu'),
|
||||
});
|
||||
|
||||
// After i18n - move to message files and use in component:
|
||||
// In component:
|
||||
const t = useTranslations('validation');
|
||||
const schema = z.object({
|
||||
phone: z.string().min(1, t('required')),
|
||||
password: z.string().min(1, t('required')),
|
||||
});
|
||||
```
|
||||
|
||||
#### 2. `lib/validations/listings.ts` (LARGE FILE)
|
||||
Update all Zod validation error messages:
|
||||
- "Vui lòng chọn loại giao dịch" → `t('validation.transaction_required')`
|
||||
- "Tiêu đề tối thiểu 5 ký tự" → `t('validation.title_min_length')`
|
||||
- All other validation messages
|
||||
|
||||
#### 3. `lib/validations/valuation.ts`
|
||||
Similar pattern to listings.
|
||||
|
||||
---
|
||||
|
||||
### PHASE 4: UTILITY UPDATES
|
||||
|
||||
#### 1. `lib/utils.ts`
|
||||
No changes (already minimal).
|
||||
|
||||
#### 2. `lib/auth-store.ts`
|
||||
```typescript
|
||||
// Check if any error messages are hardcoded
|
||||
// If so, move to i18n and pass locale context
|
||||
```
|
||||
|
||||
#### 3. `lib/api-client.ts`
|
||||
Check if error messages from API need i18n wrapping.
|
||||
|
||||
#### 4. All `lib/*-api.ts` files
|
||||
Update error message handling if needed.
|
||||
|
||||
---
|
||||
|
||||
### PHASE 5: ACCESSIBILITY UPDATES
|
||||
|
||||
#### 1. `components/ui/dialog.tsx` (CRITICAL A11y)
|
||||
**Add focus management:**
|
||||
```typescript
|
||||
// Add focus trap
|
||||
// Save initial focus element
|
||||
// On mount: move focus to dialog
|
||||
// On close: restore focus to initial element
|
||||
// On Escape key: close dialog
|
||||
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
function Dialog() {
|
||||
const initialFocusRef = useRef<HTMLElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
// Set initial focus
|
||||
const firstButton = dialogRef.current?.querySelector('button');
|
||||
firstButton?.focus();
|
||||
|
||||
// Trap focus
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Tab') {
|
||||
// Prevent focus from leaving dialog
|
||||
}
|
||||
if (e.key === 'Escape') {
|
||||
onClose?.();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('keydown', handleKeyDown);
|
||||
return () => {
|
||||
document.removeEventListener('keydown', handleKeyDown);
|
||||
// Restore focus
|
||||
(initialFocusRef.current as HTMLElement | null)?.focus();
|
||||
};
|
||||
}, []);
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. `components/ui/input.tsx`
|
||||
Add aria-describedby for error messages:
|
||||
```typescript
|
||||
export function Input({ error, ...props }) {
|
||||
const errorId = `${props.id}-error`;
|
||||
return (
|
||||
<>
|
||||
<input
|
||||
{...props}
|
||||
aria-invalid={!!error}
|
||||
aria-describedby={error ? errorId : undefined}
|
||||
/>
|
||||
{error && <p id={errorId} role="alert">{error}</p>}
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. `components/ui/button.tsx`
|
||||
Ensure all buttons have visible focus indicator (already in CSS likely).
|
||||
Add aria-busy for loading state if used:
|
||||
```typescript
|
||||
export function Button({ disabled, isLoading, ...props }) {
|
||||
return (
|
||||
<button
|
||||
{...props}
|
||||
disabled={disabled || isLoading}
|
||||
aria-busy={isLoading}
|
||||
>
|
||||
{/* content */}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. Form Components
|
||||
Update all forms to use aria-describedby for error messages:
|
||||
- `app/(auth)/login/page.tsx` — Already has role="alert" ✓ but could use aria-describedby
|
||||
- `app/(auth)/register/page.tsx` — Same
|
||||
- `components/listings/listing-form-steps.tsx` — Add aria-describedby
|
||||
- `components/search/filter-bar.tsx` — Ensure accessible labels
|
||||
|
||||
#### 5. All Icon-Only Buttons
|
||||
Find all buttons with only icons and add aria-label:
|
||||
```typescript
|
||||
// Search in components for: <Button> with only SVG children
|
||||
// Add aria-label={t('...')}
|
||||
|
||||
// Examples:
|
||||
<Button aria-label={t('common.close')}>
|
||||
<X />
|
||||
</Button>
|
||||
|
||||
<Button aria-label={t('common.toggle_dark_mode')}>
|
||||
<Moon />
|
||||
</Button>
|
||||
```
|
||||
|
||||
#### 6. Loading Spinners
|
||||
Add aria-busy and aria-label:
|
||||
```typescript
|
||||
// In app/(public)/page.tsx and similar:
|
||||
<div aria-busy={loadingFeatured} aria-label={t('common.loading')}>
|
||||
<div className="h-8 w-8 animate-spin rounded-full..." />
|
||||
</div>
|
||||
```
|
||||
|
||||
#### 7. `components/listings/image-gallery.tsx`
|
||||
Add keyboard navigation (arrow keys):
|
||||
```typescript
|
||||
// Add keyboard event handler for arrow keys
|
||||
// Left/Right arrows to navigate images
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PHASE 6: TEST SETUP UPDATES
|
||||
|
||||
#### 1. `vitest.setup.ts`
|
||||
```typescript
|
||||
// Mock next-intl for tests
|
||||
vi.mock('next-intl', () => ({
|
||||
useTranslations: () => (key) => key, // Return key as-is for testing
|
||||
getTranslations: async () => (key) => key,
|
||||
}));
|
||||
|
||||
// Or provide full mock messages
|
||||
const mockMessages = {
|
||||
common: { home: 'Home', search: 'Search' },
|
||||
auth: { login: 'Login', register: 'Register' },
|
||||
// ... etc
|
||||
};
|
||||
|
||||
vi.mock('next-intl', () => ({
|
||||
useTranslations: (namespace) => (key) => mockMessages[namespace]?.[key] || key,
|
||||
}));
|
||||
```
|
||||
|
||||
#### 2. `vitest.config.ts`
|
||||
May need to add path aliases or test environment setup.
|
||||
|
||||
#### 3. Update all test files in `__tests__/` folders
|
||||
- Add locale prop to component renders
|
||||
- Test both English and Vietnamese if applicable
|
||||
- Mock i18n translations
|
||||
|
||||
---
|
||||
|
||||
## 📊 Summary: Files by Update Complexity
|
||||
|
||||
### Trivial (5 min each)
|
||||
- `app/robots.ts`
|
||||
- `app/sitemap.ts`
|
||||
- `components/ui/badge.tsx`
|
||||
- `components/ui/card.tsx`
|
||||
- `components/ui/tabs.tsx`
|
||||
|
||||
### Simple (15-30 min each)
|
||||
- `app/(admin)/*.tsx` files (3 files)
|
||||
- `app/(dashboard)/analytics/page.tsx`
|
||||
- `app/(dashboard)/profile/page.tsx`
|
||||
- `app/(dashboard)/subscription/page.tsx`
|
||||
- `app/(dashboard)/payments/page.tsx`
|
||||
- `components/ui/*.tsx` (8 files)
|
||||
- `components/auth/oauth-buttons.tsx`
|
||||
- `components/listings/listing-status-badge.tsx`
|
||||
|
||||
### Medium (30-60 min each)
|
||||
- `app/(public)/layout.tsx`
|
||||
- `app/(auth)/login/page.tsx`
|
||||
- `app/(auth)/register/page.tsx`
|
||||
- `app/(dashboard)/layout.tsx`
|
||||
- `app/(dashboard)/dashboard/page.tsx`
|
||||
- `app/(public)/search/page.tsx`
|
||||
- `components/search/property-card.tsx`
|
||||
- `components/search/filter-bar.tsx`
|
||||
- `components/listings/image-upload.tsx`
|
||||
- `components/valuation/*.tsx` (3 files)
|
||||
|
||||
### Complex (1-2 hours each)
|
||||
- `app/(public)/page.tsx` (landing page - many sections)
|
||||
- `components/listings/listing-form-steps.tsx` (multi-step form)
|
||||
- `components/map/listing-map.tsx` (if has labels)
|
||||
- `components/charts/*.tsx` (3 files - chart labels)
|
||||
|
||||
### Critical Infrastructure
|
||||
- `middleware.ts` (30-45 min)
|
||||
- `app/layout.tsx` (30 min)
|
||||
- `lib/validations/*.ts` (3 files - 45 min)
|
||||
|
||||
---
|
||||
|
||||
## ✅ Validation Checklist
|
||||
|
||||
Before considering i18n + A11y complete:
|
||||
|
||||
### i18n Verification
|
||||
- [ ] Both `/en/*` and `/vi/*` routes work
|
||||
- [ ] All text from messages files, not hardcoded
|
||||
- [ ] Metadata changes with locale
|
||||
- [ ] Cookies/headers work for locale selection
|
||||
- [ ] Validation messages use i18n
|
||||
- [ ] All enums use translations
|
||||
- [ ] Tests mock i18n correctly
|
||||
|
||||
### A11y Verification
|
||||
- [ ] Focus trap works in dialogs
|
||||
- [ ] Focus indicator visible on all inputs
|
||||
- [ ] Form errors linked with aria-describedby
|
||||
- [ ] Icon buttons all have aria-labels
|
||||
- [ ] Color contrast >= 4.5:1 for text (AA standard)
|
||||
- [ ] Keyboard navigation works everywhere
|
||||
- [ ] Screen reader testing (NVDA/JAWS)
|
||||
- [ ] Loading spinners have aria-busy
|
||||
- [ ] All tables have proper headers
|
||||
|
||||
---
|
||||
|
||||
**Generated:** April 9, 2026
|
||||
**Confidence:** High
|
||||
**Total Estimated Files to Update:** 50-60 files
|
||||
383
docs/architecture/IMPLEMENTATION_PLAN.md
Normal file
383
docs/architecture/IMPLEMENTATION_PLAN.md
Normal file
@@ -0,0 +1,383 @@
|
||||
# GoodGo Platform AI — Implementation Plan
|
||||
|
||||
**Last Updated:** 2026-04-12
|
||||
|
||||
---
|
||||
|
||||
## Milestones
|
||||
|
||||
### Milestone 1: Walking Skeleton (Phase 0)
|
||||
|
||||
**Goal:** Any engineer can clone, install, and start developing.
|
||||
|
||||
**Execution Order:**
|
||||
|
||||
1. **[TEC-1415] Monorepo Scaffolding** + **[TEC-1416] Docker Compose** (parallel — no deps)
|
||||
2. **[TEC-1420] ESLint/Prettier** (after F1)
|
||||
3. **[TEC-1417] Prisma Schema** (after F1 + F2)
|
||||
4. **[TEC-1418] Shared Module** (after F1)
|
||||
5. **[TEC-1419] CI/CD Pipeline** (after F1)
|
||||
|
||||
```
|
||||
F1 (Monorepo) ──┬── F6 (Lint/Prettier)
|
||||
├── F3 (Prisma Schema) ←── F2 (Docker)
|
||||
├── F4 (Shared Module)
|
||||
└── F5 (CI/CD)
|
||||
F2 (Docker) ─────┘
|
||||
```
|
||||
|
||||
### Milestone 2: Core Product (Phase 1)
|
||||
|
||||
**Goal:** Users can register, post listings, and search properties.
|
||||
|
||||
**Execution Order:**
|
||||
|
||||
1. **[TEC-1421] Auth Backend** (after F3, F4)
|
||||
2. **[TEC-1425] Security Hardening** + **[TEC-1426] Error Handling** (parallel, after F1/F4)
|
||||
3. **[TEC-1422] Auth Frontend** (after C1)
|
||||
4. **[TEC-1423] Listings Backend** (after C1)
|
||||
5. **[TEC-1424] Search Backend** (after C3)
|
||||
6. **[TEC-1427] Listings Frontend** (after C3)
|
||||
7. **[TEC-1428] Search + Landing Frontend** (after C5)
|
||||
|
||||
```
|
||||
F3 + F4 ──→ C1 (Auth BE) ──┬── C2 (Auth FE)
|
||||
├── C3 (Listings BE) ──┬── C5 (Search BE) ──→ C6 (Search FE)
|
||||
│ └── C4 (Listings FE)
|
||||
├── X1 (Security)
|
||||
└── X3 (Error Handling)
|
||||
```
|
||||
|
||||
### Milestone 3: Monetization (Phase 2)
|
||||
|
||||
**Goal:** Revenue-generating MVP with payments, subscriptions, and admin tools.
|
||||
|
||||
```
|
||||
C1 ──→ M1 (Payments) ──→ M2 (Subscriptions)
|
||||
C1 ──→ M3 (Notifications)
|
||||
C1 + C3 ──→ M4 (Admin)
|
||||
Phase 1 ──→ X4 (E2E Tests)
|
||||
```
|
||||
|
||||
### Milestone 4: AI-Powered (Phase 3)
|
||||
|
||||
**Goal:** Differentiated product with AI features.
|
||||
|
||||
```
|
||||
F2 ──→ A1 (AI/ML Container) ──→ A2 (Analytics)
|
||||
C5 + A2 ──→ A3 (MCP Servers)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependency Map
|
||||
|
||||
| Task | Depends On |
|
||||
| ------------- | ---------- |
|
||||
| TEC-1415 (F1) | None |
|
||||
| TEC-1416 (F2) | None |
|
||||
| TEC-1417 (F3) | F1, F2 |
|
||||
| TEC-1418 (F4) | F1 |
|
||||
| TEC-1419 (F5) | F1 |
|
||||
| TEC-1420 (F6) | F1 |
|
||||
| TEC-1421 (C1) | F3, F4 |
|
||||
| TEC-1422 (C2) | C1 |
|
||||
| TEC-1423 (C3) | C1, F3 |
|
||||
| TEC-1424 (C5) | C3, F2 |
|
||||
| TEC-1425 (X1) | F1 |
|
||||
| TEC-1426 (X3) | F4 |
|
||||
| TEC-1427 (C4) | C3 |
|
||||
| TEC-1428 (C6) | C5 |
|
||||
| TEC-1429 (M1) | C1 |
|
||||
| TEC-1430 (M2) | M1 |
|
||||
| TEC-1431 (M3) | C1 |
|
||||
| TEC-1432 (M4) | C1, C3 |
|
||||
| TEC-1433 (X4) | Phase 1 |
|
||||
|
||||
### Milestone 5: Production Hardening (Phase 4)
|
||||
|
||||
**Goal:** Fix all critical security issues. Establish production deployment capability.
|
||||
|
||||
**Execution Order:**
|
||||
|
||||
1. **[TEC-1449] JWT Secret Fix** + **[TEC-1451] HMAC Timing Fix** + **[TEC-1452] MinIO Fix** + **[TEC-1453] CSRF** (parallel — no deps between them)
|
||||
2. **[TEC-1455] DB Index** (independent — can run parallel with above)
|
||||
3. **[TEC-1450] Deployment Pipeline** (after security fixes verified)
|
||||
4. **[TEC-1457] Backups + Logs** (after deployment infra exists)
|
||||
5. **[TEC-1456] Test Coverage** (parallel — independent of infra)
|
||||
|
||||
```
|
||||
TEC-1449 (JWT) ──────┐
|
||||
TEC-1451 (HMAC) ─────┤
|
||||
TEC-1452 (MinIO) ────┼──→ TEC-1450 (Deploy Pipeline) ──→ TEC-1457 (Backups + Logs)
|
||||
TEC-1453 (CSRF) ─────┘
|
||||
TEC-1455 (DB Index) ──────────────────────────────────(independent)
|
||||
TEC-1456 (Tests) ─────────────────────────────────────(independent)
|
||||
```
|
||||
|
||||
### Milestone 6: Quality & Polish (Phase 5)
|
||||
|
||||
**Goal:** Production-quality UX, documentation, and performance.
|
||||
|
||||
```
|
||||
Phase 4 done ──→ TEC-1458 (Redis Caching)
|
||||
TEC-1459 (Frontend Polish) (parallel)
|
||||
TEC-1460 (OpenAPI/Swagger) (parallel)
|
||||
TEC-1461 (Documentation) (parallel)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependency Map (Phase 4-5)
|
||||
|
||||
| Task | Depends On |
|
||||
| --------------- | ----------------- |
|
||||
| TEC-1449 | None |
|
||||
| TEC-1450 | TEC-1449 (security first) |
|
||||
| TEC-1451 | None |
|
||||
| TEC-1452 | None |
|
||||
| TEC-1453 | None |
|
||||
| TEC-1455 | None |
|
||||
| TEC-1456 | None |
|
||||
| TEC-1457 | TEC-1450 |
|
||||
| TEC-1458 | Phase 4 |
|
||||
| TEC-1459 | None |
|
||||
| TEC-1460 | None |
|
||||
| TEC-1461 | None |
|
||||
|
||||
### Milestone 7: MVP Feature Completion & Audit (Phase 6)
|
||||
|
||||
**Goal:** Complete remaining MVP features (Agent Portal, AI, Payments), clean up tech debt from audit.
|
||||
|
||||
**Sprint 1 — Stabilize (Week 1):**
|
||||
1. **[TEC-1592] Commit untracked files** (P0, no deps)
|
||||
2. **[TEC-1593] Fix Architect agent** (P0, no deps)
|
||||
3. **[TEC-1594] i18n consolidation** (P1, no deps)
|
||||
|
||||
**Sprint 2 — Agent Portal + Payments (Weeks 2-3):**
|
||||
4. **[TEC-1595] Agent Portal** (P1, after TEC-1592)
|
||||
5. **[TEC-1597] Payment flow** (P1, after TEC-1592)
|
||||
6. **[TEC-1598] Smoke tests** (P1, independent)
|
||||
|
||||
**Sprint 3 — AI & Quality (Weeks 4-5):**
|
||||
7. **[TEC-1596] AI/ML integration** (P1, after TEC-1592)
|
||||
8. **[TEC-1599] Test coverage** (P2, independent)
|
||||
9. **[TEC-1600] OpenAPI docs** (P2, independent)
|
||||
|
||||
**Sprint 4 — Hardening (Weeks 5-6):**
|
||||
10. **[TEC-1601] K6 baselines** (P2, independent)
|
||||
11. **[TEC-1602] Security audit** (P2, after Phase 4 security fixes)
|
||||
12. **[TEC-1603] DB index optimization** (P2, independent)
|
||||
13. **[TEC-1604] Sentry integration** (P2, independent)
|
||||
|
||||
```
|
||||
TEC-1592 (Commit) ──┬── TEC-1595 (Agent Portal)
|
||||
├── TEC-1596 (AI/ML)
|
||||
└── TEC-1597 (Payments)
|
||||
TEC-1593 (Architect Fix) ─── (independent)
|
||||
TEC-1594 (i18n) ────────────── (independent)
|
||||
TEC-1598 (Smoke Tests) ─────── (independent)
|
||||
TEC-1599..1604 (P2 quality) ── (all independent, parallel)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependency Map (Phase 6)
|
||||
|
||||
| Task | Depends On |
|
||||
| --------------- | ----------------- |
|
||||
| TEC-1592 | None |
|
||||
| TEC-1593 | None |
|
||||
| TEC-1594 | None |
|
||||
| TEC-1595 | TEC-1592 |
|
||||
| TEC-1596 | TEC-1592 |
|
||||
| TEC-1597 | TEC-1592 |
|
||||
| TEC-1598 | None |
|
||||
| TEC-1599 | None |
|
||||
| TEC-1600 | None |
|
||||
| TEC-1601 | None |
|
||||
| TEC-1602 | Phase 4 security |
|
||||
| TEC-1603 | None |
|
||||
| TEC-1604 | None |
|
||||
|
||||
### Milestone 8: Post-MVP Improvements (Phase 7)
|
||||
|
||||
**Goal:** Fix remaining bugs, harden for production, improve UX and DX.
|
||||
|
||||
**Wave 1 — Critical Bug Fixes (1-2 days):**
|
||||
1. **[TEC-1647] Fix Reviews routing** (P0, no deps)
|
||||
2. **[TEC-1648] Fix Health endpoints** (P0, no deps)
|
||||
3. **[TEC-1649] Fix Login error handling** (P0, needs DB)
|
||||
4. **[TEC-1650] Fix Listing 404** (P1, needs DB)
|
||||
|
||||
**Wave 2 — Production Readiness (3-5 days):**
|
||||
5. **[TEC-1651] E2E CI environment** (P1, no deps)
|
||||
6. **[TEC-1652] Run E2E tests** (P1, after Wave 1 fixes)
|
||||
7. **[TEC-1653] Security headers audit** (P1, no deps)
|
||||
8. **[TEC-1658] PgBouncer pooling** (P1, no deps)
|
||||
|
||||
**Wave 3 — User-Facing Quality (1-2 weeks):**
|
||||
9. **[TEC-1654] Mobile responsive** (P1, no deps)
|
||||
10. **[TEC-1655] SEO optimization** (P1, no deps)
|
||||
11. **[TEC-1656] Per-user rate limiting** (P1, no deps)
|
||||
12. **[TEC-1657] Admin audit logging** (P1, no deps)
|
||||
|
||||
**Wave 4 — Engineering Excellence (2-3 weeks):**
|
||||
13. **[TEC-1659] Graceful degradation** (P2, no deps)
|
||||
14. **[TEC-1660] Error codes documentation** (P2, no deps)
|
||||
15. **[TEC-1661] RUM + Web Vitals** (P2, no deps)
|
||||
16. **[TEC-1662] Update QA Tracker** (P2, after Wave 2)
|
||||
|
||||
```
|
||||
TEC-1647 (Reviews) ──┐
|
||||
TEC-1648 (Health) ────┼── TEC-1652 (E2E Tests) ── TEC-1662 (QA Update)
|
||||
TEC-1649 (Login) ─────┤
|
||||
TEC-1650 (Listing) ───┘
|
||||
TEC-1651 (CI E2E) ──────── (independent)
|
||||
TEC-1653 (Headers) ─────── (independent)
|
||||
TEC-1658 (PgBouncer) ───── (independent)
|
||||
TEC-1654..1657 (Wave 3) ── (all independent, parallel)
|
||||
TEC-1659..1661 (Wave 4) ── (all independent, parallel)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependency Map (Phase 7)
|
||||
|
||||
| Task | Depends On |
|
||||
| --------------- | ----------------- |
|
||||
| TEC-1647 | None |
|
||||
| TEC-1648 | None |
|
||||
| TEC-1649 | None |
|
||||
| TEC-1650 | None |
|
||||
| TEC-1651 | None |
|
||||
| TEC-1652 | TEC-1647, TEC-1648 |
|
||||
| TEC-1653 | None |
|
||||
| TEC-1654 | None |
|
||||
| TEC-1655 | None |
|
||||
| TEC-1656 | None |
|
||||
| TEC-1657 | None |
|
||||
| TEC-1658 | None |
|
||||
| TEC-1659 | None |
|
||||
| TEC-1660 | None |
|
||||
| TEC-1661 | None |
|
||||
| TEC-1662 | TEC-1652 |
|
||||
|
||||
### Milestone 9: CEO Audit Wave 5 — Security & Features (Phase 7 continued)
|
||||
|
||||
**Goal:** Address security vulnerabilities, improve test coverage, implement missing Sprint 3 feature.
|
||||
|
||||
**Wave 5a — Security (DAY 1-2, parallel):**
|
||||
1. **[TEC-1684] Fix npm vulnerabilities** (P0, Security Engineer)
|
||||
2. **[TEC-1685] Fix lint error** (P1, QA Engineer)
|
||||
|
||||
**Wave 5b — Quality & Features (WEEK 1-2):**
|
||||
3. **[TEC-1686] Test coverage push** (P1, QA Engineer, after 5a)
|
||||
4. **[TEC-1688] Saved Searches + Alerts** (P1, Architect)
|
||||
5. **[TEC-1687] Dependabot setup** (P2, DevOps Engineer)
|
||||
|
||||
```
|
||||
TEC-1684 (NPM Vuln) ─────── (independent, P0)
|
||||
TEC-1685 (Lint) ──────────── TEC-1686 (Test Coverage)
|
||||
TEC-1688 (Saved Searches) ── (independent, P1)
|
||||
TEC-1687 (Dependabot) ────── (independent, P2)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependency Map (Wave 5)
|
||||
|
||||
| Task | Depends On |
|
||||
| --------------- | ----------------- |
|
||||
| TEC-1684 | None |
|
||||
| TEC-1685 | None |
|
||||
| TEC-1686 | TEC-1685 |
|
||||
| TEC-1687 | None |
|
||||
| TEC-1688 | None |
|
||||
|
||||
---
|
||||
|
||||
## Rollout Notes
|
||||
|
||||
- **Phase 0-6 complete** — 51/51 tasks done, MVP feature-complete
|
||||
- **Phase 7 is current priority** — bug fixes and production hardening
|
||||
- **Wave 13 is current sprint** — 6 tasks (TEC-1918 through TEC-1923)
|
||||
- **Total project status** (from Paperclip, 2026-04-12): 219 done / 3 in progress / 9 todo / 3 cancelled out of 234 issues
|
||||
- **Critical path:** TEC-1918 (TS errors) → TEC-1919 (E2E unblock) → production readiness checklist (TEC-1922)
|
||||
- **Priorities:** CI green (TEC-1918), E2E (TEC-1919), backlog grooming (TEC-1920), /pricing page (TEC-1921)
|
||||
- **Production path:** Wave 13 fixes → production readiness checklist → go-live decision
|
||||
|
||||
### Milestone 13: CEO Audit Wave 13 (Phase 7 continued)
|
||||
|
||||
**Goal:** Fix remaining TS errors, unblock E2E, groom backlog, complete pricing page, production readiness checklist.
|
||||
|
||||
**Wave 13A — CI Fix (Day 1):**
|
||||
1. **[TEC-1918] Fix 7 TS compile errors in web test files** (P0, Senior Backend Engineer)
|
||||
|
||||
**Wave 13B — Features & Quality (Days 2-3):**
|
||||
2. **[TEC-1919] Unblock E2E test environment** (P1, DevOps Engineer)
|
||||
3. **[TEC-1920] Backlog grooming — deduplicate and close resolved** (P1, QA Engineer)
|
||||
4. **[TEC-1921] Complete /pricing page** (P1, Senior Frontend Engineer)
|
||||
|
||||
**Wave 13C — Documentation & Readiness (Days 3-5):**
|
||||
5. **[TEC-1922] Production readiness checklist** (P2, SRE Engineer)
|
||||
6. **[TEC-1923] Update PROJECT_TRACKER.md** (P2, Technical Writer)
|
||||
|
||||
```
|
||||
TEC-1918 (TS Errors) ──→ TEC-1919 (E2E Unblock)
|
||||
TEC-1920 (Backlog) ────── (independent)
|
||||
TEC-1921 (/pricing) ───── (independent)
|
||||
TEC-1922 (Readiness) ──── (after TEC-1918/1919)
|
||||
TEC-1923 (Tracker) ────── (independent)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependency Map (Wave 13)
|
||||
|
||||
| Task | Depends On |
|
||||
| --------------- | ----------------- |
|
||||
| TEC-1918 | None |
|
||||
| TEC-1919 | TEC-1918 |
|
||||
| TEC-1920 | None |
|
||||
| TEC-1921 | None |
|
||||
| TEC-1922 | TEC-1918, TEC-1919|
|
||||
| TEC-1923 | None |
|
||||
|
||||
### Milestone 12: CEO Audit — CI Pipeline Fix (Phase 7 Wave 12)
|
||||
|
||||
**Goal:** Restore CI pipeline to green. Fix all TypeScript, ESLint, and test failures. Commit outstanding work.
|
||||
|
||||
**Wave 12A — Fix CI (Day 1, parallel):**
|
||||
1. **[TEC-1898] Fix Prisma 7 migration** (P0, Senior Backend Engineer)
|
||||
2. **[TEC-1899] Fix 31 failing unit tests** (P0, QA Engineer)
|
||||
3. **[TEC-1900] Fix ESLint errors + commit files** (P0, Senior Backend Engineer, after TEC-1898)
|
||||
|
||||
**Wave 12B — Bug Fixes (Days 2-3):**
|
||||
4. **[TEC-1649] Login 500→401 fix** (P1, in progress)
|
||||
5. **[TEC-1657] Admin audit logging** (P1, todo)
|
||||
6. **[TEC-1878] E2E environment** (P1, DevOps Engineer)
|
||||
7. **[TEC-1847] React component tests** (P1, QA Engineer)
|
||||
|
||||
```
|
||||
TEC-1898 (Prisma Fix) ──┬── TEC-1900 (ESLint + Commit)
|
||||
TEC-1899 (Test Fixes) ──┘
|
||||
TEC-1649 (Login Fix) ─── (independent, in progress)
|
||||
TEC-1878 (E2E Env) ────── (independent)
|
||||
TEC-1657 (Audit Logs) ─── (independent)
|
||||
TEC-1847 (RTL Tests) ──── (independent)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependency Map (Wave 12)
|
||||
|
||||
| Task | Depends On |
|
||||
| --------------- | ----------------- |
|
||||
| TEC-1898 | None |
|
||||
| TEC-1899 | None |
|
||||
| TEC-1900 | TEC-1898 |
|
||||
| TEC-1649 | None |
|
||||
| TEC-1657 | None |
|
||||
| TEC-1878 | None |
|
||||
| TEC-1847 | None |
|
||||
306
docs/architecture/IMPLEMENTATION_QUICK_REFERENCE.md
Normal file
306
docs/architecture/IMPLEMENTATION_QUICK_REFERENCE.md
Normal file
@@ -0,0 +1,306 @@
|
||||
# GoodGo Frontend: i18n + A11y Implementation Quick Reference
|
||||
|
||||
## 🎯 Key Findings at a Glance
|
||||
|
||||
### Current State
|
||||
- ✅ **Next.js 14** with App Router (well-structured)
|
||||
- ✅ **React 18** + TypeScript (type-safe)
|
||||
- ✅ **Tailwind CSS** with dark mode support (HSL-based theme)
|
||||
- ✅ **Good component library** (~35 components)
|
||||
- ✅ **Some A11y basics** in place (semantic HTML, ARIA labels, skip link)
|
||||
- ❌ **NO i18n setup** (everything hardcoded Vietnamese)
|
||||
- ❌ **A11y gaps** (focus management, some ARIA missing, color contrast TBD)
|
||||
|
||||
### Strategic Entry Points for Implementation
|
||||
|
||||
#### 1. **i18n Entry Points** (Priority 1)
|
||||
```
|
||||
Files to modify for i18n:
|
||||
├── app/layout.tsx → Add i18n provider
|
||||
├── middleware.ts → Add locale routing
|
||||
├── app/(public)/layout.tsx → Navigation text
|
||||
├── app/(auth)/login/page.tsx → Form labels + errors
|
||||
├── app/(auth)/register/page.tsx → Form labels + errors
|
||||
├── components/listings/listing-form-steps.tsx → Multi-step form labels
|
||||
├── components/search/filter-bar.tsx → Filter options + city names
|
||||
├── lib/validations/*.ts → Zod error messages
|
||||
└── [All other components with text]
|
||||
|
||||
Total files to update: ~25-30 files with hardcoded strings
|
||||
```
|
||||
|
||||
#### 2. **A11y Critical Fixes** (Priority 1.5)
|
||||
```
|
||||
Components needing A11y updates:
|
||||
├── components/ui/dialog.tsx → Focus trapping + focus restoration
|
||||
├── components/listings/image-gallery.tsx → Keyboard nav + ARIA
|
||||
├── components/search/filter-bar.tsx → Proper labeling + ARIA
|
||||
├── app/(dashboard)/layout.tsx → Tab focus management
|
||||
└── Across all forms → Error message association
|
||||
|
||||
Tasks:
|
||||
- Add focus trapping in modals
|
||||
- Verify color contrast (WCAG AA)
|
||||
- Add aria-busy to loading states
|
||||
- Add proper aria-label to icon buttons
|
||||
- Link form errors to inputs with aria-describedby
|
||||
```
|
||||
|
||||
#### 3. **Message File Structure for i18n**
|
||||
```
|
||||
public/locales/
|
||||
├── en.json
|
||||
│ ├── common: { home, search, dashboard, logout, ... }
|
||||
│ ├── auth: { login, register, email, password, ... }
|
||||
│ ├── property: { apartment, house, villa, ... }
|
||||
│ ├── transaction: { sale, rent, ... }
|
||||
│ ├── directions: { north, south, east, ... }
|
||||
│ ├── status: { draft, active, sold, ... }
|
||||
│ ├── validation: { required, min_length, ... }
|
||||
│ └── errors: { oauth_failed, access_denied, ... }
|
||||
└── vi.json
|
||||
└── [Same structure]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 Implementation Checklist
|
||||
|
||||
### Phase 1: Setup (2-3 hours)
|
||||
- [ ] Install `next-intl` package
|
||||
- [ ] Create message files (en.json, vi.json)
|
||||
- [ ] Update next.config.js for i18n routing
|
||||
- [ ] Create i18n config (config.ts)
|
||||
- [ ] Update middleware.ts for locale detection
|
||||
- [ ] Wrap root layout with i18n provider
|
||||
|
||||
### Phase 2: Core Refactoring (6-8 hours)
|
||||
- [ ] Update root layout & metadata
|
||||
- [ ] Refactor all validations (Zod) to use messages
|
||||
- [ ] Extract component strings to useTranslations()
|
||||
- [ ] Update all enums (TRANSACTION_TYPES, PROPERTY_TYPES, etc.) to use i18n
|
||||
- [ ] Update page layouts (public, auth, dashboard)
|
||||
- [ ] Update all page content
|
||||
|
||||
### Phase 3: Component Updates (4-6 hours)
|
||||
- [ ] Update all UI components
|
||||
- [ ] Update form components
|
||||
- [ ] Update navigation components
|
||||
- [ ] Update search/filter components
|
||||
- [ ] Update listing form
|
||||
|
||||
### Phase 4: A11y Fixes (4-6 hours)
|
||||
- [ ] Fix focus management in dialogs
|
||||
- [ ] Add focus trapping
|
||||
- [ ] Update form error linking (aria-describedby)
|
||||
- [ ] Add aria-busy to loading states
|
||||
- [ ] Add aria-labels to icon buttons
|
||||
- [ ] Verify color contrast
|
||||
- [ ] Update test setup for i18n
|
||||
|
||||
### Phase 5: Testing & QA (3-4 hours)
|
||||
- [ ] Test both locales on all pages
|
||||
- [ ] Run axe DevTools accessibility audit
|
||||
- [ ] Test keyboard navigation
|
||||
- [ ] Test screen reader compatibility
|
||||
- [ ] Update unit tests for i18n
|
||||
|
||||
---
|
||||
|
||||
## 🗣️ Text Content Inventory
|
||||
|
||||
### Navigation & Layout (~15 items)
|
||||
| Location | Text | Status |
|
||||
|----------|------|--------|
|
||||
| Public header | Trang chủ, Tìm kiếm, Đăng nhập, Đăng ký | ❌ Hardcoded |
|
||||
| Dashboard nav | 8 nav items | ❌ Hardcoded |
|
||||
| Footer | 4 sections | ❌ Hardcoded |
|
||||
|
||||
### Forms & Validation (~40+ items)
|
||||
| Location | Type | Count | Status |
|
||||
|----------|------|-------|--------|
|
||||
| Login form | Labels + errors | 8 | ❌ Hardcoded |
|
||||
| Register form | Labels + errors | 10 | ❌ Hardcoded |
|
||||
| Listing form | Multi-step labels | 25+ | ❌ Hardcoded |
|
||||
| Search filters | Option labels | 30+ | ❌ Hardcoded |
|
||||
| Zod validation | Error messages | 20+ | ❌ Hardcoded |
|
||||
|
||||
### Enums & Constants (~50+ items)
|
||||
| File | Items | Status |
|
||||
|------|-------|--------|
|
||||
| TRANSACTION_TYPES | 2 labels | ❌ Hardcoded |
|
||||
| PROPERTY_TYPES | 6 labels | ❌ Hardcoded |
|
||||
| LISTING_STATUSES | 8 labels | ❌ Hardcoded |
|
||||
| DIRECTIONS | 8 labels | ❌ Hardcoded |
|
||||
| CITIES | 13 names | ❌ Hardcoded |
|
||||
| PRICE_RANGES | 6 ranges | ❌ Hardcoded |
|
||||
|
||||
### Page Content (~30 items)
|
||||
| Page | Sections | Status |
|
||||
|------|----------|--------|
|
||||
| Landing page | Hero, search, stats, CTA | ❌ Hardcoded |
|
||||
| Search results | No results, loading, headers | ❌ Hardcoded |
|
||||
| Dashboard | Section titles, empty states | ❌ Hardcoded |
|
||||
|
||||
---
|
||||
|
||||
## 🔑 Critical Files for i18n
|
||||
|
||||
### Must-Update Files (Blockers)
|
||||
1. **middleware.ts** — Locale routing
|
||||
2. **app/layout.tsx** — i18n provider setup
|
||||
3. **lib/validations/*.ts** — Message integration
|
||||
4. **lib/*.ts** — Any API error message handling
|
||||
|
||||
### High-Priority Files
|
||||
1. **app/(public)/layout.tsx** — Navigation
|
||||
2. **app/(auth)/login/page.tsx** — Auth forms
|
||||
3. **components/listings/listing-form-steps.tsx** — Forms
|
||||
4. **components/search/filter-bar.tsx** — Filters
|
||||
|
||||
### Medium-Priority Files
|
||||
1. All page components
|
||||
2. All UI components with text
|
||||
3. Error boundary components
|
||||
|
||||
---
|
||||
|
||||
## ♿ A11y Implementation Priority
|
||||
|
||||
### WCAG 2.1 AA Critical Fixes
|
||||
1. **Focus Management** (Level A)
|
||||
- Add focus trap in `dialog.tsx`
|
||||
- Restore focus on dialog close
|
||||
- Visible focus indicator on all buttons
|
||||
|
||||
2. **Color Contrast** (Level AA)
|
||||
- Run axe DevTools audit
|
||||
- Fix any < 4.5:1 ratio text
|
||||
- Fix < 3:1 ratio graphics
|
||||
|
||||
3. **Form Accessibility** (Level A)
|
||||
- Link all error messages with aria-describedby
|
||||
- Proper labeling with htmlFor
|
||||
- Fieldset grouping for complex forms
|
||||
|
||||
4. **Loading States** (Level A)
|
||||
- Add aria-busy to spinners
|
||||
- Add aria-label with context
|
||||
|
||||
5. **Icon Buttons** (Level A)
|
||||
- All icon-only buttons need aria-label
|
||||
- Theme toggle button already has label ✓
|
||||
|
||||
### Nice-to-Have A11y Enhancements
|
||||
- Skip link already present ✓
|
||||
- Semantic HTML already used ✓
|
||||
- Role="alert" on errors ✓
|
||||
- aria-invalid on form fields ✓
|
||||
|
||||
---
|
||||
|
||||
## 📦 Dependencies to Add
|
||||
|
||||
```bash
|
||||
npm install next-intl
|
||||
|
||||
# No new devDependencies needed if using next-intl
|
||||
# Testing with mocked i18n available
|
||||
```
|
||||
|
||||
**Total installation footprint:** ~500KB minified
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
```typescript
|
||||
// vitest.setup.ts - Mock i18n
|
||||
vi.mock('next-intl', () => ({
|
||||
useTranslations: () => (key) => mockMessages[key]
|
||||
}));
|
||||
```
|
||||
|
||||
### Component Tests
|
||||
```typescript
|
||||
// Test both locales
|
||||
describe('LoginForm', () => {
|
||||
it('renders Vietnamese labels', () => { ... });
|
||||
it('renders English labels', () => { ... });
|
||||
});
|
||||
```
|
||||
|
||||
### E2E Tests
|
||||
```typescript
|
||||
// Test locale switching
|
||||
- /en/login → English
|
||||
- /vi/login → Vietnamese
|
||||
- /en/dashboard → English dashboard
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Estimated Timeline
|
||||
|
||||
| Phase | Duration | Effort |
|
||||
|-------|----------|--------|
|
||||
| Setup | 2-3h | Low |
|
||||
| Core Refactoring | 6-8h | Medium |
|
||||
| Components | 4-6h | Medium |
|
||||
| A11y Fixes | 4-6h | Low-Medium |
|
||||
| Testing | 3-4h | Medium |
|
||||
| **Total** | **19-27h** | **~3-4 days** |
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Implementation Order (Recommended)
|
||||
|
||||
1. **Setup i18n infrastructure** (creates foundation)
|
||||
2. **Update middleware + root layout** (enables routing)
|
||||
3. **Extract & centralize all text** (main work)
|
||||
4. **Fix A11y issues** (parallelize with #3)
|
||||
5. **Test thoroughly** (final verification)
|
||||
|
||||
---
|
||||
|
||||
## 💡 Quick Win Opportunities
|
||||
|
||||
These can be done immediately:
|
||||
1. Create message file structure (30 min)
|
||||
2. Add focus trap to dialog (30 min)
|
||||
3. Add aria-busy to spinners (20 min)
|
||||
4. Color contrast audit (1 hour)
|
||||
5. Icon button aria-labels (30 min)
|
||||
|
||||
---
|
||||
|
||||
## 📝 Notes for Implementation
|
||||
|
||||
### Locale Detection (middleware)
|
||||
```typescript
|
||||
// Check in order: URL > cookie > header > default
|
||||
function getLocale(request) {
|
||||
// 1. URL pathname: /en/* or /vi/*
|
||||
// 2. Cookie: goodgo_locale
|
||||
// 3. Header: Accept-Language
|
||||
// 4. Default: vi
|
||||
}
|
||||
```
|
||||
|
||||
### Message Fallback Strategy
|
||||
```typescript
|
||||
// If translation missing, use English as fallback
|
||||
// Otherwise fallback to Vietnamese (primary)
|
||||
```
|
||||
|
||||
### Performance Considerations
|
||||
- Keep message files < 100KB each
|
||||
- Lazy load per-page messages if needed
|
||||
- Static generation for SEO-critical pages
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** April 9, 2026
|
||||
**Version:** 1.0 - Pre-Implementation
|
||||
**Confidence:** High
|
||||
Reference in New Issue
Block a user