mcpField
P
phoenix-contexts

phoenix-contexts

github.com/oliver-kriska开发57155 次安装6 天前更新
代码仓库

关于 phoenix-contexts

这是一项用于规划 Phoenix context 结构与数据访问边界的参考技能,涵盖 scope 感知 API、跨 context 引用和事务副作用,并提供拆分或合并 context 的判断依据。

主要功能

  1. 01定义 context 边界与模块结构
  2. 02在 Phoenix 1.8+ context API 中使用 scope
  3. 03保持 controller 和 LiveView 精简
  4. 04通过 ID 处理跨 context 引用
  5. 05使用 Ecto.Multi 管理副作用

适用场景

  1. 01围绕有界上下文规划数据访问
  2. 02为 context 函数添加调用者 scope
  3. 03协调带副作用的事务
  4. 04判断是否拆分 context

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/oliver-kriska/claude-elixir-phoenix --skill phoenix-contexts

安装后在 Claude Code 中输入/phoenix-contexts确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
context-patterns.md
json-api-patterns.md
plug-patterns.md
routing-patterns.md
scopes-auth.md

详细介绍

Phoenix 上下文参考

Ash 项目:Ash.Domain 可替代 Phoenix 上下文,用于数据访问——请使用 ash-framework 技能。上下文边界和 PubSub 模式仍然适用。

设计和实现 Phoenix 上下文(有界上下文)的参考。

铁律——绝不可违反

  1. 上下文拥有自己的数据——绝不可通过 Repo 直接查询其他上下文的 schema
  2. 必须使用作用域(Phoenix 1.8+)——每个上下文函数都必须将 scope 作为第一个参数
  3. 控制器和 LiveView 必须精简——控制器负责转换 HTTP,业务逻辑留在上下文中
  4. schema 中不得有副作用——使用 Ecto.Multi 执行包含副作用的事务

上下文结构

lib/my_app/
├── accounts/           # Context directory
│   ├── user.ex         # Schema
│   ├── scope.ex        # Scope struct (Phoenix 1.8+)
├── accounts.ex         # Context module (public API)

Phoenix 1.8+ 作用域(至关重要)

上下文函数将 scope 作为第一个参数,以便查询根据调用方进行筛选:

def list_posts(%Scope{} = scope) do
  from(p in Post, where: p.user_id == ^scope.user.id)
  |> Repo.all()
end

def create_post(%Scope{} = scope, attrs) do
  %Post{user_id: scope.user.id}
  |> Post.changeset(attrs)
  |> Repo.insert()
  |> broadcast(scope, :created)
end

快速决策

何时拆分上下文?
  • 模块超过约 400 行
  • 函数不共享领域术语
  • 理论上可以成为独立的微服务
  • 团队成员可以独立负责
何时保留在一起?
  • 资源共享词汇和领域概念
  • 函数经常一起操作相同数据
  • 拆分会导致过多的跨上下文调用
跨上下文引用
# ✅ Reference by ID, convert at boundary
def create_order(%Scope{} = scope, user_id, product_ids) do
  with {:ok, user} <- Accounts.fetch_user(scope, user_id) do
    do_create_order(scope, user.id, product_ids)
  end
end

# ❌ Reaching into other context's internals
alias MyApp.Accounts.User  # Don't do this
Repo.all(from o in Order, join: u in User, ...)  # Don't query other schemas

反模式

错误正确
服务对象(UserCreationService)上下文函数(Accounts.create_user/2)
用于包装 Repo 的仓储模式Repo 本身就是仓储
在控制器中直接调用 Repo委托给上下文
带有副作用的 schema 回调使用 Ecto.Multi

版本说明

  • Phoenix 1.8+:使用内置的 %Scope{} 结构体作为授权上下文
  • Phoenix 1.7:需要手动设置授权上下文(参见 ${CLAUDE_SKILL_DIR}/references/scopes-auth.md 中的 “Pre-Scopes Patterns”)

参考资料

详细模式请参见:

  • ${CLAUDE_SKILL_DIR}/references/context-patterns.md - 完整的上下文模块、PubSub、Multi 和跨边界模式
  • ${CLAUDE_SKILL_DIR}/references/scopes-auth.md - Scope 结构体、多租户、授权和 plugs
  • ${CLAUDE_SKILL_DIR}/references/routing-patterns.md - 已验证路由、管道和 API 身份验证
  • ${CLAUDE_SKILL_DIR}/references/plug-patterns.md - 函数/模块 plugs、放置位置和守卫
  • ${CLAUDE_SKILL_DIR}/references/json-api-patterns.md - JSON 控制器、FallbackController 和 API 身份验证

评论

支持 Markdown