# `Diffo.Provider.BaseParty`
[🔗](https://github.com/diffo-dev/diffo/blob/v0.9.0/lib/diffo/provider/components/base_party.ex#L5)

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
    end

Diffo 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 projection

## Attributes

- `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`. When `referred_type` is present, `type` must be `:PartyRef`.
- `referred_type` — TMF `@referredType`. One of `:Individual`, `:Organization`, `:Entity`.
  When present, indicates this is a reference to a party of that kind; `type` must 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
    end

`parties do` — declares the roles this Party kind plays with respect to other Parties:

    provider do
      parties do
        role :employer, MyApp.Organization
      end
    end

Both 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
    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 `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.

# `extensions`

# `opts`

# `persisted`

# `spark_dsl_config`

# `validate_sections`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
