Todos os artigosPublicado a

Como tirei as encomendas do Notion e troquei o Filament por um backoffice à medida

A 360Películas viveu um ano com o Notion como base de dados de encomendas e o Filament como painel. O que correu mal e como migrei por fases sem parar a loja.

Durante treze meses, todas as encomendas da 360Películas, a minha loja de películas pré-cortadas para vidros de automóveis, viveram numa base de dados do Notion. O painel de administração era o Filament. Na semana de 6 de outubro de 2026 mudei as duas coisas: as encomendas passaram para a base de dados da própria aplicação e o Filament deu lugar a um backoffice feito à medida.

Convém ser exato sobre o ponto em que isto está. Hoje a loja lê e escreve na sua base de dados, e é ela que manda. O Notion ainda recebe uma cópia de cada alteração, para a equipa poder consultar as vistas a que está habituada, e vai ser desligado em breve. O Filament já saiu por completo. Este texto conta porque comecei assim, o que correu mal e como fiz a mudança sem parar a loja.

Porque começou no Notion

A loja é uma aplicação Laravel e nasceu em setembro de 2025. No segundo dia de código, uma encomenda já era criada como uma página numa base de dados do Notion. Uma semana depois entrou o Filament, para gerir o resto: catálogo de veículos, códigos de desconto, utilizadores.

O Notion dava, sem eu construir nada, aquilo de que uma loja pequena precisa para trabalhar encomendas: uma tabela, vistas por estado, filtros e edição a partir do telemóvel. A equipa trabalhava lá. Em março de 2026 o fornecedor ganhou um portal próprio na loja, que lia e escrevia nessa mesma base de dados, e o saldo pré-pago com ele era uma segunda base de dados do Notion, preenchida à mão.

Para começar a vender depressa, funcionou. O problema é que uma folha partilhada foi passando a ser o sistema onde assentavam pagamentos, emails, o portal do fornecedor e o agente de WhatsApp.

Dados sem regras

O Notion guarda o que lhe mandarem. Não tem transações, não tem chaves únicas e não sabe nada sobre o negócio. Cada uma destas faltas apareceu a seu tempo.

  • Encomendas em duplicado. A API do Notion não tem chave de idempotência: um pedido repetido cria uma segunda página. Em junho tive de garantir do lado da loja que o mesmo envio do formulário nunca criava duas encomendas.
  • Uma fórmula como preço oficial. O valor que clientes e revendedores viam vinha de uma fórmula dentro do Notion, que refazia a conta que o servidor já tinha feito. Duas implementações do mesmo cálculo, em sítios diferentes, sem nada que as mantivesse iguais. Em agosto a aplicação passou a ser a autoridade sobre o total, e ficou um teste que repete a fórmula para avisar se as duas contas se afastarem.
  • Pagamentos presos. Quando a pesquisa de uma encomenda no Notion falhava no momento em que o Stripe avisava de um pagamento, o aviso era dado como tratado e não voltava a ser tentado. Uma encomenda paga por MB WAY podia ficar como pendente. A correção foi falhar a sério, para o Stripe repetir.
  • Um só livro de encomendas, sem cópia de ensaio. O espaço do Notion é o livro real. Uma cópia local da loja com as credenciais verdadeiras lia e escrevia em encomendas verdadeiras. Hoje qualquer chamada ao Notion fora de produção é recusada no próprio cliente HTTP.
  • Regras que não cabem numa vista. Uma encomenda só pode ter um débito de produção no saldo do fornecedor. No Notion nada impede dois, e nada impede alguém de apagar uma linha para «desfazer» um engano.

O sinal mais claro foi um vaivém em julho. Como a equipa geria tudo no Notion, passei para lá também os carrinhos abandonados. Nove dias depois voltaram para a base de dados, porque precisava de lembretes, pedidos para deixar de receber mensagens e limpeza automática, e nada disso se faz bem sobre páginas de um documento.

Onde o Filament deixou de ajudar

O Filament é muito bom naquilo para que foi feito: listas e formulários sobre os modelos da aplicação. Só que a coisa mais importante da loja, as encomendas, não era um modelo da aplicação. Estava no Notion. Por isso, tudo o que tocava em encomendas eram páginas feitas à mão dentro do painel: marcar como paga, duplicar, tratar encomendas de revendedores.

Havia ainda duas tecnologias lado a lado. A loja, a área de cliente e o portal do fornecedor são React com Inertia. O painel era Livewire. Qualquer ecrã mais elaborado obrigava a escolher entre fazê-lo duas vezes ou lutar contra o painel. As páginas dos revendedores já tinham saído do Filament em dezembro de 2025, e as conversas de WhatsApp deram trabalho mais do que uma vez para aparecerem como deviam.

E a equipa precisava de mais do que listas: um quadro de encomendas por fase, uma página de encomenda com histórico, custos e comentários, o saldo do fornecedor com regras. Isso já não é um painel de administração, é a ferramenta de trabalho de todos os dias.

Mudar sem parar a loja

Não houve um dia da mudança. Houve um interruptor com três posições, e cada passo desfaz-se trocando uma variável de ambiente.

Uma única porta para as encomendas

O primeiro passo foi pôr tudo o que lê ou escreve encomendas a passar por um só ponto do código, com três implementações: notion, dual e database. A primeira é o comportamento antigo, sem tirar nem pôr, e é o valor por omissão. Um valor mal escrito conta como notion, para um erro de digitação nunca impedir uma encomenda de ser registada.

As fases

  • Espelho. Cada escrita vai primeiro para o Notion e, se ele aceitar, também para a base de dados. De cinco em cinco minutos, o que a equipa editou no Notion é trazido para o lado de cá. Ninguém nota nada.
  • Histórico. Um comando copia todas as encomendas antigas e o saldo do fornecedor. Só lê do Notion, pode ser interrompido e retomado, e nunca cria duplicados.
  • Paridade. Outro comando compara cada encomenda dos dois lados, campo a campo, e termina com «está tudo igual» ou com a lista do que difere. É também a única forma de encontrar o que foi apagado no Notion, porque o Notion não avisa quando se apaga.
  • Base de dados primeiro. É onde a loja está hoje. A escrita cai na base de dados e é esse o resultado que o cliente e a equipa veem. Só depois segue para o Notion.
  • Só base de dados. O passo seguinte: o Notion deixa de ser chamado. Depois disso, o código que fala com ele sai.

Quando o Notion falha

Antes, o Notion em baixo significava encomendas a falhar. Agora, se o Notion estiver lento ou recusar uma escrita, a encomenda não é afetada: a escrita fica numa fila de saída e é repetida todos os minutos, pela ordem original, até entrar. Como o Notion não tem chave de idempotência, cada nova tentativa procura primeiro pelo número da encomenda antes de criar o que quer que seja.

Só há uma regra de conflito: o Notion ganha, exceto se a encomenda ainda tiver uma escrita local à espera na fila. Assim, uma falha nunca deixa um estado antigo do Notion passar por cima de uma alteração mais recente.

O saldo do fornecedor

O saldo passou de uma tabela preenchida à mão para um registo de movimentos no backoffice. Nada se apaga nem se edita: para anular uma linha, cria-se outra com o valor contrário, e a original fica como estava, com o motivo e quem a anulou. Um débito por encomenda passou a ser uma regra da base de dados, e a migração listou as encomendas que, no passado, tinham sido debitadas mais do que uma vez.

Do Filament para um backoffice à medida

O novo backoffice nasceu ao lado do antigo, num endereço próprio, com o Filament a funcionar até haver paridade. Usa o mesmo React com Inertia do resto da loja, por isso tabelas, formulários e diálogos são os mesmos componentes em todo o lado.

  • Um módulo por cada recurso antigo. Perto de quarenta secções, cada uma com o seu controlador, validação, páginas e testes: clientes, catálogo, parceiros, marketing, definições, tickets de apoio e conversas de WhatsApp.
  • Encomendas como área de trabalho. Lista com separadores por fase, vistas guardadas, pesquisa, alterações em massa e exportação para CSV. Um quadro para arrastar encomendas entre fases. Uma página de encomenda com cronologia, tracking, custos e margem, e comentários.
  • Os testes mudaram primeiro. Antes de apagar o painel, tudo o que os testes dele garantiam foi levado para o backoffice. Quando o Filament saiu, havia mais de seiscentos testes do novo lado.
  • Depois, apagar. 278 ficheiros e cerca de 22 mil linhas a menos, e 37 pacotes fora das dependências, o Livewire entre eles.

Boa parte deste trabalho foi feita com agentes de IA a programar em paralelo, cada um no seu ramo. O que tornou isso seguro não foi o modelo, foram os testes e a verificação de paridade.

O que só é possível com a base de dados

Ter as encomendas em casa abriu coisas que antes não valia a pena tentar. As encomendas passaram a ter números seguidos, no formato 360-26-00001, em vez de um código com data e letras ao acaso, com a garantia de que um número nunca é atribuído duas vezes. E a equipa pode editar uma encomenda, do contacto ao preço, com a certeza de que só muda o campo em que mexeu.

O que faria de outra forma

  • A base de dados como registo oficial desde o primeiro dia. Se a equipa gosta do Notion, o Notion pode ser um espelho. É o que ele é hoje, e podia ter sido sempre.
  • Uma só porta mais cedo. O serviço que falava com o Notion era chamado de todo o lado. Metade do trabalho da migração foi juntar essas chamadas num ponto.
  • Nenhuma conta de dinheiro fora do código. Uma fórmula numa folha não tem testes nem histórico de alterações.
  • Proteger os dados reais antes de precisar. Recusar chamadas fora de produção é uma tarde de trabalho. Devia ter sido a primeira.
  • Filament para o que é CRUD, e só. Continua a ser a forma mais rápida de ter um painel. Quando o painel passa a ser a ferramenta de trabalho da equipa, é altura de o fazer à medida.

Se o seu negócio assenta numa folha de cálculo ou num Notion que já não aguenta, e quer passar para um sistema próprio sem parar de vender, pode falar comigo.

Precisa de um site que a sua equipa atualize sem ligar a um programador?

Começar um projeto