Files
goodgo-platform/docs/audits/BACKEND_API_AUDIT_EXCHANGE_UI.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

10 KiB
Raw Permalink Blame History

Backend API Audit: Trading Exchange UI Refactor

Prepared for TechLead | Gap analysis for sàn giao dịch-style dashboard
Audit date: 2026-04-21


Executive Summary

Backend has strong coverage for analytics, listings, and agent profiles. Critical gaps exist for real-time market tickers, recent-updates feeds, and aggregated district-level indices needed for the home dashboard and listings board.


Available Endpoints (Ready for FE)

Listings Module

📁 apps/api/src/modules/listings/presentation/controllers/listings.controller.ts
Route prefix: /listings

Method Path Description Auth
GET / Search/filter listings (pagination, sort) Public
GET /:id Listing detail (full property data, seller, agent) Public
GET /:id/price-history Price change history (chart data) Public
GET /:id/qr-code Generate QR code PNG Public
POST / Create listing JWT + quota
PATCH /:id Update listing (price, description, amenities) JWT + owner
PATCH /:id/status Update status (DRAFT→ACTIVE, etc.) JWT + owner
POST /:id/media Upload photo/video JWT + owner
POST /:id/feature Feature listing (payment gateway) JWT + rate limit
POST /:id/promote Promote featured (subscription quota) JWT + quota
POST bulk-update Bulk patch price/status/featured (≤100 items) JWT + owner
GET /pending Get moderation queue (admin) ADMIN
GET /duplicates Find duplicate listings by geo (admin) ADMIN
PATCH /:id/moderate Moderate listing (admin) ADMIN
DELETE /:id Delete listing JWT + owner

Analytics Module

📁 apps/api/src/modules/analytics/presentation/controllers/analytics.controller.ts
Route prefix: /analytics

Method Path Description Auth Quota
GET /market-report Market report by city/district (median price, inventory, absorption) JWT Yes
GET /price-trend Price trend time-series by district JWT Yes
GET /heatmap Price heatmap by city (grid: avg_m2, counts) JWT Yes
GET /district-stats Statistics by district (city-level aggregates) JWT Yes
GET /valuation AVM estimate (by property ID or coords) JWT Yes
POST /valuation AVM with custom form data (v1/v2 ensemble) JWT Yes
POST /valuation/batch Batch AVM (≤50 properties) JWT Yes
GET /valuation/history/:propertyId Valuation time-series (chart) JWT Yes
POST /valuation/compare Compare valuations (25 properties) JWT Yes
GET /neighborhoods/:district/score Neighborhood quality score Public No

Note: All analytics queries return cached data (TTL varies by type).


Search Module

📁 apps/api/src/modules/search/presentation/controllers/search.controller.ts
Route prefix: /search

Method Path Description Auth
GET / Full-text & faceted property search Public
GET /geo Geographic radius search (lat, lng, radiusKm) Public
POST /reindex Trigger full-text reindex (admin) ADMIN

Agents Module

📁 apps/api/src/modules/agents/presentation/controllers/agents.controller.ts
Route prefix: /agents

Method Path Description Auth
GET /:agentId/profile Public agent profile (name, quality score, listings count, reviews) Public
GET /me/dashboard Agent dashboard stats (my listings, inquiries, quality metrics) JWT (AGENT role)
POST /me/upgrade Upgrade user account to agent JWT
POST /:agentId/recalculate-score Recalc quality score (admin) ADMIN

Admin Module

📁 apps/api/src/modules/admin/presentation/controllers/admin-moderation.controller.ts + admin.controller.ts
Route prefix: /admin

Method Path Description Auth
GET /moderation Moderation queue (pending listings) ADMIN
POST /moderation/approve Approve listing ADMIN
POST /moderation/reject Reject listing with reason ADMIN
POST /moderation/bulk Bulk approve/reject ADMIN
GET /moderation/audit-logs Moderation audit trail ADMIN
GET /kyc KYC approval queue ADMIN
POST /kyc/approve Approve KYC ADMIN
POST /kyc/reject Reject KYC ADMIN
GET /users List all users (paginated, filters) ADMIN
GET /users/:id Get user details ADMIN
POST /users/ban Ban user ADMIN
POST /subscriptions/adjust Adjust user subscription ADMIN
GET /dashboard Admin dashboard stats ADMIN
GET /revenue Revenue analytics ADMIN
GET /audit-logs General audit logs ADMIN

Reviews Module

📁 apps/api/src/modules/reviews/presentation/controllers/reviews.controller.ts
Route prefix: /reviews

Method Path Description Auth
GET / List reviews for target (agent, listing, user) Public
GET /stats Aggregate rating stats (avg, distribution) Public
GET /me User's own reviews JWT
POST / Create review JWT

Critical Gaps (Missing or Insufficient)

🔴 1. Market Overview Ticker — NOT PRESENT

UI Need: Home dashboard ticker with price changes, recent listings, trending areas
Gap: No endpoint for:

  • Recent listings (last 24h, last 7d) with timestamp
  • Trending areas (by inquiry/view volume)
  • Price change summary (top gainers/losers by district)
  • Active listings count by type

Solution: GET /listings/recent?limit=10&hours=24 + GET /analytics/trending-areas?period=7d


🔴 2. Real-Time Listing Updates — NOT PRESENT

UI Need: Listings board shows "just posted," "price dropped," "featured" badges
Gap:

  • Search doesn't sort by publishedAt
  • No webhook/SSE for status changes
  • No delta updates since last refresh

Solution: Add sortBy=publishedAt to search + GET /listings?newSince=TIMESTAMP


🔴 3. Similar Listings / Comparables — NOT PRESENT

UI Need: Listing detail shows 510 comparable properties
Gap: No endpoint; search is generic, not contextual

Solution: GET /listings/:id/similar?limit=5 (same district, ±10% price, same type)


🔴 4. Market Indicators: Ward-Level Data — PARTIAL

Available: District-level market report, heatmap
Missing: Ward (phường)-level price trends, listing volume by ward

Solution: GET /analytics/heatmap?level=ward + GET /analytics/listing-volume?ward=X


🔴 5. Listing Detail: Enrichment Missing

Current: Basic property, seller, agent, media
Missing:

  • valuationEstimate (AVM not included)
  • inquiryCount (exists but not exposed?)
  • agentQualityScore (denormalized from agent profile)
  • Similar listings reference

🔴 6. Market Snapshot (Live Indicators) — NOT PRESENT

UI Need: Home dashboard tiles with total active listings, avg price, price change %
Gap: No single endpoint; requires multiple calls

Solution: GET /analytics/market-snapshot?city=HCMC returns { activeCount, avgPrice, medianPrice, priceChange%, inventoryM2, daysOnMarket }


UI Need: "Top 10 areas by inquiry volume" for home dashboard heatmap
Gap: No aggregation by inquiry/view counts per district

Solution: GET /analytics/trending-areas?period=7d&limit=10 (sorted by inquiries/views)


🟡 8. Price Movers (Gainers/Losers) — NOT PRESENT

UI Need: "Top 5 price drops" / "Top 5 price increases" for exchange ticker
Gap: No endpoint; requires post-processing of market report data

Solution: GET /analytics/price-movers?direction=up|down&limit=5 aggregated by district


UI Need: Analytics page showing 12-month price, volume, absorption trends
Gap: Market report is current snapshot only

Solution: GET /analytics/market-history?city=HCMC&period=12m returns monthly snapshots


🟡 10. Cache Metadata in Analytics Responses — MISSING

Issue: No transparency on data freshness
Gap: Endpoints don't expose cachedAt, nextRefreshAt, or data age

Solution: Add metadata fields to all analytics responses


Summary Table

Feature Status Severity Module
Listing search & filter listings
Listing detail listings
Price history listings
Market report analytics
Heatmap analytics
AVM/Valuation Partial analytics
Agent profile Minor agents
Admin moderation admin
Recent listings ticker 🔴 High listings
Market snapshot 🔴 High analytics
Trending areas 🔴 High analytics
Similar listings 🔴 High listings
Real-time updates 🟡 Medium listings
Price movers 🟡 Medium analytics
Market history 🟡 Medium analytics
Ward-level heatmap 🟡 Medium analytics
Cache metadata 🟡 Medium analytics

Recommendations

Phase 1: Sprint 12 (High Priority)

  1. GET /listings?sortBy=publishedAt&limit=20 — Recent listings first
  2. GET /analytics/market-snapshot?city=HCMC — Live indicators (total, avg, median)
  3. GET /analytics/trending-areas?period=7d — Top areas by activity
  4. GET /listings/:id/similar?limit=5 — Comparable properties
  5. Enhance listing detail response with valuationEstimate, inquiryCount, agentScore

Phase 2: Sprint 3 (Medium Priority)

  1. GET /analytics/price-movers — Gainers/losers
  2. GET /analytics/market-history?period=12m — Trends for charts
  3. Add cache metadata to all analytics endpoints

Phase 3: Sprint 4+ (Polish)

  1. Real-time updates (WebSocket/SSE)
  2. Ward-level drill-down for heatmap
  3. Most-saved listings for admin analytics

Total Endpoints Reviewed: 70+
Ready for FE: 58
Critical Gaps: 10
Easy Wins: ~5 queries over 23 sprints