# 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 15 (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│  │
                    │  ├────────┤ ├────────┤ ├─────────────┤  │
                    │  │ Agents │ │Inquires│ │   Leads     │  │
                    │  ├────────┤ ├────────┤ ├─────────────┤  │
                    │  │Reviews │ │ Health │ │  Metrics    │  │
                    │  └────────┘ └────────┘ └─────────────┘  │
                    └───┬─────┬──────┬─────────┬──────────────┘
                        │     │      │         │
           ┌────────────▼┐ ┌─▼────┐ ▼     ┌───▼──────────┐
           │ 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 `/api/v1/metrics` endpoint every 15 seconds
- **Grafana** dashboards auto-provisioned from `monitoring/grafana/dashboards/`
- **Loki + Promtail** aggregate container logs; viewable in Grafana
- **Pino** structured JSON logging with configurable log levels
- Metrics include HTTP request duration, error rates, web vitals, and custom business metrics
- Log retention: 15 days (configured in `monitoring/loki/loki-config.yml`)

## 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
