Architecture and decisions
The human stakes of location discovery
Remote workers searching for a neighborhood need a place that matches the specific texture of somewhere they already loved. A misleading recommendation wastes relocation budgets and damages trust in the platform. The goal was building an engine that understands the multidimensional character of neighborhoods.
The failure of linear weighted scoring
My first recommendation model calculated weighted linear averages across walkability, rent price, crime rates, and transit availability. It generated false recommendations. A user who prioritized dense, transit-connected urban districts received recommendations for quiet desert retirement suburbs in Scottsdale because low rent and high safety scores mathematically canceled out the complete lack of walkability. Arithmetic averages destroy the distinct profile shape of a neighborhood.
Multidimensional vector matching with pgvector
I redesigned the matching pipeline around PostgreSQL using the pgvector extension. Neighborhood profiles are modeled as normalized six-dimensional vectors capturing density, housing costs, safety percentiles, transit access, cultural venue frequency, and weather patterns. User preferences form a target vector derived from interaction history and explicit weights. An HNSW-indexed cosine similarity query evaluates the geometric angle between vectors, identifying neighborhoods with matching characteristic profiles instead of blending disparate metrics. That user was recommended a district in Mexico City, where she relocated three months later.
Ingesting seven external data providers
The platform aggregates records from seven external data sources (Walk Score, Census ACS, OpenWeather, Mapbox, Eventbrite, and local municipal crime feeds). Each feed presented inconsistent geographic precision, varying update frequencies, and missing attributes. An ingestion pipeline built with Bun validates raw payloads against Zod schemas before persisting into 19 Prisma models. The application layer provides end-to-end type validation to React clients through 54 tRPC procedures.
Lessons from pipeline failure modes
External data integrations fail at the edges. When a third-party news API altered its response schema without notice, our local sentiment alert pipeline failed silently because errors were logged instead of queued. The ingestion worker now isolates external calls into dedicated message queues with exponential backoff and dead-letter handling.