1.5 KiB · text History b868907
defmodule GitGud.Repo.Migrations.CreateAvatars do
  use Ecto.Migration

  @moduledoc """
  Uploaded avatars for users, organizations and repositories.

  One table rather than three sets of columns: the three owners want
  exactly the same fields, and `Labels` already established the
  `{target_type, id}` shape in this schema. It also means the serving
  path and the settings form are written once.

  The bytes live in `GitGud.Storage`, like LFS objects and CI
  artifacts. Only the pointer and the metadata needed to serve a
  response — content type, size, digest — are here.

  No foreign key, for the same reason `labels` has none: a polymorphic
  owner can't have one. Deletion is handled by the contexts that own
  the rows.
  """

  def change do
    create table(:avatars) do
      add :owner_type, :string, null: false
      add :owner_id, :bigint, null: false

      add :storage_bucket, :string, null: false
      add :storage_key, :string, null: false
      add :content_type, :string, null: false
      add :size, :integer, null: false, default: 0

      # Content digest, which doubles as the cache buster: the serving
      # URL carries it, so a replaced avatar is a different URL and no
      # proxy or browser has to be asked politely to forget the old one.
      add :sha256, :string, null: false

      timestamps(type: :utc_datetime)
    end

    # One avatar per owner. The upsert on replace depends on this.
    create unique_index(:avatars, [:owner_type, :owner_id])
  end
end