chore: adds settings ressource and migration
This commit is contained in:
parent
418b42d35a
commit
193618eace
4 changed files with 255 additions and 0 deletions
|
|
@ -6,12 +6,14 @@ defmodule Mv.Membership do
|
|||
- `Member` - Club members with personal information and custom field values
|
||||
- `CustomFieldValue` - Dynamic custom field values attached to members
|
||||
- `CustomField` - Schema definitions for custom fields
|
||||
- `Setting` - Global application settings (singleton)
|
||||
|
||||
## Public API
|
||||
The domain exposes these main actions:
|
||||
- Member CRUD: `create_member/1`, `list_members/0`, `update_member/2`, `destroy_member/1`
|
||||
- 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.
|
||||
- Settings management: `get_settings/0`, `update_settings/2`
|
||||
|
||||
## Admin Interface
|
||||
The domain is configured with AshAdmin for management UI.
|
||||
|
|
@ -45,5 +47,80 @@ defmodule Mv.Membership do
|
|||
define :destroy_custom_field, action: :destroy_with_values
|
||||
define :prepare_custom_field_deletion, action: :prepare_deletion, args: [:id]
|
||||
end
|
||||
|
||||
resource Mv.Membership.Setting do
|
||||
# Note: create action exists but is not exposed via code interface
|
||||
# It's only used internally as fallback in get_settings/0
|
||||
# Settings should be created via seed script
|
||||
define :update_settings, action: :update
|
||||
end
|
||||
end
|
||||
|
||||
# Singleton pattern: Get the single settings record
|
||||
@doc """
|
||||
Gets the global settings.
|
||||
|
||||
Settings should normally be created via the seed script (`priv/repo/seeds.exs`).
|
||||
If no settings exist, this function will create them as a fallback using the
|
||||
`ASSOCIATION_NAME` environment variable or "Mitgliederverwaltung" as default.
|
||||
|
||||
## Returns
|
||||
|
||||
- `{:ok, settings}` - The settings record
|
||||
- `{:ok, nil}` - No settings exist (should not happen if seeds were run)
|
||||
- `{:error, error}` - Error reading settings
|
||||
|
||||
## Examples
|
||||
|
||||
iex> {:ok, settings} = Mv.Membership.get_settings()
|
||||
iex> settings.club_name
|
||||
"My Club"
|
||||
|
||||
"""
|
||||
def get_settings do
|
||||
# Try to get the first (and only) settings record
|
||||
case Ash.read_one(Mv.Membership.Setting, domain: __MODULE__) do
|
||||
{:ok, nil} ->
|
||||
# No settings exist - create as fallback (should normally be created via seed script)
|
||||
default_club_name = System.get_env("ASSOCIATION_NAME") || "Mitgliederverwaltung"
|
||||
|
||||
Mv.Membership.Setting
|
||||
|> Ash.Changeset.for_create(:create, %{club_name: default_club_name})
|
||||
|> Ash.create!(domain: __MODULE__)
|
||||
|> then(fn settings -> {:ok, settings} end)
|
||||
|
||||
{:ok, settings} ->
|
||||
{:ok, settings}
|
||||
|
||||
{:error, error} ->
|
||||
{:error, error}
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Updates the global settings.
|
||||
|
||||
## Parameters
|
||||
|
||||
- `settings` - The settings record to update
|
||||
- `attrs` - A map of attributes to update (e.g., `%{club_name: "New Name"}`)
|
||||
|
||||
## Returns
|
||||
|
||||
- `{:ok, updated_settings}` - Successfully updated settings
|
||||
- `{:error, error}` - Validation or update error
|
||||
|
||||
## Examples
|
||||
|
||||
iex> {:ok, settings} = Mv.Membership.get_settings()
|
||||
iex> {:ok, updated} = Mv.Membership.update_settings(settings, %{club_name: "New Club"})
|
||||
iex> updated.club_name
|
||||
"New Club"
|
||||
|
||||
"""
|
||||
def update_settings(settings, attrs) do
|
||||
settings
|
||||
|> Ash.Changeset.for_update(:update, attrs)
|
||||
|> Ash.update(domain: __MODULE__)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
80
lib/membership/setting.ex
Normal file
80
lib/membership/setting.ex
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
defmodule Mv.Membership.Setting do
|
||||
@moduledoc """
|
||||
Ash resource representing global application settings.
|
||||
|
||||
## Overview
|
||||
Settings is a singleton resource that stores global configuration for the association,
|
||||
such as the club name and branding information. There should only ever be one settings
|
||||
record in the database.
|
||||
|
||||
## Attributes
|
||||
- `club_name` - The name of the association/club (required, cannot be empty)
|
||||
|
||||
## Singleton Pattern
|
||||
This resource uses a singleton pattern - there should only be one settings record.
|
||||
The resource is designed to be read and updated, but not created or destroyed
|
||||
through normal CRUD operations. Initial settings should be seeded.
|
||||
|
||||
## Environment Variable Support
|
||||
The `club_name` can be set via the `ASSOCIATION_NAME` environment variable.
|
||||
If set, the environment variable value is used as a fallback when no database
|
||||
value exists. Database values always take precedence over environment variables.
|
||||
|
||||
## Examples
|
||||
|
||||
# Get current settings
|
||||
{:ok, settings} = Mv.Membership.get_settings()
|
||||
settings.club_name # => "My Club"
|
||||
|
||||
# Update club name
|
||||
{:ok, updated} = Mv.Membership.update_settings(settings, %{club_name: "New Name"})
|
||||
"""
|
||||
use Ash.Resource,
|
||||
domain: Mv.Membership,
|
||||
data_layer: AshPostgres.DataLayer
|
||||
|
||||
postgres do
|
||||
table "settings"
|
||||
repo Mv.Repo
|
||||
end
|
||||
|
||||
resource do
|
||||
description "Global application settings (singleton resource)"
|
||||
end
|
||||
|
||||
actions do
|
||||
defaults [:read]
|
||||
|
||||
# Internal create action - not exposed via code interface
|
||||
# Used only as fallback in get_settings/0 if settings don't exist
|
||||
# Settings should normally be created via seed script
|
||||
create :create do
|
||||
accept [:club_name]
|
||||
end
|
||||
|
||||
update :update do
|
||||
primary? true
|
||||
accept [:club_name]
|
||||
end
|
||||
end
|
||||
|
||||
attributes do
|
||||
uuid_primary_key :id
|
||||
|
||||
attribute :club_name, :string,
|
||||
allow_nil?: false,
|
||||
public?: true,
|
||||
description: "The name of the association/club",
|
||||
constraints: [
|
||||
trim?: true,
|
||||
min_length: 1
|
||||
]
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
validations do
|
||||
validate present(:club_name), on: [:create, :update]
|
||||
validate string_length(:club_name, min: 1), on: [:create, :update]
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue