defmodule Polymarket.Schemas.MarketByToken do @moduledoc """ The parent market for a given token ID, as returned by the CLOB API `GET /markets-by-token/:token_id`. Resolves a token ID to its market's `condition_id` and both the primary (Yes) and secondary (No) token IDs. The CLOB API already delivers `snake_case` keys, so `from_attrs/1` normalisation is a no-op here but kept for consistency with the other schemas. """ use TypedEctoSchema alias Polymarket.JsonUtil alias Polymarket.Schemas.Coerce @primary_key false @derive Jason.Encoder typed_embedded_schema do field(:condition_id, :string) field(:primary_token_id, :string) field(:secondary_token_id, :string) end @required [:condition_id, :primary_token_id, :secondary_token_id] @doc """ Builds a `MarketByToken` from the raw (JSON-decoded) CLOB attributes. Keys may be in `camelCase` (atom or string); they are normalised to the `snake_case` fields. Returns `{:error, {:missing_fields, fields}}` when a required field is absent. """ @spec from_attrs(map()) :: {:ok, t()} | {:error, {:missing_fields, [atom()]}} def from_attrs(attrs) do attrs = JsonUtil.snake_case_keys(attrs) %__MODULE__{ condition_id: attrs["condition_id"], primary_token_id: attrs["primary_token_id"], secondary_token_id: attrs["secondary_token_id"] } |> Coerce.require_fields(@required) end end