# CLAUDE.md: Phoenix + LiveView

## Commands
- `mix setup` · `iex -S mix phx.server` · `mix test` · `mix format` · `mix credo --strict` (if present)
- Before finishing run `mix precommit` if the project defines it, otherwise `mix compile --warnings-as-errors && mix format --check-formatted && mix test`.

## Architecture
- Business logic lives in contexts (`lib/my_app/accounts.ex`). LiveViews and controllers call context functions; they never call `Repo` directly.
- Data changes go through Ecto changesets with validations; return `{:ok, struct} | {:error, changeset}` and pattern match on it.
- Use `Ecto.Multi` or `Repo.transact` for multi-step writes.
- Generators are a starting point: `mix phx.gen.live` / `mix phx.gen.context`, then trim.

## LiveView
- Use streams (`stream/3`) for lists, not big assigns.
- Forms: `to_form(changeset)` with `<.form for={@form}>` and `<.input field={@form[:email]}>`.
- Load data in `mount` only when `connected?/1` is needed for expensive work; use `assign_async` for slow loads.
- Use `push_patch` / `<.link patch>` within a LiveView, `navigate` across LiveViews.
- Authorization in `on_mount` hooks and again in context functions taking the scope/current user.

## Style
- Pattern matching and `with` over nested `case`. No `try/rescue` for control flow.
- Tests: `DataCase` for contexts, `ConnCase` + `Phoenix.LiveViewTest` for UI.
