V151: supplier-info source/primary columns + CRM email normalization.
Completes the V149 phoenix_kit_cat_item_supplier_info junction with the
two columns the merged phoenix_kit_catalogue sourcing layer (catalogue
PR #44) reads and writes — without them every junction INSERT/UPDATE
crashes on an undefined column:
supplier_source—'crm_company' | 'crm_contact' | 'local'(CHECK). Disambiguates the polymorphic softsupplier_uuid(a CRM company, a CRM contact, or a localcat_suppliersrow) so the resolver and thephoenix_kit_catalogue.audit_supplier_refsconsistency report route lookups without a trial cascade.is_primary+ partial-unique index (at most one primary row per item). The catalogue context auto-promotes the first linked supplier and offers "make primary";Suppliers.primary_for_item/1backs the warehouse resolver.
The V146 scalar phoenix_kit_cat_items.primary_supplier_uuid is left
untouched (V149's design keeps it); the merged catalogue schema simply no
longer maps it.
Also normalises the CRM party email columns to citext
(phoenix_kit_crm_contacts.email, phoenix_kit_crm_companies.email):
case-insensitive matching is a prerequisite for the CRM v2 backfill
(match-by-email) and the user↔contact bridge (connect_user/2 finds or
creates auth users by email). citext is a core dependency since V01
(phoenix_kit_users.email), so ensure_extension!/1 is a no-op on any
existing install.
citext conversion cost: ALTER COLUMN … TYPE citext takes an ACCESS
EXCLUSIVE lock and rewrites the table — plan a maintenance window for
large CRM tables. Neither email column carries an index or a unique
constraint anywhere in the chain, so no index rebuild happens and no
latent case-duplicate can surface as a violation; if a unique index on
email is ever added later, case-variant duplicates must be resolved
first (citext compares case-insensitively).
All operations are idempotent.