Pitch: CalculeCLT — três escolhas técnicas além da fórmula
Sou responsável pelo CalculeCLT, um projeto de calculadoras trabalhistas para o Brasil feito com Astro e TypeScript. Quero compartilhar três escolhas que estão no código e podem ser úteis em outros projetos com formulários e simulações.
1. Horário, duração e hora decimal são tipos diferentes
08:30 pode representar um horário. 44:00 pode representar uma duração. Já 1,5 representa uma hora e meia em formato decimal.
No módulo de horas, a unidade interna é o minuto inteiro. A conversão acontece na entrada e a formatação fica para a saída:
parseDuration('1:30'); // 90
parseDuration('1,5'); // 90
formatHM(90); // '1:30'
Isso também deixa explícita uma decisão sobre turnos que atravessam a meia-noite. Um turno das 22:00 às 06:00, com intervalo das 02:00 às 03:00, resulta em 420 minutos: sete horas. Entrada e saída iguais são rejeitadas, porque poderiam significar zero ou 24 horas.
Esse é o comportamento da calculadora de horas trabalhadas. Trata-se de duração de jornada; o exemplo não calcula adicional noturno nem valida sozinho todas as regras de uma escala.
2. A falha do JavaScript precisa aparecer na interface
As páginas mostram um resultado inicial de exemplo. Mas esse exemplo não pode parecer um cálculo feito com os dados do visitante quando o script interativo não carrega.
O formulário compartilhado começa com os campos e o botão dentro de um fieldset disabled. A inicialização instala o tratamento de envio antes de liberar os campos. Esta é uma versão simplificada da ordem usada:
form.addEventListener('submit', (event) => {
event.preventDefault();
calcularEExibir();
});
// Os campos só são liberados depois da preparação.
fieldset.removeAttribute('disabled');
Se o script não fica pronto, os controles permanecem bloqueados e uma mensagem explica que o resultado exibido é apenas um exemplo. Quando o JavaScript está desativado, há uma mensagem em noscript.
É uma escolha com um custo: o cálculo personalizado depende de JavaScript. A contrapartida é tornar essa dependência explícita e impedir o envio nativo dos campos enquanto a interface ainda não está preparada. A referência do fieldset na MDN detalha o comportamento dos controles desabilitados.
3. O resultado precisa existir antes do HTML
Nos demonstrativos monetários, o resultado é representado por um modelo com linhas, proventos, descontos, valor líquido e avisos. O HTML e o resumo de texto recebem esse mesmo modelo.
Isso mantém o cálculo separado da apresentação e evita refazer a conta dentro do botão de copiar ou compartilhar. Os testes das funções também podem verificar valores sem depender do layout.
Essa organização não garante, por si só, que uma fórmula esteja correta. Por isso, a metodologia e as fontes do CalculeCLT registram premissas, limites e mudanças. O resultado continua sendo uma estimativa, com um escopo que precisa ser explicado.
Para quem constrói simuladores: como vocês representam premissas e estados de erro para que o usuário consiga entender o resultado? Comentários sobre essas escolhas são bem-vindos.