Capítulo 18 de 35

Automação de Registro: Sincronizando o Supabase Auth com o Banco de Dados

Índice do Manual

A criação de um novo usuário em um sistema SaaS B2B parece uma tarefa inofensiva. O usuário digita o e-mail, a senha e clica em "Cadastrar". No entanto, nos bastidores arquiteturais, esse é um dos momentos mais frágeis da engenharia de software.

Quando você utiliza uma plataforma corporativa como o Supabase, o registro ocorre em um esquema de segurança isolado (o auth.users). Porém, para que você consiga mostrar o nome ou a foto desse usuário no painel do sistema, você precisa de uma cópia dessa identidade na sua tabela pública (geralmente chamada de profiles ou usuarios).

O erro amador muito visto espalhado pelo mercado é delegar essa sincronização para o Frontend. Este manual documenta o Padrão Transacional de Registro, garantindo que o seu banco de dados nunca sofra com perfis fantasmas.


O Risco da Sincronização via Frontend

A lógica falha tradicional funciona assim no React/Next.js:

  1. O frontend chama a API de Sign Up. O usuário é criado no Supabase Auth.
  2. O frontend espera o retorno de sucesso.
  3. O frontend faz uma segunda requisição inserindo o Nome e E-mail na tabela profiles.

Onde a arquitetura quebra? Se o celular do usuário perder o sinal de internet exatamente no milissegundo entre o Passo 1 e o Passo 3, o seu sistema terá um "Usuário Fantasma". Ele existe no sistema de login, consegue autenticar, mas não tem uma linha na tabela profiles. Quando o painel do seu sistema tentar ler os dados dele, o software vai travar, disparando um erro "Null Pointer" no meio da tela.

A Solução: Automação Direta no Banco de Dados (Triggers)

A regra de ouro da engenharia de dados é: Nunca confie na rede do cliente para manter a consistência do seu banco.

Para resolvermos isso de forma definitiva, nós cortamos o Frontend da equação de sincronização. Nós configuramos o próprio motor do PostgreSQL para escutar a criação de contas e agir de forma autônoma, na velocidade da luz (latência zero).

Fazemos isso criando uma Função (Function) e um Gatilho (Trigger) diretamente no banco de dados.

O Script SQL Padrão

O script abaixo é a fundação que deve ser executada em todos os novos projetos. Ele diz ao banco de dados: "Toda vez que uma nova linha for inserida na tabela segura auth.users, copie o ID e o E-mail para a tabela pública profiles automaticamente".

-- 1. Criamos a Função de Automação
CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS trigger
LANGUAGE plpgsql
SECURITY DEFINER SET search_path = public
AS $$
BEGIN
  -- Inserimos os dados iniciais do usuário de forma automática
  INSERT INTO public.profiles (id, email, nome_completo, criado_em)
  VALUES (
    NEW.id,
    NEW.email,
    NEW.raw_user_meta_data ->> 'nome_completo', -- Extrai o nome enviado no Sign Up
    NOW()
  );
  
  RETURN NEW;
END;
$$;

-- 2. Criamos o Gatilho (Trigger) que acorda a Função
CREATE TRIGGER on_auth_user_created
  AFTER INSERT ON auth.users
  FOR EACH ROW EXECUTE PROCEDURE public.handle_new_user();

O Impacto Transacional

Ao adotar essa arquitetura, o processo se torna Atômico. O usuário não é apenas salvo; ele é registrado de forma indestrutível. Se o seu servidor cair, se a internet do cliente falhar, ou se um ataque DDoS derrubar o frontend, não importa. O banco de dados Postgres executará a inserção na tabela profiles de forma nativa e garantida.

A diferença entre um desenvolvedor que constrói "sistemas de tutorial" e um Arquiteto que orquestra plataformas B2B está na capacidade de prever a falha da rede e delegar a responsabilidade para o componente mais resiliente da infraestrutura: o banco de dados.