BEGIN; CREATE TABLE party_role ( party_id BIGINT NOT NULL REFERENCES party(id) ON DELETE CASCADE, role_code TEXT NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT NOW(), CONSTRAINT pk_party_role PRIMARY KEY (party_id, role_code), CONSTRAINT chk_party_role_code CHECK (role_code IN ('manufacturer')) ); CREATE INDEX idx_party_role_code ON party_role(role_code); ALTER TABLE stock_lot RENAME COLUMN supplier_lot_number TO manufacturer_lot_number; ALTER TABLE stock_lot ADD COLUMN manufacturer_party_id BIGINT REFERENCES party(id) ON DELETE RESTRICT; INSERT INTO party (type, name, status, created_at, updated_at) SELECT 'supplier', MIN(TRIM(supplier_name)), 'active', NOW(), NOW() FROM stock_lot WHERE supplier_name IS NOT NULL AND TRIM(supplier_name) <> '' AND NOT EXISTS ( SELECT 1 FROM party p WHERE LOWER(TRIM(p.name)) = LOWER(TRIM(stock_lot.supplier_name)) ) GROUP BY LOWER(TRIM(supplier_name)); INSERT INTO party_role (party_id, role_code) SELECT p.id, 'manufacturer' FROM party p WHERE EXISTS ( SELECT 1 FROM stock_lot sl WHERE sl.supplier_name IS NOT NULL AND LOWER(TRIM(sl.supplier_name)) = LOWER(TRIM(p.name)) ) ON CONFLICT (party_id, role_code) DO NOTHING; UPDATE stock_lot sl SET manufacturer_party_id = p.id FROM party p WHERE sl.supplier_name IS NOT NULL AND LOWER(TRIM(sl.supplier_name)) = LOWER(TRIM(p.name)); ALTER TABLE stock_lot DROP COLUMN supplier_name; CREATE INDEX idx_stock_lot_manufacturer_party ON stock_lot(manufacturer_party_id); COMMIT;