chore: import maquina-comercial-pessoal history via subtree
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> git-subtree-dir: maquina-comercial-pessoal git-subtree-mainline:f5af038e19git-subtree-split:a9ef4d776d
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
export function normalizePhone(value = '') {
|
||||
return String(value).replace(/\D/g, '');
|
||||
}
|
||||
|
||||
export function equivalentPhoneNumbers(value = '') {
|
||||
const digits = normalizePhone(value);
|
||||
const numbers = digits ? [digits] : [];
|
||||
if (!digits.startsWith('55')) return numbers;
|
||||
const prefix = digits.slice(0, 4);
|
||||
const local = digits.slice(4);
|
||||
if (local.length === 9 && local.startsWith('9')) numbers.push(`${prefix}${local.slice(1)}`);
|
||||
if (local.length === 8 && /^[6-9]/.test(local)) numbers.push(`${prefix}9${local}`);
|
||||
return [...new Set(numbers)];
|
||||
}
|
||||
|
||||
// equivalentPhoneNumbers NAO e simetrica: ela so gera a variante de 8 digitos a
|
||||
// partir de um celular de 9 digitos quando o local comeca com 6-9. Um numero
|
||||
// como 557533334444 (local '33334444') nao volta para 5575933334444, embora o
|
||||
// caminho inverso exista — o que fazia um lado do par ser bloqueado e o outro
|
||||
// nao, e escondia o grupo da tela de revisao.
|
||||
//
|
||||
// canonicalPhoneKey resolve isso reduzindo SEMPRE o celular brasileiro de 13
|
||||
// digitos com nono digito para a forma de 12 digitos (mesma regra de remocao ja
|
||||
// usada por equivalentPhoneNumbers). Dois numeros pertencem a mesma linha
|
||||
// quando compartilham a chave canonica — uma relacao simetrica por construcao.
|
||||
export function canonicalPhoneKey(value = '') {
|
||||
const digits = normalizePhone(value);
|
||||
if (!digits.startsWith('55')) return digits;
|
||||
const prefix = digits.slice(0, 4);
|
||||
const local = digits.slice(4);
|
||||
if (local.length === 9 && local.startsWith('9')) return `${prefix}${local.slice(1)}`;
|
||||
return digits;
|
||||
}
|
||||
|
||||
// Todas as formas que um numero pode ter armazenado e que reduzem a mesma chave
|
||||
// canonica. O numero informado vem sempre primeiro (o override guarda esse
|
||||
// valor). Usado para casar contra a coluna crua `leads.whatsapp`.
|
||||
export function canonicalPhoneVariants(value = '') {
|
||||
const digits = normalizePhone(value);
|
||||
if (!digits) return [];
|
||||
const key = canonicalPhoneKey(digits);
|
||||
const variants = new Set([digits, key]);
|
||||
if (key.startsWith('55') && key.length === 12) {
|
||||
variants.add(`${key.slice(0, 4)}9${key.slice(4)}`);
|
||||
}
|
||||
return [...variants];
|
||||
}
|
||||
|
||||
// Fragmentos SQL equivalentes as funcoes JS acima. Ficam neste modulo para que
|
||||
// exista uma unica origem da regra 8/9 digitos — tests/phone.test.mjs prova que
|
||||
// as duas implementacoes concordam.
|
||||
export function normalizedSql(column) {
|
||||
return `replace(replace(replace(replace(replace(${column}, '+', ''), ' ', ''), '-', ''), '(', ''), ')', '')`;
|
||||
}
|
||||
|
||||
// Espelha equivalentPhoneNumbers: alterna entre as duas variantes brasileiras.
|
||||
export function equivalentSql(column) {
|
||||
const number = normalizedSql(column);
|
||||
return `CASE
|
||||
WHEN substr(${number}, 1, 2) = '55' AND length(${number}) = 13 AND substr(${number}, 5, 1) = '9'
|
||||
THEN substr(${number}, 1, 4) || substr(${number}, 6)
|
||||
WHEN substr(${number}, 1, 2) = '55' AND length(${number}) = 12 AND substr(${number}, 5, 1) BETWEEN '6' AND '9'
|
||||
THEN substr(${number}, 1, 4) || '9' || substr(${number}, 5)
|
||||
ELSE ${number}
|
||||
END`;
|
||||
}
|
||||
|
||||
// Espelha canonicalPhoneKey.
|
||||
export function canonicalKeySql(column) {
|
||||
const number = normalizedSql(column);
|
||||
return `CASE
|
||||
WHEN substr(${number}, 1, 2) = '55' AND length(${number}) = 13 AND substr(${number}, 5, 1) = '9'
|
||||
THEN substr(${number}, 1, 4) || substr(${number}, 6)
|
||||
ELSE ${number}
|
||||
END`;
|
||||
}
|
||||
|
||||
// A outra forma da mesma chave canonica (a de 13 digitos). Junto com
|
||||
// canonicalKeySql cobre as duas formas possiveis de armazenamento, permitindo
|
||||
// `outra.whatsapp IN (chave, variante)` — comparacao contra a coluna crua, que
|
||||
// mantem o uso de idx_leads_whatsapp.
|
||||
export function canonicalVariantSql(column) {
|
||||
const number = normalizedSql(column);
|
||||
return `CASE
|
||||
WHEN substr(${number}, 1, 2) = '55' AND length(${number}) = 13 AND substr(${number}, 5, 1) = '9'
|
||||
THEN ${number}
|
||||
WHEN substr(${number}, 1, 2) = '55' AND length(${number}) = 12
|
||||
THEN substr(${number}, 1, 4) || '9' || substr(${number}, 5)
|
||||
ELSE ${number}
|
||||
END`;
|
||||
}
|
||||
Reference in New Issue
Block a user