Files
goodgo-platform/docs/explorations/from-desktop/README_analytics_package.md
Ho Ngoc Hai 08b96f9c2d docs: consolidate exploration & audit reports under docs/ (TEC-3094)
- Move 8 stray .md (+5 .txt) from ~/Desktop into docs/explorations/from-desktop/
- Reorganize 27 .md/.txt at workspace root:
  - audit reports -> docs/audits/
  - exploration reports -> docs/explorations/
  - design system -> docs/design-system/
- Keep only README/CHANGELOG/CONTRIBUTING/CLAUDE at repo root
- Refresh docs/README.md as canonical index with links to all groups
- Note: pre-existing docs/audits/AUDIT_INDEX.md and AUDIT_SUMMARY.md were
  overwritten by the newer root-level versions during the move

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-21 16:29:24 +07:00

9.6 KiB

GoodGo Analytics Module — Complete Architecture Guide

📚 Overview

This package contains 4 comprehensive guides (2,174 lines, 71 KB) to understand the GoodGo Analytics Module architecture, caching system, and endpoint patterns.

📖 Quick Navigation

File Purpose Read Time Best For
00_SUMMARY.md Overview & key findings 5 min Getting oriented
02_quick_reference.md Visual diagrams & checklists 10 min Visual learners
03_file_paths_reference.md File navigation & structure 15 min Finding code
01_analytics_architecture_guide.md Deep dive with code examples 30+ min Full understanding
  1. Start with 00_SUMMARY.md — understand what you're learning
  2. Read 02_quick_reference.md — visualize the architecture
  3. Skim 03_file_paths_reference.md — know where to find things
  4. Deep dive 01_analytics_architecture_guide.md — master the patterns

Total time: ~60 minutes to fully understand the module

🎯 What You'll Learn

Architecture

  • Domain-Driven Design (DDD) with CQRS pattern
  • 4-layer structure: Presentation → Application → Domain → Infrastructure
  • 24 endpoints across 2 controllers
  • 15+ query handlers with caching

Caching

  • Redis cache-aside pattern
  • Two caching styles: @Cacheable decorator vs manual cache.getOrSet()
  • Cache TTLs for different endpoint types
  • Graceful degradation when Redis is down
  • Cache metadata in responses

Database

  • Prisma schema for Property, Listing, MarketIndex, Valuation
  • PostGIS spatial queries
  • Indexes for query optimization

Implementation

  • How to add a new GET endpoint in 7 steps
  • Query handler patterns with real examples
  • DTO design and validation
  • Error handling conventions
  • Testing patterns

🏗️ Architecture Overview

┌─────────────────────────────────────────┐
│ PRESENTATION LAYER                      │
│ • AnalyticsController (19 endpoints)    │
│ • AvmController (5 endpoints)           │
│ • DTOs, Guards, Interceptors            │
└──────────────────┬──────────────────────┘
                   ↓ QueryBus.execute()
┌──────────────────────────────────────────┐
│ APPLICATION LAYER (CQRS)                 │
│ • 15+ Query Handlers (@QueryHandler)     │
│ • @Cacheable or cache.getOrSet()        │
│ • Try-catch error handling               │
└──────────────────┬──────────────────────┘
                   ↓ Injected services
┌──────────────────────────────────────────┐
│ DOMAIN LAYER (Business Logic)            │
│ • Entities, Repository Interfaces        │
│ • Service Interfaces, Result DTOs        │
└──────────────────┬──────────────────────┘
                   ↓ Injected implementation
┌──────────────────────────────────────────┐
│ INFRASTRUCTURE LAYER                     │
│ • Prisma Repositories                    │
│ • HTTP Services, External clients        │
└──────────────────────────────────────────┘

💾 Caching Pattern

HTTP GET /analytics/market-snapshot?city=Ho Chi Minh
    ↓
QueryHandler builds key: "cache:analytics:market_snapshot:ho_chi_minh"
    ↓
cache.getOrSet(key, loader, TTL, resource):
    ├─ Redis HIT: return cached value
    ├─ Redis MISS: call loader() → compute → store
    └─ Redis DOWN: call loader() directly (graceful degradation)
    ↓
CacheMetaInterceptor wraps: { data: result, cacheMeta: {...} }
    ↓
HTTP 200: { data: {...}, cacheMeta: { cachedAt, nextRefreshAt, source } }

🔑 Key Findings

  • 24 Endpoints: 19 in AnalyticsController + 5 in AvmController
  • 15+ Query Handlers: All with caching (except predictions)
  • 2 Caching Patterns: @Cacheable decorator or manual cache.getOrSet()
  • Redis Cache-Aside: TTL-based expiry, graceful degradation
  • 4 Prisma Models: Property, Listing, MarketIndex, Valuation
  • DTOs + Guards: All endpoints secured with JWT, Quota, Rate Limit

📚 Detailed Contents

00_SUMMARY.md

  • Overview of all 4 guides
  • Key architecture decisions
  • 7-step endpoint addition walkthrough
  • Architecture decision matrix
  • Core conventions checklist

01_analytics_architecture_guide.md COMPREHENSIVE

  • DDD layer breakdown with code examples
  • All 24 endpoints documented
  • Query handler patterns (decorator vs manual)
  • Complete Redis caching system
  • Real code from GetMarketSnapshotHandler, GetDistrictStatsHandler
  • Full Prisma schema documentation
  • Shared module utilities (CacheService, @Cacheable, CacheMetaInterceptor)
  • Complete 7-step guide: adding GET /trending-areas endpoint
  • Testing patterns & error handling conventions

02_quick_reference.md VISUAL QUICK START

  • Architecture layer stack diagram
  • Request flow visualization
  • Caching strategy matrix
  • Decorators & guards cheat sheet
  • Prisma schema snapshot
  • Response structure examples
  • 7-step endpoint addition checklist

03_file_paths_reference.md NAVIGATION MAP

  • Core module files (analytics.module.ts, index.ts)
  • All 24 endpoints mapped to file paths
  • DTO files organized by type (request vs response)
  • All 15+ query types with descriptions
  • Domain, Infrastructure, Shared layer breakdowns
  • Database schema models with fields & indexes
  • Directory tree with line counts
  • Import patterns reference
  • Key metrics & numbers

🎯 Quick Start: Adding New Endpoint

7 Steps to Add GET /analytics/trending-areas

  1. Request DTOpresentation/dto/get-trending-areas.dto.ts
  2. Query Classapplication/queries/get-trending-areas/query.ts
  3. Handlerapplication/queries/get-trending-areas/handler.ts (with @Cacheable)
  4. Register → Add to QueryHandlers array in analytics.module.ts
  5. Controller → Add method to analytics.controller.ts
  6. Export → Add to presentation/dto/index.ts
  7. Test → Create handler spec

Full walkthrough with code in guides!

Core Conventions

// Cache with TTL
Dashboard tiles: 300s (5 min)
Aggregations: 300s (5 min)
Reports: 900s (15 min)
Trends: 1800s (30 min)
Predictions: NO_CACHE (always fresh)

// Build cache keys deterministically
CacheService.buildKey(CachePrefix.MARKET_DISTRICT, city, period)
// Result: "cache:market:district:ho_chi_minh:2024_q1"

// Always wrap handlers in try-catch
try { ... } catch(error) {
  if (error instanceof DomainException) throw error;
  logger.error(...);
  throw new InternalServerErrorException('...');
}

// Always return DTOs with null metadata
return { city, data, cachedAt: null, nextRefreshAt: null };

// Always use guards
@UseGuards(JwtAuthGuard, QuotaGuard)
@RequireQuota('analytics_queries')

📊 Key Metrics

Metric Value
Controllers 2
Endpoints 24
Query Handlers 15+
DTOs 15+
Caching Patterns 2
Cache Prefixes 10+
Cache TTLs 20+
Prisma Models 4
Repository Interfaces 2
Services (interfaces) 2
Services (implementations) 6+
Module LOC ~2,000
Shared Cache LOC ~250

🧠 Test Your Understanding

After reading all guides, you should be able to:

  1. Explain the 4 DDD layers and what goes in each
  2. Describe how cache-aside pattern works
  3. Distinguish @Cacheable from cache.getOrSet()
  4. Explain why response DTOs have null metadata
  5. Build deterministic cache keys
  6. Choose appropriate TTLs for endpoints
  7. List required guards for endpoints
  8. Add a new endpoint in 7 steps
  9. Explain CacheMetaInterceptor purpose
  10. Describe graceful degradation behavior

📁 Prisma Schema Models

Property — Real estate property details

  • Type, location (PostGIS), area, rooms, condition
  • Indexes: [propertyType], [district, city], [location (Gist)]

Listing — Property listings on platform

  • Price (BigInt), status, AVM estimates
  • Indexes: [status], [sellerId, status], [publishedAt]

MarketIndex — Aggregated market data by period

  • District, city, propertyType, period
  • Median price, average price/m², statistics
  • Unique: [district, city, propertyType, period]

Valuation — AI valuation estimates

  • Property, estimated price, confidence, method
  • Features, comparables, explainers (Json)
  • Index: [propertyId, valuationDate DESC]

🚀 Next Steps

  1. Read all 4 guides in recommended order (60 min)
  2. Review the 7-step endpoint addition guide
  3. Study real handler code examples in guide
  4. Explore actual files in codebase:
    • apps/api/src/modules/analytics/
    • apps/api/src/modules/shared/
  5. Add your first new endpoint following patterns

📞 Questions & Understanding

If you have questions after reading:

  • Refer back to specific sections in guides
  • Check code examples in guide vs actual code
  • Review the 10 validation questions
  • Study the architecture decision matrix

Total package: 2,174 lines, 71 KB of comprehensive documentation

Start with 00_SUMMARY.md and follow the reading path. You'll understand the entire architecture in about 60 minutes!