Files
weatherapi/docs/integrations/weatherfeeder-postgres.md

6.8 KiB

Weatherfeeder Postgres Contract

weatherapi reads weather data from Postgres tables owned and populated by weatherfeeder. This document describes only the storage contract consumed by weatherapi; it is not a full weatherfeeder schema reference.

Version

go.mod depends on:

  • gitea.maximumdirect.net/ejr/weatherfeeder v0.11.0

The repository code also depends on weatherfeeder canonical model types. Table compatibility must match the SQL in internal/adapters/outbound/postgres.

Boundary

weatherapi is read-only:

  • it does not create tables;
  • it does not migrate tables;
  • it does not ingest provider data;
  • it does not write weatherfeeder events.

Weatherfeeder owns provider polling, normalization, table shape, and writes. Postgres owns persistence, backup, restore, and availability.

Table Families Read

Resource Tables read
Latest observation observations, observation_present_weather
Current conditions observations
Active alerts alert_runs, alerts, alert_references
Hourly forecast forecasts, forecast_periods
Narrative forecast forecasts, forecast_periods
Forecast discussion forecast_discussions, forecast_discussion_key_messages
Weather story run weather_story_runs, weather_stories
Latest weather story weather_stories
Convective outlook run outlook_runs, outlooks

Latest Row Selection

Latest parent resources use these ordering rules:

  • observations: observed_at DESC, event_emitted_at DESC;
  • alert runs: as_of DESC, event_emitted_at DESC;
  • hourly forecasts: product = 'hourly', then issued_at DESC, event_emitted_at DESC;
  • narrative forecasts: product = 'narrative', then issued_at DESC, event_emitted_at DESC;
  • forecast discussions: issued_at DESC, event_emitted_at DESC;
  • weather story runs: as_of DESC, event_emitted_at DESC;
  • latest individual weather story: updated_at DESC, as_of DESC, story_order ASC, story_index ASC.
  • convective outlook runs: as_of DESC, event_emitted_at DESC.

Current conditions aggregate observations rows where observed_at is inside the application-provided observation window.

Child Ordering

Child rows are loaded separately and attached in stored order:

  • observation present weather: weather_index ASC;
  • alerts: alert_index ASC;
  • alert references: alert_index ASC, reference_index ASC;
  • forecast periods: period_index ASC;
  • forecast discussion key messages: message_index ASC;
  • weather stories for a run: story_index ASC;
  • outlooks for a run: outlook_index ASC.

Columns Read

The repository reads only these columns.

observations

event_id, station_id, station_name, observed_at, condition_code, is_day, text_description, temperature_c, dewpoint_c, wind_direction_degrees, wind_speed_kmh, wind_gust_kmh, barometric_pressure_pa, visibility_meters, relative_humidity_percent, apparent_temperature_c, and event_emitted_at.

Current conditions additionally aggregate recent observations values for temperature, apparent temperature, dewpoint, humidity, wind speed, wind direction, condition code, and latest is_day.

observation_present_weather

weather_index, raw_text, and event_id.

raw_text is decoded as JSON when present. Empty or null raw text maps to an empty present-weather value; invalid JSON is returned as a repository error.

alert_runs

event_id, location_id, location_name, as_of, latitude, longitude, and event_emitted_at.

alerts

alert_index, alert_id, event, headline, severity, urgency, certainty, status, message_type, category, response, description, instruction, sent, effective, onset, expires, area_description, sender_name, and run_event_id.

alert_references

alert_index, reference_index, id, identifier, sender, sent, and run_event_id.

forecasts

event_id, location_id, location_name, issued_at, updated_at, product, latitude, longitude, elevation_meters, and event_emitted_at.

Only product = 'hourly' and product = 'narrative' are read by implemented routes.

forecast_periods

period_index, start_time, end_time, name, is_day, condition_code, text_description, temperature_c, temperature_c_min, temperature_c_max, dewpoint_c, relative_humidity_percent, wind_direction_degrees, wind_speed_kmh, wind_gust_kmh, barometric_pressure_pa, visibility_meters, apparent_temperature_c, cloud_cover_percent, probability_of_precipitation_percent, precipitation_amount_mm, snowfall_depth_mm, uv_index, and run_event_id.

forecast_discussions

event_id, office_id, office_name, issued_at, updated_at, product, short_term_qualifier, short_term_issued_at, short_term_text, long_term_qualifier, long_term_issued_at, long_term_text, and event_emitted_at.

forecast_discussion_key_messages

message_index, message_text, and run_event_id.

weather_story_runs

event_id, office_id, as_of, and event_emitted_at.

weather_stories

story_index, office_id, start_time, end_time, updated_at, title, description, alt_text, priority, story_order, download_url, run_event_id, and as_of.

outlook_runs

event_id, location_id, location_name, latitude, longitude, as_of, issued_at, and event_emitted_at.

outlooks

outlook_index, outlook_id, provider, product, day, outlook_type, label, label_text, severity_rank, valid_from, valid_to, issued_at, expires_at, forecaster, source_url, image_url, contains_location, geometry_json, and run_event_id.

geometry_json is copied into response GeoJSON without parsing or reserializing. It must contain valid JSON.

Nullability and Time Assumptions

The repository scans nullable columns with sql.Null* types and maps them to nil pointers or omitted zero values depending on the canonical model field.

Timestamps returned by the repository are normalized to UTC. Presentation timezone conversion happens later in HTTP presenters.

Missing latest parent rows return nil, nil from repository methods. HTTP rendering exposes this as a successful response with data: null.

Compatibility Checklist

Before changing weatherfeeder storage or upgrading the weatherfeeder module:

  • compare table names and columns with internal/adapters/outbound/postgres;
  • preserve latest-row ordering columns used by weatherapi;
  • preserve child index columns used for ordering;
  • preserve nullable behavior expected by row mappers;
  • run go test ./internal/adapters/outbound/postgres and affected HTTP tests.