AshDyan.Request (AshDyan v0.1.0)

Copy Markdown View Source

The runtime request spec for a dynamic analysis.

A caller sends a map (or a t/0 struct) describing what chart data they want. normalize/1 fills in defaults and validate/1 checks it against the resource's dyan DSL whitelist.

Shape

%{
  domain: MyApp.Shop,
  resource: MyApp.Order,
  type: :time_bucket,          # :frequency | :aggregate | :time_bucket | :percentile | :histogram
  column: :total_amount,
  function: :sum,               # required for :aggregate
  bucket: :day,                 # required for :time_bucket
  time_field: :inserted_at,
  group_by: [:status],          # optional, checked against max_group_by
  percentiles: [50, 90],        # required for :percentile
  bins: 10,                     # optional for :histogram (default 10)
  bin_width: nil,               # optional for :histogram (auto-computed if nil)
  filters: %{status: "paid", region: ["EU", "US"]},
  limit: 200
}

Summary

Functions

Normalize a request map into a t/0 struct with defaults applied.

Validate a normalized request against the resource's dyan DSL whitelist.

Types

analysis_type()

@type analysis_type() ::
  :frequency | :aggregate | :time_bucket | :percentile | :histogram

t()

@type t() :: %AshDyan.Request{
  bin_width: number() | nil,
  bins: pos_integer() | nil,
  bucket: AshDyan.time_bucket() | nil,
  column: atom() | nil,
  domain: module() | nil,
  filters: map(),
  function: AshDyan.aggregate_function() | nil,
  group_by: [atom()],
  limit: pos_integer() | nil,
  percentiles: [pos_integer()],
  resource: module(),
  time_field: atom() | nil,
  type: analysis_type()
}

Functions

normalize(request)

@spec normalize(map() | t()) :: {:ok, t()} | {:error, term()}

Normalize a request map into a t/0 struct with defaults applied.

validate(request)

@spec validate(t()) :: :ok | {:error, AshDyan.Error.t()}

Validate a normalized request against the resource's dyan DSL whitelist.

Returns :ok or {:error, %AshDyan.Error{}} naming the offending field.

Error reasons

The reason field of the returned AshDyan.Error is one of:

  • :not_a_resource / :not_analyzable — the :resource is invalid or has no dyan configuration.
  • :unknown_type:type is not one of the capabilities.
  • :not_analyzable:column/time_field is not whitelisted for the type.
  • :not_allowed:function/:bucket/:percentiles is not in the whitelist for that field, or :filters references a non-allowed field.
  • :too_many:group_by exceeds max_group_by.
  • :too_large:limit exceeds max_limit.
  • :bad_bins:bins/:bin_width is of the wrong type or non-positive.
  • :unknown_attribute:group_by references a non-existent attribute.
  • :bad_type:filters/limit is of the wrong type.