Diffo.Provider.BasePlace (Diffo v0.5.1)

Copy Markdown View Source

Ash Resource Fragment which is the foundation for TMF Place subtypes.

BasePlace is the foundation for the TMF675 cascade — Place is an abstract TMF concept, and concrete subtype identity lives on the fragments that compose with it:

Each subtype fragment composes with BasePlace on a concrete leaf:

defmodule MyApp.SydneyExchange do
  use Ash.Resource,
    fragments: [
      Diffo.Provider.BasePlace,
      Diffo.Provider.BaseGeographicSite
    ],
    domain: MyApp.Domain
  # consumer-specific attributes here
end

Diffo ships the three corresponding concrete leaves out of the box: Diffo.Provider.GeographicAddress, Diffo.Provider.GeographicSite, Diffo.Provider.GeographicLocation. Use them directly or as templates for your own domain leaves.

Diffo.Provider.Place is also kept in core but is plumbing (abstract reader for projection + PlaceRef-typed placeholder support), not a TMF subtype recommendation. See its moduledoc for details.

Preferred consumer API

The Diffo.Provider domain exposes a type-atom dispatcher that handles the subtype routing for you:

Diffo.Provider.create_place!(:GeographicSite, %{...})
Diffo.Provider.get_place_by_id!(id)    # returns concrete subtype struct via projection

Attributes

  • id — string primary key (required, no default — set by domain).
  • href — optional URI for the place.
  • name — the place name.
  • type — TMF @type. Defaults to :PlaceRef. One of :PlaceRef, :GeographicSite, :GeographicLocation, :GeographicAddress. When referred_type is present, type must be :PlaceRef.
  • referred_type — TMF @referredType. One of :GeographicSite, :GeographicLocation, :GeographicAddress. When present, indicates this is a reference to a place of that kind; type must be :PlaceRef.
  • location — optional AshGeo.GeoJson (:point, WGS-84) for point-like Places. Values are %Geo.Point{coordinates: {lon, lat}, srid: 4326}.
  • bounds — optional AshGeo.GeoJson (:polygon, WGS-84) for region Places. Values are %Geo.Polygon{coordinates: [ring], srid: 4326}. Polygon is the wire form; axis-aligned-bounding-box is the conventional use today but not type-enforced. At most one of location/bounds may be set on a record, and only when type == :GeographicLocation (per TMF675).

Usage

defmodule MyApp.GeographicSite do
  use Ash.Resource, fragments: [BasePlace], domain: MyApp.Domain

  resource do
    description "A Geographic Site"
    plural_name :geographic_sites
  end

  jason do
    pick [:id, :href, :name, :referred_type, :type]
    compact true
    rename referred_type: "@referredType", type: "@type"
  end

  outstanding do
    expect [:id, :name, :referred_type, :type]
  end

  actions do
    create :build do
      accept [:id, :href, :name]
      change set_attribute(:type, :GeographicSite)
    end
  end
end

Domain-specific attributes

Add Ash attribute declarations directly to your derived resource for any fields beyond the base set. Those attributes can only be set via actions you declare on the derived resource — the base create action provided by BasePlace only accepts the base fields (id, href, name, type, referred_type). Use your domain API to call the derived resource's action:

defmodule MyApp.DataCentre do
  use Ash.Resource, fragments: [BasePlace], domain: MyApp.Domain

  attributes do
    attribute :tier, :integer, public?: true
    attribute :power_capacity_kw, :integer, public?: true
  end

  actions do
    create :build do
      accept [:id, :href, :name, :tier, :power_capacity_kw]
      change set_attribute(:type, :GeographicSite)
    end
  end
end

# Use the domain API — Provider.create_place!/1 does not know about :tier
MyApp.Domain.create_data_centre!(%{name: "M2", tier: 3, power_capacity_kw: 40_000})

TMF type and referred_type

The type and referred_type attributes map to the TMF @type and @referredType JSON fields via the jason layer. When referred_type is present, type must be :PlaceRef; otherwise type must not be :PlaceRef.

Summary

Functions

extensions()

opts()

persisted()

spark_dsl_config()

validate_sections()