Packages

phoenix_kit

1.7.21
1.7.208 1.7.207 1.7.206 1.7.205 1.7.204 1.7.203 1.7.202 1.7.201 1.7.200 1.7.199 1.7.198 1.7.197 1.7.196 1.7.194 1.7.193 1.7.192 1.7.191 1.7.190 1.7.189 1.7.187 1.7.186 1.7.185 1.7.184 1.7.183 1.7.182 1.7.181 1.7.180 1.7.179 1.7.178 1.7.177 1.7.176 1.7.175 1.7.174 1.7.173 1.7.172 1.7.171 1.7.170 1.7.169 1.7.168 1.7.167 1.7.166 1.7.165 1.7.164 1.7.162 1.7.161 1.7.160 1.7.159 1.7.157 1.7.156 1.7.155 1.7.154 1.7.153 1.7.152 1.7.151 1.7.150 1.7.149 1.7.146 1.7.145 1.7.144 1.7.143 1.7.138 1.7.133 1.7.132 1.7.131 1.7.130 1.7.128 1.7.126 1.7.125 1.7.121 1.7.120 1.7.119 1.7.118 1.7.117 1.7.116 1.7.115 1.7.114 1.7.113 1.7.112 1.7.111 1.7.110 1.7.109 1.7.108 1.7.107 1.7.106 1.7.105 1.7.104 1.7.103 1.7.102 1.7.101 1.7.100 1.7.99 1.7.98 1.7.97 1.7.96 1.7.95 1.7.94 1.7.93 1.7.92 1.7.91 1.7.90 1.7.89 1.7.88 1.7.87 1.7.86 1.7.85 1.7.84 1.7.83 1.7.82 1.7.81 1.7.80 1.7.79 1.7.78 1.7.77 1.7.76 1.7.75 1.7.74 1.7.71 1.7.70 1.7.69 1.7.66 1.7.65 1.7.64 1.7.63 1.7.62 1.7.61 1.7.59 1.7.58 1.7.57 1.7.56 1.7.55 1.7.54 1.7.53 1.7.52 1.7.51 1.7.49 1.7.44 1.7.43 1.7.42 1.7.41 1.7.39 1.7.38 1.7.37 1.7.36 1.7.34 1.7.33 1.7.31 1.7.30 1.7.29 1.7.28 1.7.27 1.7.26 1.7.25 1.7.24 1.7.23 1.7.22 1.7.21 1.7.20 1.7.19 1.7.18 1.7.17 1.7.16 1.7.15 1.7.14 1.7.13 1.7.12 1.7.11 1.7.10 1.7.9 1.7.8 1.7.7 1.7.6 1.7.5 1.7.4 1.7.3 1.7.2 1.7.1 1.7.0 1.6.20 1.6.19 1.6.18 1.6.17 1.6.16 1.6.15 1.6.14 1.6.13 1.6.12 1.6.11 1.6.10 1.6.9 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.2 1.3.1 1.3.0 1.2.10 1.2.9 1.2.8 1.2.7 1.2.5 1.2.4 1.2.2 1.2.1 1.2.0 1.1.0 1.0.0

A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more

Current section

Files

Jump to
phoenix_kit lib modules entities mirror exporter.ex
Raw

lib/modules/entities/mirror/exporter.ex

defmodule PhoenixKit.Modules.Entities.Mirror.Exporter do
@moduledoc """
Exports entities and their data to JSON files.
Each entity is exported as a single file containing:
- The entity definition (schema)
- All data records for that entity (when data mirroring is enabled)
## File Format
{
"export_version": "1.0",
"exported_at": "2025-12-11T10:30:00Z",
"definition": {
"name": "brand",
"display_name": "Brand",
...
},
"data": [
{"title": "Acme Corp", "slug": "acme-corp", ...},
{"title": "Globex", "slug": "globex", ...}
]
}
"""
alias PhoenixKit.Modules.Entities
alias PhoenixKit.Modules.Entities.EntityData
alias PhoenixKit.Modules.Entities.Mirror.Storage
@export_version "1.0"
# ============================================================================
# Export Operations
# ============================================================================
@doc """
Exports a single entity with its definition and optionally data.
## Parameters
- `entity` - Entity struct or entity name string
## Returns
- `{:ok, file_path}` on success
- `{:error, reason}` on failure
"""
@spec export_entity(struct() | String.t()) ::
{:ok, String.t(), :with_data | :definition_only} | {:error, term()}
def export_entity(%{name: name} = entity) do
# Check per-entity mirror_data setting
include_data = Entities.mirror_data_enabled?(entity)
data_records = if include_data, do: get_entity_data(entity), else: []
content = build_export_content(entity, data_records)
case Storage.write_entity(name, content) do
{:ok, path} -> {:ok, path, if(include_data, do: :with_data, else: :definition_only)}
{:error, reason} -> {:error, reason}
end
end
def export_entity(entity_name) when is_binary(entity_name) do
case Entities.get_entity_by_name(entity_name) do
nil -> {:error, :entity_not_found}
entity -> export_entity(entity)
end
end
@doc """
Exports a single entity data record.
This re-exports the entire entity file with updated data.
"""
@spec export_entity_data(struct()) :: {:ok, String.t()} | {:error, term()}
def export_entity_data(%{entity_id: entity_id} = _entity_data) do
case Entities.get_entity(entity_id) do
nil -> {:error, :entity_not_found}
entity -> export_entity(entity)
end
end
@doc """
Exports all entities (definitions only, no data).
"""
@spec export_all_entities() :: {:ok, [result]} when result: {:ok, String.t()} | {:error, term()}
def export_all_entities do
results =
Entities.list_entities()
|> Enum.map(fn entity ->
content = build_export_content(entity, [])
Storage.write_entity(entity.name, content)
end)
{:ok, results}
end
@doc """
Exports all data for all entities.
Re-exports each entity file with its data included.
"""
@spec export_all_data() :: {:ok, [result]} when result: {:ok, String.t()} | {:error, term()}
def export_all_data do
results =
Entities.list_entities()
|> Enum.map(fn entity ->
data_records = get_entity_data(entity)
content = build_export_content(entity, data_records)
Storage.write_entity(entity.name, content)
end)
{:ok, results}
end
@doc """
Exports all entities with their data (full export).
Returns definition count and data record count.
"""
@spec export_all() :: {:ok, %{definitions: non_neg_integer(), data: non_neg_integer()}}
def export_all do
include_data = Storage.data_enabled?()
{def_count, data_count} =
Entities.list_entities()
|> Enum.reduce({0, 0}, fn entity, {defs, data} ->
data_records = if include_data, do: get_entity_data(entity), else: []
content = build_export_content(entity, data_records)
case Storage.write_entity(entity.name, content) do
{:ok, _} -> {defs + 1, data + length(data_records)}
{:error, _} -> {defs, data}
end
end)
{:ok, %{definitions: def_count, data: data_count}}
end
# ============================================================================
# Serialization
# ============================================================================
@doc """
Serializes an entity struct to a map suitable for JSON export.
"""
@spec serialize_entity(struct()) :: map()
def serialize_entity(entity) do
%{
"name" => entity.name,
"display_name" => entity.display_name,
"display_name_plural" => entity.display_name_plural,
"description" => entity.description,
"icon" => entity.icon,
"status" => to_string(entity.status),
"fields_definition" => entity.fields_definition,
"settings" => entity.settings,
"date_created" => format_datetime(entity.date_created),
"date_updated" => format_datetime(entity.date_updated)
}
end
@doc """
Serializes an entity data record to a map suitable for JSON export.
"""
@spec serialize_entity_data(struct()) :: map()
def serialize_entity_data(record) do
%{
"title" => record.title,
"slug" => record.slug,
"status" => to_string(record.status),
"data" => record.data,
"metadata" => record.metadata,
"date_created" => format_datetime(record.date_created),
"date_updated" => format_datetime(record.date_updated)
}
end
# ============================================================================
# Private Functions
# ============================================================================
defp build_export_content(entity, data_records) do
%{
"export_version" => @export_version,
"exported_at" => DateTime.utc_now() |> DateTime.to_iso8601(),
"definition" => serialize_entity(entity),
"data" => Enum.map(data_records, &serialize_entity_data/1)
}
end
defp get_entity_data(entity) do
EntityData.list_data_by_entity(entity.id)
end
defp format_datetime(nil), do: nil
defp format_datetime(%DateTime{} = dt) do
DateTime.to_iso8601(dt)
end
defp format_datetime(%NaiveDateTime{} = ndt) do
NaiveDateTime.to_iso8601(ndt)
end
defp format_datetime(other), do: to_string(other)
end