cc-changelog
CONTRIBUTOR TOOL - Track CC changelog, extract new versions since last check, analyze impact on plugin (breaking changes,…
Use when a task touches Ecto, even a how-to question: schemas, changesets, validations, queries, preloads, Multi, migrations, constraints, money fields. Load it before writing Ecto code. Skip for Ash.
Claude Code
$ npx -y skills add oliver-kriska/claude-elixir-phoenix --skill ecto-patterns --agent claude-code
Codex
$ npx skills add oliver-kriska/claude-elixir-phoenix --skill ecto-patterns -a codex -y
Cursor
$ npx skills add oliver-kriska/claude-elixir-phoenix --skill ecto-patterns -a cursor -y
Gemini CLI
$ npx skills add oliver-kriska/claude-elixir-phoenix --skill ecto-patterns -a gemini-cli -y
GitHub Copilot
$ npx skills add oliver-kriska/claude-elixir-phoenix --skill ecto-patterns -a github-copilot -y
OpenCode
$ npx skills add oliver-kriska/claude-elixir-phoenix --skill ecto-patterns -a opencode -y
Windsurf
$ npx skills add oliver-kriska/claude-elixir-phoenix --skill ecto-patterns -a windsurf -y
name: ecto-patterns description: "Use when a task touches Ecto, even a how-to question: schemas, changesets, validations, queries, preloads, Multi, migrations, constraints, money fields. Load it before writing Ecto code. Skip for Ash." effort: medium user-invocable: false paths: - "**/migrations/*.exs" - "**/*_schema.ex" - "**/*changeset*.ex"
Reference for working with Ecto schemas, queries, and migrations.
1. **CHANGESETS ARE FOR EXTERNAL DATA** — Use `cast/4` for user/API input, `change/2` or `put_change/3` for internal trusted data 2. **NEVER USE `:float` FOR MONEY** — Always use `:decimal` or `:integer` (cents) 3. **NO RAILS-STYLE POLYMORPHIC ASSOCIATIONS** — They break foreign key constraints; use multiple nullable FKs or separate join tables 4. **ALWAYS PIN VALUES IN QUERIES** — `u.name == ^user_input` is safe, string interpolation causes SQL injection 5. **PRELOAD COLLECTIONS, NOT INDIVIDUALS** — Preloading in loops = N+1 queries 6. **CONSTRAINTS BEAT VALIDATIONS FOR RACE CONDITIONS** — Validations provide quick feedback, constraints provide DB-level safety 7. **SEPARATE QUERIES FOR `has_many`, JOIN FOR `belongs_to`** — Avoids row multiplication 8. **NO IMPLICIT CROSS JOINS** — `from(a in A, b in B)` without `on:` creates Cartesian product 9. **DEDUP BEFORE `cast_assoc` WITH SHARED DATA** — When multiple parents share child data, deduplicate child records BEFORE building changesets. Dedup only works within a single changeset
defmodule MyApp.Context.Entity do
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "entities" do
field :name, :string
field :status, Ecto.Enum, values: [:draft, :active, :archived]
field :amount_cents, :integer # Never :float for money!
belongs_to :user, MyApp.Accounts.User
timestamps(type: :utc_datetime_usec)
end
def changeset(entity, attrs) do
entity
|> cast(attrs, [:name, :status, :amount_cents])
|> validate_required([:name])
|> foreign_key_constraint(:user_id)
end
end| Function | Use When | |----------|----------| | `cast/4` | External data (user input, API) | | `put_change/3` | Internal trusted data (timestamps, computed) | | `change/2` | Internal data from existing struct |
| Relationship | Strategy | |--------------|----------| | `belongs_to` | JOIN (single query) | | `has_many` | Separate queries (avoid row multiplication) |
| Wrong | Right | |-------|-------| | `field :amount, :float` | `field :amount_cents, :integer` | | `"SELECT * WHERE name = '#{name}'"` | `from(u in User, where: u.name == ^name)` | | `Repo.all(User) \|> Enum.filter(& &1.active)` | `from(u in User, where: u.active)` | | Preloading in loops | `Repo.preload(posts, :comments)` | | `Repo.get!(User, user_id)` with user input | `Repo.get(User, id)` + handle nil | | `{:ok, _} = Repo.update(cs)` inside `Repo.transaction` | `case`/`with` + `Repo.rollback(cs)` (see transactions.md) |
For detailed patterns, see:
Docs: phxagents.dev -- install guides per runtime, the runtime compatibility matrix, all 26 Iron Laws, and a browsable skill and agent catalog. Claude Code is great.
CONTRIBUTOR TOOL - Track CC changelog, extract new versions since last check, analyze impact on plugin (breaking changes,…
Run an A/B codex review experiment — holistic codex review vs 3 focused dimension passes (security, ecto, liveview) on the branch…
CONTRIBUTOR TOOL - Validate plugin against latest Claude Code documentation. Catches breaking changes, deprecations, discovers…
Guide plugin development workflow — editing skills, agents, hooks, or eval framework in this repo. Use when modifying files in…
Generate X/Twitter release promotion posts with ASCII tables and CodeSnap rendering. Use when writing release posts, promotion…
CONTRIBUTOR TOOL - Cut a plugin release: bump plugin.json version, finalize CHANGELOG, update README if needed, gate on make ci,…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.