Packages

phoenix_kit

1.7.104
1.7.208 1.7.207 1.7.206 1.7.205 1.7.204 1.7.203 1.7.202 1.7.201 1.7.200 1.7.199 1.7.198 1.7.197 1.7.196 1.7.194 1.7.193 1.7.192 1.7.191 1.7.190 1.7.189 1.7.187 1.7.186 1.7.185 1.7.184 1.7.183 1.7.182 1.7.181 1.7.180 1.7.179 1.7.178 1.7.177 1.7.176 1.7.175 1.7.174 1.7.173 1.7.172 1.7.171 1.7.170 1.7.169 1.7.168 1.7.167 1.7.166 1.7.165 1.7.164 1.7.162 1.7.161 1.7.160 1.7.159 1.7.157 1.7.156 1.7.155 1.7.154 1.7.153 1.7.152 1.7.151 1.7.150 1.7.149 1.7.146 1.7.145 1.7.144 1.7.143 1.7.138 1.7.133 1.7.132 1.7.131 1.7.130 1.7.128 1.7.126 1.7.125 1.7.121 1.7.120 1.7.119 1.7.118 1.7.117 1.7.116 1.7.115 1.7.114 1.7.113 1.7.112 1.7.111 1.7.110 1.7.109 1.7.108 1.7.107 1.7.106 1.7.105 1.7.104 1.7.103 1.7.102 1.7.101 1.7.100 1.7.99 1.7.98 1.7.97 1.7.96 1.7.95 1.7.94 1.7.93 1.7.92 1.7.91 1.7.90 1.7.89 1.7.88 1.7.87 1.7.86 1.7.85 1.7.84 1.7.83 1.7.82 1.7.81 1.7.80 1.7.79 1.7.78 1.7.77 1.7.76 1.7.75 1.7.74 1.7.71 1.7.70 1.7.69 1.7.66 1.7.65 1.7.64 1.7.63 1.7.62 1.7.61 1.7.59 1.7.58 1.7.57 1.7.56 1.7.55 1.7.54 1.7.53 1.7.52 1.7.51 1.7.49 1.7.44 1.7.43 1.7.42 1.7.41 1.7.39 1.7.38 1.7.37 1.7.36 1.7.34 1.7.33 1.7.31 1.7.30 1.7.29 1.7.28 1.7.27 1.7.26 1.7.25 1.7.24 1.7.23 1.7.22 1.7.21 1.7.20 1.7.19 1.7.18 1.7.17 1.7.16 1.7.15 1.7.14 1.7.13 1.7.12 1.7.11 1.7.10 1.7.9 1.7.8 1.7.7 1.7.6 1.7.5 1.7.4 1.7.3 1.7.2 1.7.1 1.7.0 1.6.20 1.6.19 1.6.18 1.6.17 1.6.16 1.6.15 1.6.14 1.6.13 1.6.12 1.6.11 1.6.10 1.6.9 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.2 1.3.1 1.3.0 1.2.10 1.2.9 1.2.8 1.2.7 1.2.5 1.2.4 1.2.2 1.2.1 1.2.0 1.1.0 1.0.0

A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more

Current section

Files

Jump to
phoenix_kit lib phoenix_kit migrations postgres v91.ex
Raw

lib/phoenix_kit/migrations/postgres/v91.ex

defmodule PhoenixKit.Migrations.Postgres.V91 do
@moduledoc """
V91: Add Locations tables.
Creates the three tables needed by the PhoenixKitLocations module:
- `phoenix_kit_location_types` — user-defined location categories (Showroom, Storage, etc.)
- `phoenix_kit_locations` — physical locations with full address, contact, features
- `phoenix_kit_location_type_assignments` — many-to-many join (a location can have multiple types)
"""
use Ecto.Migration
def up(opts) do
prefix = Map.get(opts, :prefix, "public")
p = prefix_str(prefix)
schema = if prefix == "public", do: "public", else: prefix
# ── Location Types ─────────────────────────────────────────────
create_if_not_exists table(:phoenix_kit_location_types,
primary_key: false,
prefix: prefix
) do
add(:uuid, :uuid, primary_key: true, default: fragment("uuid_generate_v7()"))
add(:name, :string, null: false, size: 255)
add(:description, :text)
add(:status, :string, default: "active", size: 20)
add(:data, :map, default: %{})
timestamps(type: :utc_datetime)
end
create_if_not_exists(index(:phoenix_kit_location_types, [:status], prefix: prefix))
# ── Locations ──────────────────────────────────────────────────
create_if_not_exists table(:phoenix_kit_locations,
primary_key: false,
prefix: prefix
) do
add(:uuid, :uuid, primary_key: true, default: fragment("uuid_generate_v7()"))
add(:name, :string, null: false, size: 255)
add(:description, :text)
add(:public_notes, :text)
# Address (international standard)
add(:address_line_1, :string, size: 500)
add(:address_line_2, :string, size: 500)
add(:city, :string, size: 255)
add(:state, :string, size: 255)
add(:postal_code, :string, size: 20)
add(:country, :string, size: 255)
# Contact
add(:phone, :string, size: 50)
add(:email, :string, size: 255)
add(:website, :string, size: 500)
# Internal
add(:notes, :text)
add(:status, :string, default: "active", size: 20)
# Features (JSONB with boolean flags)
add(:features, :map, default: %{})
# Multilang translations
add(:data, :map, default: %{})
timestamps(type: :utc_datetime)
end
create_if_not_exists(index(:phoenix_kit_locations, [:status], prefix: prefix))
# ── Location ↔ Type join (many-to-many) ────────────────────────
create_if_not_exists table(:phoenix_kit_location_type_assignments,
primary_key: false,
prefix: prefix
) do
add(:uuid, :uuid, primary_key: true, default: fragment("uuid_generate_v7()"))
add(
:location_uuid,
references(:phoenix_kit_locations,
column: :uuid,
type: :uuid,
on_delete: :delete_all,
prefix: prefix
),
null: false
)
add(
:location_type_uuid,
references(:phoenix_kit_location_types,
column: :uuid,
type: :uuid,
on_delete: :delete_all,
prefix: prefix
),
null: false
)
timestamps(type: :utc_datetime)
end
create_if_not_exists(
unique_index(
:phoenix_kit_location_type_assignments,
[:location_uuid, :location_type_uuid],
prefix: prefix
)
)
# ── Idempotent column additions (for existing V90 installs) ────
execute("""
DO $$
BEGIN
-- Drop old columns that were renamed/removed
IF EXISTS (
SELECT FROM information_schema.columns
WHERE table_schema = '#{schema}'
AND table_name = 'phoenix_kit_locations'
AND column_name = 'location_type_uuid'
) THEN
ALTER TABLE #{p}phoenix_kit_locations DROP COLUMN location_type_uuid;
END IF;
IF EXISTS (
SELECT FROM information_schema.columns
WHERE table_schema = '#{schema}'
AND table_name = 'phoenix_kit_locations'
AND column_name = 'address'
) THEN
ALTER TABLE #{p}phoenix_kit_locations RENAME COLUMN address TO address_line_1;
END IF;
-- Add new columns if missing
IF NOT EXISTS (
SELECT FROM information_schema.columns
WHERE table_schema = '#{schema}'
AND table_name = 'phoenix_kit_locations'
AND column_name = 'description'
) THEN
ALTER TABLE #{p}phoenix_kit_locations ADD COLUMN description TEXT;
END IF;
IF NOT EXISTS (
SELECT FROM information_schema.columns
WHERE table_schema = '#{schema}'
AND table_name = 'phoenix_kit_locations'
AND column_name = 'public_notes'
) THEN
ALTER TABLE #{p}phoenix_kit_locations ADD COLUMN public_notes TEXT;
END IF;
IF NOT EXISTS (
SELECT FROM information_schema.columns
WHERE table_schema = '#{schema}'
AND table_name = 'phoenix_kit_locations'
AND column_name = 'address_line_2'
) THEN
ALTER TABLE #{p}phoenix_kit_locations ADD COLUMN address_line_2 VARCHAR(500);
END IF;
IF NOT EXISTS (
SELECT FROM information_schema.columns
WHERE table_schema = '#{schema}'
AND table_name = 'phoenix_kit_locations'
AND column_name = 'state'
) THEN
ALTER TABLE #{p}phoenix_kit_locations ADD COLUMN state VARCHAR(255);
END IF;
IF NOT EXISTS (
SELECT FROM information_schema.columns
WHERE table_schema = '#{schema}'
AND table_name = 'phoenix_kit_locations'
AND column_name = 'postal_code'
) THEN
ALTER TABLE #{p}phoenix_kit_locations ADD COLUMN postal_code VARCHAR(20);
END IF;
IF NOT EXISTS (
SELECT FROM information_schema.columns
WHERE table_schema = '#{schema}'
AND table_name = 'phoenix_kit_locations'
AND column_name = 'website'
) THEN
ALTER TABLE #{p}phoenix_kit_locations ADD COLUMN website VARCHAR(500);
END IF;
IF NOT EXISTS (
SELECT FROM information_schema.columns
WHERE table_schema = '#{schema}'
AND table_name = 'phoenix_kit_locations'
AND column_name = 'features'
) THEN
ALTER TABLE #{p}phoenix_kit_locations ADD COLUMN features JSONB NOT NULL DEFAULT '{}';
END IF;
-- Drop unique index on location_types.name if exists (names don't need to be unique)
IF EXISTS (
SELECT FROM pg_indexes
WHERE schemaname = '#{schema}'
AND tablename = 'phoenix_kit_location_types'
AND indexname = 'phoenix_kit_location_types_name_index'
) THEN
DROP INDEX #{p}phoenix_kit_location_types_name_index;
END IF;
-- Fix address_line_1 type if it was created as text (from early V90)
IF EXISTS (
SELECT FROM information_schema.columns
WHERE table_schema = '#{schema}'
AND table_name = 'phoenix_kit_locations'
AND column_name = 'address_line_1'
AND data_type = 'text'
) THEN
ALTER TABLE #{p}phoenix_kit_locations
ALTER COLUMN address_line_1 TYPE VARCHAR(500);
END IF;
END $$;
""")
# Index on location_uuid for type assignment lookups
create_if_not_exists(
index(:phoenix_kit_location_type_assignments, [:location_uuid], prefix: prefix)
)
execute("COMMENT ON TABLE #{p}phoenix_kit IS '91'")
end
def down(opts) do
prefix = Map.get(opts, :prefix, "public")
p = prefix_str(prefix)
drop_if_exists(table(:phoenix_kit_location_type_assignments, prefix: prefix))
drop_if_exists(table(:phoenix_kit_locations, prefix: prefix))
drop_if_exists(table(:phoenix_kit_location_types, prefix: prefix))
execute("COMMENT ON TABLE #{p}phoenix_kit IS '90'")
end
defp prefix_str("public"), do: "public."
defp prefix_str(prefix), do: "#{prefix}."
end