Label Turkey station observations as MGM
This commit is contained in:
@@ -541,6 +541,34 @@ export function runTests() {
|
|||||||
"NOAA MADIS label should be reserved for US airports; non-US airport-primary fallback should use METAR wording",
|
"NOAA MADIS label should be reserved for US airports; non-US airport-primary fallback should use METAR wording",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const ankaraScanSeedChart = buildFullDayChartData(
|
||||||
|
{
|
||||||
|
city: "ankara",
|
||||||
|
local_date: "2026-06-14",
|
||||||
|
local_time: "15:10",
|
||||||
|
tz_offset_seconds: 3 * 60 * 60,
|
||||||
|
airport: "Esenboğa 机场",
|
||||||
|
temp_symbol: "°C",
|
||||||
|
} as any,
|
||||||
|
{
|
||||||
|
localDate: "2026-06-14",
|
||||||
|
localTime: "15:10",
|
||||||
|
times: ["00:00", "12:00", "18:00"],
|
||||||
|
temps: [15, 19, 18],
|
||||||
|
airportPrimary: {
|
||||||
|
temp: 19,
|
||||||
|
obs_time: "2026-06-14T12:10:00Z",
|
||||||
|
},
|
||||||
|
airportPrimaryTodayObs: [["2026-06-14T12:10:00Z", 19]],
|
||||||
|
} as any,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
const ankaraScanSeedSeries = ankaraScanSeedChart.series.find((item) => item.key === "madis");
|
||||||
|
assert(
|
||||||
|
ankaraScanSeedSeries?.label === "MGM",
|
||||||
|
"Ankara scan-row-seeded airport-primary curve should default to MGM instead of NOAA MADIS when source metadata is missing",
|
||||||
|
);
|
||||||
|
|
||||||
const guangzhouRunwayWithBadMadisChart = buildFullDayChartData(
|
const guangzhouRunwayWithBadMadisChart = buildFullDayChartData(
|
||||||
{
|
{
|
||||||
city: "guangzhou",
|
city: "guangzhou",
|
||||||
|
|||||||
@@ -775,8 +775,12 @@ function airportPrimarySeriesLabel(
|
|||||||
row?: ScanOpportunityRow | null,
|
row?: ScanOpportunityRow | null,
|
||||||
) {
|
) {
|
||||||
if (isHKO) return "HKO";
|
if (isHKO) return "HKO";
|
||||||
|
const cityKey = normalizeCityKey(row?.city);
|
||||||
const canonicalLabel = canonicalAirportPrimarySourceLabel(hourly);
|
const canonicalLabel = canonicalAirportPrimarySourceLabel(hourly);
|
||||||
if (canonicalLabel === "MGM") return canonicalLabel;
|
if (canonicalLabel === "MGM") return canonicalLabel;
|
||||||
|
if ((cityKey === "ankara" || cityKey === "istanbul") && (!canonicalLabel || canonicalLabel === "NOAA MADIS")) {
|
||||||
|
return "MGM";
|
||||||
|
}
|
||||||
const payloadLabel = String(hourly?.airportPrimary?.source_label || "").trim();
|
const payloadLabel = String(hourly?.airportPrimary?.source_label || "").trim();
|
||||||
if (payloadLabel && !isGenericAirportPrimaryLabel(payloadLabel)) return payloadLabel;
|
if (payloadLabel && !isGenericAirportPrimaryLabel(payloadLabel)) return payloadLabel;
|
||||||
if (canonicalLabel === "NOAA MADIS" && !isUsAirportCode(airportCodeForSeriesLabel(hourly, row))) {
|
if (canonicalLabel === "NOAA MADIS" && !isUsAirportCode(airportCodeForSeriesLabel(hourly, row))) {
|
||||||
|
|||||||
@@ -533,6 +533,13 @@ export interface ScanOpportunityRow {
|
|||||||
current_temp?: number | null;
|
current_temp?: number | null;
|
||||||
current_max_so_far?: number | null;
|
current_max_so_far?: number | null;
|
||||||
wunderground_current?: AirportCurrentConditions;
|
wunderground_current?: AirportCurrentConditions;
|
||||||
|
icao?: string | null;
|
||||||
|
station_source_code?: string | null;
|
||||||
|
station_source_label?: string | null;
|
||||||
|
station_code?: string | null;
|
||||||
|
station_label?: string | null;
|
||||||
|
network_provider?: string | null;
|
||||||
|
network_provider_label?: string | null;
|
||||||
metar_context?: {
|
metar_context?: {
|
||||||
source?: string | null;
|
source?: string | null;
|
||||||
station?: string | null;
|
station?: string | null;
|
||||||
|
|||||||
@@ -603,6 +603,40 @@ def test_scan_terminal_quick_row_compacts_runway_history_for_list_payload():
|
|||||||
assert len(str(row["runway_plate_history"])) < len(str(raw_history))
|
assert len(str(row["runway_plate_history"])) < len(str(raw_history))
|
||||||
|
|
||||||
|
|
||||||
|
def test_scan_terminal_quick_row_exposes_airport_primary_source_metadata():
|
||||||
|
row = _build_quick_row(
|
||||||
|
city="ankara",
|
||||||
|
data={
|
||||||
|
"display_name": "Ankara",
|
||||||
|
"local_date": "2026-06-14",
|
||||||
|
"local_time": "2026-06-14T15:10:00+03:00",
|
||||||
|
"temp_symbol": "°C",
|
||||||
|
"current": {"temp": 19.0, "max_so_far": 19.0},
|
||||||
|
"risk": {"airport": "Esenboğa", "icao": "LTAC", "level": "medium"},
|
||||||
|
"airport_primary": {
|
||||||
|
"station_code": "LTAC",
|
||||||
|
"station_label": "Esenboğa 机场",
|
||||||
|
"source_code": "mgm",
|
||||||
|
"source_label": "MGM",
|
||||||
|
},
|
||||||
|
"official_network_source": "turkey_mgm",
|
||||||
|
"official_network_status": {
|
||||||
|
"provider_code": "turkey_mgm",
|
||||||
|
"provider_label": "MGM",
|
||||||
|
},
|
||||||
|
"deb": {"prediction": 20.0},
|
||||||
|
"probabilities": {"distribution": []},
|
||||||
|
"multi_model": {},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert row["icao"] == "LTAC"
|
||||||
|
assert row["station_source_code"] == "mgm"
|
||||||
|
assert row["station_source_label"] == "MGM"
|
||||||
|
assert row["station_code"] == "LTAC"
|
||||||
|
assert row["network_provider"] == "turkey_mgm"
|
||||||
|
|
||||||
|
|
||||||
def test_metar_gate_vetoes_yes_when_observed_breaks_above_bucket():
|
def test_metar_gate_vetoes_yes_when_observed_breaks_above_bucket():
|
||||||
row = {
|
row = {
|
||||||
"id": "yes-row",
|
"id": "yes-row",
|
||||||
|
|||||||
@@ -239,6 +239,8 @@ def _build_quick_row(
|
|||||||
) -> Optional[Dict[str, Any]]:
|
) -> Optional[Dict[str, Any]]:
|
||||||
curr = data.get("current") or {}
|
curr = data.get("current") or {}
|
||||||
risk = data.get("risk") or {}
|
risk = data.get("risk") or {}
|
||||||
|
airport_primary = data.get("airport_primary") if isinstance(data.get("airport_primary"), dict) else {}
|
||||||
|
official_status = data.get("official_network_status") if isinstance(data.get("official_network_status"), dict) else {}
|
||||||
deb = data.get("deb") or {}
|
deb = data.get("deb") or {}
|
||||||
probs = data.get("probabilities") or {}
|
probs = data.get("probabilities") or {}
|
||||||
multi = data.get("multi_model") or {}
|
multi = data.get("multi_model") or {}
|
||||||
@@ -274,6 +276,13 @@ def _build_quick_row(
|
|||||||
"current_temp": curr.get("temp"),
|
"current_temp": curr.get("temp"),
|
||||||
"current_max_so_far": curr.get("max_so_far"),
|
"current_max_so_far": curr.get("max_so_far"),
|
||||||
"wunderground_current": data.get("wunderground_current") or {},
|
"wunderground_current": data.get("wunderground_current") or {},
|
||||||
|
"icao": str(risk.get("icao") or airport_primary.get("station_code") or ""),
|
||||||
|
"station_source_code": airport_primary.get("source_code") or data.get("official_network_source"),
|
||||||
|
"station_source_label": airport_primary.get("source_label") or official_status.get("provider_label"),
|
||||||
|
"station_code": airport_primary.get("station_code") or risk.get("icao"),
|
||||||
|
"station_label": airport_primary.get("station_label") or risk.get("airport"),
|
||||||
|
"network_provider": data.get("official_network_source") or official_status.get("provider_code"),
|
||||||
|
"network_provider_label": official_status.get("provider_label"),
|
||||||
"deb_prediction": deb.get("prediction"),
|
"deb_prediction": deb.get("prediction"),
|
||||||
"model_cluster_sources": (
|
"model_cluster_sources": (
|
||||||
daily_entry.get("models")
|
daily_entry.get("models")
|
||||||
|
|||||||
Reference in New Issue
Block a user