-- ========================================================================== -- Agencia PSI — Migracao: Retroativa WhatsApp-linked v2 -- ========================================================================== -- Criado por: Leonardo Nohama -- Data: 2026-04-21 · Sao Carlos/SP — Brasil -- -- Complementa a migration 20260421000009_retroactive_whatsapp_link: -- -- Pacientes vinculados via drawer antes do refactor ficaram sem a info -- de "vinculado WhatsApp". Algumas pecularidades: -- -- 1. Mensagens podem ser outbound (to_number) ou inbound (from_number) -- 2. O numero da conversa pode NAO existir ainda em contact_phones -- (paciente tinha outro telefone cadastrado, CRM WhatsApp linkou um numero diferente) -- -- Estrategia: -- - Pra cada paciente com conversa no channel 'whatsapp', coleta TODOS -- os numeros unicos (from_number + to_number conforme direction) -- - Pra cada numero: -- - Se paciente JA tem um contact_phone com esse numero → update pra WhatsApp + linked -- - Se NAO tem → insere novo com type='whatsapp' + linked -- ========================================================================== DO $$ DECLARE v_whatsapp_type_id UUID; BEGIN SELECT id INTO v_whatsapp_type_id FROM public.contact_types WHERE slug = 'whatsapp' AND tenant_id IS NULL LIMIT 1; IF v_whatsapp_type_id IS NULL THEN RAISE NOTICE 'Contact type WhatsApp nao encontrado'; RETURN; END IF; -- CTE: extrai (patient_id, phone_digits, first_msg_at) de conversation_messages WITH convs AS ( SELECT cm.tenant_id, cm.patient_id, CASE WHEN cm.direction = 'inbound' THEN regexp_replace(cm.from_number, '\D', '', 'g') WHEN cm.direction = 'outbound' THEN regexp_replace(cm.to_number, '\D', '', 'g') END AS phone_digits, MIN(COALESCE(cm.received_at, cm.responded_at, cm.created_at)) AS first_msg_at FROM public.conversation_messages cm WHERE cm.patient_id IS NOT NULL AND cm.channel = 'whatsapp' AND (cm.from_number IS NOT NULL OR cm.to_number IS NOT NULL) GROUP BY cm.tenant_id, cm.patient_id, 3 HAVING CASE WHEN cm.direction = 'inbound' THEN regexp_replace(cm.from_number, '\D', '', 'g') WHEN cm.direction = 'outbound' THEN regexp_replace(cm.to_number, '\D', '', 'g') END IS NOT NULL ), -- Atualiza phones que ja existem updated AS ( UPDATE public.contact_phones cp SET contact_type_id = v_whatsapp_type_id, whatsapp_linked_at = COALESCE(cp.whatsapp_linked_at, convs.first_msg_at) FROM convs WHERE cp.entity_type = 'patient' AND cp.entity_id = convs.patient_id AND cp.number = convs.phone_digits RETURNING cp.entity_id, cp.number ) -- Insere phones que nao existem ainda pro paciente INSERT INTO public.contact_phones (tenant_id, entity_type, entity_id, contact_type_id, number, is_primary, whatsapp_linked_at, position) SELECT convs.tenant_id, 'patient', convs.patient_id, v_whatsapp_type_id, convs.phone_digits, false, -- nao e primary (paciente ja tem outro) convs.first_msg_at, 100 -- final da lista FROM convs WHERE NOT EXISTS ( SELECT 1 FROM public.contact_phones cp WHERE cp.entity_type = 'patient' AND cp.entity_id = convs.patient_id AND cp.number = convs.phone_digits ) AND length(convs.phone_digits) BETWEEN 8 AND 15; RAISE NOTICE 'Retroactive WhatsApp link v2 complete'; END $$; -- ========================================================================== -- FIM DA MIGRACAO -- ==========================================================================