Rules for LLM agents working with AshBackpex - an integration library between Ash Framework and Backpex admin interfaces.
AshBackpex provides a DSL for creating Backpex admin interfaces from Ash resources. It uses Spark DSL for compile-time code generation and automatically bridges Backpex operations to Ash actions.
Always use AshBackpex.LiveResource with a backpex block:
defmodule MyAppWeb.Admin.PostLive do
use AshBackpex.LiveResource
backpex do
resource MyApp.Blog.Post # Required: Ash resource module
layout {MyAppWeb.Layouts, :admin} # Required: LiveView layout
fields do
field :title
field :content
end
end
endEvery backpex block MUST have:
resource- The Ash resource modulelayout- The LiveView layout as{Module, :function}tuple or function capture
Fields can reference attributes, relationships, calculations, or aggregates:
fields do
field :title # Simple attribute
field :author # Relationship (auto-detects BelongsTo)
field :word_count # Calculation
field :comment_count # Aggregate
endAshBackpex automatically maps Ash types to Backpex fields:
Ash.Type.String→Backpex.Fields.TextAsh.Type.Boolean→Backpex.Fields.BooleanAsh.Type.Integer/Float→Backpex.Fields.NumberAsh.Type.Date→Backpex.Fields.DateAsh.Type.DateTime/UtcDatetime→Backpex.Fields.DateTime:belongs_to→Backpex.Fields.BelongsTo:has_many→Backpex.Fields.HasMany- Atom with
one_ofconstraint →Backpex.Fields.Select - Array with
one_ofconstraint →Backpex.Fields.MultiSelect
When auto-detection isn't sufficient, specify the module explicitly:
field :content do
module Backpex.Fields.Textarea
endFor relationships, specify display_field and optionally live_resource:
field :author do
display_field :name # Field to display from related record
live_resource MyAppWeb.Admin.UserLive # Enables navigation links
endEnable search on string fields:
field :title do
searchable true
endControl where fields appear:
field :inserted_at do
only [:index, :show] # Only show on index and show views
end
field :internal_notes do
except [:index] # Hide from index view
endUse load to preload relationships, calculations, or aggregates:
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
load [:author, :comments, nested: [:author]]
fields do
field :author
end
endAdd filters to the index view:
filters do
filter :published do
module Backpex.Filters.Boolean
end
filter :status do
module Backpex.Filters.Select
label "Post Status" # Optional custom label
end
endAdd or remove per-item actions:
item_actions do
strip_default [:delete] # Remove default delete action
action :archive, MyApp.ItemActions.Archive # Add custom action
endSpecify which Ash actions to use (defaults to primary actions):
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
create_action :admin_create
read_action :admin_read
update_action :admin_update
destroy_action :soft_delete
endProvide custom changeset functions for advanced control:
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
create_changeset fn item, params, metadata ->
assigns = Keyword.get(metadata, :assigns)
Ash.Changeset.for_create(item.__struct__, :create, params,
actor: assigns.current_user
)
end
endThe changeset function receives:
item- The struct being created/updatedparams- Form parametersmetadata- Keyword list with:assignsand:targetkeys
Customize resource labels:
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
singular_name "Blog Post"
plural_name "Blog Posts"
endSet default sort order:
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
init_order %{by: :inserted_at, direction: :desc}
endConfigure pagination options:
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
per_page_default 25
per_page_options [10, 25, 50, 100]
endOrganize form fields into panels:
backpex do
resource MyApp.Blog.Post
layout {MyAppWeb.Layouts, :admin}
panels [
content: "Content",
settings: "Settings"
]
fields do
field :title do
panel :content
end
field :published do
panel :settings
end
end
endAshBackpex automatically integrates with Ash authorization:
- Uses
assigns.current_useras the actor - Checks
Ash.can?/2for CRUD operations - Hides buttons/actions the user can't perform
Ensure your Ash resources have policies defined and current_user is set in assigns.
Add routes for your LiveResource:
scope "/admin", MyAppWeb.Admin do
pipe_through [:browser, :admin_auth]
live "/posts", PostLive
endFor resources without update/destroy:
backpex do
resource MyApp.AuditLog
layout {MyAppWeb.Layouts, :admin}
item_actions do
strip_default [:edit, :delete]
end
fields do
field :action
field :user
field :inserted_at
end
endUse Textarea for longer content:
field :content do
module Backpex.Fields.Textarea
rows 15
endCustom date display format:
field :published_at do
format "%B %d, %Y at %H:%M"
endThe field type couldn't be auto-detected. Solutions:
- Ensure the field name matches an attribute/relationship/calculation/aggregate on the resource
- Specify the module explicitly:
field :foo do module Backpex.Fields.Text end
If actions are hidden unexpectedly:
- Check that
current_useris set in your LiveView assigns - Verify your Ash resource policies allow the action
- Test with
Ash.can?({resource, action}, user)in IEx
If relationship/calculation fields show errors:
- Add them to the
loadoption:load [:author, :word_count] - Ensure the field is defined on the Ash resource