refactor: Rename Property/PropertyType to CustomFieldValue/CustomField
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:
Moritz 2025-11-13 17:58:12 +01:00
parent 47f18e9ef3
commit 8400e727a7
Signed by: moritz
GPG key ID: 1020A035E5DD0824
31 changed files with 1002 additions and 647 deletions

View file

@ -131,11 +131,11 @@ Based on closed PRs from https://git.local-it.org/local-it/mitgliederverwaltung/
**Sprint 3 - 28.05 - 09.07**
- Member CRUD operations
- Basic property system
- Basic custom field system
- Initial UI with Tailwind CSS
**Sprint 4 - 09.07 - 30.07**
- Property types implementation
- CustomFieldValue types implementation
- Data validation
- Error handling improvements
@ -154,7 +154,7 @@ Based on closed PRs from https://git.local-it.org/local-it/mitgliederverwaltung/
**PR #147:** *Add seed data for members*
- Comprehensive seed data
- Test users and members
- Property type examples
- CustomFieldValue type examples
#### Phase 3: Search & Navigation (Sprint 6)
@ -379,21 +379,21 @@ end
**Complete documentation:** See [`docs/email-sync.md`](email-sync.md) for decision tree and sync rules.
#### 4. Property System (EAV Pattern)
#### 4. CustomFieldValue System (EAV Pattern)
**Implementation:** Entity-Attribute-Value pattern with union types
```elixir
# Property Type defines schema
defmodule Mv.Membership.PropertyType do
# CustomFieldValue Type defines schema
defmodule Mv.Membership.CustomField do
attribute :name, :string # "Membership Number"
attribute :value_type, :atom # :string, :integer, :boolean, :date, :email
attribute :immutable, :boolean # Can't change after creation
attribute :required, :boolean # All members must have this
end
# Property stores values
defmodule Mv.Membership.Property do
# CustomFieldValue stores values
defmodule Mv.Membership.CustomFieldValue do
attribute :value, :union, # Polymorphic value storage
constraints: [
types: [
@ -405,7 +405,7 @@ defmodule Mv.Membership.Property do
]
]
belongs_to :member
belongs_to :property_type
belongs_to :custom_field
end
```
@ -413,12 +413,12 @@ end
- Clubs need different custom fields
- No schema migrations for new fields
- Type safety with union types
- Centralized property management
- Centralized custom field management
**Constraints:**
- One property per type per member (composite unique index)
- One custom field value per custom field per member (composite unique index)
- Properties deleted with member (CASCADE)
- Property types protected if in use (RESTRICT)
- CustomFieldValue types protected if in use (RESTRICT)
#### 5. Authentication Strategy
@ -593,7 +593,7 @@ end
#### Database Migrations
**Key migrations in chronological order:**
1. `20250528163901_initial_migration.exs` - Core tables (members, properties, property_types)
1. `20250528163901_initial_migration.exs` - Core tables (members, custom_field_values, custom_fields)
2. `20250617090641_member_fields.exs` - Member attributes expansion
3. `20250620110850_add_accounts_domain.exs` - Users & tokens tables
4. `20250912085235_AddSearchVectorToMembers.exs` - Full-text search (tsvector + GIN index)
@ -772,7 +772,7 @@ end
- Admin user: `admin@mv.local` / `testpassword`
- Sample members: Hans Müller, Greta Schmidt, Friedrich Wagner
- Linked accounts: Maria Weber, Thomas Klein
- Property types: String, Date, Boolean, Email
- CustomFieldValue types: String, Date, Boolean, Email
**Test Helpers:**
```elixir
@ -956,9 +956,9 @@ mix credo --strict
mix credo suggest --format=oneline
```
### 8. Property Value Type Mismatch
### 8. CustomFieldValue Value Type Mismatch
**Issue:** Property value doesn't match property_type definition.
**Issue:** CustomFieldValue value doesn't match custom_field definition.
**Error:**
```
@ -966,16 +966,16 @@ mix credo suggest --format=oneline
```
**Solution:**
Ensure property value matches property_type.value_type:
Ensure custom field value matches custom_field.value_type:
```elixir
# Property Type: value_type = :integer
property_type = get_property_type("age")
# CustomFieldValue Type: value_type = :integer
custom_field = get_custom_field("age")
# Property Value: must be integer union type
{:ok, property} = create_property(%{
# CustomFieldValue Value: must be integer union type
{:ok, custom_field_value} = create_custom_field_value(%{
value: %{type: :integer, value: 25}, # Not "25" as string
property_type_id: property_type.id
custom_field_id: custom_field.id
})
```