# Como transformar uma planilha em um app web com banco de dados e login

Sua planilha já guarda os dados e as regras; ela só não consegue aplicá-las. Anexá-la a um agente de IA transforma os mesmos dados em um app multiusuário que você pode proteger, estender e publicar.

URL: https://www.back4app.com/blog/pt/como-transformar-uma-planilha-em-um-app-web-com-banco-de-dados
Publicado: 2026-10-13 · Testado: 2026-09-22
Testado em: Agente: Back4app AI Agent, plano Free, workspace de rascunho · Fonte: planilha de inventário com 25 linhas (.xlsx) · Local: macOS, Chromium
Publisher: Back4app Engineering

Sua planilha não está falhando porque foi mal construída. Ela está falhando porque está sendo cobrada por coisas que um arquivo não consegue fazer: deixar cinco pessoas trabalharem ao mesmo tempo, impedir que a pessoa errada edite a célula errada, lembrar quem mudou o quê e avisar alguém quando um número cruza uma linha.

Cada um desses itens é um recurso de banco de dados. Conseguir isso sempre significou uma reescrita: um schema, um backend, um login, um frontend, um lugar para rodar tudo. É esse custo que mantém empresas presas ao arquivo por anos depois de ele ter parado de funcionar.

Você pode pular essa etapa. Anexe o arquivo ao Back4app AI Agent, descreva em uma frase o que você quer, e recebe um app web em execução com um banco de dados gerenciado por trás, pronto para proteger, estender e publicar. Este guia leva uma planilha de inventário com 25 linhas até o fim desse caminho.

## Prefere assistir?

O mesmo caminho, do início ao fim, em vídeo: uma planilha entra, e sai um app funcional com banco de dados, login, assistente de IA e alertas por e-mail. Vinte e cinco minutos, sem código.

## O que você realmente ganha quando a planilha vira um app?

Tudo o que o arquivo estava substituindo, sem que você construa nada disso. As linhas viram registros em um banco de dados gerenciado, e em volta deles ficam uma interface web, um sistema de login e APIs que outros sistemas podem chamar.

A parte que mais importa é invisível na interface. Cada registro carrega sua própria lista de controle de acesso (ACL), então a permissão é por linha, não por arquivo, e as regras que a aplicam rodam no servidor, onde um navegador não tem como discutir.

Essa é a diferença entre compartilhar um arquivo e operar um sistema. Um arquivo compartilhado confia em todo mundo que consegue abri-lo; um registro com ACL decide, linha a linha, quem pode ler e quem pode alterar.

![Um arquivo de planilha vira uma aplicação com banco de dados real e regras de acesso por registro, login com Google, interface web gerada e APIs REST e GraphQL, com conexões opcionais a modelos de IA e provedores de e-mail e SMS, publicada em um servidor de produção próprio](/blog/blog-assets/turn-a-spreadsheet-into-a-web-app-with-a-database/architecture-diagram.svg)

## Como transformar sua planilha em um app?

Anexe o arquivo e diga no que ele deve se transformar. Abra o agente, clique em *Attach*, escolha *Attachment*, selecione o seu `.xlsx` e descreva o objetivo em linguagem natural antes de apertar *Build it*.

Arrume a planilha antes e o resultado sai melhor: uma linha de cabeçalho, uma linha por item. Células mescladas e linhas de título empilhadas dão ao agente uma estrutura para adivinhar, e ele vai adivinhar.

Mantenha o primeiro prompt sobre estrutura, não sobre aparência. Cores, textos e colunas extras saem mais baratos depois, quando já existe algo na tela para mudar.

![A tela inicial do Back4app AI Agent com inventory.xlsx anexado a um prompt pedindo para ler o arquivo, interpretar os dados e criar uma estrutura de dados correspondente](/blog/blog-assets/turn-a-spreadsheet-into-a-web-app-with-a-database/01-attach-prompt.jpg)

Alguns minutos depois, o preview troca o placeholder pelo seu app. Você pode usá-lo imediatamente (buscar, filtrar, navegar) e continuar mudando o que quiser, só pedindo.

## O que o agente descobre sozinho?

Mais do que as colunas que você entregou. Ele lê o que os seus dados significam, não só a forma deles, e constrói a interface que esse significado pede.

O nosso encontrou uma coluna de categoria e a transformou em filtros para todos os doze valores. Percebeu que estoque e nível de reposição estavam lado a lado, inferiu que um deveria ser comparado com o outro e colocou no topo da página, como alerta, a contagem de itens abaixo da linha.

![A dashboard de inventário gerada: totais no topo, uma contagem de itens que precisam de atenção, um catálogo com busca e um botão de filtro para cada categoria encontrada nos dados](/blog/blog-assets/turn-a-spreadsheet-into-a-web-app-with-a-database/02-generated-app.jpg)

Ele também soma as colunas que valem a pena somar. O nosso reportou 25 produtos, 662 unidades em estoque e 9 itens abaixo do nível de reposição, cada número batendo com a planilha, calculado sem que pedíssemos nenhum deles.

## Onde seus dados ficam, e o que eles ganham?

Em uma classe de banco de dados gerenciado que você vê e edita na aba *Database*. Cada linha da planilha é um registro, e cada registro agora carrega quatro campos que o arquivo nunca teve.

| Campo | O que ele te dá |
|---|---|
| `id` | Uma identidade permanente, para o registro continuar sendo a mesma coisa seja qual for a ordenação da visualização |
| `createdat` | Quando apareceu pela primeira vez |
| `updatedat` | Quando foi alterado pela última vez |
| `acl` | Regras de acesso por registro: quem pode ler ou escrever *nesta* linha |

Leia os nomes reais dos campos uma vez antes de construir em cima deles. Os cabeçalhos são normalizados de snake_case para camelCase (nosso `reorder_level` virou `reorderLevel`), enquanto `item`, `stock` e `category` passaram sem alteração. A aba Database renderiza todo nome de coluna em minúsculas, então confira os tipos gerados, não a linha de cabeçalho.

![A aba Database do agente listando a classe InventoryItem com todos os 25 registros e suas oito colunas](/blog/blog-assets/turn-a-spreadsheet-into-a-web-app-with-a-database/03-database-tab.jpg)

Esses registros também não ficam presos dentro da interface. Eles estão atrás de APIs REST e GraphQL, então outro sistema, um script ou um app mobile pode ler e escrever os mesmos dados.

## Como adicionar login sem configurar um provedor de identidade?

Pedindo. Não há cliente OAuth para registrar, nem redirect URI para configurar, nem console de provedor para abrir: o fluxo gerenciado já vem ligado para você, e os usuários que ele cria ficam armazenados no app.

O preview então abre em uma tela de login em vez da sua dashboard. Usuários logados chegam ao app; todo o resto para na porta.

![A tela de login gerada, com o texto "Your stock. Under lock." e um botão Continue with Google](/blog/blog-assets/turn-a-spreadsheet-into-a-web-app-with-a-database/05-login-screen.jpg)

## Como deixar o app seguro para uso real?

Colocando as regras onde não podem ser contornadas. Abra a aba *Code* e veja `cloud/main.js`: isto é Cloud Code, rodando no servidor, e foi o que o prompt de login adicionou:

```js
// Stack: Parse Server 7.5.2 | File: cloud/main.js
Parse.Cloud.beforeFind('InventoryItem', (request) => {
  if (!request.user) {
    throw new Parse.Error(Parse.Error.SESSION_MISSING, 'Sign in is required to access inventory.');
  }
});
```

Essa é a vantagem de um backend de verdade sobre um arquivo compartilhado: a checagem roda antes de cada consulta, no servidor, para todo cliente. Ninguém chega aos seus dados abrindo as ferramentas de desenvolvedor do navegador.

`beforeFind` protege a leitura. A escrita passa por seus próprios triggers, então adicione estes dois no mesmo arquivo e a mesma proteção cobre criar, atualizar e excluir:

```js
// Stack: Parse Server 7.5.2 | File: cloud/main.js
Parse.Cloud.beforeSave('InventoryItem', (request) => {
  if (!request.user) {
    throw new Parse.Error(Parse.Error.SESSION_MISSING, 'Sign in is required to change inventory.');
  }
});

Parse.Cloud.beforeDelete('InventoryItem', (request) => {
  if (!request.user) {
    throw new Parse.Error(Parse.Error.SESSION_MISSING, 'Sign in is required to delete inventory.');
  }
});
```

![A aba Code mostrando cloud/main.js com o hook beforeFind em InventoryItem](/blog/blog-assets/turn-a-spreadsheet-into-a-web-app-with-a-database/06-cloud-main-beforefind.jpg)

Depois, aperte o campo `acl` a partir do padrão da importação, para que cada registro diga quem é seu dono, e decida quais contas logadas podem entrar. Os dois ficam a um prompt de distância, e a mecânica está em [como proteger o backend que seu frontend acessa](https://www.back4app.com/blog/lock-down-a-backend-your-frontend-talks-to).

## Como conectar IA, e-mail e SMS?

Pela aba *Connections*, com uma chave da sua própria conta. Cada provedor exige um único colar: OpenRouter para modelos de IA, Resend para e-mail, Twilio para SMS e WhatsApp.

| Conecte | Para obter | Cobrança |
|---|---|---|
| OpenRouter | Um chatbot sobre seus registros, alcançando centenas de modelos com uma única chave | Sua conta OpenRouter; há modelos gratuitos |
| Resend | E-mail quando um limite é cruzado: um nível de reposição, um vencimento, um teto | Sua conta Resend; plano gratuito com 100 e-mails/dia |
| Twilio | Os mesmos alertas por SMS ou WhatsApp, quando precisam chegar a um telefone | Sua conta Twilio |

Clique em *Connect*, escolha *I already have a key*, cole a chave e espere a linha mostrar *ACTIVE*. A chave é armazenada como secret, com só os quatro últimos caracteres visíveis, fora do app e definida separadamente para rascunho e produção.

![A aba Connections com OpenRouter e Resend marcados como ACTIVE, suas chaves mascaradas, e Twilio ainda disponível para conectar](/blog/blog-assets/turn-a-spreadsheet-into-a-web-app-with-a-database/07-connections-active.jpg)

## Como adicionar um chatbot que não consegue alterar seus dados?

Diga o que ele não pode fazer, não só o que pode. Um chatbot instruído a "responder perguntas sobre o inventário" recebeu uma capacidade e nenhum limite; nomeie a proibição e você recebe uma ferramenta mais estreita.

O que volta é um botão *Ask inventory*, um painel rotulado *Read-only access* e uma Cloud Function chamada `askInventory` que faz a conversa. Pergunte algo específico e ele responde a partir dos seus registros ao vivo:

![O assistente de inventário gerado respondendo a uma pergunta sobre estoque e níveis de reposição, e depois recusando um pedido para excluir um item e alterar um nível de estoque](/blog/blog-assets/turn-a-spreadsheet-into-a-web-app-with-a-database/09-chatbot-answer.jpg)

O nosso reportou estoque 25 contra um nível de reposição de 29 para um produto, depois contou os itens de uma categoria que precisavam de reposição e nomeou os que não precisavam. Todos os números bateram com a planilha de origem.

Quando pedimos para excluir um produto e definir o estoque de outro em 999, ele recusou, e a aba Database confirmou os dois registros intactos. A recusa não é educação: a função só executa uma consulta e devolve texto, então o modelo não tem como escrever nem que tentasse.

Duas coisas vêm junto que você não pediu e quer mesmo assim. A chamada à IA acontece no Cloud Code, então sua chave do OpenRouter fica no servidor e nunca chega ao navegador; e cada usuário tem um teto de 50 perguntas por dia, rastreado em uma classe própria.

## Como enviar e-mail quando o estoque fica baixo?

Descreva o gatilho e o destinatário. O Resend já está conectado, então o prompt é sobre *quando*, não sobre *como*.

O agente escreve um trigger `afterSave` que dispara só quando um item cruza *de cima* do limite para igual ou abaixo dele, então editar um item que já está baixo não envia o mesmo alerta duas vezes. Derrube o valor de estoque abaixo do nível de reposição e o e-mail chega com item, categoria, estoque, limite e falta.

Vale provocar essa falha de propósito uma vez, porque ela ensina o ciclo que você vai usar para todo o resto: o trigger dispara, a aba Logs informa o status HTTP, você cola o erro de volta no chat e o agente corrige. O nosso corrigiu o destinatário em meio minuto, e o cruzamento de limite seguinte foi entregue.

## Como colocar no ar?

Aperte *Publish*. Tudo até aqui vive em um workspace de rascunho feito para iteração, e publicar copia tudo para um servidor de produção próprio, com dados próprios e secrets próprios.

Leia o diálogo antes de confirmar. Ele conta os arquivos que vão no deploy, as entradas de banco de dados que viajam junto e os secrets que precisam de valor do outro lado: o último momento para notar uma chave de teste prestes a virar chave de produção.

Depois disso os dois ficam separados, e esse é o ponto: você continua mandando prompts para o rascunho sem tocar no que seus usuários estão usando, e publica de novo quando a mudança estiver pronta.

## Quando esta não é a ferramenta certa?

Quando as regras são o produto. Se a parte difícil é um motor de precificação ou um fluxo de compliance que levou anos para acertar, uma interface gerada nunca foi o seu gargalo.

Quando quatro departamentos discordam sobre o que a planilha significa. Importá-la transforma a discordância em um schema sem resolvê-la, e com um schema é mais difícil discutir.

E quando os dados precisam ficar em um data warehouse ou ERP já existente. Um app dono de uma segunda cópia cria um problema de sincronização pior do que o arquivo de onde você partiu.

## O que fazer primeiro?

Pegue a planilha mais bagunçada que você tem e anexe. A distância entre ler sobre isso e saber se serve para você é de um prompt, e o resultado é um app funcional para clicar, não um plano para avaliar.

Depois adicione as guardas de escrita acima e publique. O que você terá é aquilo que a planilha fingia ser: uma cópia dos dados, várias pessoas usando ao mesmo tempo, regras que se sustentam e espaço para crescer.
