// FILE: internal/model/alert.go package model import "time" // WeatherAlertRun is a snapshot of *active* alerts for a location as-of a point in time. // // This mirrors WeatherForecastRun's "one issued snapshot -> many contained items" shape: // // - A single run may contain zero, one, or many alerts. // - Runs are intended to be immutable snapshots (“provider asserted X at AsOf”). // // Normalizers should prefer to set AsOf from a provider-supplied “updated/generated” timestamp. // If unavailable, AsOf may be set to the poll/emit time as a fallback. type WeatherAlertRun struct { // Optional location metadata (provider-dependent). LocationID string `json:"locationId,omitempty"` LocationName string `json:"locationName,omitempty"` // AsOf is when the provider asserted this alert snapshot is current (required). AsOf time.Time `json:"asOf"` // Optional spatial context. Latitude *float64 `json:"latitude,omitempty"` Longitude *float64 `json:"longitude,omitempty"` // Active alerts contained in this snapshot (order is provider-dependent). Alerts []WeatherAlert `json:"alerts"` } // WeatherAlert is the canonical representation of a single alert. // // This is intentionally a “useful subset” of rich provider payloads. // Normalizers may populate ProviderExtras for structured provider-specific fields // that don’t cleanly fit the canonical shape. type WeatherAlert struct { // Provider-stable identifier (often a URL/URI). ID string `json:"id"` // Classification / headline fields. Event string `json:"event,omitempty"` Headline string `json:"headline,omitempty"` Severity string `json:"severity,omitempty"` // e.g. Extreme/Severe/Moderate/Minor/Unknown Urgency string `json:"urgency,omitempty"` // e.g. Immediate/Expected/Future/Past/Unknown Certainty string `json:"certainty,omitempty"` // e.g. Observed/Likely/Possible/Unlikely/Unknown Status string `json:"status,omitempty"` // e.g. Actual/Exercise/Test/System/Unknown MessageType string `json:"messageType,omitempty"` // e.g. Alert/Update/Cancel Category string `json:"category,omitempty"` // e.g. Met/Geo/Safety/Rescue/Fire/Health/Env/Transport/Infra/CBRNE/Other Response string `json:"response,omitempty"` // e.g. Shelter/Evacuate/Prepare/Execute/Avoid/Monitor/Assess/AllClear/None // Narrative. Description string `json:"description,omitempty"` Instruction string `json:"instruction,omitempty"` // Timing (all optional; provider-dependent). Sent *time.Time `json:"sent,omitempty"` Effective *time.Time `json:"effective,omitempty"` Onset *time.Time `json:"onset,omitempty"` Expires *time.Time `json:"expires,omitempty"` // Scope / affected area. AreaDescription string `json:"areaDescription,omitempty"` // often a provider string // Provenance. SenderName string `json:"senderName,omitempty"` References []AlertReference `json:"references,omitempty"` } // AlertReference is a reference to a related alert (updates, replacements, etc.). type AlertReference struct { ID string `json:"id,omitempty"` // provider reference ID/URI Identifier string `json:"identifier,omitempty"` // provider identifier string, if distinct Sender string `json:"sender,omitempty"` Sent *time.Time `json:"sent,omitempty"` }