prop/priv/repo/migrations/20260429220736_add_source_to_grid_tasks.exs
Graham McIntire 020f05f8eb
feat(hrdps): grid_tasks source column, Canadian mask, HrdpsGridWorker
Stage 3 (Elixir foundation) of the HRDPS plan. Lands the scaffolding
that lets the Rust prop-grid-rs HRDPS branch be wired up cleanly when
it ships, without further DB or Elixir-side changes.

What ships:

- `grid_tasks.source` column (default 'hrrr', backfill is a no-op).
  Replaces the (run_time, forecast_hour, kind) unique index with a
  4-column key (..., source) so HRRR and HRDPS analysis/forecast rows
  for the same cycle coexist.
- `Grid.hrdps_only_points/0` — Canadian cells inside HRDPS bbox
  (49-60°N, -141 to -52°W) but outside HRRR's CONUS bbox. Disjoint
  from `conus_points/0` by construction so the two grids never
  double-write the same (lat, lon).
- `Grid.point_source/1` — `:hrrr | :hrdps | :neither` classification
  for a (lat, lon) pair. Routes per-QSO enrichment to the right NWP
  source.
- `GridTaskEnqueuer.seed_with_analysis/2` and `seed/2` accept a
  `:source` option; defaults to "hrrr" so existing callers are
  unchanged.
- `HrdpsGridWorker` cycle seeder mirroring PropagationGridWorker's
  shape but for HRDPS's 4×/day cadence. `:hrdps` queue added to base
  Oban config.

What's deferred:

- The Rust `prop-grid-rs` worker doesn't yet branch on
  `task.source`. Until that ships, `HrdpsGridWorker` stays out of
  runtime.exs cron — it would just produce rows that the Rust worker
  mishandles as HRRR. Module doc explicitly notes the dormant state.
- Map overlay extension and FreshnessMonitor HRDPS staleness deferred
  to follow-up sessions once real data flows.

Activation path documented in the updated plan file.

Coverage cap recorded as Stage 8 decision: 60°N for v1 (SRTM stops
there). Arctic CDEM deferred to a follow-up plan.
2026-04-29 17:13:00 -05:00

22 lines
973 B
Elixir

defmodule Microwaveprop.Repo.Migrations.AddSourceToGridTasks do
use Ecto.Migration
# `source` splits grid_tasks between HRRR-derived (CONUS) and HRDPS-
# derived (Canada) work. Rust workers branch on this column to pick the
# right URL pattern + decoder. Default 'hrrr' so existing rows keep
# their meaning; HRDPS rows arrive only once HrdpsGridWorker is added
# to the cron (deferred until the Rust HRDPS branch ships).
def change do
alter table(:grid_tasks) do
add :source, :string, null: false, default: "hrrr"
end
# Replace (run_time, forecast_hour, kind) uniqueness with a 4-column
# key so HRRR and HRDPS analysis/forecast rows for the same cycle can
# coexist. The index also speeds up `claim_next` filters.
drop_if_exists unique_index(:grid_tasks, [:run_time, :forecast_hour, :kind])
create unique_index(:grid_tasks, [:run_time, :forecast_hour, :kind, :source])
create index(:grid_tasks, [:source])
end
end