Agent RulesAgent Rules
Builder
Options
Browse all rules by language and framework
Templates
Pre-built rule sets ready to use
Popular Rules
Top community-ranked rules leaderboard
GuidesAnalyzePricingContact
Builder
OptionsTemplatesPopular Rules
GuidesAnalyzePricingContact

Product

  • Builder
  • Templates
  • Browse Rules
  • My Library

Learn

  • What are AI Agent Rules?
  • Guides
  • FAQ
  • About

Resources

  • Terms
  • Privacy Policy
  • Pricing
  • Contact
  • DMCA Policy

Support

Help keep this project free.

Agent RulesAgent Rules Builder
© 2026 Aurora Algorithm Inc.
Back to Templates

Elixir + Phoenix

Rules for Phoenix applications with LiveView, Ecto, and OTP patterns.

elixirElixir/phoenixPhoenix
elixir
phoenix
liveview
ecto
otp
Customize in Builder

Details

Language
elixirElixir
Framework
phoenixPhoenix

Rules Content

AGENTS.md
Edit in Builder

Elixir Phoenix Agent Rules

Project Context

You are building Phoenix 1.7+ applications with Elixir. Organize business logic in contexts, use Ecto for database access, and leverage LiveView for interactive UIs. Follow Phoenix conventions for a codebase that scales with the team.

Code Style

- Write pure functions wherever possible; push side effects to context boundaries and controllers.
- Use the pipe operator `|>` for data transformation chains.
- Use pattern matching in function heads for control flow; use `with` for multi-step fallible operations.
- Write `@doc` and `@spec` for all public context functions.
- Keep functions short (under 15 lines). Extract private helpers with `defp`.

Project Structure

- Organize business logic into contexts: `MyApp.Accounts`, `MyApp.Catalog`, `MyApp.Orders`.
- Each context exposes a public API of named functions; schemas and queries are internal to the context.
- Place web-specific code in `MyAppWeb`: controllers, live views, components, router.
- Controllers and LiveViews call context functions only — never call `Repo` directly from web layer code.
- Separate schema modules (`MyApp.Orders.Order`) from context modules (`MyApp.Orders`).

Controllers

- Keep controllers thin: parse params, call context function, render or redirect.
- Use `conn |> put_status(:created) |> json(order)` for RESTful API responses.
- Use `action_fallback MyAppWeb.FallbackController` to centralize error handling across controllers.
- Define `FallbackController` to pattern match on `{:error, reason}` tuples and return appropriate responses.
- Use `require_authenticated_user` plug for protected routes.

Ecto

- Write changesets for every data mutation — never insert or update without validating through a changeset.
- Use `validate_required`, `validate_format`, `validate_length`, `unique_constraint` in changesets.
- Use `Ecto.Multi` for operations spanning multiple database writes: `Multi.new() |> Multi.insert(...) |> Multi.update(...) |> Repo.transaction()`.
- Use `from(o in Order, where: o.status == ^:pending, order_by: [desc: o.inserted_at])` with explicit bindings.
- Add indexes in migrations with `create index(:orders, [:user_id])` and unique indexes with `create unique_index`.
- Write reversible migrations using `up/0` and `down/0` functions.

GenServer & OTP

- Use `GenServer` for stateful processes: caches, rate limiters, connection pools.
- Expose a public API module wrapping `GenServer.call/cast`: `def get_rate(limiter, key), do: GenServer.call(limiter, {:get, key})`.
- Use `Supervisor.child_spec` to configure restart strategies explicitly.
- Use `Registry` for dynamically named workers: `{:via, Registry, {MyApp.Registry, user_id}}`.

LiveView

- Use `mount/3` for initial data loading; use `handle_params/3` for URL-driven state.
- Keep socket assigns minimal — store only what the template needs to render.
- Use `handle_event/3` for user interactions; return `{:noreply, socket}` for updates, `{:reply, payload, socket}` for push replies.
- Use Phoenix LiveView streams (`stream/3`, `stream_insert/3`) for large, dynamic lists.
- Use `push_patch` for navigation that updates URL params without a full remount.

Error Handling

- Return `{:ok, value}` / `{:error, reason}` from all context functions.
- Match on error tuples in `with` chains; handle them in the `else` clause.
- Use `FallbackController` to map `{:error, %Ecto.Changeset{}}` to `422 Unprocessable Entity`.
- Log errors with `Logger.error("Operation failed", metadata: [user_id: id, reason: inspect(reason)])`.

Testing

- Write tests with ExUnit; use `async: true` on modules that do not share database state.
- Use `Ecto.Adapters.SQL.Sandbox` for database tests with automatic rollback after each test case.
- Test context functions directly: `assert {:ok, order} = Orders.create_order(valid_attrs)`.
- Test LiveViews with `Phoenix.LiveViewTest`: `{:ok, view, html} = live(conn, "/orders")`.
- Use `Mox` for external service mocks; define behavior modules and set expectations per test.

Deployment

- Use `mix release` for production releases; configure secrets in `runtime.exs` via `System.get_env`.
- Run migrations on deploy with `bin/app eval "MyApp.Release.migrate()"` — not at application startup.
- Use Oban for persistent background jobs with retries, scheduling, and observability.
- Implement `/healthz` endpoint that checks database connectivity and responds within 200ms.