defmodule Tarakan.Repo.Migrations.CreateCreditLedger do
  use Ecto.Migration

  def change do
    create table(:credit_entries) do
      add :account_id, references(:accounts), null: false
      add :amount, :integer, null: false
      add :kind, :string, null: false
      add :subject_type, :string
      add :subject_id, :bigint
      add :balance_after, :integer, null: false

      timestamps(type: :utc_datetime_usec, updated_at: false)
    end

    create index(:credit_entries, [:account_id, :id])

    # Mint idempotency: one entry per (kind, subject, account). Postgres treats
    # NULLs as distinct, and non-mint entries have no subject, so the index is
    # partial on rows that carry a subject.
    create unique_index(:credit_entries, [:kind, :subject_type, :subject_id, :account_id],
             name: :credit_entries_mint_unique_index,
             where: "subject_type IS NOT NULL"
           )

    alter table(:accounts) do
      add :credit_balance, :integer, null: false, default: 0
    end
  end
end
