Selecto.Config.OverlayDSL (Selecto v0.4.6)

Copy Markdown

A DSL (Domain-Specific Language) for defining overlay configurations.

This module provides a clean, declarative syntax for customizing Selecto domains through overlay files. Instead of manually constructing maps, you can use macros like defcolumn, deffilter, deffunction, defdetail_action, defcte, defvalues, defsubquery, defjoin, defschema, defschema_assoc, defsource_assoc, defsource_relationship, defchoice_source, defwrite_operation, defwrite_field, defwrite_relationship, defwrite_transition, defwrite_validation, defwrite_constraint, defwrite_tenant_scope, defwrite_hook, defaction, and defcapability along with module attributes.

Usage

defmodule MyApp.SelectoDomains.Overlays.ProductDomainOverlay do
  use Selecto.Config.OverlayDSL,
    # Selecto.Extensions.PostGIS is provided by the :selecto_postgis package
    extensions: [Selecto.Extensions.PostGIS]

  # Module attributes for common configurations
  @redactions [:internal_notes, :cost_price]

  # Column customizations
  defcolumn :price do
    label "Product Price"
    format :currency
    aggregate_functions [:sum, :avg, :min, :max]
  end

  defcolumn :description do
    label "Product Description"
    max_length 100
  end

  # Custom filters
  deffilter "price_range" do
    name "Price Range"
    type :string
    description "Filter products by price range (e.g., '10-100')"
  end

  deffilter "in_stock" do
    name "In Stock"
    type :boolean
    description "Show only items currently in stock"
  end

  # Named query members
  defcte :active_products do
    query &__MODULE__.active_products_cte/1
    columns ["id", "name"]
    join [owner_key: :id, related_key: :id, fields: :infer]
  end

  defvalues :status_lookup do
    rows [["active", "Active"], ["archived", "Archived"]]
    columns ["status", "label"]
    as "status_lookup"
    join [owner_key: :status, related_key: :status]
  end

  defsubquery :high_value_orders do
    query &__MODULE__.high_value_orders_subquery/1
    type :inner
    on [%{left: "id", right: "customer_id"}]
  end
end

Available Directives

Module Attributes

  • @redactions - List of field atoms to redact from queries

JSONB Schema (with defjsonb_schema)

Define structured schemas for JSONB columns to enable typed access, filtering, and display:

defjsonb_schema :attributes do
  field :color, :string, label: "Color"
  field :weight, :decimal, label: "Weight (kg)", precision: 2
  field :organic, :boolean, label: "Organic"
  field :certifications, {:array, :string}, label: "Certifications"
  field :dimensions, :object do
    field :width, :decimal, label: "Width"
    field :height, :decimal, label: "Height"
  end
end

Supported types: :string, :integer, :decimal, :boolean, :date, :datetime, {:array, type}, :object (with nested fields)

Column Directives (within defcolumn)

Filter Directives (within deffilter)

  • name/1 - Human-readable filter name
  • type/1 - Filter type (:string, :integer, :boolean, :date, etc.)
  • description/1 - Help text for the filter
  • required/1 - Whether filter is required (boolean)
  • default/1 - Default value for the filter
  • options/1 - List of valid options for select-type filters

Detail Action Macros

  • defdetail_action id do ... end - Define a detail-row action under detail_actions
  • defpopup id do ... end - Define a modal detail-row action under detail_actions

Query Member Macros

  • defcte id do ... end - Define a named CTE preset under query_members.ctes
  • defvalues id do ... end - Define a named VALUES preset under query_members.values
  • defsubquery id do ... end - Define a named subquery-join preset under query_members.subqueries
  • deflateral id do ... end - Define a named LATERAL preset under query_members.laterals
  • defunnest id do ... end - Define a named UNNEST preset under query_members.unnests

Function Macros

  • deffunction id do ... end - Define a named UDF spec under functions

Domain Registry Macros

  • defjoin id, config - Define a top-level join entry under joins
  • defschema id, config - Define a top-level schema entry under schemas
  • defschema_assoc schema_id, assoc_id, config - Define a schema associations entry
  • defsource_assoc id, config - Define a root source.associations entry
  • defsource_relationship id, config - Define a top-level source_relationships entry
  • defchoice_source id, config - Define a top-level choice_sources entry
  • defwrite_operation id, config_or_block - Define writes.operations[id]
  • defwrite_field id, config_or_block - Define writes.fields[id]
  • defwrite_relationship id, config_or_block - Define writes.relationships[id]
  • defwrite_transition field, graph - Define writes.transitions[field]
  • defwrite_validation rule - Append a writes.validations rule
  • defwrite_constraint rule - Append a writes.constraints rule
  • defwrite_tenant_scope config_or_block - Define writes.scope.tenant
  • defwrite_hook id, refs - Define writes.hooks[id]
  • defaction id, config_or_block - Define a top-level domain action
  • defcapability id, config_or_block - Define a top-level capability

Query Member Directives

Examples

Basic Column Customization

defcolumn :price do
  label "Product Price"
  format :currency
  precision 2
  aggregate_functions [:sum, :avg]
end

Complex Filter

deffilter "status" do
  name "Order Status"
  type :string
  description "Filter by order status"
  options ["pending", "shipped", "delivered", "cancelled"]
  default "pending"
end

Using Redactions

@redactions [:password, :secret_key, :internal_notes]

Computed Properties

defcolumn :total_value do
  label "Total Value"
  format :currency
  aggregate_functions [:sum]
  computed true
end

Summary

Functions

Sets an action reference for a capability.

Sets the allowed aggregate functions for a column.

Sets the allowed call sites for a UDF registration.

Sets allowed write operations for a relationship.

Adds an argument definition to a UDF registration.

Sets the UNNEST array field/expression for named UNNEST members.

Sets the SQL alias/table name for named VALUES members.

Sets recursive CTE base query function.

Sets whether a write operation is bulk-capable.

Sets the capability required by a query-facing overlay entry.

Sets relationship cardinality.

Sets cascade delete behavior for a write relationship.

Sets cascade update behavior for a write relationship.

Binds a field to a declared choice source.

Sets declared columns for CTE/VALUES query members.

Marks a column as computed (not from database).

Sets write operation conflict targets.

Alias for rows/1 in named VALUES members.

Defines a domain action under the top-level actions registry.

Sets the default value for the filter.

Sets a default provider for a write field.

Defines a capability under the top-level capabilities registry.

Defines a choice source under the top-level choice_sources registry.

Defines a column customization.

Defines a named CTE preset for Selecto.with_cte/2.

Defines a detail-row action.

Defines a custom filter.

Defines a named UDF specification.

Defines a join configuration under the top-level joins registry.

Defines a JSONB schema for a JSONB column, enabling typed field access, filtering, and display of structured JSON data.

Defines a named LATERAL preset for Selecto.with_lateral/2.

Defines a modal detail-row action.

Defines a schema configuration under the top-level schemas registry.

Defines an association under a schema entry in schemas.

Defines a root source association under source.associations.

Defines a source relationship under the top-level source_relationships registry.

Defines a named subquery preset for Selecto.with_subquery/2.

Defines a named UNNEST preset for Selecto.with_unnest/2.

Defines a named VALUES preset for Selecto.with_values/2.

Appends a write constraint rule under writes.constraints.

Defines a write field under writes.fields.

Defines declared host-runtime hook references under writes.hooks.

Defines a write operation under writes.operations.

Defines a write relationship under writes.relationships.

Defines canonical tenant scope metadata under writes.scope.tenant.

Defines a transition graph under writes.transitions.

Appends a write validation rule under writes.validations.

Sets CTE dependency names.

Sets the filter description/help text.

Sets whether a write operation, field, or relationship is enabled.

Sets execution metadata for a domain action.

Defines a field within a JSONB schema.

Sets whether the column is filterable.

Sets write operations that forbid the field.

Sets the foreign key for a write relationship.

Sets the display format for a column.

Marks a write field immutable.

Sets whether a write field is insertable.

Sets join options for query member auto-join behavior.

Sets explicit join id for named subquery members.

Sets the join type for named LATERAL members.

Sets named subquery kind (:join currently supported).

Sets the human-readable label for a column or filter.

Alias for source/1 in named LATERAL members.

Sets maximum item count for a write relationship.

Sets the maximum display length for string columns.

Sets minimum item count for a write relationship.

Sets the human-readable name for a filter.

Sets ON conditions for named subquery members.

Sets operations for a capability.

Sets the valid options for a select-type filter.

Sets ordinality alias for named UNNEST members.

Sets orphan strategy metadata for a write relationship.

Sets ownership metadata for a relationship.

Sets a payload map for a detail-row action.

Sets the numeric precision for decimal columns.

Sets a query builder function for named query members.

Sets recursive CTE recursive query function.

Sets rich reference metadata for a field, including choice-source caption/value paths.

Sets whether a write operation requires a filter.

Sets whether the filter is required.

Sets required fields for a detail-row action.

Sets write operations that require the field.

Sets write operation returning behavior.

Sets the declared return type or return metadata for a UDF registration.

Sets VALUES rows for a named defvalues member.

Marks a write field as server-managed.

Sets whether the column is sortable.

Sets a source expression for named LATERAL members.

Sets the SQL function name for a UDF registration.

Sets transition metadata for a domain action.

Sets the filter type.

Sets uniqueness fields for a write relationship.

Sets whether a write field is updatable.

Sets validators for a write field or relationship.

Sets relationship writability.

Marks a write field as write-once.

Functions

action(value)

(macro)

Sets an action reference for a capability.

aggregate_functions(value)

(macro)

Sets the allowed aggregate functions for a column.

Options: :sum, :avg, :count, :min, :max

allowed_in(value)

(macro)

Sets the allowed call sites for a UDF registration.

allowed_ops(value)

(macro)

Sets allowed write operations for a relationship.

arg(name, type, opts \\ [])

(macro)

Adds an argument definition to a UDF registration.

array_field(value)

(macro)

Sets the UNNEST array field/expression for named UNNEST members.

as(value)

(macro)

Sets the SQL alias/table name for named VALUES members.

base_query(value)

(macro)

Sets recursive CTE base query function.

bulk(value)

(macro)

Sets whether a write operation is bulk-capable.

capability(value)

(macro)

Sets the capability required by a query-facing overlay entry.

cardinality(value)

(macro)

Sets relationship cardinality.

cascade_delete(value)

(macro)

Sets cascade delete behavior for a write relationship.

cascade_update(value)

(macro)

Sets cascade update behavior for a write relationship.

choice_source(value)

(macro)

Binds a field to a declared choice source.

columns(value)

(macro)

Sets declared columns for CTE/VALUES query members.

computed(value)

(macro)

Marks a column as computed (not from database).

conflict_targets(value)

(macro)

Sets write operation conflict targets.

data(value)

(macro)

Alias for rows/1 in named VALUES members.

defaction(action_id, action_config)

(macro)

Defines a domain action under the top-level actions registry.

default(value)

(macro)

Sets the default value for the filter.

default_provider(value)

(macro)

Sets a default provider for a write field.

defcapability(capability_id, capability_config)

(macro)

Defines a capability under the top-level capabilities registry.

defchoice_source(choice_source_id, choice_source_config)

(macro)

Defines a choice source under the top-level choice_sources registry.

Example

defchoice_source(:assignees, %{
  domain: :employee,
  value_field: :id,
  label_field: :full_name,
  source_relationship: :assignee
})

defcolumn(column_name, list)

(macro)

Defines a column customization.

Example

defcolumn :price do
  label "Product Price"
  format :currency
  aggregate_functions [:sum, :avg]
end

defcte(cte_id, list)

(macro)

Defines a named CTE preset for Selecto.with_cte/2.

Example

defcte :active_customers do
  query &__MODULE__.active_customers_cte/1
  columns ["id", "name"]
  join [owner_key: :id, related_key: :id, fields: :infer]
end

defdetail_action(action_id, list)

(macro)

Defines a detail-row action.

Example

defdetail_action :customer_profile do
  name("Customer Profile")
  description("Open the customer profile in a new tab")
  type(:external_link)
  required_fields([:customer_id])
  payload(%{url_template: "https://app.example.test/customers/{{customer_id}}"})
end

deffilter(filter_name, list)

(macro)

Defines a custom filter.

Example

deffilter "price_range" do
  name "Price Range"
  type :string
  description "Filter by price range"
end

deffunction(function_id, list)

(macro)

Defines a named UDF specification.

defjoin(join_id, join_config)

(macro)

Defines a join configuration under the top-level joins registry.

Example

defjoin :initiative, %{
  type: :left,
  schema: MyApp.Initiative,
  owner_key: :initiative_id,
  related_key: :id
}

defjsonb_schema(column_name, list)

(macro)

Defines a JSONB schema for a JSONB column, enabling typed field access, filtering, and display of structured JSON data.

Example

defjsonb_schema :attributes do
  field :color, :string, label: "Color"
  field :weight, :decimal, label: "Weight (kg)", precision: 2
  field :organic, :boolean, label: "Organic"
  field :origin_country, :string, label: "Country of Origin"
  field :certifications, {:array, :string}, label: "Certifications"
  field :dimensions, :object do
    field :width, :decimal, label: "Width"
    field :height, :decimal, label: "Height"
    field :depth, :decimal, label: "Depth"
  end
end

Supported Field Types

  • :string - Text values
  • :integer - Whole numbers
  • :decimal - Decimal numbers (supports precision option)
  • :boolean - True/false values
  • :date - Date values (ISO 8601 format)
  • :datetime - DateTime values (ISO 8601 format)
  • {:array, type} - Arrays of the specified type
  • :object - Nested object (use nested field calls)

Field Options

  • label - Human-readable label for display
  • precision - Decimal precision (for :decimal type)
  • required - Whether the field is required (default: false)
  • default - Default value for the field
  • filterable - Whether the field can be filtered (default: true)
  • sortable - Whether the field can be sorted (default: true)
  • format - Display format (:currency, :percentage, etc.)

deflateral(lateral_id, list)

(macro)

Defines a named LATERAL preset for Selecto.with_lateral/2.

Example

deflateral :tag_expansion do
  source {:unnest, ""selecto_root"."tags""}
  as "tag_expansion"
  join_type :inner
end

defpopup(action_id, list)

(macro)

Defines a modal detail-row action.

This is a convenience wrapper around defdetail_action that defaults type to :modal.

defschema(schema_id, schema_config)

(macro)

Defines a schema configuration under the top-level schemas registry.

Example

defschema :initiative, %{
  source_table: "initiatives",
  columns: %{id: %{type: :integer}, name: %{type: :string}}
}

defschema_assoc(schema_id, association_id, association_config)

(macro)

Defines an association under a schema entry in schemas.

Example

defschema_assoc(:bundle_parent_load, :split_parent_load, %{
  queryable: :split_parent_load,
  field: :split_parent_load,
  owner_key: :split_parent_id,
  related_key: :id
})

defsource_assoc(association_id, association_config)

(macro)

Defines a root source association under source.associations.

Example

defsource_assoc(:bundle_parent_load, %{
  queryable: :bundle_parent_load,
  field: :bundle_parent_load,
  owner_key: :bundle_parent_id,
  related_key: :id
})

defsource_relationship(relationship_id, relationship_config)

(macro)

Defines a source relationship under the top-level source_relationships registry.

Example

defsource_relationship(:assignee, %{
  target_domain: :employee,
  source_field: :assignee_id,
  target_field: :id,
  source_path: "assignee"
})

defsubquery(subquery_id, list)

(macro)

Defines a named subquery preset for Selecto.with_subquery/2.

Example

defsubquery :high_value_orders do
  query &__MODULE__.high_value_orders_subquery/1
  type :inner
  on [%{left: "id", right: "customer_id"}]
end

defunnest(unnest_id, list)

(macro)

Defines a named UNNEST preset for Selecto.with_unnest/2.

Example

defunnest :product_tags do
  array_field "tags"
  as "tag"
  ordinality "tag_position"
end

defvalues(values_id, list)

(macro)

Defines a named VALUES preset for Selecto.with_values/2.

Example

defvalues :status_lookup do
  rows [["active", "Active"], ["inactive", "Inactive"]]
  columns ["status", "label"]
  as "status_lookup"
  join [owner_key: :status, related_key: :status]
end

defwrite_constraint(rule)

(macro)

Appends a write constraint rule under writes.constraints.

defwrite_field(field_id, field_config)

(macro)

Defines a write field under writes.fields.

defwrite_hook(hook_id, hook_refs)

(macro)

Defines declared host-runtime hook references under writes.hooks.

Hook references remain host-owned code. Domain inspection and exported contracts expose only safe metadata for these references.

defwrite_operation(operation_id, operation_config)

(macro)

Defines a write operation under writes.operations.

Examples

defwrite_operation :insert do
  enabled true
  returning :record
end

defwrite_operation :delete, %{enabled: true, require_filter: true}

defwrite_relationship(relationship_id, relationship_config)

(macro)

Defines a write relationship under writes.relationships.

defwrite_tenant_scope(scope_config)

(macro)

Defines canonical tenant scope metadata under writes.scope.tenant.

Examples

defwrite_tenant_scope do
  required(true)
  field(:tenant_id)
  satisfied_by([:trusted_context, :prefix])
end

defwrite_tenant_scope %{required: true, field: :tenant_id}

defwrite_transition(field_id, transition_graph)

(macro)

Defines a transition graph under writes.transitions.

defwrite_validation(rule)

(macro)

Appends a write validation rule under writes.validations.

dependencies(value)

(macro)

Sets CTE dependency names.

description(value)

(macro)

Sets the filter description/help text.

enabled(value)

(macro)

Sets whether a write operation, field, or relationship is enabled.

execution(value)

(macro)

Sets execution metadata for a domain action.

field(name, type, opts \\ [])

(macro)

Defines a field within a JSONB schema.

This macro is only valid inside a defjsonb_schema block.

Examples

# Simple field with type and label
field :color, :string, label: "Color"

# Field with multiple options
field :weight, :decimal, label: "Weight", precision: 2, required: true

# Array field
field :tags, {:array, :string}, label: "Tags"

# Nested object field
field :dimensions, :object do
  field :width, :decimal
  field :height, :decimal
end

filterable(value)

(macro)

Sets whether the column is filterable.

forbidden_on(value)

(macro)

Sets write operations that forbid the field.

foreign_key(value)

(macro)

Sets the foreign key for a write relationship.

format(value)

(macro)

Sets the display format for a column.

Common formats: :currency, :percentage, :number, :date, :datetime, :yes_no

immutable(value)

(macro)

Marks a write field immutable.

insertable(value)

(macro)

Sets whether a write field is insertable.

join(value)

(macro)

Sets join options for query member auto-join behavior.

join_id(value)

(macro)

Sets explicit join id for named subquery members.

join_type(value)

(macro)

Sets the join type for named LATERAL members.

kind(value)

(macro)

Sets named subquery kind (:join currently supported).

label(value)

(macro)

Sets the human-readable label for a column or filter.

lateral_source(value)

(macro)

Alias for source/1 in named LATERAL members.

max_items(value)

(macro)

Sets maximum item count for a write relationship.

max_length(value)

(macro)

Sets the maximum display length for string columns.

min_items(value)

(macro)

Sets minimum item count for a write relationship.

name(value)

(macro)

Sets the human-readable name for a filter.

on(value)

(macro)

Sets ON conditions for named subquery members.

operations(value)

(macro)

Sets operations for a capability.

options(value)

(macro)

Sets the valid options for a select-type filter.

ordinality(value)

(macro)

Sets ordinality alias for named UNNEST members.

orphan_strategy(value)

(macro)

Sets orphan strategy metadata for a write relationship.

ownership(value)

(macro)

Sets ownership metadata for a relationship.

payload(value)

(macro)

Sets a payload map for a detail-row action.

precision(value)

(macro)

Sets the numeric precision for decimal columns.

query(value)

(macro)

Sets a query builder function for named query members.

recursive_query(value)

(macro)

Sets recursive CTE recursive query function.

reference(value)

(macro)

Sets rich reference metadata for a field, including choice-source caption/value paths.

require_filter(value)

(macro)

Sets whether a write operation requires a filter.

required(value)

(macro)

Sets whether the filter is required.

required_fields(value)

(macro)

Sets required fields for a detail-row action.

required_on(value)

(macro)

Sets write operations that require the field.

returning(value)

(macro)

Sets write operation returning behavior.

returns(value)

(macro)

Sets the declared return type or return metadata for a UDF registration.

rows(value)

(macro)

Sets VALUES rows for a named defvalues member.

server_managed(value)

(macro)

Marks a write field as server-managed.

sortable(value)

(macro)

Sets whether the column is sortable.

source(value)

(macro)

Sets a source expression for named LATERAL members.

sql_name(value)

(macro)

Sets the SQL function name for a UDF registration.

transition(value)

(macro)

Sets transition metadata for a domain action.

type(value)

(macro)

Sets the filter type.

Common types: :string, :integer, :boolean, :date, :datetime, :decimal

unique_by(value)

(macro)

Sets uniqueness fields for a write relationship.

updatable(value)

(macro)

Sets whether a write field is updatable.

validators(value)

(macro)

Sets validators for a write field or relationship.

writable(value)

(macro)

Sets relationship writability.

write_once(value)

(macro)

Marks a write field as write-once.