ecto-thinkinglisted
Install: claude install-skill ahmedxx99/claude-code-elixir
# Ecto Thinking
Mental shifts for Ecto and data layer design. These insights challenge typical ORM patterns.
## Context = Setting That Changes Meaning
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?"
## Cross-Context References: IDs, Not Associations
```elixir
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.
## DDD Patterns as Pipelines
```elixir
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.
## Schema ≠ Database Table
| Use Case | Approach |
|----------|----------|
| Database table | Standard `schema/2` |
| Form validation only | `embedded_schema/1` |
| API request/response | Embedded schema or schemaless |
## Multiple Changesets per Schema
```elixir
def registration_changeset(user, attrs) # Full validation + password
def profil