- 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>
10 KiB
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.tsapps/api/src/modules/analytics/infrastructure/services/http-avm.service.tsapps/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.tsapps/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
InquiryCreatedEventpublished → listener incrementsListing.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:
- Update relevant sections in these documents
- Add new findings to EXPLORATION_SUMMARY_LISTINGS.md
- Update LISTINGS_QUICK_REFERENCE.md with any formula/algorithm changes
- Update LISTINGS_DATA_SCHEMA.md if schema changes
Last Updated: April 21, 2026
Status: Complete and comprehensive
Recommendation: Print or bookmark for frequent reference