Em resumo
O registo de horas numa sociedade de auditoria não é sobre o cronómetro. É sobre duas coisas: quem pode ver as horas de que cliente, e se os totais dos relatórios são verdadeiros. Ao construir um sistema de registo de horas para uma sociedade de auditoria, achei quatro erros que nenhum ecrã mostrava: totais de relatórios que sairiam baixos sem ninguém notar, cerca de 30 ações que diziam “guardado” quando nada tinha sido guardado, um cliente confidencial cuja existência se revelava nos relatórios e nas contagens de etiquetas, e uma entrada rejeitada que uma aprovação posterior podia esconder. Cada um destes erros leva minutos a testar em qualquer ferramenta, comprada ou construída.
Sou o Denys, engenheiro full-stack e de IA. Entre maio e outubro de 2026, uma sociedade de auditoria passou de uma ferramenta onde todos podiam abrir todos os clientes para um sistema de registo de horas que construí só para ela, ao longo de 388 commits. A sociedade não é nomeada aqui. Este texto é para quem dirige uma firma e escolhe as suas ferramentas: o que uma sociedade de auditoria precisa do registo de horas, os quatro erros que encontrei e como verificar qualquer ferramenta quanto a eles.
O que precisa uma sociedade de auditoria do registo de horas?
Uma sociedade de auditoria vende horas, por isso o registo de horas é o registo em que assenta todo o negócio. A firma para quem construí precisava de:
- Horas por cliente, projeto e tarefa. Cada entrada pertence a um trabalho, para que as horas possam ser lidas por cliente, por projeto e por pessoa.
- Folhas de horas semanais com aprovação. Os colaboradores submetem a semana, o administrador do projeto aprova ou rejeita cada entrada, e só as horas aprovadas contam.
- Lembretes. Quem ainda tem a folha de horas vazia antes do prazo recebe um email. Desde setembro de 2026 avisa apenas sobre horas em falta e ignora quem tem capacidade zero.
- Alocação de recursos. Quem trabalha em que trabalho nas próximas semanas, face à capacidade de cada pessoa.
- Clientes confidenciais. O proprietário pode restringir um cliente, com os seus projetos, tarefas e horas, a membros escolhidos.
- Arquivar, nunca apagar. Um membro que sai é desativado e anonimizado, e um projeto concluído é arquivado, para que o histórico das folhas de horas fique intacto.
Não emite faturas. O tipo de faturação e os orçamentos de horas dos projetos ficam atrás de uma permissão própria, e a faturação continua no sistema de contabilidade da firma.
Quem deve ver as horas de quem numa sociedade de auditoria?
Antes deste projeto, todos na firma podiam abrir todos os clientes e as horas de toda a gente. Numa sociedade de auditoria, isto é um problema de confidencialidade antes de ser um problema de software: nem todos os membros devem ver todos os clientes, e ninguém precisa de ver a semana de um colega a não ser que a aprove.
O modelo de acesso que a firma confirmou é este:
| Função | Vê | Pode aprovar |
|---|---|---|
| Colaborador | Apenas as próprias horas | Nada |
| Administrador do projeto | Horas da equipa nos seus próprios projetos | As semanas da equipa nesses projetos |
| Proprietário | Todos os clientes, projetos e pessoas | Tudo |
| Cliente confidencial | Visível só para os membros que o proprietário escolheu | — |
O proprietário define cada função numa matriz de caixas de seleção, área contra ação, e todas as regras vivem na base de dados e não nos ecrãs, por isso uma página não pode mostrar o que a base de dados recusa. Cada caixa foi testada numa cópia de produção antes do lançamento; como, e o que esse teste encontrou, está em como testar Supabase RLS.
Uma pergunta que a matriz não conseguia responder veio da própria firma. Em junho de 2026, um membro com a função mais limitada viu outros membros e os seus projetos no ecrã de alocação, e esperava ver apenas a si próprio e um colega. Deve um membro restrito ver as pessoas dos seus próprios projetos? A regra a que chegámos: sim, só nos projetos partilhados, com a capacidade e as ausências dos outros escondidas.
Como se chega a um modelo de acesso com que uma firma realmente concorda? Não pedi ao cliente que o descrevesse de memória. Enviei um questionário de 72 perguntas em 9 secções, com as grelhas de permissões já preenchidas como o sistema em funcionamento as tinha a 7 de agosto de 2026. O cliente corrigiu o que estava errado, e cada célula alterada foi assinalada. As pessoas corrigem melhor a realidade do que a descrevem.
Erro 1: os totais dos relatórios sairiam baixos
A página de folhas de horas tem as vistas “Este trimestre” e “Ano até à data” para toda a firma. Carregavam todas as entradas de tempo do intervalo num único pedido. A API da base de dados por trás da aplicação devolve no máximo 1000 linhas por pedido e, quando pára nas 1000, não levanta nenhum erro. Devolve simplesmente as primeiras 1000.
A Supabase documenta este valor por omissão: os projetos devolvem no máximo 1000 linhas, salvo se o limite for alterado nas definições da API.
Assim, quando a firma passasse as 1000 entradas num intervalo, membros e semanas desapareceriam da vista, e os totais sairiam baixos sem nada no ecrã a indicá-lo. Com cerca de 70 entradas por semana, a vista do ano até à data ia passar as 1000 entradas por volta de meados de novembro de 2026. Uma auditoria ao código a 24 de setembro de 2026 encontrou-o antes de acontecer. A correção lê cada intervalo página a página, e todas as exportações de relatórios passam agora a paginar da mesma forma.
Como verificar a sua ferramenta: escolha um intervalo longo, exporte as entradas em bruto, some-as você mesmo e compare com o total do relatório. Se os dois diferem, o relatório está a cortar linhas.
Erro 2: “Guardado” quando nada foi guardado
Quando a base de dados recusa uma alteração por causa de uma permissão, ou porque uma regra exige início de sessão com dois fatores, pode responder “0 linhas alteradas” sem qualquer erro. Cerca de 30 sítios da aplicação que atualizam ou apagam registos liam essa resposta como sucesso e mostravam “guardado”. A pessoa segue em frente. A alteração nunca aconteceu.
A correção é falhar de forma fechada: uma escrita que não toca em nenhuma linha é um erro, mostrado como erro, e um teste verifica agora que todos os caminhos de escrita o tratam assim.
Como verificar a sua ferramenta: entre como um membro sem direito a editar algo, tente editá-lo e depois recarregue a página. Se viu “guardado” e o valor antigo voltou, a ferramenta mente sobre as gravações.
Erro 3: um cliente confidencial exposto pelos relatórios
Alguns trabalhos só são conhecidos das pessoas que neles trabalham. Desde 24 de agosto de 2026, o proprietário pode restringir um cliente a membros indicados. Todos os outros não recebem nada desse cliente, dos seus projetos, tarefas ou horas. O proprietário tem sempre acesso, e esse acesso é calculado a partir de quem tem hoje a função de proprietário, não guardado, por isso acompanha a função quando esta muda.
Esconder o cliente da lista de clientes foi a parte fácil. As fugas estavam nas portas laterais. Uma revisão a 8 de setembro de 2026 encontrou que:
- três funções de relatórios ignoravam a restrição, porque correm com direitos que saltam as regras normais de acesso, e por isso as horas de um cliente confidencial podiam aparecer nos relatórios;
- as contagens de utilização de etiquetas na vista de administração contavam os projetos e as tarefas do cliente confidencial, o que denunciava que o trabalho existia e, mais ou menos, a sua dimensão;
- as mensagens de erro distinguiam os casos: tentar alterar um registo real mas escondido devolvia “proibido”, tentar um inventado devolvia “não encontrado”, pelo que qualquer pessoa podia sondar se um cliente confidencial existia.
As três aplicam agora a mesma verificação das tabelas principais, e um registo escondido parece exatamente um registo em falta. Mover um projeto ou uma entrada para fora de um cliente confidencial exige também o proprietário ou uma permissão dedicada, e cada movimento fica registado.
Como verificar a sua ferramenta: restrinja um cliente a uma única pessoa. Depois, como outra pessoa, execute todos os relatórios, veja todas as contagens e filtros, procure o nome do cliente e abra uma ligação direta para um dos seus projetos. Não deve encontrar rasto, nem sequer na mensagem de erro.
Erro 4: uma rejeição podia ser escondida por uma aprovação posterior
Uma semana pode ter entradas em vários projetos, e por isso várias pessoas aprovam-na. Se um administrador de projeto rejeitava uma entrada e outro aprovava depois a sua parte, a aprovação posterior podia fechar a semana inteira e mascarar a rejeição. Mover entradas entre tarefas ou reabrir uma semana podia escondê-la da mesma forma.
A 24 de setembro de 2026, a lógica de aprovação mudou: uma semana continua rejeitada enquanto existir uma entrada rejeitada ativa, e um administrador de projeto só pode arquivar uma entrada rejeitada se tiver sido ele a rejeitá-la. Uma sonda à base de dados corre agora cada um destes casos, e todos têm de dizer PASS.
Como verificar a sua ferramenta: use dois aprovadores numa semana. Rejeite uma entrada como o primeiro, aprove tudo o resto como o segundo, e veja em que estado a semana acaba.
Comprar ou construir o registo de horas de uma sociedade de auditoria?
Compre primeiro. O Toggl, o BigTime, o ZenWorkflow e ferramentas semelhantes já cobrem cronómetros, aprovações semanais e faturação a clientes, e pode começar com uma esta semana. Um sistema à medida faz sentido quando a firma tem regras que os produtos não conseguem exprimir, por exemplo clientes confidenciais visíveis apenas a membros indicados, aprovação por vários administradores de projeto numa só semana, ou funções que o proprietário quer moldar caixa a caixa.
Seja qual for o caminho, as quatro verificações acima levam uma tarde e dizem-lhe mais do que uma lista de funcionalidades. Todas as páginas de produto dizem “permissões granulares”. Poucas mostram o que acontece quando se desmarca uma caixa.
Limites deste relatório
- Uma só firma. O modelo de acesso, o volume de cerca de 70 entradas por semana e o questionário vêm de uma única firma.
- O erro 1 foi apanhado antes de se manifestar. A data de meados de novembro é uma projeção a partir do ritmo de entradas da firma, não um incidente medido.
- Sem faturação. O sistema guarda horas, tipo de faturação e orçamentos de horas, mas não fatura clientes, por isso não posso falar de fluxos do tempo até à fatura.
As regras de acesso aqui são row level security do Postgres. Dois buracos que uma matriz de funções não apanha estão descritos à parte: um utilizador que pertence a duas orgs e um IF que falha em aberto com NULL. A construção em si está no caso do registo de horas para a empresa de auditoria, e este tipo de trabalho enquadra-se em ferramentas internas e dashboards.
A escolher ou a construir um registo de horas para a sua firma?
Troco impressões com gosto sobre regras de acesso e aprovações. Sem pitch.
Fale comigo