Skip to content

PRD — Unificar Máscara de Inputs no blu-utils #32

@devin-ai-integration

Description

@devin-ai-integration

PRD — Unificar Máscara de Inputs no blu-utils

Jira: OR-145
Tipo: Feature Técnica
Plataforma(s) alvo: Web
Plataforma(s) com tracking: Web (impacto indireto — sem novos eventos)
Status: Draft
Autor: Vertical Origination
Data: 2026-05-06
Versão: 1.1


1. Contexto e Problema

A Blu possui a biblioteca compartilhada @useblu/utils (repositório Pagnet/blu-utils) que centraliza normalizers, formatters e utilitários de uso geral pelos Micro-Frontends (MFEs). O @useblu/utils já é re-exportado pelo mfe-core via Module Federation (acessível como core/blu-utils), o que significa que todos os MFEs já possuem acesso direto à biblioteca sem necessidade de instalação individual — basta importar de core/blu-utils. Entretanto, as máscaras de input — CPF, CNPJ, telefone, CEP, código de barras, data, moeda, entre outras — não estão centralizadas nesta biblioteca.

Atualmente, 34 repositórios MFE possuem seu próprio arquivo local de máscaras (src/utils/masks.ts ou src/utils/masks.js), todos usando a dependência vanilla-masker. Os arquivos são praticamente idênticos entre si, com pequenas variações.

Este cenário gera dois problemas críticos:

  1. Manutenção pulverizada: Qualquer correção ou evolução em uma máscara precisa ser replicada manualmente em dezenas de repositórios, gerando risco de inconsistência e retrabalho.

  2. Bloqueio para CNPJ Alfanumérico: A Receita Federal está adotando o novo formato de CNPJ alfanumérico (contendo letras e números). As máscaras atuais utilizam padrões exclusivamente numéricos (99.999.999/9999-99) e a lib vanilla-masker remove caracteres não-numéricos com \D regex, tornando impossível suportar o novo formato sem alterar cada repositório individualmente.

O card pai OR-98 — Suporte a CNPJ Alfanumérico, pertencente ao epic OR-47 — Aceitar o novo formato de CNPJ (com letras e números), exige que toda a plataforma suporte o CNPJ alfanumérico. Esta feature é a etapa fundacional: centralizar as máscaras no blu-utils para que a atualização do formato de CNPJ precise ser feita em um único lugar.

Consulta ao Redshift não aplicável: Feature de infraestrutura de biblioteca sem dados históricos de comportamento de usuário a serem levantados. Após a migração dos MFEs, métricas de adoção poderão ser acompanhadas via dependência no package.json de cada repositório.


2. Objetivo

Centralizar todas as funções de máscara de input na biblioteca @useblu/utils (Pagnet/blu-utils), de forma que:

  1. Toda máscara de input usada nos MFEs esteja disponível como export do @useblu/utils
  2. O suporte a CNPJ alfanumérico já esteja incorporado na máscara de CNPJ desde o início
  3. Os MFEs possam migrar para o consumo centralizado via core/blu-utils (re-export do mfe-core), sem necessidade de instalar @useblu/utils individualmente em cada repositório — todos os MFEs já possuem acesso via Module Federation
  4. Futuras atualizações de máscaras precisem ser feitas em um único ponto, com propagação automática para todos os MFEs via mfe-core

3. Personas / Sistemas Impactados

Ator Tipo Impacto
Industria (Fornecedor) Usuário final Inputs com máscara de CNPJ passarão a aceitar o formato alfanumérico; demais campos mantêm comportamento idêntico
Varejo (Lojista) Usuário final Mesmo impacto — inputs de CNPJ, CPF, telefone, CEP continuam funcionando, com suporte a CNPJ alfanumérico
MFEs (34 repositórios) Sistema interno Passarão a consumir máscaras do @useblu/utils em vez de arquivos locais + vanilla-masker
mfe-core Sistema interno Já re-exporta @useblu/utils via Module Federation como core/blu-utils — as novas funções de máscara ficarão disponíveis automaticamente para todos os MFEs sem necessidade de instalação individual
Desenvolvedores Frontend Usuário interno Ponto único de manutenção para máscaras; DX melhorada
Grupo Econômico Contexto de visualização Sem impacto — ver análise na ETAPA 5.5

4. Escopo

Dentro do Escopo (In Scope)

  • Implementar no @useblu/utils todas as funções de máscara de input encontradas nos arquivos locais dos MFEs:
    • Máscaras de padrão: CPF, CNPJ (alfanumérico), CPF/CNPJ combinado, telefone, telefone com IDD (phone_idd), CEP, código de barras (convênio e título), data, DARF, agência bancária (bank_branch), conta bancária (bank_account) por código de compensação
    • Máscaras monetárias: moeda (BRL) e percentual
    • Máscaras numéricas
    • Funções auxiliares: maskInput (aplicar máscara a elemento DOM), maskValue (aplicar máscara a string, com suporte a options.compensationCode para máscaras bancárias dinâmicas), maskComplete (verificar se valor está completo para a máscara, com suporte a compensationCode), maskCpf, maskCpfOrCnpj, maskBankBranch, maskBankAccount
    • Interface MaskValueOptions exportada para tipagem das options de maskValue
  • Garantir que a máscara de CNPJ suporte o formato alfanumérico (letras + números no corpo do CNPJ)
  • Atualizar formatCnpj, normalizeCpfOrCnpj, isCnpj e stripNumbers existentes no blu-utils para suportar CNPJ alfanumérico
  • Exportar todas as novas funções e constantes de máscaras via src/index.ts
  • Testes unitários para todas as funções de máscara
  • Documentação no README com exemplos de uso

Fora do Escopo (Out of Scope)

  • Migrar os MFEs individuais para consumir as máscaras via core/blu-utils em vez dos arquivos locais (será feita em etapa posterior, conforme descrito no card OR-145). Nota: como o mfe-core já re-exporta @useblu/utils, a migração nos MFEs consiste apenas em trocar os imports de ./utils/masks para core/blu-utils — sem necessidade de instalar dependências adicionais
  • Remover vanilla-masker dos MFEs e os arquivos locais masks.ts/masks.js (consequência da migração)
  • Alterar validação de CNPJ no backend (Pagnet/pagnet ou microserviços)
  • Suporte a máscaras de input em plataformas mobile (iOS/Android)

Fases Futuras

  • Fase 2: Migrar cada MFE para consumir máscaras via core/blu-utils (import do Module Federation), removendo os arquivos locais masks.ts/masks.js e a dependência vanilla-masker. Como todos os MFEs já referenciam o mfe-core, não será necessário instalar @useblu/utils em cada repositório individualmente
  • Fase 3: Deprecar e remover funções de máscara duplicadas dentro dos MFEs

5. Comportamento Esperado

⚠️ UX obrigatório: diretrizes de conventions/ux-best-practices.md aplicadas nesta seção.

Fluxo Principal

Esta feature é uma mudança de infraestrutura de biblioteca. O fluxo principal é de consumo por desenvolvedores:

  1. Desenvolvedor importa funções de máscara de core/blu-utils (re-export via Module Federation do mfe-core) — não é necessário instalar @useblu/utils no package.json do MFE, pois todos os MFEs já possuem acesso ao mfe-core
  2. Aplica máscara a um campo de input usando maskInput(inputElement, 'cnpj') ou formata um valor com maskValue('12ABC345DE67FG', 'cnpj')
  3. A máscara formata corretamente o valor, inclusive para CNPJ alfanumérico

Exemplo de import no MFE:

// Direto via Module Federation (recomendado — já disponível em todos os MFEs)
import { maskValue, maskInput, masks } from 'core/blu-utils';

// Alternativa: import direto do pacote npm (caso o MFE tenha @useblu/utils instalado)
import { maskValue, maskInput, masks } from '@useblu/utils';

Comportamento no Contexto de Grupo Econômico

Sem impacto no Grupo Econômico — a centralização de máscaras no blu-utils não altera nenhuma lógica específica do Grupo Econômico. Os inputs de CNPJ dentro do mfe-economic-group-configuration e do seletor ClientSelector continuarão funcionando normalmente, com o benefício adicional de suportar CNPJ alfanumérico após a migração (Fase 2).

Comportamento das Máscaras

CNPJ Numérico (formato atual)

  • Input: 11222333000181
  • Output: 11.222.333/0001-81
  • Padrão: XX.XXX.XXX/XXXX-XX (onde X = dígito)

CNPJ Alfanumérico (novo formato)

  • Input: 12ABC34501DE35
  • Output: 12.ABC.345/01DE-35
  • Padrão: XX.XXX.XXX/XXXX-XX (onde X = dígito ou letra)
  • Regra: A máscara mantém a mesma estrutura posicional (pontos, barra, hífen), mas aceita caracteres alfanuméricos nas posições do corpo do CNPJ

CPF (sem alteração)

  • Input: 93231097037
  • Output: 932.310.970-37
  • Padrão: ###.###.###-## (onde # = dígito)

CPF/CNPJ Combinado

  • Se o valor limpo tiver até 11 caracteres → aplica máscara de CPF
  • Se o valor limpo tiver mais de 11 caracteres → aplica máscara de CNPJ (alfanumérico)

Telefone (sem alteração)

  • Input: 11999998888
  • Output: (11) 99999-8888

Telefone com IDD (novo — mfe-pix)

  • Input: 5511999998888
  • Output: +55 (11) 99999-8888
  • Padrão: +99 (99) 99999-9999
  • Chave: phone_idd

CEP (sem alteração)

  • Input: 01310100
  • Output: 01310-100

Moeda (sem alteração)

  • Input: 150000Output: 1.500,00 (com opções de precisão, separador, delimitador, unidade)

Agência Bancária (novo — bank_branch)

  • Sem código de compensação (noop): maskValue('1234', 'bank_branch')1234 (padrão 9999)
  • Com código Itaú (341): maskValue('123456', 'bank_branch', { compensationCode: '341' })12345-6 (padrão 99999-9)
  • Chave: bank_branch

Conta Bancária (novo — bank_account)

  • Sem código (noop): maskValue('1234567890123', 'bank_account')123456789012-3 (padrão 999999999999-9)
  • Com código BB (1): maskValue('123456789', 'bank_account', { compensationCode: '1' })12345678-9
  • Com código Bradesco (237): maskValue('12345678', 'bank_account', { compensationCode: '237' })1234567-8
  • Com código Itaú (341): maskValue('123456', 'bank_account', { compensationCode: '341' })12345-6
  • Chave: bank_account

Máscara bancária dinâmica via maskValue (novo — compensationCode)

O maskValue aceita um terceiro parâmetro options com compensationCode para resolver a máscara do banco em runtime:

import { maskValue } from 'core/blu-utils';

// Sem compensationCode → usa padrão noop
maskValue('1234', 'bank_branch'); // '1234'
maskValue('1234567890123', 'bank_account'); // '123456789012-3'

// Com compensationCode → resolve a máscara do banco
maskValue('123456', 'bank_branch', { compensationCode: '341' }); // '12345-6' (Itaú)
maskValue('123456789', 'bank_account', { compensationCode: '1' }); // '12345678-9' (BB)

Isso elimina a necessidade de dot-notation (bank.341.branch) usada nos MFEs locais e permite migração limpa sem alterar o InputControl.

Estados de Tela (para MFEs que consomem as máscaras)

Tela Default Loading Sucesso Erro Vazio
Input com máscara Campo vazio com placeholder indicando formato esperado N/A — máscara é aplicada em tempo real (keyup) Valor formatado corretamente conforme a máscara Valor parcialmente formatado; validação do formulário indica campo inválido Campo vazio — placeholder exibe formato esperado

Comportamento em Erro / Falha

  • Valor inválido para a máscara: a função retorna o valor parcialmente formatado (best-effort), sem lançar exceção
  • Valor nulo/undefined: retorna string vazia ''
  • Tipo de máscara desconhecido: maskInput e maskValue retornam false / não aplicam transformação
  • Mensagens de erro para campos com CNPJ inválido devem seguir o padrão Web (max 30 palavras): "CNPJ inválido. Verifique o número informado."

Comportamento de Borda (Edge Cases)

  • CNPJ alfanumérico com letras maiúsculas e minúsculas: normalizar para maiúsculas antes de aplicar a máscara
  • CNPJ com caracteres especiais injetados: strip de caracteres que não sejam alfanuméricos antes de aplicar a máscara
  • Campo com máscara CPF/CNPJ: transição dinâmica — ao digitar o 12º caractere, a máscara muda de CPF para CNPJ
  • Copiar e colar valor com formatação: strip de separadores antes de reaplicar a máscara
  • CNPJ alfanumérico em campo que só aceita numérico (legado): a função centralizada deve aceitar ambos; a validação do campo determina a restrição

6. Plano de Tracking de Eventos (blu-lytics)

Tracking não aplicável para esta feature: é uma refatoração de infraestrutura de biblioteca (@useblu/utils) que centraliza máscaras de input sem alterar fluxos de usuário visíveis. Não há novas telas, ações ou fluxos que justifiquem novos eventos de tracking.

Os eventos de tracking existentes nos MFEs que utilizam inputs com máscara (ex: _view, _action, _success) não serão afetados, pois o comportamento externo do input permanece idêntico.


7. Requisitos Funcionais

ID Requisito Prioridade
RF-01 Implementar constante masks com todos os padrões de máscara: cpf, cnpj, cpf_cnpj, phone, zipcode, barCode, barCodeUtilities, date, number, currency, percentage, darf, bank Must Have
RF-02 Implementar função maskInput(input: HTMLInputElement, type: string) que aplica máscara a um elemento DOM em tempo real (keyup) Must Have
RF-03 Implementar função maskValue(value: string, type: string): string que formata um valor de acordo com a máscara especificada Must Have
RF-04 Implementar função maskCpf(cpf: string): string para formatação específica de CPF Must Have
RF-05 Implementar função maskCpfOrCnpj(value: string): string para formatação dinâmica CPF/CNPJ Must Have
RF-06 Implementar função maskComplete(value: string, type: string): boolean para verificar se valor atende a máscara completa Must Have
RF-07 A máscara de CNPJ (cnpj e cpf_cnpj) deve aceitar caracteres alfanuméricos (letras + dígitos), não apenas dígitos Must Have
RF-08 Atualizar formatCnpj existente para suportar CNPJ alfanumérico (não usar \D para strip — preservar letras) Must Have
RF-09 Atualizar normalizeCpfOrCnpj existente para suportar CNPJ alfanumérico Must Have
RF-10 Atualizar isCnpj existente para suportar validação de CNPJ alfanumérico (novo algoritmo de dígitos verificadores) Must Have
RF-11 Atualizar stripNumbers para oferecer variante que preserve caracteres alfanuméricos Must Have
RF-12 Exportar todas as novas funções e constantes via src/index.ts Must Have
RF-13 Implementar função setupMultipleMask para transição dinâmica CPF↔CNPJ em tempo real Must Have
RF-14 Implementar suporte a máscaras de conta bancária por código de compensação (1, 33, 41, 104, 213, 237, 341, 399, 745) Should Have
RF-15 Implementar função maskHintBankAccount(compensationCode: string): string para exibir hint de formato de conta Nice to Have
RF-16 Implementar máscara phone_idd com padrão '+99 (99) 99999-9999' para telefone com código de país (usado pelo mfe-pix) Must Have
RF-17 Implementar bank_branch e bank_account como tipos válidos do MaskType, acessíveis via maskValue e maskComplete Must Have
RF-18 Estender maskValue para aceitar options.compensationCode (interface MaskValueOptions) para resolver máscaras bancárias dinâmicas por banco em runtime Must Have
RF-19 Estender maskComplete para aceitar compensationCode como 3º parâmetro para validação de completude por banco Must Have
RF-20 Implementar funções dedicadas maskBankBranch(value, code?) e maskBankAccount(value, code?) como API pública Should Have
RF-21 Exportar interface MaskValueOptions via src/index.ts para consumo externo tipado Must Have

8. Requisitos Não Funcionais

ID Categoria Requisito
RNF-01 Performance Aplicação de máscara em campo de input deve ser imperceptível — sem lag ou delay visível durante digitação (< 5ms por evento keyup)
RNF-02 Compatibilidade A biblioteca deve ser compatível com React 18.x e Node.js 16+
RNF-03 Bundle Size A adição das funções de máscara não deve aumentar o bundle size em mais de 5KB gzipped
RNF-04 Zero dependência externa As funções de máscara devem ser implementadas sem dependência de vanilla-masker ou qualquer lib externa — usar apenas TypeScript nativo
RNF-05 TypeScript Todas as funções devem ter tipagem completa — tipos exportados para masks, parâmetros e retornos
RNF-06 Retrocompatibilidade As funções existentes (normalizeCpfOrCnpj, formatCnpj, isCnpj, maskString) devem manter retrocompatibilidade — CNPJ numérico deve continuar funcionando exatamente como antes
RNF-07 Testabilidade Cobertura de testes ≥ 90% para todas as funções de máscara
RNF-08 Tree-shaking As funções devem ser exportadas de forma que permita tree-shaking — imports individuais não devem carregar funções não utilizadas

9. Regras de Negócio

⚠️ UX obrigatório: taxonomia de saldo não se aplica a esta feature (não envolve operações de saldo).

ID Regra Observação
RN-01 CNPJ alfanumérico mantém a mesma estrutura posicional do CNPJ numérico: XX.XXX.XXX/XXXX-XX, onde X pode ser letra (A-Z) ou dígito (0-9) Conforme definição da Receita Federal
RN-02 Letras no CNPJ alfanumérico devem ser normalizadas para maiúsculas Evita inconsistência de display
RN-03 A strip function para CNPJ alfanumérico deve remover apenas separadores (., /, -), preservando letras e dígitos Diferente do strip atual que remove tudo que não é dígito
RN-04 CPF permanece exclusivamente numérico — não é afetado pelo CNPJ alfanumérico CPF não muda de formato
RN-05 A transição dinâmica CPF↔CNPJ no campo combinado deve ser baseada no comprimento do valor limpo (≤11 = CPF, >11 = CNPJ) Mesmo critério atual
RN-06 Máscaras de moeda e percentual devem usar formato brasileiro: separador decimal vírgula, separador de milhar ponto Padrão BRL
RN-07 Código de barras de títulos e convênios mantêm seus formatos distintos Títulos: 99999.99999 99999.999999 99999.999999 9 99999999999999; Convênios: 999999999999 999999999999 999999999999 999999999999
RN-08 As funções centralizadas devem produzir output idêntico às funções locais dos MFEs para todos os inputs numéricos existentes Garante retrocompatibilidade na migração

10. Critérios de Aceite

CA-01: Máscara de CNPJ alfanumérico

  • Dado que o valor 12ABC34501DE35 é passado para maskValue
  • Quando o tipo é cnpj
  • Então o retorno é 12.ABC.345/01DE-35

CA-02: Máscara de CNPJ numérico (retrocompatibilidade)

  • Dado que o valor 11222333000181 é passado para maskValue
  • Quando o tipo é cnpj
  • Então o retorno é 11.222.333/0001-81 (idêntico ao comportamento atual)

CA-03: Máscara CPF/CNPJ combinada com CNPJ alfanumérico

  • Dado que o valor 12ABC34501DE35 é passado para maskCpfOrCnpj
  • Quando o comprimento limpo é > 11
  • Então a máscara de CNPJ alfanumérico é aplicada: 12.ABC.345/01DE-35

CA-04: Máscara CPF/CNPJ combinada com CPF

  • Dado que o valor 93231097037 é passado para maskCpfOrCnpj
  • Quando o comprimento limpo é ≤ 11
  • Então a máscara de CPF é aplicada: 932.310.970-37

CA-05: formatCnpj atualizado para alfanumérico

  • Dado que formatCnpj é chamado com 12ABC34501DE35
  • Quando a função processa o valor
  • Então retorna 12.ABC.345/01DE-35 sem remover as letras

CA-06: isCnpj atualizado para alfanumérico

  • Dado que isCnpj é chamado com um CNPJ alfanumérico válido
  • Quando a validação é executada
  • Então retorna true (aplicando o algoritmo de dígitos verificadores para CNPJ alfanumérico)

CA-07: Retrocompatibilidade das funções existentes

  • Dado que normalizeCpfOrCnpj, formatCnpj, isCnpj são chamados com valores numéricos
  • Quando os valores são válidos no formato numérico atual
  • Então o comportamento é idêntico à versão anterior

CA-08: Todas as máscaras dos MFEs disponíveis

  • Dado que um desenvolvedor importa de @useblu/utils
  • Quando consulta as funções disponíveis
  • Então encontra: masks, maskInput, maskValue, maskCpf, maskCpfOrCnpj, maskComplete, maskHintBankAccount, maskBankBranch, maskBankAccount, e os tipos MaskType, MaskValueOptions, BankCompensationCode

CA-10: Máscara de telefone com IDD

  • Dado que o valor 5511999998888 é passado para maskValue
  • Quando o tipo é phone_idd
  • Então o retorno é +55 (11) 99999-8888

CA-11: Máscara bancária dinâmica com compensationCode

  • Dado que o valor 123456 é passado para maskValue com tipo bank_branch e options.compensationCode = '341'
  • Quando a máscara é aplicada
  • Então o retorno é 12345-6 (padrão Itaú)

CA-12: Máscara bancária com compensationCode desconhecido

  • Dado que o valor 1234 é passado para maskValue com tipo bank_branch e options.compensationCode = '999'
  • Quando o código de compensação não é reconhecido
  • Então o retorno usa o padrão noop: 1234

CA-13: maskComplete com compensationCode

  • Dado que o valor 123456 é passado para maskComplete com tipo bank_branch e compensationCode = '341'
  • Quando a validação de completude é executada
  • Então retorna true (Itaú espera 5+1 dígitos)

CA-09: Zero dependência de vanilla-masker

  • Dado que o package.json do blu-utils é inspecionado
  • Quando as dependências são verificadas
  • Então vanilla-masker NÃO está listada como dependência

CA-UX-01: Validação antecipada de pré-condições

  • Dado que um MFE utiliza maskValue para formatar um valor de CNPJ
  • Quando o valor é nulo, undefined ou vazio
  • Então a função retorna string vazia '' sem lançar exceção, permitindo que o MFE trate o estado vazio antes de qualquer ação do usuário

CA-UX-02: Estados de feedback — Loading

  • Dado que o usuário digita em um campo com maskInput aplicado
  • Quando cada caractere é digitado (keyup)
  • Então a máscara é aplicada instantaneamente (< 5ms), sem necessidade de loading state separado

CA-UX-03: Estados de feedback — Erro

  • Dado que o usuário insere um valor inválido para a máscara
  • Quando o valor não preenche completamente o padrão
  • Então o valor é exibido parcialmente formatado (best-effort) e a validação do formulário do MFE indica campo inválido com mensagem adequada (max 30 palavras para Web)

CA-UX-04: Estados de feedback — Vazio

  • Dado que o campo de input está vazio
  • Quando o usuário foca no campo
  • Então o placeholder exibe o formato esperado (ex: 00.000.000/0000-00 para CNPJ)

11. Cenários de Teste

ID Tipo Cenário Dados de Entrada Resultado Esperado
CT-01 Happy Path Máscara CNPJ alfanumérico 12ABC34501DE35 12.ABC.345/01DE-35
CT-02 Happy Path Máscara CNPJ numérico 11222333000181 11.222.333/0001-81
CT-03 Happy Path Máscara CPF 93231097037 932.310.970-37
CT-04 Happy Path Máscara telefone 11999998888 (11) 99999-8888
CT-05 Happy Path Máscara CEP 01310100 01310-100
CT-06 Happy Path Máscara moeda 150000, config BRL 1.500,00
CT-07 Happy Path Máscara código de barras (título) Valor de 47 dígitos Formato correto com pontos e espaços
CT-08 Happy Path Máscara data 01012026 01/01/2026
CT-09 Happy Path maskCpfOrCnpj com CPF 93231097037 932.310.970-37
CT-10 Happy Path maskCpfOrCnpj com CNPJ alfanumérico 12ABC34501DE35 12.ABC.345/01DE-35
CT-11 Edge Case CNPJ alfanumérico com letras minúsculas 12abc34501de35 12.ABC.345/01DE-35 (normalizado para maiúsculas)
CT-12 Edge Case Valor nulo/undefined null ou undefined '' (string vazia)
CT-13 Edge Case Valor parcial para CNPJ 12ABC 12.ABC (formatação parcial)
CT-14 Edge Case Transição CPF→CNPJ em campo combinado Digitar 12 chars após 11 Máscara muda de CPF para CNPJ
CT-15 Edge Case Valor colado com separadores 12.ABC.345/01DE-35 Strip + reaplicação → 12.ABC.345/01DE-35
CT-16 Edge Case maskComplete com valor incompleto 12ABC, tipo cnpj false
CT-17 Edge Case maskComplete com valor completo 12.ABC.345/01DE-35, tipo cnpj true
CT-18 Retrocompatibilidade formatCnpj com CNPJ numérico 11222333000181 11.222.333/0001-81 (idêntico ao comportamento anterior)
CT-19 Retrocompatibilidade isCnpj com CNPJ numérico válido 11222333000181 true
CT-20 Retrocompatibilidade isCnpj com CNPJ alfanumérico válido CNPJ alfanumérico com DV correto true
CT-21 Retrocompatibilidade normalizeCpfOrCnpj com CPF 93231097037 932.310.970-37
CT-22 Performance Aplicação de máscara em evento keyup Simulação de digitação rápida (50 chars/s) Cada aplicação < 5ms
CT-23 UX — Loading Máscara aplicada em tempo real Digitação no input Formatação instantânea, sem flicker
CT-24 UX — Erro Máscara com tipo desconhecido maskValue('123', 'invalido') Retorna false sem exceção
CT-25 UX — Validação antecipada Campo CNPJ com valor impossível Todos zeros 00000000000000 isCnpj retorna false (blacklist)
CT-26 Conta bancária Máscara de conta do Banco do Brasil (001) 123456789, banco 1 12345678-9
CT-27 Conta bancária Máscara de conta genérica (banco desconhecido) 1234567890123, banco 999 123456789012-3 (padrão noop)
CT-28 Telefone IDD Máscara phone_idd 5511999998888 +55 (11) 99999-8888
CT-29 Telefone IDD Strip e reaplicação phone_idd +55 (11) 99999-8888 +55 (11) 99999-8888
CT-30 Banco dinâmico bank_branch com compensationCode Itaú 123456, code 341 12345-6
CT-31 Banco dinâmico bank_branch com compensationCode desconhecido 1234, code 999 1234 (fallback noop)
CT-32 Banco dinâmico bank_account com compensationCode BB 123456789, code 1 12345678-9
CT-33 Banco dinâmico bank_account com compensationCode Bradesco 12345678, code 237 1234567-8
CT-34 Banco dinâmico bank_account com compensationCode Itaú 123456, code 341 12345-6
CT-35 Banco dinâmico maskComplete bank_branch com compensationCode Itaú 123456, code 341 true (completo)
CT-36 Banco dinâmico maskComplete bank_branch incompleto com code Itaú 1234, code 341 false (incompleto)
CT-37 Banco dinâmico maskComplete bank_account com compensationCode BB 123456789, code 1 true (completo)

12. Estratégia de Rollout e Feature Flag

Campo Valor
Requer feature flag? Não — feature de biblioteca, não de runtime
Nome da flag sugerida N/A
Rollout inicial Publicação de nova versão do @useblu/utils no npm registry + atualização da versão no mfe-core
Critério para expansão Validação em staging com MFE piloto (sugestão: mfe-bill ou mfe-login) consumindo via core/blu-utils
Rollout completo Após validação do MFE piloto, migrar os demais MFEs na Fase 2. Como o mfe-core já re-exporta @useblu/utils, todos os MFEs terão acesso às novas funções automaticamente — a migração é apenas trocar imports
Plano de rollback Reverter a versão do @useblu/utils no package.json dos MFEs migrados
Migração de dados necessária? Não
Usuários elegíveis Todos — a mudança é transparente para o usuário final
Impacto em Grupo Econômico? Não — sem impacto
Flag específica de GE necessária? Não

13. Métricas de Sucesso (KPIs)

Métrica Baseline Atual Meta Prazo de Avaliação
Repositórios MFE com vanilla-masker como dependência 34 (estimativa com base nos arquivos masks.ts/masks.js encontrados) 0 (após Fase 2) Q3 2026
Arquivos locais masks.ts/masks.js nos MFEs 34 0 (após Fase 2) Q3 2026
MFEs consumindo máscaras via core/blu-utils 0 34 (100%) Q3 2026
Cobertura de testes das funções de máscara no blu-utils 0% (funções ainda não existem) ≥ 90% Entrega da Fase 1
Bugs de formatação de CNPJ alfanumérico N/A (formato ainda não em produção) 0 Pós-lançamento do CNPJ alfanumérico pela RF

14. Observabilidade e Alertas

Item Ferramenta Critério de Alerta
Falha no CI do blu-utils (build/test) GitHub Actions Build ou testes falhando na branch principal
Publicação de nova versão no npm GitHub Actions Falha na publicação automática ao merge na master
Erros de runtime em MFEs após migração (Fase 2) Sentry (via core/tracing-exception) Aumento > 5% na taxa de erros de JavaScript em MFEs que migraram
Bundle size do @useblu/utils GitHub Actions (CI check) Aumento > 5KB gzipped em relação à versão anterior

15. Dependências

Dependência Tipo Status Responsável
Definição oficial do formato alfanumérico de CNPJ pela Receita Federal Externa Em andamento Receita Federal / Produto
Algoritmo de validação de dígitos verificadores para CNPJ alfanumérico Externa A ser confirmado Engenharia + Produto
mfe-core re-export via core/blu-utils Interna Já funcionalmfe-core já re-exporta @useblu/utils via Module Federation; basta atualizar a versão Squad Core
Versionamento e publicação no npm (@useblu/utils) Interna Funcional (bump version + merge = publish) Vertical Origination

16. Riscos e Considerações

Risco Probabilidade Impacto Mitigação Justificativa
Algoritmo de DV para CNPJ alfanumérico ainda não definido oficialmente Média Alto Implementar com base na documentação disponível da RF; manter função de validação isolada para fácil substituição A Receita Federal pode ajustar regras antes do lançamento
Quebra de retrocompatibilidade em funções existentes (formatCnpj, isCnpj, normalizeCpfOrCnpj) Baixa Alto Manter testes de regressão com todos os cenários numéricos atuais; não alterar assinaturas de funções Funções já são consumidas por MFEs
MFEs com variações locais nas máscaras (customizações específicas) Baixa Médio Varredura em 33 MFEs concluída: todas as constantes masks possuem as mesmas chaves e padrões. Única variação: phone_idd no mfe-pix (já coberto). O mfe-payment-transfer usa bank.${code} dinâmico (coberto via compensationCode) Risco mitigado pela varredura completa
Performance degradada com implementação TypeScript nativa (sem vanilla-masker) Baixa Baixo Benchmark de performance no CI; máscaras são operações simples de string A implementação nativa tende a ser mais rápida que a lib
Resistência à migração na Fase 2 (34 repos) Baixa Médio Como o mfe-core já re-exporta @useblu/utils, a migração é apenas trocar imports locais por core/blu-utils — criar codemod ou script de migração automática para substituir import ... from './utils/masks' por import ... from 'core/blu-utils' A barreira de entrada é baixa pois não exige instalação de dependência

17. Pontos em Aberto (Open Questions)

ID Pergunta Responsável Prazo
OQ-01 Qual é o algoritmo oficial de cálculo dos dígitos verificadores para CNPJ alfanumérico? A Receita Federal já publicou a especificação final? Produto / Engenharia Antes do início da implementação
OQ-02 A máscara de CNPJ alfanumérico deve aceitar letras em TODAS as posições ou apenas em posições específicas? Produto Antes do início da implementação
OQ-03 Deve haver flag para ativar/desativar o suporte a CNPJ alfanumérico nos inputs (ex: período de transição onde ambos formatos coexistem)? Produto Antes da Fase 2
OQ-04 O mfe-company-settings (mencionado no card) tem customizações de máscara diferentes dos outros MFEs? Resolvido: Varredura em 33 MFEs confirmou que todas as constantes masks são idênticas, com exceção do phone_idd no mfe-pix (já coberto) e do padrão dinâmico bank.${code} no mfe-payment-transfer (coberto via compensationCode) Vertical Origination ✅ Concluído
OQ-05 Existe necessidade de oferecer uma função de "unmask" (remover formatação) que seja alfanumérica-aware? Engenharia Durante implementação

18. Referências

  • Jira (origem): OR-145 — Unificar máscara de inputs no blu-utils
  • Jira (parent): OR-98 — Suporte a CNPJ Alfanumérico
  • Jira (epic): OR-47 — Aceitar o novo formato de CNPJ (com letras e números)
  • Knowledge bases lidas:
    • skills/create-prd.md — playbook de geração de PRD
    • conventions/ux-best-practices.md — diretrizes de UX (todas as 11 seções)
    • conventions/ocean-ds.md — Ocean Design System
    • conventions/mfe-core-shared-modules.md — módulos compartilhados do mfe-core
    • conventions/i18n-keys-naming.md — convenção de chaves i18n
    • architecture/system-overview.md — visão geral do ecossistema
    • architecture/cross-mfe-navigation.md — navegação entre MFEs
    • skills/create-event-tracking.md — padrões de tracking
  • Diretrizes de UX aplicadas:
    • Seção 1 (Validações): inputs devem validar formato antes de submissão
    • Seção 3 (Feedback): estados Default, Loading, Sucesso, Erro, Vazio definidos para inputs com máscara
    • Seção 5 (Copy): limites por plataforma Web (max 30 palavras para mensagens de erro)
    • Seção 6 (Consistência): máscaras centralizadas garantem consistência entre MFEs
    • Seção 9.5 (CTAs): não aplicável diretamente, mas botões de submissão de formulários seguem padrão
  • Repositórios de tracking lidos: Não aplicável — feature de infraestrutura de biblioteca
  • Análise de Grupo Econômico: Sem impacto — a centralização de máscaras não altera nenhuma lógica do Grupo Econômico. Campos de CNPJ no mfe-economic-group-configuration se beneficiarão automaticamente após a Fase 2 de migração.
  • Documentos relacionados: N/A
  • Arquivos identificados no codebase:
    • Pagnet/blu-utils/src/index.ts — exports centrais da lib
    • Pagnet/blu-utils/src/formatters/formatCnpj.ts — formatter de CNPJ (a ser atualizado)
    • Pagnet/blu-utils/src/normalizers/normalizeCpfOrCnpj.ts — normalizer CPF/CNPJ (a ser atualizado)
    • Pagnet/blu-utils/src/validations/isCnpj.ts — validação de CNPJ (a ser atualizado)
    • Pagnet/blu-utils/src/utils/maskString.ts — utilitário de máscara (base para extensão)
    • Pagnet/blu-utils/src/utils/stripNumbers.ts — strip de caracteres (a ser atualizado)
    • 34 arquivos mfe-*/src/utils/masks.ts ou masks.js — arquivos locais a serem substituídos na Fase 2
    • 50 arquivos referenciando vanilla-masker nos MFEs
  • Varredura de gaps (33 MFEs):
    • 23 MFEs com constantes masks idênticas (hash f29fe228)
    • Única variação encontrada: phone_idd no mfe-pix ('+99 (99) 99999-9999')
    • mfe-payment-transfer usa padrão dinâmico bank.${compensationCode}.branch/account via getMask() + _.get(masks, type)
    • mfe-bill usa darf.referenceNumber e bank.noop.branch como chaves de máscara
    • Relatório completo: mask-scan-report.md
  • PRs relacionados:
  • Queries Redshift executadas: Não aplicável — feature de infraestrutura
  • Prompt do Devin: Sessão do Devin

Metadata

Metadata

Assignees

No one assigned

    Labels

    prd-readyPRD pronto para reviewtechnicalFeature técnica

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions