Files
PolyWeather/frontend/lib/dashboard-types.ts
T

713 lines
19 KiB
TypeScript

export type RiskLevel = "low" | "medium" | "high" | string;
export interface CityListItem {
name: string;
display_name: string;
lat: number;
lon: number;
utc_offset_seconds?: number;
risk_level: RiskLevel;
deb_recent_tier?: RiskLevel;
deb_recent_hit_rate?: number | null;
deb_recent_sample_count?: number;
deb_recent_mae?: number | null;
deb_recent_last_date?: string | null;
risk_emoji?: string;
airport: string;
icao: string;
temp_unit: "celsius" | "fahrenheit";
is_major?: boolean;
settlement_source?: string;
settlement_source_label?: string;
settlement_station_code?: string;
settlement_station_label?: string;
network_provider?: string;
network_provider_label?: string;
}
export interface ProbabilityBucket {
value?: number | null;
label?: string | null;
bucket?: string | null;
range?: string | null;
unit?: string | null;
probability?: number | null;
}
export interface ModelForecastEntry {
label: string;
value: number;
}
export interface DashboardRisk {
level: RiskLevel;
emoji?: string;
airport?: string;
icao?: string;
distance_km?: number | null;
warning?: string | null;
}
export interface CloudLayer {
cover: string;
base: number | null;
}
export interface CurrentConditions {
temp: number | null;
max_so_far: number | null;
max_temp_time: string | null;
wu_settlement: number | null;
settlement_source?: string | null;
settlement_source_label?: string | null;
station_code?: string | null;
station_name?: string | null;
obs_time: string | null;
obs_age_min: number | null;
observation_status?: "live" | "missing" | "stale" | string | null;
wind_speed_kt: number | null;
wind_dir: number | null;
humidity: number | null;
cloud_desc: string | null;
clouds_raw: CloudLayer[];
visibility_mi: number | null;
wx_desc: string | null;
raw_metar?: string | null;
report_time?: string | null;
receipt_time?: string | null;
obs_time_epoch?: number | null;
dewpoint?: number | null;
}
export interface AirportCurrentConditions {
temp: number | null;
obs_time: string | null;
max_so_far?: number | null;
max_temp_time?: string | null;
obs_age_min?: number | null;
report_time?: string | null;
receipt_time?: string | null;
obs_time_epoch?: number | null;
wind_speed_kt?: number | null;
wind_dir?: number | null;
humidity?: number | null;
cloud_desc?: string | null;
visibility_mi?: number | null;
wx_desc?: string | null;
raw_metar?: string | null;
source_label?: string | null;
station_code?: string | null;
station_label?: string | null;
is_airport_station?: boolean;
is_official?: boolean;
is_settlement_anchor?: boolean;
stale_for_today?: boolean;
last_observation_local_date?: string | null;
current_local_date?: string | null;
}
export interface NearbyStation {
name?: string;
icao?: string;
station_code?: string | null;
station_label?: string | null;
lat: number;
lon: number;
temp: number | null;
wind_dir?: number | null;
wind_speed?: number | null;
wind_speed_kt?: number | null;
source_code?: string | null;
source_label?: string | null;
is_official?: boolean;
is_airport_station?: boolean;
is_settlement_anchor?: boolean;
obs_time?: string | null;
obs_time_epoch?: number | string | null;
obs_time_label?: string | null;
obs_time_display_tz?: "city_local" | string | null;
age_minutes?: number | null;
time_delta_vs_anchor_minutes?: number | null;
sync_status?: "synced" | "near_realtime" | "lagged" | "stale" | "unknown" | string | null;
usable_for_intraday?: boolean;
wind_direction_text?: string | null;
wind_power_text?: string | null;
}
export interface HourlyTrendPoint {
time: string;
temp: number;
}
export interface TrendInfo {
direction?: string;
recent?: HourlyTrendPoint[];
is_cooling?: boolean;
is_dead_market?: boolean;
}
export interface PeakInfo {
hours?: string[];
first_h?: number;
last_h?: number;
status?: string;
}
export interface MgmData {
temp?: number | null;
time?: string | null;
today_high?: number | null;
today_low?: number | null;
hourly?: Array<{
time?: string | null;
temp?: number | null;
}>;
}
export interface ForecastDay {
date: string;
max_temp: number | null;
min_temp?: number | null;
}
export interface ForecastData {
today_high?: number | null;
daily?: ForecastDay[];
sunrise?: string | null;
sunset?: string | null;
sunshine_hours?: number | null;
}
export interface DebForecast {
prediction: number | null;
weights_info?: string | null;
}
export interface CitySummary {
name: string;
display_name?: string | null;
icao?: string | null;
utc_offset_seconds?: number | null;
local_time?: string | null;
temp_symbol?: string | null;
current?: {
temp?: number | null;
obs_time?: string | null;
settlement_source?: string | null;
settlement_source_label?: string | null;
};
deb?: {
prediction?: number | null;
};
deviation_monitor?: DeviationMonitor;
risk?: {
level?: RiskLevel;
warning?: string | null;
};
updated_at?: string | null;
}
export interface DeviationMonitor {
available?: boolean;
current_delta?: number | null;
reference_temp?: number | null;
direction?: "normal" | "cold" | "hot" | string;
severity?: "normal" | "light" | "strong" | string;
trend?: "stable" | "expanding" | "contracting" | string;
label_zh?: string | null;
label_en?: string | null;
trend_label_zh?: string | null;
trend_label_en?: string | null;
}
export interface HourlySeries {
times?: string[];
temps?: Array<number | null>;
dew_point?: Array<number | null>;
pressure_msl?: Array<number | null>;
wind_speed_10m?: Array<number | null>;
wind_direction_10m?: Array<number | null>;
wind_speed_180m?: Array<number | null>;
wind_direction_180m?: Array<number | null>;
precipitation_probability?: Array<number | null>;
cloud_cover?: Array<number | null>;
radiation?: Array<number | null>;
cape?: Array<number | null>;
convective_inhibition?: Array<number | null>;
lifted_index?: Array<number | null>;
boundary_layer_height?: Array<number | null>;
}
export interface WeatherGovPeriod {
name?: string;
start_time?: string;
end_time?: string;
short_forecast?: string | null;
detailed_forecast?: string | null;
temperature?: number | null;
temperature_unit?: string | null;
}
export interface SourceForecasts {
weather_gov?: {
forecast_periods?: WeatherGovPeriod[];
};
open_meteo_multi_model?: {
source?: string | null;
provider?: string | null;
dates?: string[];
model_metadata?: Record<
string,
{
label?: string | null;
provider?: string | null;
model?: string | null;
tier?: string | null;
resolution_km?: number | null;
horizon?: string | null;
open_meteo_model?: string | null;
}
>;
model_keys?: Record<string, string>;
attribution?: string | null;
};
}
export interface DailyModelForecast {
models?: Record<string, number | null>;
deb?: {
prediction?: number | null;
};
probabilities?: ProbabilityBucket[];
probabilities_all?: ProbabilityBucket[];
}
export interface MarketToken {
outcome?: string | null;
token_id?: string | null;
implied_probability?: number | null;
buy_price?: number | null;
sell_price?: number | null;
midpoint?: number | null;
last_trade_price?: number | null;
quote_source?: string | null;
quote_age_ms?: number | null;
}
export interface MarketPrimary {
id?: string | null;
question?: string | null;
slug?: string | null;
market_url?: string | null;
condition_id?: string | null;
end_date?: string | null;
active?: boolean;
closed?: boolean;
liquidity?: number | null;
volume?: number | null;
}
export interface MarketTopBucket {
label?: string | null;
value?: number | null;
temp?: number | null;
lower?: number | null;
upper?: number | null;
unit?: string | null;
probability?: number | null;
market_price?: number | null;
yes_buy?: number | null;
yes_sell?: number | null;
no_buy?: number | null;
no_sell?: number | null;
yes_token_id?: string | null;
no_token_id?: string | null;
quote_source?: string | null;
quote_age_ms?: number | null;
slug?: string | null;
question?: string | null;
is_primary?: boolean;
}
export interface MarketPriceSide {
side?: "yes" | "no" | string | null;
model_probability?: number | null;
ask?: number | null;
bid?: number | null;
edge?: number | null;
edge_percent?: number | null;
kelly_fraction?: number | null;
quarter_kelly?: number | null;
}
export interface MarketPriceAnalysis {
available?: boolean;
source?: string | null;
model_probability?: number | null;
yes?: MarketPriceSide | null;
no?: MarketPriceSide | null;
best_side?: "yes" | "no" | string | null;
lock?: {
available?: boolean;
ask_sum?: number | null;
edge?: number | null;
} | null;
sell_side?: {
bid_sum?: number | null;
edge?: number | null;
} | null;
}
export interface MarketScan {
available?: boolean;
reason?: string | null;
primary_market?: MarketPrimary | null;
market_url?: string | null;
primary_market_url?: string | null;
selected_date?: string | null;
selected_condition_id?: string | null;
selected_slug?: string | null;
temperature_bucket?: ProbabilityBucket | null;
model_probability?: number | null;
market_price?: number | null;
midpoint?: number | null;
spread?: number | null;
edge_percent?: number | null;
signal_label?: string | null;
confidence?: string | null;
probability_engine?: string | null;
probability_calibration_mode?: string | null;
yes_token?: MarketToken | null;
no_token?: MarketToken | null;
yes_buy?: number | null;
yes_sell?: number | null;
yes_midpoint?: number | null;
yes_spread?: number | null;
no_buy?: number | null;
no_sell?: number | null;
no_midpoint?: number | null;
no_spread?: number | null;
last_trade_price?: number | null;
liquidity?: number | null;
volume?: number | null;
quote_source?: string | null;
quote_age_ms?: number | null;
price_analysis?: MarketPriceAnalysis | null;
sparkline?: number[];
top_buckets?: MarketTopBucket[] | null;
all_buckets?: MarketTopBucket[] | null;
recent_trades?: unknown[];
scan_scope?: "lite" | "full" | string | null;
websocket?: Record<string, unknown>;
}
export interface IntradayMeteorologySignal {
label?: string | null;
label_en?: string | null;
direction?: "support" | "suppress" | "neutral" | string | null;
strength?: "weak" | "medium" | "strong" | string | null;
summary?: string | null;
summary_en?: string | null;
}
export interface IntradayMeteorology {
headline?: string | null;
headline_en?: string | null;
confidence?: "low" | "medium" | "high" | string | null;
base_case_bucket?: string | null;
upside_bucket?: string | null;
downside_bucket?: string | null;
next_observation_time?: string | null;
peak_window?: string | null;
invalidation_rules?: string[] | null;
invalidation_rules_en?: string[] | null;
confirmation_rules?: string[] | null;
confirmation_rules_en?: string[] | null;
signal_contributions?: IntradayMeteorologySignal[] | null;
}
export interface AiAnalysisStructured {
summary?: string | null;
text?: string | null;
message?: string | null;
highlights?: string[];
points?: string[];
}
export interface CityDetail {
name: string;
display_name: string;
detail_depth?: "panel" | "market" | "nearby" | "full";
lat: number;
lon: number;
utc_offset_seconds?: number;
temp_symbol: string;
local_time: string;
local_date: string;
risk: DashboardRisk;
current: CurrentConditions;
settlement_station?: {
provider_code?: string | null;
settlement_source?: string | null;
settlement_station_code?: string | null;
settlement_station_label?: string | null;
airport_code?: string | null;
airport_name?: string | null;
is_airport_anchor?: boolean;
is_official_station_anchor?: boolean;
};
airport_current?: AirportCurrentConditions;
airport_primary?: AirportCurrentConditions;
airport_primary_today_obs?: Array<{
time?: string;
temp?: number | null;
}>;
mgm?: MgmData;
mgm_nearby?: NearbyStation[];
official_nearby?: NearbyStation[];
nearby_source?: string;
official_network_source?: string;
official_network_status?: {
provider_code?: string | null;
provider_label?: string | null;
available?: boolean;
mode?: string | null;
row_count?: number | null;
};
network_lead_signal?: {
available?: boolean;
delta?: number | null;
leader_station_code?: string | null;
leader_station_label?: string | null;
leader_temp?: number | null;
leader_obs_time?: string | null;
leader_obs_time_label?: string | null;
leader_sync_status?: string | null;
leader_time_delta_vs_anchor_minutes?: number | null;
};
network_spread_signal?: {
available?: boolean;
spread?: number | null;
hottest_station_code?: string | null;
coolest_station_code?: string | null;
};
center_station_candidate?: NearbyStation | null;
airport_vs_network_delta?: number | null;
forecast?: ForecastData;
multi_model?: Record<string, number | null>;
deb?: DebForecast;
deviation_monitor?: DeviationMonitor;
probabilities?: {
mu?: number | null;
distribution?: ProbabilityBucket[];
distribution_all?: ProbabilityBucket[];
engine?: string | null;
calibration_mode?: string | null;
calibration_version?: string | null;
raw_mu?: number | null;
raw_sigma?: number | null;
calibrated_mu?: number | null;
calibrated_sigma?: number | null;
shadow_distribution?: ProbabilityBucket[];
shadow_distribution_all?: ProbabilityBucket[];
};
hourly?: {
times?: string[];
temps?: Array<number | null>;
};
hourly_next_48h?: HourlySeries;
metar_recent_obs?: Array<{
time?: string;
temp?: number | null;
}>;
metar_today_obs?: Array<{
time?: string;
temp?: number | null;
}>;
metar_status?: {
available_for_today?: boolean;
stale_for_today?: boolean;
last_observation_time?: string | null;
last_observation_local_date?: string | null;
current_local_date?: string | null;
last_temp?: number | null;
};
settlement_today_obs?: Array<{
time?: string;
temp?: number | null;
}>;
trend?: TrendInfo;
peak?: PeakInfo;
dynamic_commentary?: {
summary?: string | null;
notes?: string[] | null;
headline_zh?: string | null;
headline_en?: string | null;
bullets_zh?: string[] | null;
bullets_en?: string[] | null;
source?: string | null;
};
taf?: {
source?: string | null;
icao?: string | null;
issue_time?: string | null;
valid_time_from?: string | null;
valid_time_to?: string | null;
raw_taf?: string | null;
signal?: {
available?: boolean;
source?: string | null;
peak_window?: string | null;
segments?: Array<{
type?: string | null;
start_local?: string | null;
end_local?: string | null;
tokens?: string[] | null;
}> | null;
markers?: Array<{
label_time?: string | null;
marker_type?: string | null;
start_local?: string | null;
end_local?: string | null;
suppression_level?: string | null;
summary_zh?: string | null;
summary_en?: string | null;
}> | null;
low_ceiling_ft?: number | null;
ceiling_cover?: string | null;
wind_regimes?: string[] | null;
wind_shift?: boolean | null;
suppression_level?: string | null;
disruption_level?: string | null;
summary_zh?: string | null;
summary_en?: string | null;
};
};
vertical_profile_signal?: {
source?: string | null;
window_start?: string | null;
window_end?: string | null;
cape_max?: number | null;
cin_min?: number | null;
lifted_index_min?: number | null;
boundary_layer_height_max?: number | null;
shear_10m_180m_max?: number | null;
suppression_risk?: string | null;
trigger_risk?: string | null;
mixing_strength?: string | null;
shear_risk?: string | null;
heating_setup?: string | null;
heating_score?: number | null;
summary_zh?: string | null;
summary_en?: string | null;
};
ai_analysis?: string | AiAnalysisStructured | null;
updated_at?: string;
multi_model_daily?: Record<string, DailyModelForecast>;
source_forecasts?: SourceForecasts;
market_scan?: MarketScan;
intraday_meteorology?: IntradayMeteorology;
}
export interface HistoryPoint {
date: string;
actual: number | null;
deb: number | null;
mu?: number | null;
mgm?: number | null;
forecasts?: Record<string, number | null>;
model_reference?: {
available?: boolean;
truth_layer?: string | null;
reference_layer?: string | null;
deb?: {
value?: number | null;
error?: number | null;
};
models?: Array<{
model?: string | null;
value?: number | null;
error?: number | null;
participates_in_deb?: boolean;
}>;
model_count?: number | null;
};
settlement_source?: string | null;
settlement_station_code?: string | null;
settlement_station_label?: string | null;
truth_version?: string | null;
updated_by?: string | null;
truth_updated_at?: number | null;
actual_peak_time?: string | null;
deb_at_peak_minus_12h?: number | null;
deb_at_peak_minus_12h_time?: string | null;
deb_at_peak_minus_12h_error?: number | null;
}
export interface HistoryPayloadMeta {
mode: "preview" | "full";
hasMore: boolean;
fullCount: number;
previewCount: number;
settlementSource?: string | null;
settlementSourceLabel?: string | null;
}
export interface HistoryPayload {
history: HistoryPoint[];
has_more?: boolean;
full_count?: number;
preview_count?: number;
mode?: "preview" | "full";
settlement_source?: string | null;
settlement_source_label?: string | null;
}
export interface LoadingState {
cities: boolean;
cityDetail: boolean;
refresh: boolean;
history: boolean;
marketScan?: boolean;
futureDeep?: boolean;
historyRecords?: boolean;
}
export interface HistoryState {
isOpen: boolean;
loading: boolean;
recordsLoading: boolean;
error: string | null;
dataByCity: Record<string, HistoryPoint[]>;
metaByCity: Record<string, HistoryPayloadMeta>;
}
export interface ProAccessState {
loading: boolean;
authenticated: boolean;
userId: string | null;
subscriptionActive: boolean;
subscriptionPlanCode: string | null;
subscriptionExpiresAt: string | null;
subscriptionTotalExpiresAt: string | null;
subscriptionQueuedDays: number;
points: number;
error: string | null;
}
export type ForecastModalMode = "today" | "future";
export interface DashboardState {
cities: CityListItem[];
cityDetailsByName: Record<string, CityDetail>;
citySummariesByName: Record<string, CitySummary>;
selectedCity: string | null;
isPanelOpen: boolean;
selectedForecastDate: string | null;
forecastModalMode: ForecastModalMode | null;
loadingState: LoadingState;
historyState: HistoryState;
proAccess: ProAccessState;
}