phoenix-contexts について
Phoenix のコンテキスト構成とデータアクセス境界を設計するためのリファレンススキルです。scope 対応 API、コンテキスト間の参照、トランザクションの副作用を扱い、分割するか維持するかの判断も支援します。
主な機能
- 01コンテキスト境界とモジュール構成の定義
- 02Phoenix 1.8+ の API で scope を使用
- 03コントローラーと LiveView の簡素化
- 04ID によるコンテキスト間参照
- 05Ecto.Multi による副作用の処理
活用シーン
- 01境界づけられたコンテキストに沿うデータアクセス設計
- 02コンテキスト関数への呼び出し元 scope の追加
- 03副作用を伴うトランザクションの調整
- 04コンテキストを分割するかの判断
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ oliver-kriska/ claude-elixir-phoenix --skill phoenix-contextsインストール後、Claude Code で/phoenix-contextsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/context-patterns.mdjson-api-patterns.mdplug-patterns.mdrouting-patterns.mdscopes-auth.md詳細
Phoenix コンテキストリファレンス
Ash プロジェクト:データアクセスでは、
Ash.Domainが Phoenix コンテキストの役割を担います。ash-frameworkスキルを使用してください。コンテキスト境界と PubSub のパターンは引き続き適用されます。
Phoenix コンテキスト(境界づけられたコンテキスト)の設計と実装に関するリファレンスです。
絶対に守るべき原則 — 決して違反しないでください
- コンテキストは自分のデータを所有します — Repo を介して、別のコンテキストのスキーマを直接クエリしてはいけません
- スコープは必須です(Phoenix 1.8+) — すべてのコンテキスト関数は、最初の引数としてスコープを受け取る必要があります
- コントローラー/LiveView は薄く保ちます — コントローラーは HTTP を変換し、ビジネスロジックはコンテキストに置きます
- スキーマに副作用を持たせません — 副作用を伴うトランザクションには
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+ のスコープ(重要)
コンテキスト関数はスコープを最初の引数として受け取るため、クエリは呼び出し元に応じてフィルタリングされます。
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 を直接呼び出す | コンテキストに委譲する |
| 副作用を伴うスキーマコールバック | 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 構造体、マルチテナント、認可、プラグ${CLAUDE_SKILL_DIR}/references/routing-patterns.md- 検証済みルート、パイプライン、API 認証${CLAUDE_SKILL_DIR}/references/plug-patterns.md- 関数/モジュールプラグ、配置、ガード${CLAUDE_SKILL_DIR}/references/json-api-patterns.md- JSON コントローラー、FallbackController、API 認証
コメント
Markdown 対応