defmodule Tarakan.Repo.Migrations.CreateBounties do use Ecto.Migration def change do create table(:bounties) do add :public_id, :uuid, null: false, default: fragment("gen_random_uuid()") add :sponsor_account_id, references(:accounts), null: false add :target_type, :string, null: false add :repository_id, references(:repositories) add :pattern_key, :string add :canonical_finding_id, references(:canonical_findings) add :title, :string, null: false add :description, :string, null: false add :funding, :string, null: false add :amount_cents, :integer add :credit_amount, :integer add :take_rate, :decimal, precision: 4, scale: 3, null: false add :status, :string, null: false, default: "pending_funding" add :stripe_checkout_session_id, :string add :winner_account_id, references(:accounts) add :expires_at, :utc_datetime_usec timestamps(type: :utc_datetime_usec) end create unique_index(:bounties, [:public_id]) create index(:bounties, [:status]) create index(:bounties, [:repository_id]) create index(:bounties, [:pattern_key]) create index(:bounties, [:canonical_finding_id]) create index(:bounties, [:sponsor_account_id]) create index(:bounties, [:stripe_checkout_session_id]) # Target shape (exactly one ref matching target_type) is validated in the # Bounty changeset; see Tarakan.Market.Bounty.validate_target/1. create constraint(:bounties, :bounties_target_type_must_be_valid, check: "target_type IN ('repository','infestation','finding')" ) create constraint(:bounties, :bounties_funding_must_be_valid, check: "funding IN ('fiat','credits')" ) create constraint(:bounties, :bounties_status_must_be_valid, check: "status IN ('pending_funding','open','claimed','fulfilled','payout_pending','paid','cancelled','expired')" ) create table(:bounty_claims) do add :bounty_id, references(:bounties), null: false add :account_id, references(:accounts), null: false add :review_task_id, references(:review_tasks) add :status, :string, null: false, default: "claimed" timestamps(type: :utc_datetime_usec) end create index(:bounty_claims, [:bounty_id]) create index(:bounty_claims, [:account_id]) create constraint(:bounty_claims, :bounty_claims_status_must_be_valid, check: "status IN ('claimed','submitted','accepted','rejected','withdrawn')" ) # One active claim per hunter per bounty. create unique_index(:bounty_claims, [:bounty_id, :account_id], name: :bounty_claims_active_unique_index, where: "status IN ('claimed','submitted')" ) end end