# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Property Map is a full-stack geospatial web application that visualizes UK property price data aggregated by H3 hexagonal spatial indices. It combines Land Registry price data with postcode geolocation to create an interactive map for exploring property markets. ## Commands All commands use [Task](https://taskfile.dev) runner. Install with: `curl -1sLf 'https://dl.cloudsmith.io/public/task/task/setup.deb.sh' | sudo -E bash` ```bash # Initial setup (downloads ~GB of data, runs pipeline) task prepare # Development (run in separate terminals) task server # FastAPI backend on :8001 task frontend # Webpack dev server on :3030 (proxies /api to :8001) # Code quality task lint # Lint Python (ruff) + TypeScript (ESLint + Prettier) task format # Auto-fix formatting task typecheck # TypeScript type checking task check # All checks (lint + typecheck + build) # Production task build # Build frontend task prod # Serve built frontend via FastAPI ``` ## Architecture ``` frontend/ React + TypeScript SPA (deck.gl/MapLibre for visualization) src/App.tsx Main component with filters and map state src/components/ Map.tsx (deck.gl H3HexagonLayer), Filters UI server/ FastAPI backend main.py App setup, CORS, static file mounting routes/hexagons.py GET /api/hexagons - returns aggregated price data pipeline/ Data processing (Polars + H3) config.py Central config (H3 resolutions 6-11, year/price ranges) sources/ Postcode loading, property price joins processors/ H3 aggregation (count, avg/median/min/max by cell+year) tfl_journey_client/ Generated TFL API client (local package) ``` ## Data Flow 1. **Download**: Land Registry prices + ArcGIS postcode→lat/lon mappings → `data_sources/` 2. **Pipeline**: Join data, compute H3 indices, aggregate stats → `data_sources/processed/aggregates/*.parquet` 3. **Serve**: Load parquet files into memory, filter by bounds/year/price, return as GeoJSON-like response 4. **Visualize**: Frontend fetches on viewport change, renders hexagons colored by average price ## Tech Stack - **Frontend**: React 18, TypeScript, Webpack, TailwindCSS, deck.gl, MapLibre GL - **Backend**: Python 3.12, FastAPI, Polars, H3 - **Package managers**: `uv` (Python), `npm` (frontend) ## Key Implementation Details - Backend caches dataframes in memory and uses LRU cache on queries - Bounds rounded to 0.01° precision to improve cache hits - Results capped at 50,000 hexagons per request (truncated flag in response) - Frontend debounces API calls on map movement