Packages

phoenix_kit

1.7.219
1.7.220 1.7.219 1.7.218 1.7.217 1.7.216 1.7.215 1.7.214 1.7.213 1.7.212 1.7.211 1.7.210 1.7.209 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 v159.ex
Raw

lib/phoenix_kit/migrations/postgres/v159.ex

defmodule PhoenixKit.Migrations.Postgres.V159 do
@moduledoc """
V159: Publishing categories + post view counters
(`phoenix_kit_publishing` module).
## phoenix_kit_publishing_categories
Hierarchical, per-group taxonomy (WordPress-parity categories). The tree
is a nullable `parent_uuid` self-FK — same shape as V103's catalogue
categories; cycle/scope rules are context-layer responsibilities. `slug`
is unique per group (not globally — two groups can both have "news").
`name_i18n` carries per-language display names keyed by language code,
mirroring the group-name convention in the groups table's `data` JSONB.
Deleting a group cascades its categories; deleting a parent lifts its
children to the root (`ON DELETE SET NULL`) rather than orphaning a
subtree.
## phoenix_kit_publishing_post_categories
Post↔category assignment (M:N — WordPress semantics: taxonomy is
post-level, not per-version). Both sides cascade.
## phoenix_kit_publishing_post_views
Per-day view rollups: one `(post_uuid, view_date)` row incremented in
place. Totals are `SUM(count)`; time-series come free. Deduplication /
bot filtering happen app-side before the increment — the table stores
accepted counts only, no per-request rows and no reader PII.
All operations are idempotent.
"""
use Ecto.Migration
@disable_ddl_transaction true
def up(opts) do
prefix = Map.get(opts, :prefix, "public")
p = prefix_str(prefix)
execute("""
CREATE TABLE IF NOT EXISTS #{p}phoenix_kit_publishing_categories (
uuid UUID PRIMARY KEY DEFAULT #{p}uuid_generate_v7(),
group_uuid UUID NOT NULL REFERENCES #{p}phoenix_kit_publishing_groups(uuid) ON DELETE CASCADE,
parent_uuid UUID REFERENCES #{p}phoenix_kit_publishing_categories(uuid) ON DELETE SET NULL,
name VARCHAR(255) NOT NULL,
slug VARCHAR(255) NOT NULL,
name_i18n JSONB NOT NULL DEFAULT '{}',
description VARCHAR(1024),
position INTEGER NOT NULL DEFAULT 0,
inserted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT phoenix_kit_publishing_categories_group_slug_uniq UNIQUE (group_uuid, slug)
)
""")
execute("""
CREATE INDEX IF NOT EXISTS idx_publishing_categories_group
ON #{p}phoenix_kit_publishing_categories (group_uuid)
""")
execute("""
CREATE INDEX IF NOT EXISTS idx_publishing_categories_parent
ON #{p}phoenix_kit_publishing_categories (parent_uuid)
""")
execute("""
CREATE TABLE IF NOT EXISTS #{p}phoenix_kit_publishing_post_categories (
post_uuid UUID NOT NULL REFERENCES #{p}phoenix_kit_publishing_posts(uuid) ON DELETE CASCADE,
category_uuid UUID NOT NULL REFERENCES #{p}phoenix_kit_publishing_categories(uuid) ON DELETE CASCADE,
inserted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
PRIMARY KEY (post_uuid, category_uuid)
)
""")
execute("""
CREATE INDEX IF NOT EXISTS idx_publishing_post_categories_category
ON #{p}phoenix_kit_publishing_post_categories (category_uuid)
""")
execute("""
CREATE TABLE IF NOT EXISTS #{p}phoenix_kit_publishing_post_views (
post_uuid UUID NOT NULL REFERENCES #{p}phoenix_kit_publishing_posts(uuid) ON DELETE CASCADE,
view_date DATE NOT NULL,
count INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY (post_uuid, view_date)
)
""")
execute("COMMENT ON TABLE #{p}phoenix_kit IS '159'")
end
@doc """
Rolls V159 back by dropping the categories, assignment, and view tables.
**Lossy rollback:** all categories, assignments, and view counts are
lost. Back up before rolling back in production.
"""
def down(opts) do
prefix = Map.get(opts, :prefix, "public")
p = prefix_str(prefix)
execute("DROP TABLE IF EXISTS #{p}phoenix_kit_publishing_post_views CASCADE")
execute("DROP TABLE IF EXISTS #{p}phoenix_kit_publishing_post_categories CASCADE")
execute("DROP TABLE IF EXISTS #{p}phoenix_kit_publishing_categories CASCADE")
execute("COMMENT ON TABLE #{p}phoenix_kit IS '158'")
end
defp prefix_str("public"), do: "public."
defp prefix_str(prefix), do: "#{prefix}."
end