Files
goodgo-platform/docs/architecture.md
2026-04-08 05:03:29 +07:00

12 KiB

Architecture

System Overview

GoodGo Platform AI is a monorepo containing a NestJS backend, Next.js frontend, Python AI services, and MCP (Model Context Protocol) servers. The system is orchestrated with Turborepo and pnpm workspaces.

                    ┌──────────────────────────────────────────┐
                    │            Client (Browser)              │
                    └──────────────────┬───────────────────────┘
                                       │
                    ┌──────────────────▼───────────────────────┐
                    │         Next.js 14 (apps/web)            │
                    │   ┌─────────┐  ┌──────────┐  ┌───────┐  │
                    │   │ Pages   │  │Components│  │Zustand │  │
                    │   │(App     │  │(UI +     │  │(State) │  │
                    │   │ Router) │  │ Domain)  │  │        │  │
                    │   └─────────┘  └──────────┘  └───────┘  │
                    └──────────────────┬───────────────────────┘
                                       │ REST API
                    ┌──────────────────▼───────────────────────┐
                    │         NestJS 11 (apps/api)             │
                    │                                          │
                    │  ┌────────┐ ┌────────┐ ┌─────────────┐  │
                    │  │  Auth  │ │Listings│ │  Payments   │  │
                    │  ├────────┤ ├────────┤ ├─────────────┤  │
                    │  │ Search │ │ Admin  │ │Subscriptions│  │
                    │  ├────────┤ ├────────┤ ├─────────────┤  │
                    │  │Analytics│ │  MCP  │ │Notifications│  │
                    │  └────────┘ └────────┘ └─────────────┘  │
                    └───┬─────┬──────┬─────────┬──────────────┘
                        │     │      │         │
           ┌────────────▼┐ ┌─▼────┐ ▼     ┌───▼──────────┐
           │ PostgreSQL  │ │Redis │ │     │  Typesense   │
           │ + PostGIS   │ │      │ │     │  (Search)    │
           └─────────────┘ └──────┘ │     └──────────────┘
                                    │
                    ┌───────────────▼──────────────────────┐
                    │       MCP Servers (libs/mcp-servers)  │
                    │  ┌──────────┐┌──────────┐┌────────┐  │
                    │  │ Property ││ Market   ││Valua-  │  │
                    │  │ Search   ││Analytics ││tion    │  │
                    │  └──────────┘└──────────┘└───┬────┘  │
                    └──────────────────────────────┼───────┘
                                                   │
                    ┌──────────────────────────────▼───────┐
                    │   AI Services (libs/ai-services)     │
                    │   FastAPI + XGBoost + Claude API      │
                    │   ┌──────────┐  ┌────────────────┐   │
                    │   │   AVM    │  │  Moderation    │   │
                    │   │(Pricing) │  │ (Claude API)   │   │
                    │   └──────────┘  └────────────────┘   │
                    └──────────────────────────────────────┘

Module Architecture

Each API module follows a layered Domain-Driven Design structure:

modules/{module-name}/
├── presentation/          # HTTP layer
│   ├── controllers/       # Route handlers
│   └── dtos/              # Request/response DTOs (class-validator)
├── application/           # Business orchestration
│   ├── commands/          # Write operations (CQRS)
│   ├── queries/           # Read operations (CQRS)
│   ├── handlers/          # Command/query handlers
│   └── services/          # Application services
├── domain/                # Core business logic
│   ├── entities/          # Domain entities & value objects
│   ├── repositories/      # Repository interfaces (abstractions)
│   └── events/            # Domain events
├── infrastructure/        # External integrations
│   ├── repositories/      # Prisma repository implementations
│   └── services/          # External service adapters
└── {module-name}.module.ts # NestJS module definition

CQRS Pattern

The platform uses NestJS CQRS (@nestjs/cqrs) for complex operations:

  • Commands — mutate state (create listing, process payment, register user)
  • Queries — read state (search properties, get analytics)
  • Events — cross-module communication (listing published → index in Typesense, payment completed → send notification)

Shared Module

The shared/ module provides cross-cutting concerns:

  • Prisma service — database connection and client
  • Redis service — caching and session management
  • Guards — JWT auth guard, roles guard, throttle guard
  • Pipes — global validation pipe (whitelist mode)
  • Filters — exception filters for consistent error responses
  • Decorators@CurrentUser(), @Roles(), @Public()

Data Flow

Property Listing Lifecycle

DRAFT → PENDING_REVIEW → ACTIVE → RESERVED → SOLD/RENTED
                │                                  │
                ▼                                   │
            REJECTED                            EXPIRED
  1. Seller/Agent creates listing (status: DRAFT)
  2. Seller submits for review → PENDING_REVIEW
  3. Admin moderates (AI moderation score assists) → ACTIVE or REJECTED
  4. Active listings are indexed in Typesense for search
  5. Buyer makes inquiry → Inquiry record created
  6. Transaction workflow: OFFER_MADE → DEPOSIT_PAID → CONTRACT_SIGNING → COMPLETED

Search Flow

User Query → NestJS Search Module → Typesense
                                      │
                                      ├─ Full-text on title/description
                                      ├─ Faceted filters (price, type, bedrooms)
                                      └─ Geo-spatial (lat/long + radius)

Payment Flow

User → API (create payment) → Provider (VNPay/MoMo/ZaloPay)
                                    │
                              [User pays on provider page]
                                    │
Provider callback → API → Verify signature → Update Payment status
                                                    │
                                              SUCCESS / FAILED

AI Valuation Flow

API Request → MCP Valuation Server → AI Service (FastAPI)
                                          │
                                    XGBoost Model
                                          │
                                    ┌─────▼──────┐
                                    │ Estimated   │
                                    │ Price +     │
                                    │ Confidence  │
                                    │ + Factors   │
                                    └─────────────┘

Database Schema

Core Models

User ──┬── Agent (1:1, for AGENT role users)
       ├── OAuthAccount (1:N, Google/Zalo)
       ├── RefreshToken (1:N, token families)
       ├── Subscription (1:N)
       ├── SavedSearch (1:N)
       └── UsageRecord (1:N)

Property ──┬── PropertyMedia (1:N, images/videos)
           ├── Listing (1:N)
           └── Valuation (1:N)

Listing ──┬── Inquiry (1:N)
          ├── Lead (1:N)
          ├── Transaction (1:N)
          └── Agent (N:1)

Transaction ── Payment (1:N)

Plan ── Subscription (1:N)

MarketIndex (standalone — city/district/month aggregates)

Key Design Decisions

  • PostGIS for spatial queries — property locations stored as Point geometry
  • JSON columns for flexible data: amenities, nearby POIs, KYC data, subscription features
  • Token family tracking for secure refresh token rotation (detects reuse attacks)
  • Soft statuses over soft deletes — listings use status workflow, not deletedAt

MCP Servers

Three Model Context Protocol servers provide AI tool interfaces:

Server Tools Data Source
Property Search search_properties, compare_properties, get_property_details Typesense
Market Analytics get_market_report, analyze_trends, get_price_indices PostgreSQL
Valuation estimate_valuation, extract_features, compare_valuations AI Services (FastAPI)

MCP servers are registered via McpModule in NestJS, managed by McpRegistryService, and exposed through McpTransportController over HTTP.

AI Services

Python FastAPI microservice (libs/ai-services/) provides:

Endpoint Model Purpose
POST /avm/estimate XGBoost Property price estimation with confidence score
POST /moderation/check Claude API Content moderation for listing descriptions
GET /health Health check
  • Underthesea handles Vietnamese text tokenization and NLP preprocessing
  • XGBoost model uses engineered features (area, location, property type, amenities)

Security

  • JWT + Refresh Token Rotation — 15-minute access tokens, 7-day refresh tokens with family-based rotation
  • OAuth — Google and Zalo social login
  • Rate Limiting — 60 req/60s default, 10 req/60s for auth endpoints
  • Helmet — HTTP security headers
  • CORS — Configurable origins via CORS_ORIGINS
  • Input Validation — class-validator (backend), Zod (frontend)
  • Content Sanitization — sanitize-html for user-generated content
  • KYC — Agent verification workflow (NONE → PENDING → VERIFIED/REJECTED)

Monitoring

  • Prometheus scrapes /metrics endpoint every 15 seconds
  • Grafana dashboards auto-provisioned from monitoring/grafana/dashboards/
  • Pino structured JSON logging with configurable log levels
  • Metrics include HTTP request duration, error rates, and custom business metrics

Event System

The platform uses @nestjs/event-emitter for loose coupling between modules:

  • listing.published → Typesense indexer updates search index
  • payment.completed → Notification service sends confirmation
  • inquiry.created → Agent notification triggered
  • user.registered → Welcome email sent