lgtm
Some checks failed
Build and publish Docker image / build-and-push (push) Successful in 18m12s
CI / Check (push) Failing after 23m38s

This commit is contained in:
Andras Schmelczer 2026-06-22 22:12:27 +01:00
parent f7e0814a38
commit fd2860070a
55 changed files with 4084 additions and 186 deletions

View file

@ -325,10 +325,21 @@ struct Cli {
#[arg(long, env = "ACTUAL_LISTINGS_PATH")]
actual_listings_path: PathBuf,
/// Path to a parquet of planned/pipeline development sites (MHCLG brownfield
/// register + Homes England Land Hub) for the "new developments" layer.
#[arg(long, env = "DEVELOPMENTS_PATH")]
developments_path: PathBuf,
/// Path to the per-LSOA per-year crime parquet (display-only side table for the right pane).
#[arg(long, env = "CRIME_BY_YEAR_PATH")]
crime_by_year_path: PathBuf,
/// Path to the per-unit-postcode population parquet (ONS Census 2021 usual
/// residents; display-only side table for the right pane). Optional: when
/// absent or missing, the area pane simply omits the population figure.
#[arg(long, env = "POPULATION_PATH")]
population_path: Option<PathBuf>,
/// Google Maps API key for Street View metadata lookups
#[arg(long, env = "GOOGLE_MAPS_API_KEY")]
google_maps_api_key: String,
@ -692,6 +703,18 @@ async fn main() -> anyhow::Result<()> {
Arc::new(listings)
};
let developments = {
let path = &cli.developments_path;
if !path.exists() {
bail!("Development sites parquet not found: {}", path.display());
}
info!("Loading development sites from {}", path.display());
let data = data::DevelopmentData::load(path)?;
trim_allocator("development sites load");
info!(rows = data.lat.len(), "Development sites loaded");
Arc::new(data)
};
let crime_by_year = {
let path = &cli.crime_by_year_path;
if !path.exists() {
@ -702,6 +725,34 @@ async fn main() -> anyhow::Result<()> {
Arc::new(data)
};
let population = match &cli.population_path {
Some(path) if path.exists() => {
let data = data::PostcodePopulation::load(path)?;
trim_allocator("postcode population load");
Arc::new(data)
}
Some(path) => {
tracing::warn!(
"Population parquet not found at {}; area pane will omit population",
path.display()
);
Arc::new(data::PostcodePopulation::empty())
}
None => Arc::new(data::PostcodePopulation::empty()),
};
let area_crime_averages = {
let data = property_data.compute_area_crime_averages();
info!(
outcodes = data.by_outcode.len(),
sectors = data.by_sector.len(),
crime_types = data.crime_types.len(),
"Per-outcode/sector crime averages computed"
);
trim_allocator("area crime averages");
Arc::new(data)
};
let app_state = AppState {
data: property_data,
grid,
@ -728,7 +779,10 @@ async fn main() -> anyhow::Result<()> {
gemini_model: cli.gemini_model,
travel_time_store,
actual_listings,
developments,
crime_by_year,
population,
area_crime_averages,
token_cache,
superuser_token_cache,
share_cache,
@ -801,6 +855,10 @@ async fn main() -> anyhow::Result<()> {
"/api/actual-listings",
get(routes::get_actual_listings).layer(ConcurrencyLimitLayer::new(20)),
)
.route(
"/api/developments",
get(routes::get_developments).layer(ConcurrencyLimitLayer::new(20)),
)
.route(
"/api/poi-categories",
get(routes::get_poi_categories).layer(ConcurrencyLimitLayer::new(20)),