PhoenixKit.Modules.Entities (phoenix_kit v1.7.69)

Copy Markdown View Source

Dynamic entity system for PhoenixKit.

This module provides both the Ecto schema definition and business logic for managing custom content types (entities) with flexible field schemas.

Schema Fields

  • name: Unique identifier for the entity (e.g., "brand", "product")
  • display_name: Human-readable singular name shown in UI (e.g., "Brand")
  • display_name_plural: Human-readable plural name (e.g., "Brands")
  • description: Description of what this entity represents
  • icon: Icon identifier for UI display (hero icons)
  • status: Workflow status string - one of "draft", "published", or "archived"
  • fields_definition: JSONB array of field definitions
  • settings: JSONB map of entity-specific settings
  • created_by: User ID of the admin who created the entity
  • date_created: When the entity was created
  • date_updated: When the entity was last modified

Field Definition Structure

Each field in fields_definition is a map with:

  • type: Field type (text, textarea, number, boolean, date, select, etc.)
  • key: Unique field identifier (snake_case)
  • label: Display label for the field
  • required: Whether the field is required
  • default: Default value
  • validation: Map of validation rules
  • options: Array of options (for select, radio, checkbox types)

Core Functions

Entity Management

System Settings

Usage Examples

# Check if system is enabled
if PhoenixKit.Modules.Entities.enabled?() do
  # System is active
end

# Create a brand entity
# Note: fields_definition requires string keys, not atom keys
{:ok, entity} = PhoenixKit.Modules.Entities.create_entity(%{
  name: "brand",
  display_name: "Brand",
  display_name_plural: "Brands",
  description: "Brand content type for company profiles",
  icon: "hero-building-office",
  created_by_uuid: admin_user.uuid,
  fields_definition: [
    %{"type" => "text", "key" => "name", "label" => "Name", "required" => true},
    %{"type" => "textarea", "key" => "tagline", "label" => "Tagline"},
    %{"type" => "rich_text", "key" => "description", "label" => "Description", "required" => true},
    %{"type" => "select", "key" => "industry", "label" => "Industry",
      "options" => ["Technology", "Manufacturing", "Retail"]},
    %{"type" => "date", "key" => "founded_date", "label" => "Founded Date"},
    %{"type" => "boolean", "key" => "featured", "label" => "Featured Brand"}
  ]
})

# Get entity by name
entity = PhoenixKit.Modules.Entities.get_entity_by_name("brand")

# List all active entities
entities = PhoenixKit.Modules.Entities.list_active_entities()

Summary

Functions

Returns an %Ecto.Changeset{} for tracking entity changes.

Creates a changeset for entity creation and updates.

Counts the total number of entity data records across all entities.

Counts the total number of entities in the system.

Counts the total number of entities created by a user.

Creates an entity.

Deletes an entity.

Disables data mirroring for all entities.

Disables definition mirroring for all entities.

Disables the entities system.

Enables data mirroring for all entities.

Enables definition mirroring for all entities.

Enables the entities system.

Checks if the entities system is enabled.

Dynamic children function for Entities sidebar tabs.

Gets the current entities system configuration.

Gets a single entity by integer ID or UUID.

Gets a single entity by integer ID or UUID.

Gets a single entity by its unique name.

Gets the translation for a specific language on an entity definition.

Gets all translations for an entity definition.

Gets the maximum number of entities a single user can create.

Gets the mirror settings for an entity.

Gets the sort mode for an entity.

Gets the sort mode for an entity by UUID.

Gets summary statistics for the entities system.

Invalidates the cached entity summaries in the Dashboard Registry's ETS table. Called when entity lifecycle PubSub events are received.

Returns the list of active (published) entities.

Returns the list of entities ordered by creation date.

Lists all entities with their mirror status and data counts.

Returns a lightweight list of published entity summaries for sidebar display.

Checks if an entity uses manual sorting.

Checks if data mirroring is enabled for this entity.

Checks if definition mirroring is enabled for this entity.

Checks if multilang is globally enabled (Languages module has 2+ languages).

Removes all translations for a specific language from an entity definition.

Resolves translated fields on an entity struct for a given language.

Resolves translations on a list of entity structs.

Sets the translation for a specific language on an entity definition.

Updates an entity.

Updates the mirror settings for an entity.

Updates the sort mode for an entity.

Validates that a user hasn't exceeded their entity creation limit.

Types

t()

@type t() :: %PhoenixKit.Modules.Entities{
  __meta__: term(),
  created_by_uuid: term(),
  creator: term(),
  date_created: term(),
  date_updated: term(),
  description: term(),
  display_name: term(),
  display_name_plural: term(),
  entity_data: term(),
  fields_definition: term(),
  icon: term(),
  name: term(),
  settings: term(),
  status: term(),
  uuid: term()
}

Functions

change_entity(entity, attrs \\ %{})

Returns an %Ecto.Changeset{} for tracking entity changes.

Examples

iex> PhoenixKit.Modules.Entities.change_entity(entity)
%Ecto.Changeset{data: %PhoenixKit.Entities{}}

changeset(entity, attrs)

Creates a changeset for entity creation and updates.

Validates that name is unique, fields_definition is valid, and all required fields are present. Automatically sets date_created on new records.

count_all_entity_data()

Counts the total number of entity data records across all entities.

Examples

iex> PhoenixKit.Modules.Entities.count_all_entity_data()
243

count_entities()

Counts the total number of entities in the system.

Examples

iex> PhoenixKit.Modules.Entities.count_entities()
15

count_user_entities(user_uuid)

Counts the total number of entities created by a user.

Examples

iex> PhoenixKit.Modules.Entities.count_user_entities(1)
5

create_entity(attrs \\ %{})

Creates an entity.

Examples

iex> PhoenixKit.Modules.Entities.create_entity(%{name: "brand", display_name: "Brand"})
{:ok, %PhoenixKit.Entities{}}

iex> PhoenixKit.Modules.Entities.create_entity(%{name: ""})
{:error, %Ecto.Changeset{}}

Note: created_by is auto-filled with the first admin or user ID if not provided, but only if at least one user exists in the system. If no users exist, the changeset will fail with a validation error on created_by.

delete_entity(entity)

Deletes an entity.

Note: This will also delete all associated entity_data records due to the ON DELETE CASCADE constraint defined in the database migration (V17).

Examples

iex> PhoenixKit.Modules.Entities.delete_entity(entity)
{:ok, %PhoenixKit.Entities{}}

iex> PhoenixKit.Modules.Entities.delete_entity(entity)
{:error, %Ecto.Changeset{}}

disable_all_data_mirror()

Disables data mirroring for all entities.

Examples

iex> PhoenixKit.Modules.Entities.disable_all_data_mirror()
{:ok, count}

disable_all_definitions_mirror()

Disables definition mirroring for all entities.

Examples

iex> PhoenixKit.Modules.Entities.disable_all_definitions_mirror()
{:ok, count}

disable_system()

Disables the entities system.

Sets the "entities_enabled" setting to false.

Examples

iex> PhoenixKit.Modules.Entities.disable_system()
{:ok, %Setting{}}

enable_all_data_mirror()

Enables data mirroring for all entities.

Examples

iex> PhoenixKit.Modules.Entities.enable_all_data_mirror()
{:ok, count}

enable_all_definitions_mirror()

Enables definition mirroring for all entities.

Examples

iex> PhoenixKit.Modules.Entities.enable_all_definitions_mirror()
{:ok, count}

enable_system()

Enables the entities system.

Sets the "entities_enabled" setting to true.

Examples

iex> PhoenixKit.Modules.Entities.enable_system()
{:ok, %Setting{}}

enabled?()

Checks if the entities system is enabled.

Returns true if the "entities_enabled" setting is true.

Examples

iex> PhoenixKit.Modules.Entities.enabled?()
false

entities_children(scope)

Dynamic children function for Entities sidebar tabs.

get_config()

Gets the current entities system configuration.

Returns a map with the current settings.

Examples

iex> PhoenixKit.Modules.Entities.get_config()
%{enabled: false, max_per_user: 100, allow_relations: true, file_upload: false, entity_count: 0, total_data_count: 0}

get_entity(uuid, opts \\ [])

Gets a single entity by integer ID or UUID.

Returns the entity if found, nil otherwise.

Accepts:

  • Integer ID (e.g., 123)
  • UUID string (e.g., "550e8400-e29b-41d4-a716-446655440000")
  • Integer string (e.g., "123")

Examples

iex> PhoenixKit.Modules.Entities.get_entity(123)
%PhoenixKit.Entities{}

iex> PhoenixKit.Modules.Entities.get_entity("550e8400-e29b-41d4-a716-446655440000")
%PhoenixKit.Entities{}

iex> PhoenixKit.Modules.Entities.get_entity(456)
nil

get_entity!(id, opts \\ [])

Gets a single entity by integer ID or UUID.

Raises Ecto.NoResultsError if the entity does not exist.

Examples

iex> PhoenixKit.Modules.Entities.get_entity!(123)
%PhoenixKit.Entities{}

iex> PhoenixKit.Modules.Entities.get_entity!(456)
** (Ecto.NoResultsError)

get_entity_by_name(name, opts \\ [])

Gets a single entity by its unique name.

Returns the entity if found, nil otherwise.

Examples

iex> PhoenixKit.Modules.Entities.get_entity_by_name("brand")
%PhoenixKit.Entities{}

iex> PhoenixKit.Modules.Entities.get_entity_by_name("invalid")
nil

get_entity_translation(entity, lang_code)

Gets the translation for a specific language on an entity definition.

Returns the translated fields merged with the primary language values as defaults. Returns primary language values if no translation exists.

Examples

iex> get_entity_translation(entity, "es-ES")
%{"display_name" => "Productos", "display_name_plural" => "Productos", "description" => "..."}

get_entity_translations(entities)

Gets all translations for an entity definition.

Returns a map of language codes to translated fields. Only includes languages that have at least one translated field.

Examples

iex> get_entity_translations(entity)
%{
  "es-ES" => %{"display_name" => "Productos", "display_name_plural" => "Productos"},
  "fr-FR" => %{"display_name" => "Produits"}
}

iex> get_entity_translations(entity_without_translations)
%{}

get_max_per_user()

Gets the maximum number of entities a single user can create.

Returns the system-wide limit for entity creation per user. Defaults to 100 if not set.

Examples

iex> PhoenixKit.Modules.Entities.get_max_per_user()
100

get_mirror_settings(entities)

Gets the mirror settings for an entity.

Returns a map with mirror_definitions and mirror_data booleans. Defaults to false if not explicitly set.

Examples

iex> PhoenixKit.Modules.Entities.get_mirror_settings(entity)
%{mirror_definitions: true, mirror_data: false}

get_sort_mode(entities)

Gets the sort mode for an entity.

Returns "auto" (sort by creation date, default) or "manual" (sort by position).

Examples

iex> PhoenixKit.Modules.Entities.get_sort_mode(entity)
"auto"

get_sort_mode_by_uuid(entity_uuid)

Gets the sort mode for an entity by UUID.

Convenience wrapper that looks up the entity first. Returns "auto" if the entity is not found.

Examples

iex> PhoenixKit.Modules.Entities.get_sort_mode_by_uuid(entity_uuid)
"manual"

get_system_stats()

Gets summary statistics for the entities system.

Returns counts and metrics useful for admin dashboards.

Examples

iex> PhoenixKit.Modules.Entities.get_system_stats()
%{total_entities: 5, active_entities: 4, total_data_records: 150}

invalidate_entities_cache()

@spec invalidate_entities_cache() :: :ok

Invalidates the cached entity summaries in the Dashboard Registry's ETS table. Called when entity lifecycle PubSub events are received.

list_active_entities(opts \\ [])

Returns the list of active (published) entities.

Examples

iex> PhoenixKit.Modules.Entities.list_active_entities()
[%PhoenixKit.Entities{status: "published"}, ...]

list_entities(opts \\ [])

Returns the list of entities ordered by creation date.

Examples

iex> PhoenixKit.Modules.Entities.list_entities()
[%PhoenixKit.Entities{}, ...]

list_entities_with_mirror_status()

Lists all entities with their mirror status and data counts.

Returns a list of maps suitable for the settings UI.

Examples

iex> PhoenixKit.Modules.Entities.list_entities_with_mirror_status()
[%{id: 1, name: "test", display_name: "Test", data_count: 8, mirror_definitions: true, mirror_data: false}, ...]

list_entity_summaries()

@spec list_entity_summaries() :: [map()]

Returns a lightweight list of published entity summaries for sidebar display.

Selects only sidebar-relevant fields without preloading associations.

manual_sort?(entity)

Checks if an entity uses manual sorting.

Examples

iex> PhoenixKit.Modules.Entities.manual_sort?(entity)
true

mirror_data_enabled?(entities)

Checks if data mirroring is enabled for this entity.

Examples

iex> PhoenixKit.Modules.Entities.mirror_data_enabled?(entity)
false

mirror_definitions_enabled?(entities)

Checks if definition mirroring is enabled for this entity.

Examples

iex> PhoenixKit.Modules.Entities.mirror_definitions_enabled?(entity)
true

multilang_enabled?()

Checks if multilang is globally enabled (Languages module has 2+ languages).

Convenience wrapper around Multilang.enabled?/0.

Examples

iex> PhoenixKit.Modules.Entities.multilang_enabled?()
true

remove_entity_translation(entity, lang_code)

Removes all translations for a specific language from an entity definition.

Examples

iex> remove_entity_translation(entity, "es-ES")
{:ok, %PhoenixKit.Modules.Entities{}}

resolve_language(entity, lang_code)

@spec resolve_language(t(), String.t()) :: t()

Resolves translated fields on an entity struct for a given language.

Merges translations from settings["translations"][lang_code] onto the entity's display_name, display_name_plural, and description fields.

For the primary language (or when no translation exists), returns the entity unchanged. For secondary languages, applies override values where they exist and keeps primary values as defaults.

Examples

iex> resolve_language(entity, "es-ES")
%PhoenixKit.Modules.Entities{display_name: "Productos", ...}

iex> resolve_language(entity, "en-US")  # primary language
%PhoenixKit.Modules.Entities{display_name: "Products", ...}

resolve_languages(entities, lang_code)

@spec resolve_languages([t()], String.t()) :: [t()]

Resolves translations on a list of entity structs.

Examples

iex> resolve_languages(entities, "es-ES")
[%PhoenixKit.Modules.Entities{display_name: "Productos"}, ...]

set_entity_translation(entity, lang_code, attrs)

Sets the translation for a specific language on an entity definition.

Merges the provided fields into the existing translation for that language. Empty string values are treated as "remove override" (field falls back to primary).

Examples

iex> set_entity_translation(entity, "es-ES", %{
...>   "display_name" => "Productos",
...>   "display_name_plural" => "Productos"
...> })
{:ok, %PhoenixKit.Modules.Entities{}}

update_entity(entity, attrs)

Updates an entity.

Examples

iex> PhoenixKit.Modules.Entities.update_entity(entity, %{display_name: "Updated"})
{:ok, %PhoenixKit.Entities{}}

iex> PhoenixKit.Modules.Entities.update_entity(entity, %{name: ""})
{:error, %Ecto.Changeset{}}

update_mirror_settings(entity, mirror_settings)

Updates the mirror settings for an entity.

Parameters

  • entity - The entity to update
  • mirror_settings - Map with keys "mirror_definitions" and/or "mirror_data"

Examples

iex> PhoenixKit.Modules.Entities.update_mirror_settings(entity, %{"mirror_definitions" => true})
{:ok, %PhoenixKit.Entities{}}

update_sort_mode(entity, mode)

Updates the sort mode for an entity.

Valid modes: "auto" (sort by creation date) or "manual" (sort by position).

When switching to manual mode, existing records retain their auto-populated positions from creation order. Admins can then reorder as needed.

Examples

iex> PhoenixKit.Modules.Entities.update_sort_mode(entity, "manual")
{:ok, %PhoenixKit.Modules.Entities{}}

validate_user_entity_limit(user_uuid)

Validates that a user hasn't exceeded their entity creation limit.

Checks the current number of entities created by the user against the system limit. Returns {:ok, :valid} if within limits, {:error, reason} if limit exceeded.

Examples

iex> PhoenixKit.Modules.Entities.validate_user_entity_limit(1)
{:ok, :valid}

iex> PhoenixKit.Modules.Entities.validate_user_entity_limit(1)
{:error, "You have reached the maximum limit of 100 entities"}