refactor: Rename Property/PropertyType to CustomFieldValue/CustomField
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Complete refactoring of resources, database tables, code references, tests, and documentation for improved naming consistency.
This commit is contained in:
parent
47f18e9ef3
commit
8400e727a7
31 changed files with 1002 additions and 647 deletions
|
|
@ -1,18 +1,18 @@
|
|||
defmodule Mv.Membership.PropertyType do
|
||||
defmodule Mv.Membership.CustomField do
|
||||
@moduledoc """
|
||||
Ash resource defining the schema for custom member properties.
|
||||
Ash resource defining the schema for custom member fields.
|
||||
|
||||
## Overview
|
||||
PropertyTypes define the "schema" for custom fields in the membership system.
|
||||
Each PropertyType specifies the name, data type, and behavior of a custom field
|
||||
that can be attached to members via Property resources.
|
||||
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 property (e.g., "phone_mobile", "birthday")
|
||||
- `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, property values cannot be changed after creation
|
||||
- `required` - If true, all members must have this property (future feature)
|
||||
- `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)
|
||||
|
|
@ -22,22 +22,22 @@ defmodule Mv.Membership.PropertyType do
|
|||
- `:email` - Validated email addresses
|
||||
|
||||
## Relationships
|
||||
- `has_many :properties` - All property values of this type
|
||||
- `has_many :custom_field_values` - All custom field values of this type
|
||||
|
||||
## Constraints
|
||||
- Name must be unique across all property types
|
||||
- Cannot delete a property type that has existing property values (RESTRICT)
|
||||
- Name must be unique across all custom fields
|
||||
- Cannot delete a custom field that has existing custom field values (RESTRICT)
|
||||
|
||||
## Examples
|
||||
# Create a new property type
|
||||
PropertyType.create!(%{
|
||||
# Create a new custom field
|
||||
CustomField.create!(%{
|
||||
name: "phone_mobile",
|
||||
value_type: :string,
|
||||
description: "Mobile phone number"
|
||||
})
|
||||
|
||||
# Create a required property type
|
||||
PropertyType.create!(%{
|
||||
# Create a required custom field
|
||||
CustomField.create!(%{
|
||||
name: "emergency_contact",
|
||||
value_type: :string,
|
||||
required: true
|
||||
|
|
@ -48,7 +48,7 @@ defmodule Mv.Membership.PropertyType do
|
|||
data_layer: AshPostgres.DataLayer
|
||||
|
||||
postgres do
|
||||
table "property_types"
|
||||
table "custom_fields"
|
||||
repo Mv.Repo
|
||||
end
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ defmodule Mv.Membership.PropertyType do
|
|||
attribute :value_type, :atom,
|
||||
constraints: [one_of: [:string, :integer, :boolean, :date, :email]],
|
||||
allow_nil?: false,
|
||||
description: "Defines the datatype `Property.value` is interpreted as"
|
||||
description: "Defines the datatype `CustomFieldValue.value` is interpreted as"
|
||||
|
||||
attribute :description, :string, allow_nil?: true, public?: true
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ defmodule Mv.Membership.PropertyType do
|
|||
end
|
||||
|
||||
relationships do
|
||||
has_many :properties, Mv.Membership.Property
|
||||
has_many :custom_field_values, Mv.Membership.CustomFieldValue
|
||||
end
|
||||
|
||||
identities do
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
defmodule Mv.Membership.Property do
|
||||
defmodule Mv.Membership.CustomFieldValue do
|
||||
@moduledoc """
|
||||
Ash resource representing a custom property value for a member.
|
||||
Ash resource representing a custom field value for a member.
|
||||
|
||||
## Overview
|
||||
Properties implement the Entity-Attribute-Value (EAV) pattern, allowing
|
||||
dynamic custom fields to be attached to members. Each property links a
|
||||
member to a property type and stores the actual value.
|
||||
CustomFieldValues implement the Entity-Attribute-Value (EAV) pattern, allowing
|
||||
dynamic custom fields to be attached to members. Each custom field value links a
|
||||
member to a custom field and stores the actual value.
|
||||
|
||||
## Value Storage
|
||||
Values are stored using Ash's union type with JSONB storage format:
|
||||
|
|
@ -24,19 +24,19 @@ defmodule Mv.Membership.Property do
|
|||
- `:email` - Validated email addresses (custom type)
|
||||
|
||||
## Relationships
|
||||
- `belongs_to :member` - The member this property belongs to (CASCADE delete)
|
||||
- `belongs_to :property_type` - The property type definition
|
||||
- `belongs_to :member` - The member this custom field value belongs to (CASCADE delete)
|
||||
- `belongs_to :custom_field` - The custom field definition
|
||||
|
||||
## Constraints
|
||||
- Each member can have only one property per property type (unique composite index)
|
||||
- Properties are deleted when the associated member is deleted (CASCADE)
|
||||
- Each member can have only one custom field value per custom field (unique composite index)
|
||||
- Custom field values are deleted when the associated member is deleted (CASCADE)
|
||||
"""
|
||||
use Ash.Resource,
|
||||
domain: Mv.Membership,
|
||||
data_layer: AshPostgres.DataLayer
|
||||
|
||||
postgres do
|
||||
table "properties"
|
||||
table "custom_field_values"
|
||||
repo Mv.Repo
|
||||
|
||||
references do
|
||||
|
|
@ -46,7 +46,7 @@ defmodule Mv.Membership.Property do
|
|||
|
||||
actions do
|
||||
defaults [:create, :read, :update, :destroy]
|
||||
default_accept [:value, :member_id, :property_type_id]
|
||||
default_accept [:value, :member_id, :custom_field_id]
|
||||
end
|
||||
|
||||
attributes do
|
||||
|
|
@ -68,16 +68,16 @@ defmodule Mv.Membership.Property do
|
|||
relationships do
|
||||
belongs_to :member, Mv.Membership.Member
|
||||
|
||||
belongs_to :property_type, Mv.Membership.PropertyType
|
||||
belongs_to :custom_field, Mv.Membership.CustomField
|
||||
end
|
||||
|
||||
calculations do
|
||||
calculate :value_to_string, :string, expr(value[:value] <> "")
|
||||
end
|
||||
|
||||
# Ensure a member can only have one property per property type
|
||||
# For example: A member can have only one "email" property, one "phone" property, etc.
|
||||
# Ensure a member can only have one custom field value per custom field
|
||||
# For example: A member can have only one "phone" custom field value, one "email" custom field value, etc.
|
||||
identities do
|
||||
identity :unique_property_per_member, [:member_id, :property_type_id]
|
||||
identity :unique_custom_field_per_member, [:member_id, :custom_field_id]
|
||||
end
|
||||
end
|
||||
|
|
@ -4,7 +4,7 @@ defmodule Mv.Membership.Email do
|
|||
|
||||
## Overview
|
||||
This type extends `:string` with email-specific validation constraints.
|
||||
It ensures that email values stored in Property resources are valid email
|
||||
It ensures that email values stored in CustomFieldValue resources are valid email
|
||||
addresses according to a standard regex pattern.
|
||||
|
||||
## Validation Rules
|
||||
|
|
@ -14,12 +14,12 @@ defmodule Mv.Membership.Email do
|
|||
- Automatic trimming of leading/trailing whitespace
|
||||
|
||||
## Usage
|
||||
This type is used in the Property union type for properties with
|
||||
`value_type: :email` in PropertyType definitions.
|
||||
This type is used in the CustomFieldValue union type for custom fields with
|
||||
`value_type: :email` in CustomField definitions.
|
||||
|
||||
## Example
|
||||
# In a property type definition
|
||||
PropertyType.create!(%{
|
||||
# In a custom field definition
|
||||
CustomField.create!(%{
|
||||
name: "work_email",
|
||||
value_type: :email
|
||||
})
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ defmodule Mv.Membership.Member do
|
|||
can have:
|
||||
- Personal information (name, email, phone, address)
|
||||
- Optional link to a User account (1:1 relationship)
|
||||
- Dynamic custom properties via PropertyType system
|
||||
- Dynamic custom field values via CustomField system
|
||||
- Full-text searchable profile
|
||||
|
||||
## Email Synchronization
|
||||
|
|
@ -16,7 +16,7 @@ defmodule Mv.Membership.Member do
|
|||
See `Mv.EmailSync` for details.
|
||||
|
||||
## Relationships
|
||||
- `has_many :properties` - Dynamic custom fields
|
||||
- `has_many :custom_field_values` - Dynamic custom fields
|
||||
- `has_one :user` - Optional authentication account link
|
||||
|
||||
## Validations
|
||||
|
|
@ -48,8 +48,8 @@ defmodule Mv.Membership.Member do
|
|||
|
||||
create :create_member do
|
||||
primary? true
|
||||
# Properties can be created along with member
|
||||
argument :properties, {:array, :map}
|
||||
# Custom field values can be created along with member
|
||||
argument :custom_field_values, {:array, :map}
|
||||
# Allow user to be passed as argument for relationship management
|
||||
# user_id is NOT in accept list to prevent direct foreign key manipulation
|
||||
argument :user, :map, allow_nil?: true
|
||||
|
|
@ -70,7 +70,7 @@ defmodule Mv.Membership.Member do
|
|||
:postal_code
|
||||
]
|
||||
|
||||
change manage_relationship(:properties, type: :create)
|
||||
change manage_relationship(:custom_field_values, type: :create)
|
||||
|
||||
# Manage the user relationship during member creation
|
||||
change manage_relationship(:user, :user,
|
||||
|
|
@ -95,8 +95,8 @@ defmodule Mv.Membership.Member do
|
|||
primary? true
|
||||
# Required because custom validation function cannot be done atomically
|
||||
require_atomic? false
|
||||
# Properties can be updated or created along with member
|
||||
argument :properties, {:array, :map}
|
||||
# Custom field values can be updated or created along with member
|
||||
argument :custom_field_values, {:array, :map}
|
||||
# Allow user to be passed as argument for relationship management
|
||||
# user_id is NOT in accept list to prevent direct foreign key manipulation
|
||||
argument :user, :map, allow_nil?: true
|
||||
|
|
@ -117,7 +117,7 @@ defmodule Mv.Membership.Member do
|
|||
:postal_code
|
||||
]
|
||||
|
||||
change manage_relationship(:properties, on_match: :update, on_no_match: :create)
|
||||
change manage_relationship(:custom_field_values, on_match: :update, on_no_match: :create)
|
||||
|
||||
# Manage the user relationship during member update
|
||||
change manage_relationship(:user, :user,
|
||||
|
|
@ -349,7 +349,7 @@ defmodule Mv.Membership.Member do
|
|||
end
|
||||
|
||||
relationships do
|
||||
has_many :properties, Mv.Membership.Property
|
||||
has_many :custom_field_values, Mv.Membership.CustomFieldValue
|
||||
# 1:1 relationship - Member can optionally have one User
|
||||
# This references the User's member_id attribute
|
||||
# The relationship is optional (allow_nil? true by default)
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@ defmodule Mv.Membership do
|
|||
Ash Domain for membership management.
|
||||
|
||||
## Resources
|
||||
- `Member` - Club members with personal information and custom properties
|
||||
- `Property` - Dynamic custom field values attached to members
|
||||
- `PropertyType` - Schema definitions for custom properties
|
||||
- `Member` - Club members with personal information and custom field values
|
||||
- `CustomFieldValue` - Dynamic custom field values attached to members
|
||||
- `CustomField` - Schema definitions for custom fields
|
||||
|
||||
## Public API
|
||||
The domain exposes these main actions:
|
||||
- Member CRUD: `create_member/1`, `list_members/0`, `update_member/2`, `destroy_member/1`
|
||||
- Property management: `create_property/1`, `list_property/0`, etc.
|
||||
- PropertyType management: `create_property_type/1`, `list_property_types/0`, etc.
|
||||
- Custom field value management: `create_custom_field_value/1`, `list_custom_field_values/0`, etc.
|
||||
- Custom field management: `create_custom_field/1`, `list_custom_fields/0`, etc.
|
||||
|
||||
## Admin Interface
|
||||
The domain is configured with AshAdmin for management UI.
|
||||
|
|
@ -31,18 +31,18 @@ defmodule Mv.Membership do
|
|||
define :destroy_member, action: :destroy
|
||||
end
|
||||
|
||||
resource Mv.Membership.Property do
|
||||
define :create_property, action: :create
|
||||
define :list_property, action: :read
|
||||
define :update_property, action: :update
|
||||
define :destroy_property, action: :destroy
|
||||
resource Mv.Membership.CustomFieldValue do
|
||||
define :create_custom_field_value, action: :create
|
||||
define :list_custom_field_values, action: :read
|
||||
define :update_custom_field_value, action: :update
|
||||
define :destroy_custom_field_value, action: :destroy
|
||||
end
|
||||
|
||||
resource Mv.Membership.PropertyType do
|
||||
define :create_property_type, action: :create
|
||||
define :list_property_types, action: :read
|
||||
define :update_property_type, action: :update
|
||||
define :destroy_property_type, action: :destroy
|
||||
resource Mv.Membership.CustomField do
|
||||
define :create_custom_field, action: :create
|
||||
define :list_custom_fields, action: :read
|
||||
define :update_custom_field, action: :update
|
||||
define :destroy_custom_field, action: :destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue