defmodule Microwaveprop.Weather.Era5CdsJob do @moduledoc """ Tracks an in-flight ERA5 CDS request submitted by `Era5SubmitWorker` and awaiting download+decode by `Era5PollWorker`. Persisting the CDS job IDs decouples the Oban worker lifecycle from the 30+ minute CDS queue time, so a pod restart resumes polling instead of re-submitting. """ use Ecto.Schema import Ecto.Changeset @primary_key {:id, :binary_id, autogenerate: true} @foreign_key_type :binary_id schema "era5_cds_jobs" do field :year, :integer field :month, :integer field :tile_lat, :integer field :tile_lon, :integer field :single_job_id, :string field :pressure_job_id, :string field :submitted_at, :utc_datetime field :last_polled_at, :utc_datetime field :poll_count, :integer, default: 0 timestamps(type: :utc_datetime) end @type t :: %__MODULE__{} @required_fields ~w(year month tile_lat tile_lon single_job_id pressure_job_id submitted_at)a @optional_fields ~w(last_polled_at poll_count)a @spec changeset(t() | Ecto.Changeset.t(), map()) :: Ecto.Changeset.t() def changeset(job, attrs) do job |> cast(attrs, @required_fields ++ @optional_fields) |> validate_required(@required_fields) |> unique_constraint([:year, :month, :tile_lat, :tile_lon], name: :era5_cds_jobs_year_month_tile_lat_tile_lon_index, error_key: :tile_month ) end end