Current section
Files
Jump to
Current section
Files
priv/templates/context.eex
defmodule <%= inspect @context_module %> do
@moduledoc """
Generated by Caravela from <%= inspect @domain_module %>.
CRUD context with hooks and standalone authorization.
Regenerate with `mix caravela.gen.context <%= inspect @domain_module %>`.
Custom code placed below the `# --- CUSTOM ---` marker is preserved.
"""
alias <%= inspect @repo_module %>
<%= for e <- @entities do %> alias <%= inspect e.module %>
<% end %>
<%= for e <- @entities do %>
@doc "List `<%= e.plural %>` the caller is allowed to read."
def <%= e.list_fn %>(context \\ %{}) do
<%= e.module_short %>
|> apply_read_permission(<%= inspect e.entity_name %>, context)
|> Repo.all()
end
@doc "Fetch a single `<%= e.singular %>` by id. Returns `nil` if not found or not visible."
def <%= e.get_fn %>(id, context \\ %{}) do
<%= e.module_short %>
|> apply_read_permission(<%= inspect e.entity_name %>, context)
|> Repo.get(id)
end
@doc "Fetch a single `<%= e.singular %>` by id. Raises if not found or not visible."
def <%= e.get_bang_fn %>(id, context \\ %{}) do
<%= e.module_short %>
|> apply_read_permission(<%= inspect e.entity_name %>, context)
|> Repo.get!(id)
end
@doc "Build an unsaved `<%= e.singular %>` changeset, for use in forms."
def <%= e.change_fn %>(%<%= e.module_short %>{} = <%= e.singular %>, attrs \\ %{}) do
<%= e.module_short %>.changeset(<%= e.singular %>, attrs)
end
@doc "Create a `<%= e.singular %>`: authorize, apply on_create hook, insert."
def <%= e.create_fn %>(attrs, context \\ %{}) do
with :ok <- authorize_create(<%= inspect e.entity_name %>, context) do
%<%= e.module_short %>{}
|> <%= e.module_short %>.changeset(attrs)
|> apply_changeset_hook(:on_create, <%= inspect e.entity_name %>, context)
|> Repo.insert()
end
end
@doc "Update a `<%= e.singular %>`: authorize, apply on_update hook, update."
def <%= e.update_fn %>(%<%= e.module_short %>{} = <%= e.singular %>, attrs, context \\ %{}) do
with :ok <- authorize_update(<%= inspect e.entity_name %>, <%= e.singular %>, context) do
<%= e.singular %>
|> <%= e.module_short %>.changeset(attrs)
|> apply_changeset_hook(:on_update, <%= inspect e.entity_name %>, context)
|> Repo.update()
end
end
@doc "Delete a `<%= e.singular %>`: authorize, run on_delete hook, delete."
def <%= e.delete_fn %>(%<%= e.module_short %>{} = <%= e.singular %>, context \\ %{}) do
with :ok <- authorize_delete(<%= inspect e.entity_name %>, <%= e.singular %>, context),
:ok <- run_delete_hook(<%= inspect e.entity_name %>, <%= e.singular %>, context) do
Repo.delete(<%= e.singular %>)
end
end
<% end %>
# --- Internal: permission + hook dispatch ---------------------------------
defp apply_read_permission(query, entity, context) do
<%= inspect @domain_module %>.__caravela_permission__(:can_read, entity, query, context)
end
defp authorize_create(entity, context) do
case <%= inspect @domain_module %>.__caravela_permission__(:can_create, entity, context) do
true -> :ok
false -> {:error, :unauthorized}
end
end
defp authorize_update(entity, struct, context) do
case <%= inspect @domain_module %>.__caravela_permission__(:can_update, entity, struct, context) do
true -> :ok
false -> {:error, :unauthorized}
end
end
defp authorize_delete(entity, struct, context) do
case <%= inspect @domain_module %>.__caravela_permission__(:can_delete, entity, struct, context) do
true -> :ok
false -> {:error, :unauthorized}
end
end
defp apply_changeset_hook(changeset, action, entity, context) do
<%= inspect @domain_module %>.__caravela_hook__(action, entity, changeset, context)
end
defp run_delete_hook(entity, struct, context) do
case <%= inspect @domain_module %>.__caravela_hook__(:on_delete, entity, struct, context) do
:ok -> :ok
{:error, _} = err -> err
other -> raise "on_delete hook must return :ok or {:error, reason}, got: " <> inspect(other)
end
end
<%= @custom_marker %>