O que é
EDITe é um marketplace onde estudantes montam cadernos de estudo ligados a editais de concurso, publicam como ebooks e vendem para outros candidatos. O nome mudou de Caderno Edital para EDITe, mas a ideia continua: dar ao candidato uma ferramenta de criação de verdade, e não um formulário, além de um lugar para revender o que produziu.
O trabalho de engenharia mais interessante, e o mais difícil, foi o editor. Quase todo o resto do sistema é um marketplace conhecido; o editor é onde o projeto vira um problema de verdade.
Arquitetura dual-database
O sistema roda em Next.js 16 (App Router) com duas fontes de dados, cada uma para o que faz bem. O PostgreSQL, via Prisma, guarda o que é relacional e transacional: usuários, autenticação, pedidos, repasses e avaliações. O MongoDB, via Mongoose, guarda o conteúdo do caderno, que é uma árvore profundamente aninhada (subjects → items → pages → sheets) e muda de forma o tempo todo conforme o usuário edita.
Usar os dois não foi modismo, foi questão de formato de dado. Forçar uma árvore de conteúdo livre num schema relacional, ou forçar pedido e repasse dentro de um documento, seria empurrar cada coisa para a ferramenta errada. A autenticação é NextAuth v5 com Google, Facebook e credenciais, e os arquivos vão para storage compatível com S3 (MinIO).
O editor: rich text estruturado e canvas livre
Cada folha do caderno combina duas coisas que normalmente não convivem: um editor de rich text estruturado (TipTap) e um canvas de desenho livre (Fabric.js). O usuário escreve prosa organizada e, ao lado, desenha diagramas, anota e importa uma página de PDF para marcar por cima.
O canvas não é um brinquedo. Tem um sistema de ferramentas completo (caneta, formas, texto, borracha, seleção e a mão para navegar), um gerenciador de histórico próprio para desfazer e refazer, e controle de interatividade dos objetos. O desafio central foi fazer os dois modelos coexistirem sem que um corrompesse o outro: ao reabrir um caderno, o rich text precisa voltar como rich text, e o canvas como objetos editáveis do Fabric, não como uma imagem achatada.
O problema da página A4
A parte que mais me consumiu foi tratar o editor como papel de verdade. As folhas têm tamanho A4 fixo (794 por 1123 pixels a 96 DPI), e isso cria um problema que editores web normalmente ignoram: o que acontece quando o texto passa do fim da página?
Tentei primeiro a solução elegante: detectar o overflow no DOM e redistribuir o excedente para a próxima folha de forma automática, criando páginas conforme a necessidade. Funcionava, mas era uma fonte sem fim de casos de borda, porque mexer no documento durante a digitação briga com o cursor, com o autosave e com o próprio histórico do editor. Depois de muito tempo nisso, troquei por algo mais previsível: um bloqueio por limite de página. Quando a folha enche, o plugin para de aceitar entrada que adicione conteúdo, mas continua permitindo navegar, apagar, desfazer e refazer.
O aprendizado foi duro e claro: redistribuir rich text paginado de forma automática é um buraco sem fundo. Um limite explícito e honesto, que o usuário entende na hora, vale mais que uma mágica que falha de formas sutis.
Do canvas ao PDF
Publicar um caderno como ebook significa transformar tudo aquilo em um PDF fiel, e isso exige capturar cada folha. Capturar um canvas no momento certo é metade da batalha. Aprendi na marra que o toDataURL do Fabric nem sempre corresponde ao que está na tela, que a captura precisa ser adiada para o quadro seguinte de renderização, e que, quando não há miniatura gerada no cliente, dá para renderizar o JSON do Fabric no servidor com Puppeteer. O PDF final combina as imagens das folhas de canvas com o rich text convertido, e o leitor do ebook publicado renderiza as páginas com pdf.js.
Pagamentos e marketplace
Por ser multi-vendedor, o dinheiro é tão importante quanto o conteúdo. Cada autor é um vendedor com onboarding próprio, e a plataforma retém uma taxa. A primeira versão usava o Asaas para o lado brasileiro, mas migramos tudo para o Stripe Connect, com cobranças e transferências separadas, o que simplificou ter um único provedor cuidando de cobrança, repasse e saque. Há ainda um ciclo de escrow: o valor do autor fica retido e é liberado por um job, com um livro-razão por vendedor registrando cada movimento.
Status
Em produção e em evolução, hoje sob a Forge Labs. O projeto começou como Caderno Edital na AAMLabs e seguiu junto com a migração do time. O editor continua sendo o coração e o maior desafio do produto: é onde cada decisão de modelagem aparece, porque mistura texto estruturado, desenho livre e a restrição teimosa de uma folha de papel.