From fcef47cb22274eabb3016347c64d91a8f5080c76 Mon Sep 17 00:00:00 2001 From: Deeman Date: Sun, 8 Mar 2026 15:32:06 +0100 Subject: [PATCH] chore: update CHANGELOG + admin dependency graph for score v4/v5 - CHANGELOG.md: document Market Score v4 and Opportunity Score v5 changes - pipeline_routes.py: add dim_countries to location_profiles dependency list Co-Authored-By: Claude Opus 4.6 --- CHANGELOG.md | 3 +++ web/src/padelnomics/admin/pipeline_routes.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e25557a..31be105 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [Unreleased] ### Changed +- **Market Score v3 → v4** — fixes Spain averaging 54 (should be 65-80). Four calibration changes: count gate threshold lowered from 5 → 3 venues (3 establishes a market pattern), density ceiling lowered from LN(21) → LN(11) (10/100k is reachable for mature markets), demand evidence fallback raised from 0.4 → 0.65 multiplier with 0.3 floor (existence of venues IS evidence of demand), economic context ceiling changed from income/200 → income/25000 (actual discrimination instead of free 10 pts for everyone). +- **Opportunity Score v4 → v5** — fixes structural flaws: supply gap (30pts) + catchment gap (15pts) merged into single supply deficit (35pts, GREATEST of density gap and distance gap) eliminating ~80% correlated double-count. New sports culture signal (10pts) using tennis court density as racquet-sport adoption proxy. New construction affordability signal (5pts) using income relative to PLI construction costs from `dim_countries`. Economic power reduced from 20 → 15pts. New dependency on `foundation.dim_countries` for `pli_construction`. + - **Unified `location_profiles` serving model** — merged `city_market_profile` and `location_opportunity_profile` into a single `serving.location_profiles` table at `(country_code, geoname_id)` grain. Both Marktreife-Score (Market Score) and Marktpotenzial-Score (Opportunity Score) are now computed per location. City data enriched via LEFT JOIN `dim_cities` on `geoname_id`. Downstream models (`planner_defaults`, `pseo_city_costs_de`, `pseo_city_pricing`) updated to query `location_profiles` directly. `city_padel_venue_count` (exact from dim_cities) distinguished from `padel_venue_count` (spatial 5km from dim_locations). - **Both scores on all map tooltips** — country map shows avg Market Score + avg Opportunity Score; city map shows Market Score + Opportunity Score per city; opportunity map shows Opportunity Score + Market Score per location. All score labels use the trademarked "Padelnomics Market Score" / "Padelnomics Opportunity Score" names. - **API endpoints** — `/api/markets/countries.json` adds `avg_opportunity_score`; `/api/markets//cities.json` adds `opportunity_score`; `/api/opportunity/.json` adds `market_score`. diff --git a/web/src/padelnomics/admin/pipeline_routes.py b/web/src/padelnomics/admin/pipeline_routes.py index 3189da0..3bb2291 100644 --- a/web/src/padelnomics/admin/pipeline_routes.py +++ b/web/src/padelnomics/admin/pipeline_routes.py @@ -111,7 +111,7 @@ _DAG: dict[str, list[str]] = { "fct_daily_availability": ["fct_availability_slot", "dim_venue_capacity"], # Serving "venue_pricing_benchmarks": ["fct_daily_availability"], - "location_profiles": ["dim_locations", "dim_cities", "venue_pricing_benchmarks"], + "location_profiles": ["dim_locations", "dim_cities", "dim_countries", "venue_pricing_benchmarks"], "planner_defaults": ["venue_pricing_benchmarks", "location_profiles"], "pseo_city_costs_de": [ "location_profiles", "planner_defaults",