INSERT INTO custom_attribute_definitions ( account_id, attribute_name, attribute_display_name, attribute_type, attribute_model, description, created_at, updated_at ) SELECT accounts.id, definitions.attribute_name, definitions.attribute_display_name, definitions.attribute_type, 'conversation_attribute', definitions.description, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP FROM accounts CROSS JOIN (VALUES ('swt_source_url', '来源页面', 'link', '商务通访客进入咨询时的来源页面'), ('swt_source_search_term', '搜索词', 'text', '商务通 kind=8 来源信息中的搜索词'), ('swt_source_purchase_term', '购买词', 'text', '商务通 kind=8 来源信息中的购买词'), ('swt_source_keyword_id', '关键词 ID', 'text', '商务通 kind=8 来源信息中的推广关键词 ID'), ('swt_source_channel', '流量渠道', 'text', '商务通 kind=8 来源信息中的流量渠道'), ('swt_source_realtime_location', '实时位置', 'text', '商务通 kind=8 来源信息中的访客实时位置'), ('swt_source_region', '地域', 'text', '商务通 kind=8 来源信息中的地域'), ('swt_source_ad_account_id', '推广账户 ID', 'text', '商务通 kind=8 来源信息中的推广账户 ID'), ('swt_source_wakeable', '是否可唤醒', 'text', '商务通 kind=8 来源信息中的访客可唤醒状态'), ('swt_baidu_conversation_type', '百度会话类型', 'text', '商务通 kind=8 来源信息中的百度会话类型'), ('swt_baidu_agent_name', '百度智能体名称', 'text', '商务通 kind=8 来源信息中的百度智能体名称'), ('swt_baidu_ssid', '百度 SSID', 'text', '商务通 kind=8 来源信息中的百度会话 SSID') ) AS definitions(attribute_name, attribute_display_name, attribute_type, description) WHERE NOT EXISTS ( SELECT 1 FROM custom_attribute_definitions existing WHERE existing.account_id = accounts.id AND existing.attribute_name = definitions.attribute_name AND existing.attribute_model = 'conversation_attribute' AND existing.deleted_at IS NULL ); -- Historical values are backfilled by replaying the raw kind=8 events from the -- Shangwutong Connector store. PostgreSQL does not contain the original encoded -- payload, so this migration intentionally limits itself to schema definitions.