- 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>
322 lines
10 KiB
Markdown
322 lines
10 KiB
Markdown
# GoodGo Platform API Exploration Summary
|
||
|
||
## Executive Summary
|
||
|
||
Complete audit of GoodGo Platform monorepo API endpoints and data structures. All field names, types, and response formats documented for UI component mapping.
|
||
|
||
**Generated**: April 21, 2026
|
||
**Scope**: `apps/api/src/modules/{analytics,listings,agents,search}` + `prisma/schema.prisma`
|
||
|
||
---
|
||
|
||
## 📋 Key Findings
|
||
|
||
### Analytics Module (✅ Fully Explored)
|
||
|
||
**Endpoints Count**: 15+ key endpoints
|
||
**Architecture**: CQRS with query handlers → DTOs
|
||
**Caching**: 30min - 24hr TTL across endpoints
|
||
**Auth**: JWT required (except public endpoints)
|
||
|
||
**Core Features**:
|
||
1. **Market Data** (snapshot, trends, heatmap, district stats)
|
||
- Real-time aggregation from active listings
|
||
- Price change metrics (1d, 7d, 30d)
|
||
- Per-district inventory & absorption data
|
||
|
||
2. **Valuations (AVM)** (v1 & v2 models)
|
||
- GET by property ID or coordinates
|
||
- POST manual input with extended features
|
||
- Batch operations (up to 50 properties)
|
||
- Historical tracking & comparisons
|
||
- Confidence scoring with explanations
|
||
|
||
3. **Trending Areas**
|
||
- Scoring algorithm: `inquiries×0.6 + views×0.3 + listings×0.1`
|
||
- Time-window configurable (default 30 days)
|
||
- District/ward level aggregation
|
||
|
||
4. **Neighborhood Scores**
|
||
- 6 dimensional scoring (education, healthcare, transport, shopping, greenery, safety)
|
||
- POI counting (schools, hospitals, transit, malls, parks, restaurants)
|
||
- 0-100 scale with aggregation
|
||
|
||
5. **Nearby POIs** (Public)
|
||
- Geographic search within radius
|
||
- 6 main categories with type mapping
|
||
- Distance calculation using PostGIS
|
||
|
||
### Listings Module (✅ Fully Explored)
|
||
|
||
**Entity Count**: 2 main aggregates (Listing + Property)
|
||
**Field Count**: ~45 total fields across entities
|
||
**Key Features**:
|
||
- Listing status state machine (DRAFT → PENDING_REVIEW → ACTIVE → SOLD/RENTED)
|
||
- AI price estimates with confidence scores
|
||
- Moderation workflow with scoring
|
||
- Engagement metrics (views, saves, inquiries)
|
||
- Featured promotion with expiry tracking
|
||
- Rent pricing support
|
||
- Commission tracking
|
||
|
||
**Property Fields**:
|
||
- Core: type, title, description, location (PostGIS), area
|
||
- Rooms: bedrooms, bathrooms, floors, floor level
|
||
- Infrastructure: direction, year built, legal status, metro distance
|
||
- Amenities: JSON-based (flexible schema)
|
||
- Enhanced: furnishing, condition, parking, maintenance fee, pet-friendly, view types, suitability tags
|
||
|
||
### Agents Module (✅ Explored)
|
||
|
||
**Key Fields**:
|
||
- Profile: userId, licenseNumber, agency, bio
|
||
- Credentials: isVerified (boolean)
|
||
- Performance: qualityScore (0-100), totalDeals, responseTimeAvg
|
||
- Coverage: serviceAreas (array of district IDs)
|
||
|
||
**Performance Metrics**:
|
||
- Quality score as composite metric
|
||
- Response time in seconds (need conversion for display)
|
||
- Deal count as credibility indicator
|
||
|
||
### Search Module (✅ Explored)
|
||
|
||
**Architecture**: Meilisearch (typesense-compatible backend)
|
||
**Index Fields**: 31 fields per document
|
||
**Key Features**:
|
||
- Full-text + filtering + geo-search
|
||
- Featured listing flag
|
||
- Engagement metrics copied to index
|
||
- Amenities as string array
|
||
|
||
**Supported Filters**:
|
||
- propertyType, transactionType
|
||
- Price range, area range
|
||
- Bedrooms (>= operator)
|
||
- District, city
|
||
- Featured status
|
||
|
||
### Prisma Schema (✅ Full Review)
|
||
|
||
**Key Models**:
|
||
- User (role-based: BUYER, SELLER, AGENT, DEVELOPER, PARK_OPERATOR, ADMIN)
|
||
- Property (core real estate entity)
|
||
- Listing (marketplace listing wrapper)
|
||
- Agent (performance tracking)
|
||
- Valuation (AVM history)
|
||
- MarketIndex (market analytics cache)
|
||
- Transaction, Inquiry, Lead, Payment, Order, Escrow models
|
||
|
||
**Enums**:
|
||
- PropertyType: 6 values (APARTMENT, VILLA, TOWNHOUSE, LAND, OFFICE, SHOPHOUSE)
|
||
- TransactionType: 2 values (SALE, RENT)
|
||
- ListingStatus: 8 values (DRAFT...REJECTED)
|
||
- Direction: 8 compass values
|
||
- Furnishing: 3 levels
|
||
- PropertyCondition: 4 conditions
|
||
|
||
---
|
||
|
||
## 🎯 API Field Reference by Use Case
|
||
|
||
### For Property Card Display
|
||
```
|
||
Price → listing.priceVND (format as VND)
|
||
Type → listing.transactionType
|
||
Status → listing.status
|
||
Area → property.areaM2
|
||
Beds/Baths → property.bedrooms, property.bathrooms
|
||
Location → property.district, property.ward, property.city
|
||
Agent → listing.agent.user.fullName, listing.agent.qualityScore
|
||
Engagement → listing.viewCount, listing.saveCount, listing.inquiryCount
|
||
Featured → listing.featuredUntil (if > now, show badge)
|
||
```
|
||
|
||
### For Valuation Display
|
||
```
|
||
Estimate → ValuationDto.estimatedPrice (string, format as VND)
|
||
Confidence → ValuationDto.confidence (0.0-1.0, convert to %)
|
||
Price/m² → ValuationDto.pricePerM2
|
||
Model Version → ValuationDto.modelVersion (v1|v2|ensemble)
|
||
Comparables → ValuationDto.comparables[] with distance & price
|
||
```
|
||
|
||
### For Market Analysis
|
||
```
|
||
Market Snapshot → GET /analytics/market-snapshot
|
||
├─ activeCount, avgPrice, medianPrice, avgPricePerM2
|
||
├─ daysOnMarket, newListings24h
|
||
└─ priceChangePct { d1, d7, d30 }
|
||
|
||
Price Trend → GET /analytics/price-trend
|
||
├─ trend[] { period, medianPrice, avgPriceM2, totalListings }
|
||
|
||
Heatmap → GET /analytics/heatmap
|
||
├─ dataPoints[] { district, avgPriceM2, totalListings, medianPrice }
|
||
|
||
District Stats → GET /analytics/district-stats
|
||
├─ districts[] { district, medianPrice, avgPriceM2, totalListings, daysOnMarket, yoyChange }
|
||
|
||
Trending Areas → GET /analytics/trending-areas
|
||
├─ areas[] { name, listings, inquiries, views, priceChangePct, scoreRank }
|
||
```
|
||
|
||
### For Location Intelligence
|
||
```
|
||
Neighborhood Score → GET /analytics/neighborhoods/:district/score
|
||
├─ educationScore, healthcareScore, transportScore, shoppingScore
|
||
├─ greeneryScore, safetyScore, totalScore (all 0-100)
|
||
├─ poiCounts { schools, hospitals, transit, shopping, parks, restaurants }
|
||
|
||
Nearby POIs → GET /analytics/pois/nearby
|
||
├─ pois[] { name, type, category, lat, lng, distance, address }
|
||
```
|
||
|
||
---
|
||
|
||
## 🔌 Quick Integration Checklist
|
||
|
||
### Before Mapping UI Components:
|
||
|
||
- [ ] **Understand Caching**: Most analytics endpoints have 30min-24hr cache
|
||
- Include `cachedAt` and `nextRefreshAt` in UI
|
||
- Plan refresh UX accordingly
|
||
|
||
- [ ] **Price Handling**: All prices in VND
|
||
- Received as strings (precision preservation)
|
||
- Must format for display (thousand separators, currency symbol)
|
||
- BigInt in DB, may overflow JS numbers
|
||
|
||
- [ ] **Confidence Scores**: Different scales
|
||
- Valuation confidence: 0.0-1.0 (multiply by 100 for %)
|
||
- Moderation score: 0-100 (direct use)
|
||
- Quality score (agent): 0-100 (convert 0-5 stars)
|
||
|
||
- [ ] **Enum Handling**: Map enum values to display labels
|
||
- PropertyType: 6 values (need translations)
|
||
- ListingStatus: 8 values (map to colors/icons)
|
||
- TransactionType: 2 values (SALE vs RENT)
|
||
|
||
- [ ] **Coordinates**: Use `property.location` (PostGIS geometry)
|
||
- Accessible as `lat`, `lng` in API responses
|
||
- Distance calculations use PostGIS functions
|
||
|
||
- [ ] **Rate Limits**: Per endpoint
|
||
- Valuation POST: 10 req/min/user
|
||
- Search: 200 req/min/user
|
||
- Implement backoff/retry logic
|
||
|
||
- [ ] **Null Handling**: Many fields optional
|
||
- `bedrooms`/`bathrooms` can be null (studio)
|
||
- `agentId` can be null (direct seller)
|
||
- Valuation `confidence` may have `null` comparables
|
||
- Handle gracefully in UI
|
||
|
||
- [ ] **Pagination**: Search results include
|
||
- `page`, `perPage`, `totalPages`, `totalFound`
|
||
- Implement lazy loading or infinite scroll
|
||
|
||
---
|
||
|
||
## 📚 Documentation Files Generated
|
||
|
||
1. **API_ENDPOINTS_REFERENCE.md** (~800 lines)
|
||
- Complete endpoint documentation
|
||
- Request/response schemas in TypeScript
|
||
- Query parameters & caching info
|
||
- Prisma model definitions
|
||
|
||
2. **UI_MAPPING_QUICK_GUIDE.md** (~400 lines)
|
||
- Visual mockups with field mappings
|
||
- Pre-formatted example layouts
|
||
- Common conversions (price, confidence, distance)
|
||
- UI integration patterns
|
||
|
||
3. **API_EXPLORATION_SUMMARY.md** (this file)
|
||
- Executive overview
|
||
- Key findings by module
|
||
- Integration checklist
|
||
- References
|
||
|
||
---
|
||
|
||
## 🔗 Source Files Analyzed
|
||
|
||
### Analytics Module
|
||
- `controllers/analytics.controller.ts` → 15 endpoints
|
||
- `domain/services/avm-service.ts` → AVM interface & types
|
||
- `application/queries/{...}/handler.ts` → 10+ query handlers with DTO definitions
|
||
- `presentation/dto/{...}.ts` → Request/response types
|
||
|
||
### Listings Module
|
||
- `domain/entities/listing.entity.ts` → Listing aggregate (status machine, events)
|
||
- `domain/entities/property.entity.ts` → Property aggregate (updateable fields)
|
||
|
||
### Agents Module
|
||
- `domain/entities/agent.entity.ts` → Agent profile & performance metrics
|
||
|
||
### Search Module
|
||
- `domain/repositories/search.repository.ts` → SearchResult interface & 31 indexed fields
|
||
|
||
### Database
|
||
- `prisma/schema.prisma` → 30+ models with enums & indexes
|
||
|
||
---
|
||
|
||
## ✅ Data Quality Notes
|
||
|
||
**Strengths**:
|
||
- Strong type safety (NestJS + Prisma)
|
||
- Comprehensive DTOs for API contracts
|
||
- Clear status machine for listings
|
||
- Well-indexed database schema
|
||
- Separation of concerns (domain → application → presentation)
|
||
|
||
**Considerations**:
|
||
- JSON fields in Property (amenities, nearbyPOIs) — verify schema client-side
|
||
- Price precision — use strings, not numbers, for financial data
|
||
- Confidence scores use different scales — easy to mix up
|
||
- Service areas stored as JSON array of district IDs — need mapping table
|
||
- Valuation comparables may be null if insufficient data
|
||
|
||
---
|
||
|
||
## 🎓 Next Steps
|
||
|
||
1. **API Client Generation**
|
||
- Use Swagger/OpenAPI docs from NestJS controllers
|
||
- Generate TypeScript client with `openapi-generator`
|
||
|
||
2. **Component Development**
|
||
- Start with property card components
|
||
- Wire market snapshot widget
|
||
- Build valuation display components
|
||
|
||
3. **Data Transformation Layer**
|
||
- Create utility functions for price formatting
|
||
- Build confidence score converters
|
||
- Implement district ID → name mappings
|
||
|
||
4. **Testing**
|
||
- Mock response data from this reference
|
||
- Test edge cases (null values, precision, formatting)
|
||
- Verify caching behavior
|
||
|
||
---
|
||
|
||
## 📞 Key Contacts & Resources
|
||
|
||
**API Documentation**: Swagger/OpenAPI available at `/api/docs` (NestJS Swagger module)
|
||
|
||
**Prisma Models**: Comprehensive schema with relationships in `prisma/schema.prisma`
|
||
|
||
**Code Examples**: Query handlers in `apps/api/src/modules/analytics/application/queries/`
|
||
|
||
---
|
||
|
||
**Document Version**: 1.0
|
||
**Last Updated**: April 21, 2026
|
||
**Status**: Complete ✅
|
||
|
||
All information current as of repository scan on 2026-04-21.
|