Pular para o conteúdo

Projeto

Sistema de gestão hoteleira

Papel
Backend, módulo financeiro e LGPD
Contexto
Produto de cliente
Stack
  • typescript
  • nestjs
  • prisma
  • postgresql
  • react
  • lgpd

o200k_base · 199 tokens · o que o modelo lê

Produto comercial em produção, com o financeiro modelado como livro-razão: erro vira estorno, nunca UPDATE.

O problema

Gestão hoteleira concentra três coisas que raramente convivem bem: operação diária que não pode parar, um módulo financeiro onde erro de centavo é erro de verdade, e dados pessoais de hóspedes sob LGPD.

É o tipo de sistema em que a parte difícil não é nenhuma tecnologia específica, e sim a consistência entre módulos que precisam concordar sobre o mesmo fato. A diária lançada no check-in é o mesmo fato que o caixa do dia fecha, que o relatório do mês soma e que alguém vai precisar explicar três meses depois, quando o contador perguntar. Se esses quatro números divergirem, não existe bug pequeno.

A solução

PMS hoteleiro completo, de reserva e hospedagem a caixa, estoque e documentos fiscais, com o financeiro modelado como livro-razão append-only e a trilha de auditoria escrita na mesma transação da mutação.

Como a consulta atravessa o sistema

  1. 01

    Check-in

    a hospedagem começa e vira fato financeiro.

  2. 02

    Cobrança

    a diária entra como lançamento, e lançamento não se edita.

  3. 03

    Pagamento

    entra como movimento próprio, sem alterar a cobrança que quitou.

  4. 04

    Caixa

    o fechamento soma movimentos, nunca um saldo que alguém edita.

  5. 05

    Auditoria

    cada passo grava a trilha na mesma transação que o produziu.

Decisões de engenharia

  1. 01

    O financeiro é livro-razão, não CRUD.

    Alternativa considerada
    UPDATE e DELETE nas tabelas financeiras, com cada linha refletindo sempre o estado atual.
    Por quê
    Histórico que pode ser reescrito não é histórico. As tabelas de movimento, cobrança e pagamento são append-only: lançamento errado não é corrigido, é estornado por um novo movimento que aponta para o original. Dinheiro é Decimal do banco ao front, com formatação por helper, porque float em cálculo monetário não é uma escolha de precisão, é um erro adiado.
    O que custou
    Mais código e telas mais chatas. Todo estorno mostra o contexto do movimento original antes de confirmar, e nenhuma correção é um clique só.
  2. 02

    A auditoria é escrita na mesma transação da mutação.

    Alternativa considerada
    Gravar a trilha depois da mutação, em try/catch ou numa fila.
    Por quê
    Auditoria gravada depois é auditoria que some exatamente no incidente em que você precisa dela. O que ela grava passa por allowlist, IDs e flags e nunca o DTO inteiro: o log de auditoria é o lugar mais fácil de vazar dado pessoal sem ninguém perceber.
    O que custou
    A transação fica mais longa, e cada campo novo exige decidir explicitamente se entra na allowlist antes de subir.
  3. 03

    Dado pessoal é restrição de arquitetura, não página de política.

    Alternativa considerada
    Guardar o arquivo no banco e resolver LGPD na camada de consentimento e política de privacidade.
    Por quê
    Consentimento cobre a coleta. Não cobre o dado que escapa por um log, um toast ou uma URL que ficou válida por seis meses. O binário fica em object storage e o banco guarda só metadado e referência; a URL assinada é curta, gerada sob demanda e só depois da checagem de permissão, nunca pré-computada. E-mail, telefone, token e URL não aparecem em log, console nem query string, e a tela de auditoria tem redaction própria.
    O que custou
    Nenhum atalho de depuração. Rastrear o problema de um hóspede específico exige ir pelo identificador, e não pelo dado que a pessoa usou para reclamar.
  4. 04

    Monolito modular, por decisão explícita.

    Alternativa considerada
    Quebrar por serviço desde o começo, com fila entre os módulos que se falam.
    Por quê
    Um cliente, uma operação, um time pequeno. Complexidade distribuída aqui seria custo diário em troca de um benefício hipotético. A fronteira que interessa nesse tamanho é a de módulo: controller, service e repository, com o controller proibido de tocar no Prisma. Quando o produto justificar o corte, ele já está desenhado.
    O que custou
    Escalar significa escalar o processo inteiro, e um erro num módulo derruba os outros junto. O corte, quando vier, vai ser feito com o sistema em produção.

Resultado

Sistema em produção, vendido a cliente e rodando a operação diária de um hotel.

Voltar aos projetos