Packages

phoenix_kit

1.7.201
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 v115.ex
Raw

lib/phoenix_kit/migrations/postgres/v115.ex

defmodule PhoenixKit.Migrations.Postgres.V115 do
@moduledoc """
V115: `phoenix_kit_annotations` — drawn-on-image annotations created via
the Etcher overlay layer.
Stores user-drawn shapes (rectangle, circle, polygon, freehand) tied to
a `phoenix_kit_files` row, in image-pixel coordinates. The discussion
thread for an annotation lives in `phoenix_kit_comments` anchored to
the **file** (`resource_type = "file"`, `resource_uuid = file_uuid`)
with `metadata.annotation_uuid` carrying the back-reference — no
`comment_uuid` column on annotations is needed; the linkage is
one-directional from the comment side, and annotation-rooted comments
show up in the file's main thread alongside non-annotated ones.
Cascade-on-delete on `file_uuid`: deleting a file removes its
annotations (and the comments module's own cascade handles their
discussion threads). `creator_uuid` is nullable + `ON DELETE SET NULL`
so user removals don't take their annotations down with them.
Indexes:
* `(file_uuid)` — per-file listing in the MediaBrowser modal.
* `(creator_uuid)` — author lookups, partial on NOT NULL.
## Geometry
All shape coordinates live in image pixels:
* rectangle: `{x, y, w, h}`
* circle: `{cx, cy, r}`
* polygon: `{points: [[x, y], ...]}`
* freehand: `{points: [[x, y], ...]}`
Fresco's pan/zoom rescales them for free at render time.
"""
use Ecto.Migration
def up(opts) do
prefix = Map.get(opts, :prefix, "public")
p = prefix_str(prefix)
create_if_not_exists table(:phoenix_kit_annotations,
primary_key: false,
prefix: prefix
) do
add(:uuid, :uuid,
primary_key: true,
default: fragment("#{prefix}.uuid_generate_v7()"),
null: false
)
add(
:file_uuid,
references(:phoenix_kit_files,
column: :uuid,
type: :uuid,
on_delete: :delete_all,
prefix: prefix
),
null: false
)
add(
:creator_uuid,
references(:phoenix_kit_users,
column: :uuid,
type: :uuid,
on_delete: :nilify_all,
prefix: prefix
)
)
add(:kind, :string, size: 32, null: false)
add(:geometry, :map, null: false)
add(:style, :map)
add(:metadata, :map)
add(:position, :integer, null: false, default: 0)
timestamps(type: :utc_datetime)
end
create_if_not_exists(index(:phoenix_kit_annotations, [:file_uuid], prefix: prefix))
execute("""
CREATE INDEX IF NOT EXISTS phoenix_kit_annotations_creator_uuid_index
ON #{p}phoenix_kit_annotations (creator_uuid)
WHERE creator_uuid IS NOT NULL
""")
# DB-level guard on the kind enum — matches the four tools Etcher
# ships in v0.1. Adding a new kind means a follow-up migration that
# widens this constraint; the schema's validate_inclusion is the
# user-facing check.
execute("""
DO $$ BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE conname = 'phoenix_kit_annotations_kind_check'
AND conrelid = '#{p}phoenix_kit_annotations'::regclass
) THEN
ALTER TABLE #{p}phoenix_kit_annotations
ADD CONSTRAINT phoenix_kit_annotations_kind_check
CHECK (kind IN ('rectangle', 'circle', 'polygon', 'freehand'));
END IF;
END $$
""")
execute("COMMENT ON TABLE #{p}phoenix_kit IS '115'")
end
def down(opts) do
prefix = Map.get(opts, :prefix, "public")
p = prefix_str(prefix)
execute("DROP INDEX IF EXISTS #{p}phoenix_kit_annotations_creator_uuid_index")
drop_if_exists(table(:phoenix_kit_annotations, prefix: prefix))
execute("COMMENT ON TABLE #{p}phoenix_kit IS '114'")
end
defp prefix_str("public"), do: "public."
defp prefix_str(prefix), do: "#{prefix}."
end