README.md

<div align="center">

```
██████╗  ██████╗████████╗ ██████╗      █████╗ ███╗   ██╗███╗   ██╗ ██████╗ ████████╗ █████╗ ████████╗███████╗
██╔══██╗██╔════╝╚══██╔══╝██╔═══██╗    ██╔══██╗████╗  ██║████╗  ██║██╔═══██╗╚══██╔══╝██╔══██╗╚══██╔══╝██╔════╝
██████╔╝██║        ██║   ██║   ██║    ███████║██╔██╗ ██║██╔██╗ ██║██║   ██║   ██║   ███████║   ██║   █████╗
██╔══██╗██║        ██║   ██║   ██║    ██╔══██║██║╚██╗██║██║╚██╗██║██║   ██║   ██║   ██╔══██║   ██║   ██╔══╝
██████╔╝╚██████╗   ██║   ╚██████╔╝    ██║  ██║██║ ╚████║██║ ╚████║╚██████╔╝   ██║   ██║  ██║   ██║   ███████╗
╚═════╝  ╚═════╝   ╚═╝    ╚═════╝     ╚═╝  ╚═╝╚═╝  ╚═══╝╚═╝  ╚═══╝ ╚═════╝    ╚═╝   ╚═╝  ╚═╝   ╚═╝   ╚══════╝
```

**A powerful Mix task to annotate your Ecto schemas with comprehensive database information**

*Inspired by Ruby's `annotate` gem and `schema_plus`*

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Elixir](https://img.shields.io/badge/Elixir-1.16+-purple.svg)](https://elixir-lang.org/)

</div>

## Features

### Core Functionality
- 🔍 Scans all Ecto migrations to extract table, column, index, and foreign key information
- 📋 Parses Ecto schemas to detect associations and relationships
- 🎨 Beautiful colored CLI output with organized sections
- 📝 **Actually writes annotations to your schema files** (not just display!)

### Display Features
- 📑 **Primary Keys**: Shows primary key type (integer id or binary_id)
- 🔗 **Foreign Keys**: Displays foreign key constraints with `on_delete` and `on_update` actions
- 📊 **Indexes**: Shows all indexes with unique flags
- 🆔 **ID Type Detection**: Identifies and displays binary_id vs integer id in relationships
- 📋 **Columns**: Displays column types, options, and constraints
- 🔗 **Associations**: Shows `belongs_to`, `has_many`, `has_one`, and `many_to_many` with ID types

### Configuration
- ⚙️ **Config File Support**: Use `.ecto_annotate.exs` for custom paths and settings
- 🎯 **Customizable Paths**: Configure migrations and schemas directories
- 🚫 **Exclude Directories**: Skip specific directories from scanning

## Installation

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

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

Then run:

```bash
mix deps.get
```

## Usage

### Display Schema Information

Run the Mix task to display schema information:

```bash
mix ecto_annotate
```

This will scan all migrations in `priv/repo/migrations/` and all schema files in `lib/`, then display a beautifully formatted output.

### Annotate Schema Files

To actually write annotations to your schema files:

```bash
mix ecto_annotate --annotate
```

This will add comprehensive comments to each schema file with:
- Table name
- Primary key type
- All columns with types and options
- All indexes with unique flags
- Foreign keys with on_delete/on_update actions
- All associations with ID types

### Remove Annotations

To remove existing annotations:

```bash
mix ecto_annotate --remove
```

### Annotation Position

Control where annotations are placed:

```bash
mix ecto_annotate --annotate --position top    # Insert at top of file
mix ecto_annotate --annotate --position before # Insert before schema declaration (default)
```

### Output Format

The default output is a colored table format. You can also output JSON:

```bash
mix ecto_annotate --format json
```

### Custom Paths

Specify custom paths for migrations and schemas:

```bash
mix ecto_annotate --migrations-path custom/migrations --schemas-path app/schemas
```

## Configuration File

Create a `.ecto_annotate.exs` file in your project root:

```elixir
%{
  migrations_path: "priv/repo/migrations",
  schemas_path: "lib",
  exclude: ["ecto_annotate", "some_other_dir"],
  position: :before,  # or :top
  show_indexes: true,
  show_foreign_keys: true,
  show_primary_keys: true
}
```

## Example Output

### CLI Display

```
================================================================================
Table: users
================================================================================
Module: TestApp.User

Primary Key:
--------------------------------------------------------------------------------
  integer id

Columns:
--------------------------------------------------------------------------------
  age : integer
  balance : decimal [default: "0.0", precision: 10, scale: 2]
  bio : text
  email : string [null: :false]
  is_active : boolean [default: :true]
  name : string

Indexes:
--------------------------------------------------------------------------------
  index_users_on_email: [email] (unique)

Foreign Keys:
--------------------------------------------------------------------------------
  user_id: user_id -> users.id (on_delete: delete_all)

Associations:
--------------------------------------------------------------------------------
  has_one :profile -> TestApp.Profile (integer id)
  has_many :posts -> TestApp.Post (integer id)
```

### Generated Annotation Comments

When you run `mix ecto_annotate --annotate`, it adds comments like this to your schema files:

```elixir
defmodule MyApp.User do
  use Ecto.Schema

  # == Schema Information
  #
  # Table name: users
  #
  # Primary Key: integer id
  #
  # Columns:
  #   age : integer
  #   balance : decimal [default: "0.0", precision: 10, scale: 2]
  #   bio : text
  #   email : string [null: :false]
  #   is_active : boolean [default: :true]
  #   name : string
  #
  # Indexes:
  #   index_users_on_email: [email] (unique)
  #
  # Foreign Keys:
  #   user_id -> users.id (on_delete: delete_all)
  #
  # Associations:
  #   has_one :profile -> MyApp.Profile (integer id)
  #   has_many :posts -> MyApp.Post (integer id)

  schema "users" do
    field :email, :string
    field :name, :string
    # ... rest of schema
  end
end
```

## Features in Detail

### Primary Key Detection
- Automatically detects primary key type from migrations
- Supports both `:id` (integer) and `:binary_id` (UUID)
- Shows in both CLI output and file annotations

### Index Display
- Lists all indexes for each table
- Marks unique indexes with `(unique)` flag
- Shows indexed columns

### Foreign Key Details
- Extracts `on_delete` actions (e.g., `:delete_all`, `:restrict`, `:nilify_all`)
- Extracts `on_update` actions
- Shows referenced table and column

### Binary ID Detection
- Detects if schemas use `@primary_key` or `@foreign_key_type` with `:binary_id`
- Displays ID type in associations (e.g., "binary_id" or "integer id")
- Helps understand relationship key types

## Development

To contribute or develop locally:

```bash
git clone <repository>
cd ecto_annotate
mix deps.get
mix test
mix format  # Format code
```

## License

MIT