PhoenixKit.Migrations.Postgres.V173 (phoenix_kit v2.7.0)

Copy Markdown View Source

V173: Catalogue attribute groups — reusable, translatable product options.

Four additive objects for the phoenix_kit_catalogue module. A group ("Idea doors") owns attributes ("Color", "Trim"), each attribute owns ordered values ("White", "Oak"); an item is linked to a group through an assignment table and inherits everything the group defines. This replaces nothing: the hand-typed per-item metadata in cat_items.data["meta"] stays untouched and is surfaced read/editable by the module UI.

phoenix_kit_cat_attribute_groups

Global (cross-catalogue) definition roots. name is the primary-language display text; other languages live in data per the module's JSONB translation convention. status archived ≠ deleted: an archived group stays readable on items that hold it but leaves the assignment picker.

phoenix_kit_cat_attributes

One row per characteristic in a group. key is a stable slug unique within its group — the durable identity translations can never change. kind semantics come from the product design: 'fixed' = a single value shown on the product card; 'multi' = a list of options, one of which is chosen downstream (per order line, in the parent app).

phoenix_kit_cat_attribute_values

Ordered values per attribute. is_default is explicit — display order and commercial default are independent (finishes may sort alphabetically while Oak is the standard) — with a partial unique index allowing at most one default per attribute.

phoenix_kit_cat_item_attribute_groups

Item↔group assignment. A join table from day one — the current one-group-per-item business rule is carried by the UNIQUE (item_uuid) index, so the planned multi-group future is "drop one index", not a data migration. ON DELETE RESTRICT on the group side makes archive (not delete) the only path for a group any item still references. The definition-tree FKs are RESTRICT as well — the module convention is app-level cascades (permanently_delete_* deletes values → attributes → group in one transaction, gated on no remaining assignments), never a silent DB cascade, because future exception rules and parent-app order lines will hold value UUIDs.

Downstream contract (documented, not enforced here): order lines in the parent app that record a chosen value must snapshot the resolved labels and keys at order time — the UUID reference alone is identity, not history, and later renames/translation fixes must not rewrite old orders.

All operations are idempotent.

Summary

Functions

Rolls V173 back by dropping the four tables in dependency order.

Functions

down(opts)

Rolls V173 back by dropping the four tables in dependency order.

Lossy rollback: all attribute groups, attributes, values, and item↔group assignments are lost. Items themselves — including their legacy hand-typed data["meta"] metadata — are untouched.

up(opts)