defmodule Mv.Membership.CustomField do @moduledoc """ Ash resource defining the schema for custom member fields. ## Overview CustomFields define the "schema" for custom fields in the membership system. Each CustomField specifies the name, data type, and behavior of a custom field that can be attached to members via CustomFieldValue resources. ## Attributes - `name` - Unique identifier for the custom field (e.g., "phone_mobile", "birthday") - `value_type` - Data type constraint (`:string`, `:integer`, `:boolean`, `:date`, `:email`) - `description` - Optional human-readable description - `immutable` - If true, custom field values cannot be changed after creation - `required` - If true, all members must have this custom field (future feature) ## Supported Value Types - `:string` - Text data (unlimited length) - `:integer` - Numeric data (64-bit integers) - `:boolean` - True/false flags - `:date` - Date values (no time component) - `:email` - Validated email addresses ## Relationships - `has_many :custom_field_values` - All custom field values of this type ## Constraints - Name must be unique across all custom fields - Cannot delete a custom field that has existing custom field values (RESTRICT) ## Examples # Create a new custom field CustomField.create!(%{ name: "phone_mobile", value_type: :string, description: "Mobile phone number" }) # Create a required custom field CustomField.create!(%{ name: "emergency_contact", value_type: :string, required: true }) """ use Ash.Resource, domain: Mv.Membership, data_layer: AshPostgres.DataLayer postgres do table "custom_fields" repo Mv.Repo end actions do defaults [:create, :read, :update, :destroy] default_accept [:name, :value_type, :description, :immutable, :required] end attributes do uuid_primary_key :id attribute :name, :string, allow_nil?: false, public?: true attribute :value_type, :atom, constraints: [one_of: [:string, :integer, :boolean, :date, :email]], allow_nil?: false, description: "Defines the datatype `CustomFieldValue.value` is interpreted as" attribute :description, :string, allow_nil?: true, public?: true attribute :immutable, :boolean, default: false, allow_nil?: false attribute :required, :boolean, default: false, allow_nil?: false end relationships do has_many :custom_field_values, Mv.Membership.CustomFieldValue end identities do identity :unique_name, [:name] end end