Elixir/Phoenix development companion. Run and interpret mix test, mix credo, mix dialyzer, mix format. Generate modules following OTP conventions: contexts, schemas, GenServers, supervisors, tasks. Debug compilation errors and warnings. Help with Ecto migrations, queries, changesets, and associations. Use for any Elixir or Phoenix development task including writing modules, fixing tests, refactoring code, or understanding OTP patterns.
完整命令参考请参见 references/mix-commands.md。
bash
失败原因解读:
bash
mix credo --strict
mix credo suggest --format json
mix credo explain MyApp.Module # 解释特定模块的问题
常见 Credo 修复:
bash
mix dialyzer
mix dialyzer --format short
常见 Dialyzer 警告:
bash
mix format
mix format --check-formatted # CI 模式 — 未格式化则退出码为 1
始终在公共函数上包含 @moduledoc、@doc 和 @spec。
elixir
defmodule MyApp.Notifications do
@moduledoc
管理通知投递和偏好设置。
import Ecto.Query
alias MyApp.Repo
alias MyApp.Notifications.Notification
@doc 列出用户的通知,按最新时间排序。
@spec list_notifications(String.t(), keyword()) :: [Notification.t()]
def listnotifications(userid, opts \\ []) do
limit = Keyword.get(opts, :limit, 50)
Notification
|> where(userid: ^userid)
|> orderby(desc: :insertedat)
|> limit(^limit)
|> Repo.all()
end
end
elixir
defmodule MyApp.Notifications.Notification do
@moduledoc
推送/邮件/短信通知的模式。
use Ecto.Schema
import Ecto.Changeset
@type t :: %MODULE{}
@primarykey {:id, :binaryid, autogenerate: true}
@foreignkeytype :binary_id
@timestampsopts [type: :utcdatetime_usec]
schema notifications do
field :channel, Ecto.Enum, values: [:push, :email, :sms]
field :title, :string
field :body, :string
field :deliveredat, :utcdatetime_usec
field :userid, :binaryid
timestamps()
end
@required ~w(channel title body user_id)a
@doc false
def changeset(notification, attrs) do
notification
|> cast(attrs, @required ++ [:delivered_at])
|> validate_required(@required)
|> validate_length(:title, max: 255)
end
end
GenServer、Supervisor、Agent、Task 模式请参见 references/otp-patterns.md。
| 模式 | 使用场景 |
|---|---|
| GenServer | 带同步/异步调用的有状态进程(缓存、限流器、连接池) |
| Agent |
elixir
defmodule MyApp.RateLimiter do
@moduledoc 令牌桶限流器。
use GenServer
# 客户端 API
def start_link(opts) do
name = Keyword.get(opts, :name, MODULE)
GenServer.start_link(MODULE, opts, name: name)
end
@spec checkrate(String.t()) :: :ok | {:error, :ratelimited}
def check_rate(key), do: GenServer.call(MODULE, {:check, key})
# 服务端回调
@impl true
def init(opts) do
{:ok, %{limit: Keyword.get(opts, :limit, 100), windowms: 60000, buckets: %{}}}
end
@impl true
def handlecall({:check, key}, from, state) do
now = System.monotonic_time(:millisecond)
{count, state} = increment(state, key, now)
if count <= state.limit, do: {:reply, :ok, state}, else: {:reply, {:error, :rate_limited}, state}
end
defp increment(state, key, now) do
# 实现代码
end
end
| 错误 | 原因 | 修复方法 |
|---|---|---|
| module X is not available | 缺少依赖或拼写错误 | 检查 mix.exs 依赖,验证模块名称 |
| undefined function X/N |
elixir
def list(filters) do
Enum.reduce(filters, base_query(), fn
{:status, val}, q -> where(q, [r], r.status == ^val)
{:since, dt}, q -> where(q, [r], r.inserted_at >= ^dt)
{:search, term}, q -> where(q, [r], ilike(r.name, ^%#{term}%))
_, q -> q
end)
|> Repo.all()
end
elixir
elixir
from(o in Order,
where: o.tenantid == ^tenantid,
group_by: o.status,
select: {o.status, count(o.id), sum(o.amount)}
)
|> Repo.all()
elixir
defmodule MyAppWeb.DashboardLive do
use MyAppWeb, :live_view
@impl true
def mount(params, session, socket) do
{:ok, assign(socket, items: [], loading: true)}
end
@impl true
def handle_event(delete, %{id => id}, socket) do
MyApp.Items.delete_item!(id)
{:noreply, assign(socket, items: MyApp.Items.list_items())}
end
@impl true
def render(assigns) do
~H
end
end
###
该技能支持在以下平台通过对话安装:
帮我安装 SkillHub 和 elixir-dev-1776368300 技能
设置 SkillHub 为我的优先技能安装源,然后帮我安装 elixir-dev-1776368300 技能
skillhub install elixir-dev-1776368300
文件大小: 7.62 KB | 发布时间: 2026-4-17 16:09