-- sql/143-vendor-compat-template-fill.sql -- Fills transceivers.vendor_compat (Flexoptix OEM-coding-pattern reference data, -- feeds v_coding_coverage / check_switch_quality's "coding matrix" metric) for -- Flexoptix products that are missing it. -- -- Investigated 2026-07-17 (Rene: "die sind in der API alle zum auslesen drinnen"): -- vendor_compat is NOT derived per-SKU from fx_compatibilities (found rows with -- vendor_compat fully populated but fx_compatibilities completely empty, and vice -- versa -- no correlation). It is a SHARED REFERENCE TEMPLATE keyed by -- (speed_gbps, form_factor): only 11 distinct templates exist across the entire -- Flexoptix catalog, and every (speed, form_factor) family maps to exactly one -- template except 100G/SFP (2 templates -- ambiguous, deliberately excluded -- below). This was clearly seeded once (likely seed-from-npm.ts) for a subset of -- products and never propagated to new SKUs added since -- 167 of 192 missing -- rows (87%) have an unambiguous sibling template available to copy. -- -- Fill-only, idempotent, no-false-positive design matching this project's other -- migrations: only touches rows with an EMPTY vendor_compat, only copies a -- template when exactly one distinct template exists for that (speed, -- form_factor) family among Flexoptix's own catalog, never invents new data. -- Competitor vendors are explicitly OUT OF SCOPE here -- see accompanying memory -- for why blind propagation to competitor products needs a separate, more -- careful pass. with templates as ( select speed_gbps, form_factor, (array_agg(vendor_compat))[1] as template from transceivers t join vendors v on v.id = t.vendor_id where v.name = 'Flexoptix' and jsonb_array_length(coalesce(t.vendor_compat,'[]'::jsonb)) > 0 group by speed_gbps, form_factor having count(distinct vendor_compat::text) = 1 ) update transceivers t set vendor_compat = tpl.template, updated_at = now() from vendors v, templates tpl where v.id = t.vendor_id and v.name = 'Flexoptix' and tpl.speed_gbps = t.speed_gbps and tpl.form_factor = t.form_factor and jsonb_array_length(coalesce(t.vendor_compat,'[]'::jsonb)) = 0; -- Durable fix: new/updated Flexoptix products inherit the family template -- automatically once speed_gbps + form_factor are known (i.e. after the detail -- enricher runs), instead of relying on another one-off backfill. create or replace function tip_fill_vendor_compat_from_family() returns trigger language plpgsql as $$ declare fx_vendor_id uuid; tpl jsonb; tpl_count int; begin if jsonb_array_length(coalesce(NEW.vendor_compat,'[]'::jsonb)) > 0 or NEW.speed_gbps is null or NEW.form_factor is null then return NEW; end if; select id into fx_vendor_id from vendors where upper(name) like '%FLEXOPTIX%' limit 1; if NEW.vendor_id is distinct from fx_vendor_id then return NEW; end if; select count(distinct vendor_compat::text), (array_agg(vendor_compat))[1] into tpl_count, tpl from transceivers where vendor_id = fx_vendor_id and speed_gbps = NEW.speed_gbps and form_factor = NEW.form_factor and jsonb_array_length(coalesce(vendor_compat,'[]'::jsonb)) > 0 and id is distinct from NEW.id; if tpl_count = 1 then NEW.vendor_compat := tpl; end if; return NEW; end $$; comment on function tip_fill_vendor_compat_from_family() is 'BEFORE INSERT/UPDATE on transceivers: for Flexoptix products with empty vendor_compat, copies the OEM-coding-pattern template from an existing sibling of the same (speed_gbps, form_factor) family, if exactly one distinct template exists for that family. Never invents a template, never overwrites existing data, skips ambiguous families (>1 template).'; drop trigger if exists trg_fill_vendor_compat_from_family on transceivers; create trigger trg_fill_vendor_compat_from_family before insert or update of speed_gbps, form_factor, vendor_compat on transceivers for each row execute function tip_fill_vendor_compat_from_family(); insert into _migrations (filename, applied_at) select '143-vendor-compat-template-fill.sql', now() where not exists (select 1 from _migrations where filename = '143-vendor-compat-template-fill.sql');