PhoenixKitCRM.Schemas.PartyRole (PhoenixKitCRM v0.3.3)

Copy Markdown View Source

A commercial party role — marks an existing CRM company or contact as a supplier, client, or partner (Odoo's supplier_rank/customer_rank, SAP's Business-Partner roles, expressed as rows). One party can hold several roles at once (a company that's both supplier and client has two rows).

roleable_type + roleable_uuid point at phoenix_kit_crm_companies or phoenix_kit_crm_contacts — a soft ref, no FK (a single FK can't express the polymorphic target; integrity lives here in the changeset, mirroring the staff_person_uuid precedent on InteractionParty).

metadata is never cast from raw UI params — the Roles checkboxes in the company/contact forms only ever toggle role membership via PhoenixKitCRM.PartyRoles.grant_role/3 and revoke_role/2, which don't accept caller-supplied metadata either. Role-scoped commercial attributes land here only through a future dedicated context function.

Summary

Functions

Changeset for controlled lifecycle transitions (revoke / reactivate) driven by the context, not user input. Deliberately skips validate_date_range/1: stamping valid_to = today when revoking a role whose valid_from is in the future would otherwise fail the ordering check and turn revoke into a silent no-op. Only is_active and valid_to are castable here.

Types

t()

@type t() :: %PhoenixKitCRM.Schemas.PartyRole{
  __meta__: term(),
  inserted_at: DateTime.t() | nil,
  is_active: boolean(),
  metadata: map(),
  role: String.t() | nil,
  roleable_type: String.t() | nil,
  roleable_uuid: UUIDv7.t() | nil,
  updated_at: DateTime.t() | nil,
  uuid: UUIDv7.t() | nil,
  valid_from: Date.t() | nil,
  valid_to: Date.t() | nil
}

Functions

changeset(party_role, attrs)

@spec changeset(t() | Ecto.Changeset.t(t()), map()) :: Ecto.Changeset.t(t())

lifecycle_changeset(party_role, attrs)

@spec lifecycle_changeset(t() | Ecto.Changeset.t(t()), map()) :: Ecto.Changeset.t(t())

Changeset for controlled lifecycle transitions (revoke / reactivate) driven by the context, not user input. Deliberately skips validate_date_range/1: stamping valid_to = today when revoking a role whose valid_from is in the future would otherwise fail the ordering check and turn revoke into a silent no-op. Only is_active and valid_to are castable here.

roleable_types()

@spec roleable_types() :: [String.t()]

roles()

@spec roles() :: [String.t()]