Voltar ao portfólio
ENESFRPT
Engenharia

Como Construí um ERP Completo que Gere uma Operação de E-Commerce Multi-Marketplace

18 min de leitura · 2026

Um único engenheiro. Uma plataforma totalmente personalizada. 12 contas de marketplace. ~100 encomendas/dia. 5 colaboradores a utilizá-la diariamente. Esta é a história técnica completa de como concebi, construí e operei toda a plataforma de produção por detrás da REUSALIA — desde o primeiro bot Selenium até um ERP completo com APIs obtidas por engenharia inversa, pipelines de IA e integração com hardware físico.

O Problema: Gerir um Negócio Real com Processos Manuais

Em abril de 2023, fundei a REUSALIA — uma empresa de e-commerce que compra paletes de liquidação da Amazon, processa o inventário e revende artigos individuais em vários marketplaces (Wallapop, eBay, PortalHero). O modelo de negócio é simples. As operações por detrás dele não são.

Cada palete que chega contém 50 a 200 artigos variados. Cada artigo tem de ser inspecionado, fotografado, categorizado, avaliado, anunciado em várias plataformas, acompanhado ao longo das vendas, embalado e expedido. Multiplique isto por milhares de SKUs distribuídos por 12 contas de marketplace e começa a perceber a dimensão do problema.

Quando comecei, tudo era manual. Anunciar um único artigo no Wallapop demorava 5 a 10 minutos a escrever. As encomendas chegavam através de várias contas e tinham de ser verificadas uma a uma. O inventário era controlado em Google Sheets. Não existia qualquer sistema — apenas uma pessoa com um portátil e um armazém.

Três anos mais tarde, toda a operação assenta numa plataforma que construí de raiz: um backend FastAPI com mais de 25 modelos de base de dados, um ERP personalizado em Retool com mais de 10 módulos operacionais, APIs de marketplace obtidas por engenharia inversa, enriquecimento de produtos com IA e uma ponte de hardware personalizada que liga interfaces na cloud a impressoras de etiquetas físicas. Esta é a história de como tudo evoluiu.

Fase 1: A Era do Selenium (2023)

O primeiro problema técnico que resolvi foi o mais penoso: publicar anúncios no Wallapop.

O Wallapop não tem qualquer API de publicação em massa. Não há importação por CSV. Não há forma de anunciar produtos em escala. Cada anúncio tinha de ser criado manualmente através da interface web — preencher o título, a descrição, a categoria, o preço, carregar fotografias, definir a localização, confirmar. A 5 a 10 minutos por artigo, anunciar um catálogo de 500 a 600 artigos era um trabalho a tempo inteiro.

Então construí um bot Selenium que automatizava todo o fluxo. Abria um navegador, navegava até ao formulário de anúncio, preenchia todos os campos, carregava imagens e submetia. Cada anúncio demorava cerca de 1 minuto (deliberadamente abrandado para evitar deteção).

Mas 1 minuto por artigo ao longo de 600 artigos continua a ser 10 horas. E eu precisava de voltar a anunciar de 3 em 3 dias para manter o posicionamento no marketplace. Por isso escalei da única forma que conseguia: horizontalmente, em várias máquinas físicas.

Montei 5 a 6 PCs, liguei-me a cada um remotamente via AnyDesk e lancei várias instâncias de bot por máquina. Cada instância usava cookies e user agents diferentes. Desta forma, conseguia publicar todo o meu catálogo em cerca de uma hora. De 3 em 3 dias, passava uma hora a gerir a frota distribuída de bots.

Era feio. Era frágil. Funcionava.

O Que Aprendi

Fase 2: Engenharia Inversa da API Privada do Wallapop (2023-2024)

À medida que o negócio crescia, também crescia a complexidade operacional. Passámos de 10 encomendas por dia para quase 100. De 1 conta Wallapop para 12. A abordagem com Selenium já não conseguia escalar — nem para publicação, e muito menos para a gestão de encomendas.

O problema é que o Wallapop é um ecossistema fechado. Sem API pública. Sem documentação. Sem integrações de terceiros. Tudo acontece dentro da sua aplicação e do seu site. Para a maioria das pessoas, isto é um muro. Para mim, foi um convite.

Comecei a intercetar o tráfego de rede. Em cada ação que realizava no site — navegar por anúncios, verificar encomendas, ler conversas — capturava o pedido HTTP, estudava os cabeçalhos, descodificava os payloads e mapeava as estruturas das respostas.

O Processo de Descoberta

Fazer engenharia inversa de uma API privada é trabalho de detetive:

  1. Capturar — Usar as DevTools do navegador para intercetar todos os pedidos durante uma sessão
  2. Classificar — Agrupar pedidos por padrão de endpoint e método HTTP
  3. Descodificar — Analisar os cabeçalhos dos pedidos (em especial a autorização), os parâmetros de query e as estruturas JSON das respostas
  4. Cruzar referências — Comparar respostas de diferentes contas para identificar o que é específico do utilizador face ao que é universal
  5. Replicar — Construir um cliente Python capaz de se autenticar e fazer os mesmos pedidos fora do navegador
  6. Iterar — Quando o Wallapop altera a sua API (e altera), atualizar o cliente

Ao longo de 5 versões principais da base de código do extrator, mapeei o seu sistema de autenticação (baseado em cookies com bearer tokens), os seus endpoints de gestão de encomendas, a sua API de conversas e o seu sistema de metadados de anúncios. O resultado: mais de 2100 linhas de código Python de produção capazes de:

A arquitetura multi-conta foi a parte mais difícil. Cada conta tem o seu próprio ciclo de vida de autenticação: os cookies expiram, os tokens precisam de ser renovados, as sessões são invalidadas. Construí um gestor de autenticação centralizado que armazena as credenciais em PostgreSQL, renova automaticamente os tokens entre sessões e fornece contextos de autenticação limpos a cada extrator.

Ninguém mais construiu isto. Existem ferramentas como o PortalHero para publicação em massa, mas nada para extração. Os nossos extratores são únicos — e são eles que tornam possível gerir uma operação de 12 contas com uma equipa de 5 pessoas, em vez de uma equipa de operações manuais muito maior.

Fase 3: A Plataforma Central — FastAPI + PostgreSQL (2024-2025)

Com os extratores a alimentar dados de forma fiável, precisava de um sítio onde esses dados pudessem viver e de algo que fizesse uso deles. O Google Sheets já não chegava (isso é uma história totalmente à parte).

Concebi a plataforma central em torno de três princípios:

  1. Fonte única de verdade — Cada elemento de dados vive em PostgreSQL. Sem folhas de cálculo, sem ficheiros locais, sem "atualizo depois"
  2. API-first — Cada operação passa pelo backend FastAPI. O frontend do ERP personalizado construído em Retool, os extratores, os motores de sincronização — todos comunicam com a mesma API
  3. Automação operacional — Se um humano faz algo mais de duas vezes, deve ser automatizado

Desenho da Base de Dados

O esquema PostgreSQL tem mais de 25 modelos com mais de 35 migrações, abrangendo:

Uso SQLModel (SQLAlchemy + Pydantic) para a camada ORM, o que me dá modelos type-safe que funcionam tanto para operações de base de dados como para serialização da API. O Alembic trata das migrações e nunca tive de reverter uma em produção.

Arquitetura da API

O backend FastAPI expõe ~60 endpoints que cobrem operações CRUD, lógica de negócio e integrações. Decisões de desenho fundamentais:

Fase 4: O ERP — Frontend em Retool (2025)

Uma base de dados e uma API não servem de nada se a sua equipa não conseguir interagir com elas. Precisava de uma interface que 6 colaboradores não técnicos pudessem usar diariamente — para tudo, desde processar paletes que chegavam até expedir encomendas e acompanhar incidentes.

Escolhi o Retool porque me permitiu construir um frontend de ERP complexo e multi-módulo em semanas, em vez de meses. O resultado: um ERP personalizado com mais de 10 módulos operacionais:

O grande desafio com o Retool foi fazer com que parecesse nativo. As aplicações Retool por defeito parecem painéis de administração. Investi um esforço considerável em CSS personalizado, renderização condicional e fluxos de UX intuitivos para colaboradores de armazém que nunca tinham usado software empresarial.

Fase 5: Pipeline de Enriquecimento de Produtos com IA

Uma das partes mais demoradas do negócio é a criação de anúncios de produtos. Cada artigo precisa de:

Escrever isto manualmente para milhares de SKUs é uma loucura. A ~15 minutos por artigo, são mais de 40 horas por semana só em descrições. Por isso construí um pipeline de IA:

  1. Amazon Scraper — Identifica produtos do nosso inventário de paletes na Amazon.es, extrai títulos, descrições, características, imagens e preços. Anti-deteção com rotação de UA e limitação de pedidos para evitar bloqueios
  2. GPT Enrichment — Alimenta os dados extraídos no GPT-4 com prompts estruturados. O modelo categoriza artigos, gera títulos específicos para cada marketplace (o estilo do Wallapop é muito diferente do estilo do eBay), escreve descrições e sugere preços
  3. Image Pipeline — Descarrega imagens de produtos, aplica transformações anti-duplicação (OpenCV) para evitar os filtros de imagens duplicadas dos marketplaces, redimensiona e comprime para um carregamento ótimo
  4. Listing Sync — Envia os dados enriquecidos para cada marketplace com adaptações específicas de formato

O pipeline corre de forma autónoma. Alimento-o com um lote de novos artigos e, horas depois, tenho anúncios totalmente enriquecidos prontos a publicar em todos os marketplaces. O que antes ocupava a semana inteira de um colaborador a tempo inteiro corre agora em segundo plano enquanto processamos a palete seguinte.

Fase 6: A Ponte Cloud-Local (O Problema Mais Difícil)

Eis um problema de que ninguém fala nos blogues de arquitetura: como se imprime uma etiqueta de expedição física a partir de uma UI na cloud?

O frontend do nosso ERP personalizado corre no Retool Cloud. A nossa impressora de etiquetas é uma Brother QL-700 ligada por USB a um PC no armazém. Não existe um caminho cloud-nativo entre os dois. Precisava de fazer a ponte sem obrigar a equipa do armazém a alternar entre aplicações.

A solução é aquilo a que chamo o Command Bridge Pattern:

  1. A UI do Retool escreve um registo de comando em PostgreSQL (por exemplo, "imprimir etiqueta para a encomenda #1234")
  2. Um daemon Python local no PC do armazém sonda novos comandos de poucos em poucos segundos
  3. Quando encontra um, adquire um bloqueio exclusivo na base de dados, processa o comando (gera e imprime a etiqueta) e marca-o como concluído
  4. A UI do Retool deteta a atualização de estado e reflete-a ao utilizador

A parte complicada é a fiabilidade. E se o daemon local falhar? E se duas instâncias correrem em simultâneo? Implementei:

Este padrão trata agora não só da impressão de etiquetas, mas de qualquer operação que exija interação com hardware local a partir de uma interface na cloud.

Fase 7: Sincronização Multi-Marketplace

Com o inventário em PostgreSQL, os anúncios enriquecidos por IA e as encomendas a fluir pelos extratores, a peça final era manter tudo sincronizado entre os marketplaces.

O motor de sincronização mantém o PostgreSQL como fonte única de verdade e envia dados formatados para cada plataforma:

Quando um artigo é vendido numa plataforma, o motor de sincronização retira-o das outras em poucos minutos. Quando atualizo um preço no ERP, ele propaga-se para todo o lado. Quando chega novo inventário, os anúncios vão para todos os marketplaces em simultâneo.

A Arquitetura Completa

Afastando o zoom, o sistema completo tem o seguinte aspeto:


Data Sources          Processing Layer        Core              Outputs
─────────────         ────────────────        ────              ───────
Wallapop API ──┐                           ┌──────────┐
eBay API ──────┤      FastAPI Backend       │PostgreSQL│ Custom ERP Frontend
Amazon Scraper ┤──→   ( extractors )   ──→  │25+ models│──→ (   Retool ERP    )
PortalHero ────┤      ThreadPoolExecutor    │35+ migr. │      10+ modules
Google Drive ──┘      OpenAI GPT-4          └──────────┘
                                                │
                                      Command Bridge Pattern
                                      (excl. lock + heartbeat)
                                                │
                                         Local Hardware
                                      (Brother QL-700 printer)

Cada componente comunica com a mesma API. Cada elemento de dados vive na mesma base de dados. Cada operação é registada, acompanhada e recuperável.

Escala e Impacto

Eis o que este sistema gere em produção, diariamente:

MétricaValor
Encomendas processadas/dia~100+
Contas de marketplace ativas12
Membros da equipa a usar o ERP diariamente6
Marketplaces sincronizados3 (Wallapop, eBay, PortalHero)
Processamento manual de encomendas substituído~5h/dia
Criação manual de anúncios substituída~40h/semana
APIs de marketplace obtidas por engenharia inversaWallapop, eBay
Módulos do ERP (Retool)10+
Modelos de base de dados25+
Migrações de base de dados35+
Versões do extrator (Wallapop)5 principais

Isto não é um projeto de demonstração. É um sistema de produção que gere inventário real, dinheiro real e operações reais de clientes. Todos os dias. Construído e mantido por um único engenheiro.

O Que Faria de Forma Diferente

Três anos de iteração ensinam-nos muito sobre os nossos próprios erros:

A Conclusão

Construir um ERP de produção como engenheiro solo enquanto se gere o próprio negócio que ele foi concebido para automatizar é um desafio de engenharia único. Somos, em simultâneo, o arquiteto, o programador, o DBA, o QA, o engenheiro de DevOps e o gestor de produto — além de CEO, gestor de armazém e responsável pelo apoio ao cliente.

O trabalho técnico é a parte fácil. A parte difícil é:

Não trocaria isto por nada. É assim que se parece a engenharia a sério — não código perfeito, mas código que resolve problemas reais para pessoas reais, todos os dias.

Os componentes da plataforma são open-source: github.com/AspiranteD/AspiranteD