# Listings Module Exploration - Complete Index **Date:** April 21, 2026 **Status:** ✅ Comprehensive exploration complete **Total Documentation:** 2,434 lines across 4 markdown files --- ## 📚 Documentation Files ### 1. **LISTINGS_MODULE_EXPLORATION.md** (965 lines) **→ START HERE for detailed understanding** **Contents:** - Section 1: GET /listings/:id handler (controller + query + cache pattern) - Section 2: Response DTO/schema (ListingDetailData interface with all fields) - Section 3: AVM Service integration (HttpAVMService, AI client, comparables) - Section 4: Agent Quality Score (formula, storage, calculation service) - Section 5: Inquiries module (tracking, events, denormalization) - Section 6: Similar listings algorithm (matching criteria, sorting, performance) - Section 7: Redis caching patterns (cache-aside, TTLs, invalidation, metrics) - Summary table with file paths and key details - Key insights and next steps **Best for:** Getting complete context, understanding code flow, seeing actual code snippets --- ### 2. **LISTINGS_QUICK_REFERENCE.md** (306 lines) **→ QUICK LOOKUP for everyday reference** **Contents:** - 1️⃣ GET /listings/:id flow (ASCII diagram) - 2️⃣ ListingDetailData structure (TypeScript interface with comments) - 3️⃣ AVM Service integration (call path, inputs, outputs, batch processing) - 4️⃣ Agent Quality Score (formula, storage, inputs) - 5️⃣ Inquiries tracking (create flow, fields, denormalization) - 6️⃣ Similar listings algorithm (query pattern, SQL WHERE clauses) - 7️⃣ Redis caching (methods, TTLs, prefixes, metrics) - Key file paths table - Important behaviors checklist **Best for:** Quick lookups, status meetings, implementation reference --- ### 3. **LISTINGS_DATA_SCHEMA.md** (456 lines) **→ DATABASE & PERFORMANCE focus** **Contents:** - Listing table definition (SQL, fields, indexes) - Property table definition (PostGIS geometry, JSONB fields) - PropertyMedia table definition (media ordering) - Inquiry table definition (HTML sanitization, isRead tracking) - Agent table definition (quality score storage) - Review table definition (for aggregation) - Related tables (User reference) - Query patterns (listing detail, similar, count inquiries, quality score calc) - Cache invalidation triggers (events → cache keys) - Performance considerations (indexes, optimization) - Denormalization strategy & eventual consistency model **Best for:** Database queries, performance tuning, schema changes, cache planning --- ### 4. **EXPLORATION_SUMMARY_LISTINGS.md** (320 lines) **→ EXECUTIVE SUMMARY & ARCHITECTURE overview** **Contents:** - 3 documents overview - 7 key findings (one per component) - File organization (directory structure) - Data flow diagram - Component dependencies (ASCII diagram) - Important implementation details (cache envelope, denormalization, AVM fallback, quality formula) - Potential issues & edge cases (7 items) - Recommended next steps (6 items) - References to all documents **Best for:** Architecture review, team onboarding, stakeholder briefing --- ## 🎯 Quick Navigation by Task ### "I need to understand how GET /listings/:id works" → Read **LISTINGS_QUICK_REFERENCE.md** Section 1️⃣ → Then **LISTINGS_MODULE_EXPLORATION.md** Section 1 → Reference **LISTINGS_DATA_SCHEMA.md** Query Patterns ### "What fields are returned in the API response?" → **LISTINGS_QUICK_REFERENCE.md** Section 2️⃣ → **LISTINGS_MODULE_EXPLORATION.md** Section 2 → Source: `apps/api/src/modules/listings/domain/repositories/listing-read.dto.ts` ### "How does the AVM service work?" → **LISTINGS_QUICK_REFERENCE.md** Section 3️⃣ → **LISTINGS_MODULE_EXPLORATION.md** Section 3 → Sources: - `apps/api/src/modules/analytics/domain/services/avm-service.ts` - `apps/api/src/modules/analytics/infrastructure/services/http-avm.service.ts` - `apps/api/src/modules/analytics/infrastructure/services/ai-service.client.ts` ### "How is agent quality score calculated?" → **LISTINGS_QUICK_REFERENCE.md** Section 4️⃣ (formula) → **LISTINGS_MODULE_EXPLORATION.md** Section 4 → Source: `apps/api/src/modules/agents/domain/services/quality-score.service.ts` ### "How are inquiries tracked and counted?" → **LISTINGS_QUICK_REFERENCE.md** Section 5️⃣ → **LISTINGS_MODULE_EXPLORATION.md** Section 5 → **LISTINGS_DATA_SCHEMA.md** Denormalization Strategy → Sources: - `apps/api/src/modules/inquiries/application/commands/create-inquiry/create-inquiry.handler.ts` - `apps/api/src/modules/inquiries/domain/repositories/inquiry-read.dto.ts` ### "How do we find similar listings?" → **LISTINGS_QUICK_REFERENCE.md** Section 6️⃣ → **LISTINGS_MODULE_EXPLORATION.md** Section 6 → **LISTINGS_DATA_SCHEMA.md** Query Patterns → Source: `apps/api/src/modules/listings/infrastructure/repositories/listing-read.queries.ts` (lines 296-369) ### "How does caching work?" → **LISTINGS_QUICK_REFERENCE.md** Section 7️⃣ → **LISTINGS_MODULE_EXPLORATION.md** Section 7 → **LISTINGS_DATA_SCHEMA.md** Cache Invalidation Triggers → Source: `apps/api/src/modules/shared/infrastructure/cache.service.ts` ### "I need to understand the database schema" → **LISTINGS_DATA_SCHEMA.md** (all sections) → References Prisma schema at `prisma/schema.prisma` ### "I'm doing performance optimization" → **LISTINGS_DATA_SCHEMA.md** Performance Considerations → **EXPLORATION_SUMMARY_LISTINGS.md** Key Findings → **LISTINGS_DATA_SCHEMA.md** Denormalization Strategy ### "I need an architectural overview for stakeholders" → **EXPLORATION_SUMMARY_LISTINGS.md** (entire document) → **LISTINGS_QUICK_REFERENCE.md** for tactical details --- ## 🔑 Key File Paths All paths relative to `apps/api/src/modules/`: | Component | Path | |-----------|------| | **GET Handler** | `listings/presentation/controllers/listings.controller.ts` (L236-247) | | **Query Logic** | `listings/application/queries/get-listing/get-listing.handler.ts` | | **Response DTO** | `listings/domain/repositories/listing-read.dto.ts` | | **Listing Entity** | `listings/domain/entities/listing.entity.ts` | | **SQL Queries** | `listings/infrastructure/repositories/listing-read.queries.ts` | | **AVM Interface** | `analytics/domain/services/avm-service.ts` | | **AVM HTTP** | `analytics/infrastructure/services/http-avm.service.ts` | | **AI Client** | `analytics/infrastructure/services/ai-service.client.ts` | | **Quality Score** | `agents/domain/services/quality-score.service.ts` | | **Agent Queries** | `agents/infrastructure/repositories/agent-profile.queries.ts` | | **Inquiry Handler** | `inquiries/application/commands/create-inquiry/create-inquiry.handler.ts` | | **Inquiry DTO** | `inquiries/domain/repositories/inquiry-read.dto.ts` | | **Cache Service** | `shared/infrastructure/cache.service.ts` | --- ## 🎨 Visual Reference ### High-Level Flow ``` Client Request: GET /listings/{id} ↓ ListingsController ↓ GetListingHandler ├─ Cache Check (Redis) ├─ DB Query (Prisma) ├─ PostGIS Geometry └─ Cache Write ↓ ListingDetailData Response ``` ### Component Relationships ``` Listings ├─ Properties ├─ Media ├─ Inquiries (count) ├─ Reviews (seller) ├─ Agent (reference) └─ Cache Analytics (AVM) ├─ AI Service (HTTP) └─ PostGIS Fallback Agents ├─ Quality Score (calc'd from) ├─ Reviews ├─ Inquiries └─ Listings (active count) Inquiries ├─ Listing (denorm counter) └─ User (inquirer) ``` --- ## 📊 Statistics | Metric | Value | |--------|-------| | Total documentation lines | 2,434 | | Code snippets shown | 50+ | | Database tables covered | 6 | | API endpoints explained | 8 | | Services documented | 10+ | | Key formulas | 2 (quality score, cache envelope) | | Algorithms explained | 3 (similar listings, AVM, quality calc) | | Performance patterns | 5 (caching, denormalization, indexing, batch processing, fallback) | --- ## ⚠️ Critical Concepts ### 1. Cache-Aside Pattern - Check cache first, fall back to loader if miss - Store result in Redis with TTL - **Not-found signal**: Don't cache null to allow newly-created listings to be discoverable ### 2. Denormalization via Events - `InquiryCreatedEvent` published → listener increments `Listing.inquiryCount` - Avoids expensive COUNT() queries - Eventual consistency (may lag seconds) - Should have reconciliation job ### 3. AVM Fallback Strategy - Primary: Python AI service (v1 or v2) - Fallback: PostGIS comparables-based estimation - Graceful degradation with metrics tracking ### 4. Similar Listings Algorithm - Rule-based (not ML): price ±10%, area ±20%, same type & district - Fetch 3x limit, sort by delta, return top N - Sorted by price difference (closest first) ### 5. Quality Score Formula - 40% review rating + 30% response time + 20% conversion + 10% listing activity - Recalculated on review/inquiry events - Stored in Agent table (denormalized) --- ## 🚀 Implementation Tips ✅ **Cache invalidation:** Invalidate `cache:listing:{id}` on status change, price update, media upload, featured status change ✅ **Denormalization drift:** Implement periodic reconciliation job to recount inquiries per listing ✅ **AVM errors:** Always have fallback ready; log confidence scores to track when fallback is used ✅ **PostGIS:** Raw SQL queries required for geometry extraction (`$queryRaw`); Prisma doesn't map types ✅ **Batch operations:** Never exceed 5 concurrent AVM requests to avoid overloading Python service ✅ **Cache envelope:** Legacy entries (plain JSON) work transparently; new entries include metadata --- ## 📝 Notes - All code snippets are from **actual source files** (paths provided) - Exploration performed April 21, 2026 - Database schema inferred from Prisma usage patterns - Denormalization strategy validated against event handlers - Performance recommendations based on index analysis --- ## 🤝 Contributing to These Docs When making changes to the listings module: 1. Update relevant sections in these documents 2. Add new findings to EXPLORATION_SUMMARY_LISTINGS.md 3. Update LISTINGS_QUICK_REFERENCE.md with any formula/algorithm changes 4. Update LISTINGS_DATA_SCHEMA.md if schema changes --- **Last Updated:** April 21, 2026 **Status:** Complete and comprehensive **Recommendation:** Print or bookmark for frequent reference