Ash Resource Fragment which is the foundation for TMF Party subtypes.
BaseParty is the foundation for the TMF632 cascade — Party is an abstract
TMF concept, and concrete subtype identity lives on the fragments that
compose with it:
Diffo.Provider.BaseOrganization— TMF632 Organization fields (tradingName, organizationType, isLegalEntity, isHeadOffice, …)Diffo.Provider.BaseIndividual— TMF632 Individual fields (givenName, familyName, gender, birthDate, …)
Each subtype fragment composes with BaseParty on a concrete leaf:
defmodule MyApp.Carrier do
use Ash.Resource,
fragments: [
Diffo.Provider.BaseParty,
Diffo.Provider.BaseOrganization
],
domain: MyApp.Domain
# consumer-specific attributes here
endDiffo ships the two corresponding concrete leaves out of the box:
Diffo.Provider.Organization and Diffo.Provider.Individual. Use them
directly or as templates for your own domain leaves.
Diffo.Provider.Party is also kept in core but is plumbing (abstract
reader for projection + PartyRef-typed placeholder support + :Entity
routing), 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_party!(:Organization, %{...})
Diffo.Provider.get_party_by_id!(id) # returns concrete subtype struct via projectionAttributes
id— string primary key, defaults to a generated uuid4. Can be set by the domain to any meaningful string (e.g. an ABN or a data centre identifier).href— optional URI for the party.name— the party name.type— TMF@type. Defaults to:PartyRef. One of:PartyRef,:Individual,:Organization,:Entity. Whenreferred_typeis present,typemust be:PartyRef.referred_type— TMF@referredType. One of:Individual,:Organization,:Entity. When present, indicates this is a reference to a party of that kind;typemust be:PartyRef.
Party Extension DSL
The party DSL provides two compile-time declaration blocks, both nested inside a single
provider do section. Role names are domain-specific nouns from the party's perspective
— timeless, camelCase when multi-word.
instances do — declares the roles this Party kind plays with respect to Instances:
provider do
instances do
role :operator, MyApp.Cluster
role :dataCentre, MyApp.Facility
end
endparties do — declares the roles this Party kind plays with respect to other Parties:
provider do
parties do
role :employer, MyApp.Organization
end
endBoth blocks are introspectable via Diffo.Provider.Party.Extension.Info.
Usage
defmodule MyApp.RSP do
use Ash.Resource, fragments: [BaseParty], domain: MyApp.Domain
resource do
description "A Retail Service Provider"
plural_name :rsps
end
jason do
pick [:id, :name, :type]
compact true
end
outstanding do
expect [:id, :name, :type]
end
actions do
create :build do
accept [:id, :href, :name]
change set_attribute(:referred_type, :Organization)
end
end
provider do
instances do
role :provider, MyApp.AccessService
end
end
endDomain-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 BaseParty only accepts the base fields (id, href,
name, type, referred_type). Use your domain API to call the derived resource's action:
defmodule MyApp.Carrier do
use Ash.Resource, fragments: [BaseParty], domain: MyApp.Domain
attributes do
attribute :abn, :string, public?: true
attribute :carrier_code, :string, public?: true
end
actions do
create :build do
accept [:id, :href, :name, :abn, :carrier_code]
change set_attribute(:type, :Organization)
end
end
end
# Use the domain API — Provider.create_party!/1 does not know about :abn
MyApp.Domain.create_carrier!(%{name: "Acme", abn: "51824753556", carrier_code: "ACM"})TMF type and referred_type
The type and referred_type attributes map to the TMF @type and @referredType JSON
fields via the jason layer. Use the build action to declare the TMF identity of your
domain party — this is also the contract for how the party appears in TMF serialisation
of relatedParty on instances.
type: :Organization— this party IS an Organization (direct).referred_type: :Organization— this is a PartyRef pointing to an Organization.