elixir
Write and refactor idiomatic Elixir functions, modules, and data structures. Use for pattern matching, control flow, error handling, protocols, behaviours, and…
Design and debug Elixir persistence with Ecto. Use for schemas, changesets, queries, preloads, transactions, migrations, multi-tenancy, and data access through application contexts. Covers database query performance and connection pools.
$ npx -y skills add georgeguimaraes/claude-code-elixir --skill ecto --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/ectoContext preview
The summary Claude sees to decide when to auto-load this skill.
Design and debug Elixir persistence with Ecto. Use for schemas, changesets, queries, preloads, transactions, migrations, multi-tenancy, and data access through application contexts. Covers database query performance and connection pools.
name: ecto description: Design and debug Elixir persistence with Ecto. Use for schemas, changesets, queries, preloads, transactions, migrations, multi-tenancy, and data access through application contexts. Covers database query performance and connection pools.
Model persistence, compose queries, and keep data access within application boundaries.
Context isn't just a namespace—it changes what words mean. "Product" means different things in Checkout (SKU, name), Billing (SKU, cost), and Fulfillment (SKU, warehouse). Each bounded context may have its OWN Product schema/table.
**Think top-down:** Subdomain → Context → Entity. Not "What context does Product belong to?" but "What is a Product in this business domain?"
schema "cart_items" do field :product_id, :integer # Reference by ID # NOT: belongs_to :product, Catalog.Product end
Query through the context, not across associations. Keeps contexts independent and testable.
def create_product(params) do params |> Products.build() # Factory: unstructured → domain |> Products.validate() # Aggregate: enforce invariants |> Products.insert() # Repository: persist end
Use events (as data structs) to compose bounded contexts with minimal coupling.
| Use Case | Approach | |----------|----------| | Database table | Standard `schema/2` | | Form validation only | `embedded_schema/1` | | API request/response | Embedded schema or schemaless |
def registration_changeset(user, attrs) # Full validation + password def profile_changeset(user, attrs) # Name, bio only def admin_changeset(user, attrs) # Role, verified_at
Different operations = different changesets.
add :post_id, references(:posts, with: [org_id: :org_id], match: :full)
Use `prepare_query/3` for automatic scoping. Raise if `org_id` missing.
| Approach | Best For | |----------|----------| | Separate preloads | Has-many with many records (less memory) | | Join preloads | Belongs-to, has-one (single query) |
Join preloads can use 10x more memory for has-many.
> "If you have a CRUD bounded context, go for it. No need to add complexity."
Use generators for simple cases. Add DDD patterns only when business logic demands it.
In multi-tenant apps, CTEs don't get the parent query's prefix.
**Fix:** Explicitly set prefix: `%{recursive_query | prefix: "tenant"}`
**pgbouncer:** Use `prepare: :unnamed` (disables prepared statements, keeps parameterized queries).
More pools with fewer connections = better for benchmarks. **But** with mixed fast/slow queries, a single larger pool gives better latency.
**Rule:** `pool_count` for uniform workloads, larger `pool_size` for real apps.
Cachex, separate GenServers, or anything outside the test process won't share the sandbox transaction.
**Fix:** Make the external service use the test process, or accept it's not in the same transaction.
PostgreSQL rejects null bytes even though they're valid UTF-8.
**Fix:** Sanitize at boundaries: `String.replace(string, "\x00", "")`
has_many :comments, Comment, preload_order: [desc: :inserted_at]
Note: Doesn't work for `through` associations.
Ecto.Migrator.run(Repo, [{0, Migration1}, {1, Migration2}], :up, opts)**Any of these? Re-read the Gotchas section.**
Elixir development guidance for coding agents, with optional Mix checks and Expert language server integration. Five skills covering language idioms, Phoenix interfaces, Ecto persistence, OTP processes, and Oban jobs.
Write and refactor idiomatic Elixir functions, modules, and data structures. Use for pattern matching, control flow, error handling, protocols, behaviours, and…
Build and debug durable background jobs with Oban and Oban Pro. Use for workers, job argument serialization, retries, scheduled or recurring jobs, uniqueness,…
Design and debug Elixir runtime concurrency, process state, and supervision. Use for GenServer, Supervisor, Task, Registry, ETS, process bottlenecks, and…
Build and debug Phoenix web interfaces and HTTP endpoints. Use for LiveView lifecycle and data loading, components, forms, routes, controllers, Plug, channels,…