SEMTRAS · Santarém · Modelagem

Modelo de dados

Um único banco PostgreSQL para todos os municípios. Toda tabela de dados leva tenant_id, e o próprio banco só devolve as linhas do município da conexão (Row-Level Security). Escolha uma tabela para ver suas colunas, com quem ela se liga e o SQL de isolamento. Cada módulo tem as suas tabelas e só aponta para o núcleo; os vínculos entre módulos passam por eventos, não por chave estrangeira.

Nenhuma tabela encontrada.

Quem aponta para ela

ninguém

Para quem ela aponta

ninguém

O tenant_id aponta para tenants em todas as tabelas e não entra neste desenho.

ColunaTipoMarcasObservação

Um ? depois do tipo indica coluna que aceita vazio.

Restrições no banco

Isolamento desta tabela


          

Os módulos continuam independentes?

Conferência feita sobre as chaves estrangeiras acima: cada módulo só pode apontar para o núcleo e para os módulos de que declara depender. Se uma FK passar disso, a linha fica vermelha.

MóduloDeclara depender deFKs apontam paraSituação

Estoque e Patrimônio não têm FK para Contratos, Pedidos nem Distribuição. As colunas referencia_tipo e referencia_id, e o bem_id de entrega_itens, guardam o vínculo sem constraint, preenchidas a partir dos eventos “item recebido” e “entrega confirmada”.

Como o tenant chega ao banco

  1. O middleware lê o subdomínio e descobre o tenant.
  2. Dentro da transação, ele grava o id na conexão: select set_config('app.tenant_id', ?, true).
  3. O global scope do trait BelongsToTenant filtra pelo mesmo id. É a primeira barreira.
  4. A policy de RLS é a segunda: mesmo uma query escrita sem o scope só enxerga as linhas do município.
  5. Sem o app.tenant_id definido, a comparação resulta em nulo e nenhuma linha aparece.

Jobs de fila e comandos do Artisan também precisam definir o tenant antes de tocar no banco.

Cuidados com o isolamento

  • A aplicação conecta com um usuário sem BYPASSRLS e que não é dono das tabelas. Por isso o FORCE ROW LEVEL SECURITY.
  • Para impedir uma FK que ligue linhas de municípios diferentes, as tabelas filhas podem usar FK composta: (tenant_id, pedido_id) referenciando um único (tenant_id, id).
  • Os únicos são sempre por município: dois municípios podem ter o pedido 2026/000001 e o mesmo CNPJ de fornecedor.
  • A tabela audits só aceita inserção: o usuário da aplicação perde UPDATE, DELETE e TRUNCATE.

Regras de negócio que o banco também garante

A aplicação valida primeiro, para dar uma mensagem clara. O banco fica como rede de segurança, caso algo escape. Clique em uma linha para abrir a tabela.

TabelaTipoRegra

Pontos em aberto que mexem no modelo

  1. Dois setores, um veredito. A SEMTRAS definiu uma etapa só, com a NSUAS 1 e a NSUAS 2 como aprovadoras e regra “qualquer”: fluxo_etapas com uma linha e fluxo_etapa_aprovadores com duas. Cada decisão grava o usuário, o setor dele (setor_id, guardado porque o servidor pode mudar de setor depois), a data e a hora. Falta decidir como tratar dois servidores decidindo o mesmo pedido ao mesmo tempo: a chave única atual não impede, então a action precisa travar o pedido.
  2. Quem recebe tem sempre login? Por enquanto entregas aceita recebedor_id ou recebedor_nome. Se for sempre servidor com login, o nome em texto sai.
  3. Forma de assinatura do termo. termos.forma_assinatura e arquivo_path cobrem o impresso com upload do escaneado. A assinatura eletrônica pode pedir outras colunas (data, IP, certificado).

Modelo proposto, a validar na criação das migrations · nenhum dado real · fonte: docs/requisitos/analise-requisitos.md, seções 5, 7 e 9. Fluxo completo em docs/fluxos/01-fluxo-do-sistema.html.