defmodule Microwaveprop.Repo.Migrations.CreateHrrrFetchTasks do use Ecto.Migration # Hand-off queue between the Elixir enrichment enqueuer and the Rust # hrrr-point-worker (Phase 3 Stream C). One row per valid_time with a # JSONB array of {lat, lon} points the workers needs to extract from # that hour's HRRR cycle. Rust claims by SKIP LOCKED, fetches the # GRIB2 once, extracts every point in the batch, bulk-upserts to # hrrr_profiles, and marks the row done. def change do create table(:hrrr_fetch_tasks, primary_key: false) do add :id, :binary_id, primary_key: true add :valid_time, :utc_datetime, null: false # [{"lat": f, "lon": f}, …] — additional points for the same # valid_time get merged via jsonb array-union UPSERT so a # backfill tick doesn't schedule a new row per contact. add :points, :map, null: false, default: fragment("'[]'::jsonb") add :status, :string, null: false, default: "queued" add :attempt, :integer, null: false, default: 0 add :claimed_at, :utc_datetime_usec add :completed_at, :utc_datetime_usec add :error, :text timestamps(type: :utc_datetime) end # One task per valid_time. Merges all points for the hour into a # single fetch so a full backfill scan costs one GRIB2 download # per hour, not one per contact. create unique_index(:hrrr_fetch_tasks, [:valid_time]) # Hot-path claim query scans the queued subset. create index(:hrrr_fetch_tasks, [:status], where: "status = 'queued'", name: :hrrr_fetch_tasks_queued_idx ) # Prune index for retention. create index(:hrrr_fetch_tasks, [:completed_at]) end end