feat: custom field deletion

This commit is contained in:
Moritz 2025-11-13 20:03:58 +01:00
parent 21ec86839a
commit 2af23f4042
Signed by: moritz
GPG key ID: 1020A035E5DD0824
11 changed files with 938 additions and 16 deletions

View file

@ -28,7 +28,10 @@ defmodule Mv.Membership.CustomField do
## Constraints
- Name must be unique across all custom fields
- Name maximum length: 100 characters
- Cannot delete a custom field that has existing custom field values (RESTRICT)
- Deleting a custom field will cascade delete all associated custom field values
## Calculations
- `assigned_members_count` - Returns the number of distinct members with values for this custom field
## Examples
# Create a new custom field
@ -55,7 +58,7 @@ defmodule Mv.Membership.CustomField do
end
actions do
defaults [:read, :update, :destroy]
defaults [:read, :update]
default_accept [:name, :value_type, :description, :immutable, :required]
create :create do
@ -63,6 +66,17 @@ defmodule Mv.Membership.CustomField do
change Mv.Membership.CustomField.Changes.GenerateSlug
validate string_length(:slug, min: 1)
end
destroy :destroy_with_values do
primary? true
end
read :prepare_deletion do
argument :id, :uuid, allow_nil?: false
filter expr(id == ^arg(:id))
prepare build(load: [:assigned_members_count])
end
end
attributes do
@ -111,6 +125,17 @@ defmodule Mv.Membership.CustomField do
has_many :custom_field_values, Mv.Membership.CustomFieldValue
end
calculations do
calculate :assigned_members_count,
:integer,
expr(
fragment(
"(SELECT COUNT(DISTINCT member_id) FROM custom_field_values WHERE custom_field_id = ?)",
id
)
)
end
identities do
identity :unique_name, [:name]
identity :unique_slug, [:slug]

View file

@ -25,11 +25,12 @@ defmodule Mv.Membership.CustomFieldValue do
## Relationships
- `belongs_to :member` - The member this custom field value belongs to (CASCADE delete)
- `belongs_to :custom_field` - The custom field definition
- `belongs_to :custom_field` - The custom field definition (CASCADE delete)
## Constraints
- 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)
- Custom field values are deleted when the associated custom field is deleted (CASCADE)
- String values maximum length: 10,000 characters
- Email values maximum length: 254 characters (RFC 5321)
@ -46,12 +47,19 @@ defmodule Mv.Membership.CustomFieldValue do
references do
reference :member, on_delete: :delete
reference :custom_field, on_delete: :delete
end
end
actions do
defaults [:create, :read, :update, :destroy]
default_accept [:value, :member_id, :custom_field_id]
read :by_custom_field_id do
argument :custom_field_id, :uuid, allow_nil?: false
filter expr(custom_field_id == ^arg(:custom_field_id))
end
end
attributes do

View file

@ -42,7 +42,8 @@ defmodule Mv.Membership 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
define :destroy_custom_field, action: :destroy_with_values
define :prepare_custom_field_deletion, action: :prepare_deletion, args: [:id]
end
end
end