Vantage · Vancouver
PortfolioHow it works
← back to map

How Vantage Vancouver was built

End-to-end walkthrough of the data pipeline, backend, and frontend behind this MVP.

1 · The problem

Vancouver real estate has rich public data (BC Assessment annual valuations, parcel polygons, zoning) but it's scattered across CSV dumps, shapefiles, and government APIs. Vantage stitches it into a single map-first explorer where you can click any parcel, drill into a building, and inspect every strata title within it.

2 · Data layer

  • Source: BC Assessment yearly roll (2016–2026), City of Vancouver parcel polygons, zoning bylaw shapefiles.
  • Store: PostgreSQL 18 + PostGIS 3.6, hosted on Railway.
  • Schema: a wide core.property_current table (last-known state per PID), core.assessment_yearly for time series, and core.site_events for subdivisions / demolitions / redevelopments.
  • Lineage: a UUID per physical lot (lineage_id) groups strata titles and tracks parcels across PID changes.

3 · The strata-to-lot link (the hard part)

BC Assessment doesn't link an individual condo PID to its parent land parcel via a foreign key. The bridge is spatial: each STRATA centroid is point-in-polygon joined to the LAND parcel that covers it (ST_Covers(land.parcel_polygon, strata.centroid)). That's how clicking 833 Seymour reveals all 374 strata titles inside Capitol Residences.

4 · Backend

  • Stack: FastAPI + Pydantic + SQLAlchemy Core, deployed on Railway.
  • Endpoints:bbox parcel fetch with truncation guard, point-in-polygon lookup, address search, per-PID detail & history, per-lot timeline (events + aggregated values), per-PID units list.
  • Performance: GiST spatial indexes on every polygon column, server-side bbox clipping, hard cap at 2,000 features per viewport request.

5 · Frontend

  • Stack: Next.js 16 (App Router) + React 19 + Tailwind 4 + TanStack Query.
  • Map: Mapbox GL JS with a custom geocoder constrained to Vancouver. Parcel layer renders as a thin outline; clicking fills it red and opens the inspector drawer.
  • IA: two tabs per building — Building (aggregate story: total stack value, sparkline, lot events) and Units (per-strata drill-in with search). Single-PID lots hide the Units tab.
  • UX details: recent searches in localStorage, Mapbox red-pin marker, default landing on a busy strata so the flow is visible on first paint.

6 · What's next

  • Sales data integration (LTSA or HouseSigma) for actual transaction prices.
  • Permit pipeline overlay (approved + under-review developments).
  • Comparables and price-per-sqft analytics.