README.md

# Simple Schema Context

A simple library to replace boilerplate Phoenix contexts with common CRUD operations. This library provides an easy way to standardize your contexts across a Phoenix application.

## Installation

Add `simple_schema_context` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:simple_schema_context, "~> 0.1.0"}
  ]
end
```

## Getting Started

Create your schema module and use SimpleSchemaContext.Schema, providing your Repo module:

```elixir
defmodule MyApp.Blog.Post do
  use SimpleSchemaContext.Schema, repo: MyApp.Repo
  
  schema "posts" do
    field :title, :string
    field :body, :string
    
    timestamps()
  end
  
  def changeset(post, attrs) do
    post
    |> cast(attrs, [:title, :body])
    |> validate_required([:title, :body])
  end
end
```

## Usage

Once you've set up your schema, you can immediately use the built-in context functions:

### Reading Data

```elixir
# List all records
posts = Post.list()

# Get a specific record (returns {:ok, post} or {:error, :not_found})
{:ok, post} = Post.fetch(id: 123)

# Get a specific record with preloads
{:ok, post} = Post.fetch([id: 123], preload: [:comments, :author])

# Get a record or raise an error
post = Post.get!(123)

# List with filtering (supports associations)
posts = Post.list(%{
  "title" => "My Post",                  # Filter by title
  "author.name" => "John",               # Filter by association
  "metadata->published" => true          # Filter by map field
})

# List with complex filters
posts = Post.list(%{
  "title" => ["like", "Search Term"],    # ILIKE search
  "views" => ["gt", 100],                # Greater than
  "tags" => ["in", ["elixir", "phoenix"]] # IN query
})
```

### Creating and Updating

```elixir
# Create a new record
{:ok, post} = Post.create(%{title: "New Post", body: "Content"})

# Create with a custom changeset function
{:ok, post} = Post.create(%{title: "New Post"}, changeset: &Post.custom_changeset/2)

# Update a record
{:ok, updated_post} = Post.update(post, %{title: "Updated Title"})

# Get a changeset for validation
changeset = Post.change(post, %{title: ""})
```

### Deleting

```elixir
{:ok, deleted_post} = Post.delete(post)
```

## Form Helpers

SimpleSchemaContext also includes helpers for form handling:

```elixir
# Transform entities to options for a select input
options = FormHelper.entities_to_options(users, label_key: :name)

# Add a nil option to a select
options = FormHelper.add_nil_option(options, label: "Select a user")

# Handle many-to-many relationships
def changeset(post, attrs) do
  post
  |> cast(attrs, [:title, :body])
  |> validate_required([:title, :body])
  |> maybe_put_many_assoc(:tags, &Tags.list_by_ids/1)
end
```

## License

This library is released under the MIT License.