Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Clojure BR - Brazilian Utils: Simplificando o c...

Clojure BR - Brazilian Utils: Simplificando o caos brasileiro com Clojure em uma biblioteca open source

Brazilian Utils: Simplificando o caos brasileiro com Clojure em uma biblioteca open source
https://youtu.be/_rqa5CSdcuk

Avatar for Ana Luiza Portello

Ana Luiza Portello

May 28, 2026

More Decks by Ana Luiza Portello

Other Decks in Programming

Transcript

  1. Engenheira de software & cientista da computação Programming languages, musica,

    web Gêmeos ascendente em escorpião Sometimes speaker, sometimes community manager, always shitposter Ana Luiza Portello Bastos
  2. • States / Cities - UF codes, state names, area

    codes, Cities by state, city lookup • CEP - Postal codes, address lookup via ViaCEP • CPF, CNPJ - Brazilian personal and business ID validation & generation • PIS - Social integration program number validation • CNH - Driver's license validation • RENAVAM - Vehicle registration validation • Título Eleitoral - Voter ID validation & generation • Inscrição Estadual - State registration (IE) by UF • Email - Email format validation • Phone - Brazilian phone number validation (mobile & landline) • Capitalize - Smart capitalization with Portuguese rules • Currency - Brazilian Real (BRL) formatting & parsing • License Plate - Traditional & Mercosul plate validation & conversion • Processo Jurídico - Court case number validation BIBLIOTECA
  3. Pra quem? • Quem tem interesse em comecar a mexer

    com clojure ou colaborar com open source -> clojure basico • Mindset clojure • Diferencas entre clojure e clojurescript • Um pouco sobre como foi meu processo de pensar / fazer / organizar a lib
  4. Brazilian Utils • ORG da CumbucaDev • Fornecer ferramentas para

    validar, gerar, manipular dados de particularidades do brasil • Unificar e democratizar essa acesso
  5. Premissas • Precisa rodar Clojure ClojureScript • Precisa ter uma

    boa quantidade de features que tenham em outros brazilian utils
  6. Checklist • Passei por todos os os projetos do brazilian

    utils e vi o que eles tinham • O que a partir do meu código seria fácil de fazer ou seria mais útil. • Necessario, nice to have etc
  7. Checklist Cada módulo JS será refeito como um namespace CLJ

    + CLJS: • boleto • capitalize • cep • cities • cnpj • cpf • currency • email • inscricao-estadual • license-plate • phone • pis • processo-juridico • states
  8. Checklist • Lista completa de estados (UF + nome +

    códigos) • Tabela de cidades por estado • Tabelas e pesos para cálculos de DV (CPF, CNPJ, PIS) • Regras por UF da inscrição estadual. Transformar esses dados em json ou outros formatos em .edn e consumir eles.
  9. • A conversa foi em novembro • Comecei a implementação

    em janeiro • Estamos em quase junho
  10. CPF • 11 digitos • pode ter ou nao máscara

    (123.456.789-09) • 1 digitos verificador(MOD11) com pesos decrescentes a partir de 10 • 2 digito verificador(MOD11) com pesos decrescentes a partir de 11 • nono digito regional (SP: 8, PR: 9, DF: 1)
  11. CPF • Format: Considera com o sem mascara? • Is

    Valid?: a. Remove a mascara ou valida com regex b. Tamanho(11 digitos) c. CheckSum(DV1 e DV2) Todas validam digito verificador com modulo 11 • Generate: a. Gera 9 numeros aleatorios b. Gera digitos validos por checksum c. Em algumas libs há variação por UF(influencia no 9 digitos do CPF)
  12. CNPJ • 14 digitos • pode ter ou nao máscara

    (12.345.678/0001-09) • 2 digitos verificadores no final(MOD11) com pesos especificos • [5 4 3 2 9 8 7 6 5 4 3 2] e [6 5 4 3 2 9 8 7 6 5 4 3 2] • Branch -> a. 12.345.678/0001-09 MATRIZ b. 12.345.678/0002-09 FILIAL
  13. PIS: 1 DV com mod 11 com pesos: [3 2

    9 8 7 6 5 4 3 2 ] RENAVAM: 1 DV com mod 11 com pesos: [3 2 9 8 7 6 5 4 3 2] Resto 0 ou vira DV 0 senao DV = 11 - resto Titulo Eleitoral: DV1 use os 8 primeiros digitos com pesos [2 3 4 5 6 7 8 9] DV2 usa UF + DV1 com pesos [7 8 9]
  14. • Clojure trabalho com transformação de dados / fluxo de

    dados • Pensar em soluções em funções como um pipeline que reduz para um resultado • () () () <- Funcoes podem ser valores / dados
  15. Digito Verificador • Separar digitos base (sem digitos validadores ou

    mascaras) • Aplicar pesos (podem ser fixos, ou algum padrão) • Calcular o resto do modulo (na maior parte das vezes mod11) • Transformar o resto em digito (regras a serem aplicadas)
  16. Funcao: Aplicar pesos Digits “12345” Weights 9 ou “1534” Transformo

    os dados - Let - Seq - Caso venha 9 significa que [9 8 7 6]
  17. - Loops em clojure da forma declarativa de linguagens funcionais

    padrão. - Tudo em clojure são funções. Ate operadores. Entao *, + sao funções que estão sendo passadas no map, reduce - Map: Aplica uma função para todos items de uma lista - Ele multiplica os digitos com os pesos - Reduce: Aplica uma função cumulativa para todos os items - Soma todos os resultados
  18. - Thread macros: PIPE Gerenciador de fluxo Pega o resultado

    de um e coloca como argumento pro outro (reduce + (map * digits-seq weights-seq)) Comum em muitas langs funcionais
  19. Digito Verificador - Multi-aridade (check-digit "123" [9 8 7]) -

    (check-digit "123" [9 8 7] {:threshold 3}) - Keys (destructuring / acessar map) - Pego a soma - Faco o mod - Threshold padrao 2 - Calculo o digito
  20. CNPJ 2026 • Pode ter alfanumericos nos 9 primeiros digitos

    (1A.3B5.6C8/0001-09) • Para calcular os digitos verificadores precisa converter a letra em ASCII • Subtraia por 48 -> 65(A) - 48 = 17
  21. Char -> Digit • Se for letra / char •

    Faz a continha • Se nao, deixa quieto
  22. Aplicar pesos Transformando os dados para usar na função MAP

    para que caso eles sejam letras eu transforme adequadamente nos numeros
  23. #? Reader conditional Durante leitura/compilação (nao runtime) O codigo decide

    se vai ler a parte :clj ou a parte :cljs Se estiver na JVM ele le o que tiver no :clj Se estiver no Javascript ele le o que tiver no :cljs
  24. Clojure Interpretado / LISP -> () https://clojure.org/api/cheatsheet Clojure pode ter

    runtimes diferentes (JVM, JavaScript, .NET, Node.js, Browser, CLR, Babashka(GraalVM))
  25. Java Interop (.toUpperCase "hello") / /"hello".toUpperCase() (java.util.Date.) / / (new

    java.util.Date) (:import [java.time LocalDate] [java.util UUID]))
  26. Javascript Interop (.log js/console "hello") / / console.log(“hello”) (set! (.-title

    js/document) "Novo título") / /document.title = "Novo título" - acessa globals (js/Date.) / / new Date cria obj (:require ["react" :as react] ["axios" :as axios]
  27. :clj :clj não necessariamente significa Java e que existem outros

    runtimes Usar funções muito específicas de java provavelmente vão piorar a compatibilidade E pesquisando de fato o babashka nao teria compatibilidade com lib java
  28. babashka - Mistura SCI e GraalVM - Apenas partes do

    Java funciona - #?(:bb ….., :clj ….., :cljs: ….)
  29. JVM(:clj) No Clojure, existem vários tipos numéricos reais(Integer, Long, Double,BigInt,

    BigDecimal,Ratio) Então: (Integer/parseInt "123") realmente retorna um: java.lang.Integer Se for inteiro invalido ele retorna um erro! (Integer/parseInt "banana") / / erro!
  30. Fetch / HTTP - Existe uma lib cljs chamada https-clj

    (em clj: http-clj) - Baseada no XMLHTTMLRequest (callback) - Fetch (promises) ou outras libs de http de clojure script.
  31. CAPITALIZE (capitalize "josé ama maria" {:lower-case-words ["ama"]}) Configuração da função

    e um mapa declarativo Homoiconicidade: Codigo parece dado / dado parece codigo •
  32. Portable core / native edges - Core puro - Portátil

    - Separo e isolo alguns cantinhos
  33. Abstracao Camadas - API Publica (generate-cpf) - SubModulos - Helpers:

    (format-with-precision 12.345 2) (parse-int “1239”)
  34. Projeto • CLAREZA: Beginner friendly, legivel, se manter idiomático ao

    clojure separar em funções claras e simples pra poder navegar. • COMPLETO: Cobrir o maximo possivel de features corretamente • BOA QUALIDADE: Testes, code quality, workflows, fmt. • .DOC FIRST: Criar o máximo possível de documentação para facilitar consulta seja por humanos normais querendo entender a logica por tras ou IA.
  35. Maior parte das libs seguem o mesmo padrão Maior parte

    estilo meio funcional Separação por domínio ou feature Exposição pública da API da lib (lib.rs, __init__.py, index.js) Arquivos focados: validator, formatter, generator
  36. - Features de validacao - Features de geracao - Lookups

    / Aggregations - Features de formatacao - Features de conversao
  37. Muitas das logicas sao simples entao cabem em 3 a

    4 linhas Passo a passo do processo deve estar claro em lets legiveis Se a logica começou a ficar um pouco mais complicada separa-se em outro passo em funções auxiliares Se um processo no core ta grande, separar em arquivos especificos.
  38. Projeto • Modulos ◦ Core ◦ Validations ◦ Internal ◦

    Format (se necessario) ◦ Outros (se necessario)
  39. Todos os módulos validate vão ter os schemas malli visíveis

    e documentados Para os tipos de dados (cpf, cnpj, cep) Schemas tbm vao ser funcoes funcoes is-valid? referentes ao schema malli
  40. Telefone • (DDD) + Numero • DD precisa ser valido

    (is-valid-ddd?) • Celular: Numero pode ser que comeca com 9 e tem 9 digitos dps do DDD valid-mobile-first-number? valid-mobile-length? • Fixo(landline): Comeca com 2,3,4,5 e tem 8 digitos. valid-landline-first-number? valid-landline-length? • (11) 98765-4321 ou 11 98765 4321 ou +55 11 98765-4321
  41. - Features de validacao - Features de geracao - Lookups

    / Aggregations - Features de formatacao - Features de conversao
  42. m/generate A partir do schema ele gera dados de teste(regex,

    regras) Onde fazia sentido n achei idiomatico
  43. Geradores • Random digits/certo tamanho de um certo tamanho •

    Geramos digitos verificadores matematicamente validos no checksum • Adicionamos numeros / letras dadas as regras especificas regionais
  44. - Features de validacao - Features de geracao - Lookups

    / Aggregations - Features de formatacao - Features de conversao
  45. - Features de validacao - Features de geracao - Lookups

    / Aggregations - Features de formatacao - Features de conversao
  46. Estados / Cidades • Python : Pega do IBGE •

    Ruby: Mapa local • Go: ViaCEP • JS: Mapa local + IBGE • Clojure: Maps local
  47. Enderecos / CEP • Ruby : ViaCEP • Python: ViaCEP

    • Go: ViaCEP • Rust: ViaCEP • JS: ViaCEP, Widenet, BrasilAPI • Clojure: ViaCEP
  48. Datas(Feriados) • Todas: Usam lib / calculo local • Clojure:

    BrasilAPI (feriados) -> calculo local fallback
  49. • CNH ◦ usa duas etapas com regra especial de

    penalização ◦ os pesos são aplicados de forma decrescente a partir de um valor inicial ◦ não basta olhar só pesos; a transformação do resultado também muda via regra ◦ 1 digitos verificadores no final(MOD11) com pesos decrescentes (10 a 2) ◦ [10, 9, 8, 7, 6, 5, 4, 3, 2] • Processo Juridico ◦ Nao segue padrao peso por posicao, usa logica especifica por CNJ, com rearranjo e verificacao de mod ◦ Inscricao Estadual
  50. Boleto • Nao usa mod 11 igual todos. Usa mod

    10 e 11 • Nao e so vetor de pesos, a transformação do resultado muda via regra • Formatos: Linha digitavel, boleto normal, boleto de arrecadacao • Transformações de um pro outro -> barcore -> linha digitavel • Parse de boleto(data validade, banco, valor
  51. Inscricao Estadual • Regra muda por estado ◦ Quantidade de

    dígitos ◦ Vetor de pesos(ex: comeca no 3, decrementa e faz wrap de 1 a 9) ◦ Ponto de reinicio do peso ◦ Qual o modulo ◦ Qual a regra do resto do módulo ◦ Estado q mudou a regra em 99 mas ainda tem q estar válido entao tem duas regras
  52. Inscricao Estadual • Validator para cada estado e funcoes para

    cada regra • (alguns pequenos outros gigantes) • Roubei os testes que achei em outras libs e quero muito acreditar que está tudo certo e atualizado.
  53. TDD - Setup cljfmt - Setup de teste - Workflow

    para CLJ e CLJS - Buscava em outras libs testes, botava eles no codigo e dps implementava
  54. Docs - Consistencia entre DOCStrings - Input, output, regras de

    negocio - Bem detalhados nas funções específicas dos submódulos(Clojars) - Docs explicando regras especificas de validacao de cada documento (sanity check)
  55. Projeto • CLAREZA: Beginner friendly, legivel, se manter idiomático ao

    clojure separar em funções claras e simples pra poder navegar. • COMPLETO: Cobrir o maximo possivel de features corretamente • BOA QUALIDADE: Testes, code quality, workflows, fmt. • .DOC FIRST: Criar o máximo possível de documentação para facilitar consulta seja por humanos normais querendo entender a logica por tras ou IA.
  56. IA - Gerar e ajustar textos nas DOCs - Criar

    mais variações de testes - Consultar regras de validações / pedir explicações - Sugestoes de rename / refactor / commits - Achar codigo inutil ou reutilizavel
  57. Problemas com IA - Discutindo sobre DOCString (Sempre esquecia de

    escapar string /“” - Errava o idioma - Infos desatualizadas (mercosul, telefone) - O dia do boleto
  58. Pontos de melhora - Algumas inconsistencias / refactors - A

    parte de inscricao estadual ainda pode ficar mais clara / genérica - Lib de JS -> Formatter - Algumas features faltando - Em currency n transforma em dinheiro em “frase” - Alguns geradores de teste de podem ser úteis - Talvez usar esses gerados em testes - Gerar img de boleto - CNPJ não recebe branch como argumento
  59. CREDITS: This presentation template was created by Slidesgo, including icons

    by Flaticon and infographics & images by Freepik Perguntas? [email protected] anabastos.dev Contact @naluhh anabastos