Pular para o conteúdo principal

Como construí esta aplicação usando ferramentas de IA

Motivação

Comecei a usar Duplicati como ferramenta de backup para meus servidores domésticos. Testei o painel oficial do Duplicati e Duplicati Monitoring, mas tinha dois requisitos principais: (1) auto-hospedado; e (2) uma API exposta para integração com Homepage, pois a uso para a página inicial do meu laboratório doméstico.

Também tentei conectar diretamente a cada servidor Duplicati na rede, mas o método de autenticação não era compatível com o Homepage (ou não consegui configurá-lo adequadamente).

Como também estava experimentando ferramentas de código com IA, decidi tentar usar IA para construir esta ferramenta. Aqui está o processo que utilizei...

Ferramentas utilizadas

  1. Para a interface: Firebase Studio do Google
  2. Para a implementação: Cursor (https://www.cursor.com/)
nota

Usei Firebase para a interface, mas você também pode usar v0.app ou qualquer outra ferramenta para gerar o protótipo. Usei Cursor para gerar a implementação, mas você pode usar outras ferramentas, como VS Code/Copilot, Windsurf, ...

Interface

Criei um novo projeto no Firebase Studio e usei este prompt no recurso "Prototipar um aplicativo com IA":

Um aplicativo de dashboard web usando tailwind/react para consolidar em um banco de dados sqlite3 os resultados de backup enviados pela solução de backup duplicati usando a opção --send-http-url (formato json) de várias máquinas, mantendo o rastreamento do status do backup, tamanho, tamanhos carregados.

A primeira página do dashboard deve ter uma tabela com o último backup de cada máquina, incluindo o nome da máquina, número de backups armazenados no banco de dados, o status do último backup, duração (hh:mm:ss), número de avisos e erros.

Ao clicar em uma linha da máquina, mostrar uma página de detalhes da máquina selecionada com uma lista dos backups armazenados (paginada), incluindo o nome do backup, data e hora do backup, incluindo há quanto tempo foi realizado, o status, número de avisos e erros, número de arquivos, tamanho dos arquivos, tamanho carregado e o tamanho total do armazenamento. Incluir também na página de detalhes um gráfico usando Tremor com a evolução dos campos: tamanho carregado; duração em minutos, número de arquivos examinados, tamanho dos arquivos examinados. O gráfico deve plotar um campo por vez, com uma caixa de seleção para escolher o campo desejado a plotar. O gráfico também deve apresentar todos os backups armazenados no banco de dados, não apenas os mostrados na tabela paginada.

A aplicação deve expor um endpoint de api para receber o post do servidor duplicati e outro endpoint de api para recuperar todos os detalhes do último backup de uma máquina como json.

O design deve ser moderno, responsivo e incluir ícones e outros auxílios visuais para facilitar a leitura. O código deve ser limpo, conciso e fácil de manter. Use ferramentas modernas como pnpm para lidar com dependências.

A aplicação deve ter um tema escuro e claro selecionável.

O banco de dados deve armazenar estes campos recebidos pelo json do duplicati:

"{ "Data": { "DeletedFiles": 0, "DeletedFolders": 0, "ModifiedFiles": 0, "ExaminedFiles": 15399, "OpenedFiles": 1861, "AddedFiles": 1861, "SizeOfModifiedFiles": 0, "SizeOfAddedFiles": 13450481, "SizeOfExaminedFiles": 11086692615, "SizeOfOpenedFiles": 13450481, "NotProcessedFiles": 0, "AddedFolders": 419, "TooLargeFiles": 0, "FilesWithError": 0, "ModifiedFolders": 0, "ModifiedSymlinks": 0, "AddedSymlinks": 0, "DeletedSymlinks": 0, "PartialBackup": false, "Dryrun": false, "MainOperation": "Backup", "ParsedResult": "Success", "Interrupted": false, "Version": "2.1.0.5 (2.1.0.5_stable_2025-03-04)", "EndTime": "2025-04-21T23:46:38.3568274Z", "BeginTime": "2025-04-21T23:45:46.9712217Z", "Duration": "00:00:51.3856057", "WarningsActualLength": 0, "ErrorsActualLength": 0, "BackendStatistics": { "BytesUploaded": 8290314, "BytesDownloaded": 53550393, "KnownFileSize": 9920312634, "LastBackupDate": "2025-04-22T00:45:46+01:00", "BackupListCount": 6, "ReportedQuotaError": false, "ReportedQuotaWarning": false, "MainOperation": "Backup", "ParsedResult": "Success", "Interrupted": false, "Version": "2.1.0.5 (2.1.0.5_stable_2025-03-04)", "BeginTime": "2025-04-21T23:45:46.9712252Z", "Duration": "00:00:00", "WarningsActualLength": 0, "ErrorsActualLength": 0 } }, "Extra": { "OperationName": "Backup", "machine-id": "66f5ffc7ff474a73a3c9cba4ac7bfb65", "machine-name": "WSJ-SER5", "backup-name": "WSJ-SER5 Local files", "backup-id": "DB-2" } } "

isso gerou um Blueprint de Aplicativo, que depois modifiquei ligeiramente (como abaixo) antes de clicar em Prototype this App:

appblueprint

Depois usei estes prompts para ajustar e refinar o design e o comportamento:

remova o botão "Ver detalhes" da página de visão geral do dashboard e o link no nome da máquina, se o usuário clicar em qualquer lugar da linha, será mostrada a página de detalhes.

ao apresentar tamanhos em bytes, use uma escala automática (KB, MB, GB, TB).

na página de detalhes, mova o gráfico após a tabela. Altere a cor do gráfico de barras para outra cor compatível com temas claro e escuro.

na página de detalhes, reduza o número de linhas para apresentar 5 backups por página.

na visão geral do dashboard, coloque um resumo no topo com o número de máquinas no banco de dados, número total de backups de todas as máquinas, o tamanho total carregado de todos os backups e armazenamento total usado por todas as máquinas. Inclua ícones para facilitar a visualização.

por favor, persista a seleção de tema do usuário. também, adicione algumas margens laterais e faça a interface usar 90% da largura disponível.

no cabeçalho do cartão de detalhes da máquina, inclua um resumo com o total de backups armazenados para esta máquina, uma estatística do status do backup, o número de avisos e erros do último backup, a duração média em hh:mm:ss, o tamanho total carregado de todos os backups e o tamanho de armazenamento usado com base nas informações do último backup recebido.

torne o resumo menor e mais compacto para reduzir o espaço utilizado.

ao apresentar a data do último backup, mostre na mesma célula, em fonte cinza pequena, o tempo decorrido desde que o backup aconteceu (por exemplo, x minuto atrás, x horas atrás, x dias atrás, x semanas atrás, x meses atrás, x anos atrás).

na visão geral do painel, coloque a data do último backup antes do status do último backup

Após iterar por esses prompts, o Firebase gerou o protótipo conforme mostrado nas capturas de tela abaixo:

protótipo

protótipo-detalhe

nota

Um ponto interessante foi que, desde a primeira interação, o Firebase Studio gerou dados aleatórios para preencher as páginas/gráficos, fazendo o protótipo funcionar como uma aplicação ao vivo.

Após concluir o protótipo inicial, acessei o código-fonte clicando no botão </> na interface. Em seguida, usei a extensão Git para exportar o código e enviá-lo para um repositório privado no GitHub.

Backend

Configuração​

Baixei o código do GitHub (usando o comando git clone) para uma pasta local (no meu caso, um Raspberry Pi 5 executando Linux) e instalei as dependências Node.js, npm e pnpm. Veja mais detalhes em DEVELOPMENT.md.

Configurei o Cursor para acessar a pasta de código da minha máquina Windows usando uma conexão SSH.

Copiei uma amostra do JSON enviado pelo Duplicati para um arquivo (veja o documento relatório de backup de amostra), removendo alguns campos indesejados.

Implementação​

Usei um prompt inicial para começar a implementação, focando em persistência, correções e novos recursos. Foi um processo longo, mas muito interessante.

Usando IA para gerar o prompt​

Criei um prompt detalhado usando o Cursor Chat (modo Manual, modelo Auto):

melhore este texto como um prompt para a ferramenta cursor ai para gerar a implementação de um protótipo de aplicação:

por favor, crie um plano e gere a implementação completa de um protótipo de aplicação Next.js a partir desta base de código. Sua implementação deve analisar minuciosamente a base de código fornecida para manter a estética visual exata, a experiência do usuário e o fluxo de navegação. Para armazenamento de dados, utilize SQLite3. Gere o banco de dados e popule-o usando a estrutura e o conteúdo encontrados no documento relatório de backup de amostra, garantindo que cada campo do JSON seja totalmente integrado e persistido.

A IA gerou o seguinte prompt:

Crie um plano de implementação abrangente para um protótipo de aplicativo Next.js com os seguintes requisitos:

  1. Pilha Técnica:
  • Next.js 14+ com App Router

  • TypeScript para segurança de tipos

  • SQLite3 para persistência de dados

  • TailwindCSS para estilização

  • Componentes de Servidor React onde apropriado

  • Componentes de cliente para elementos interativos

  1. Design do Banco de Dados:
  • Analise o documento de relatório de backup de amostra para criar um esquema SQLite ótimo

  • Projete tabelas para armazenar todos os dados de backup de forma eficiente

  • Inclua índices para consultas comuns

  • Implemente validação de dados e segurança de tipos

  1. Estrutura do Aplicativo:
  • Implemente a UI/UX exata do código-fonte fornecido

  • Crie componentes reutilizáveis para elementos comuns

  • Configure a roteirização adequada usando App Router

  • Implemente layouts responsivos

  • Adicione suporte para temas escuro e claro

  1. Funcionalidades Principais:
  • Visão geral do painel com tabela de status da máquina

  • Visualização detalhada da máquina com histórico de backup

  • Visualização de dados usando gráficos

  • Atualizações em tempo real do status do backup

  • Tratamento de erros e estados de carregamento adequados

  1. Gerenciamento de Dados:
  • Crie rotas de API para operações de dados
  • Implemente estratégias eficientes de busca de dados
  • Adicione validação de dados adequada
  • Inclua tratamento de erros para operações de banco de dados

Por favor, forneça um plano de implementação detalhado que aborde todos esses aspectos, mantendo o design visual e a experiência do usuário existentes.

Copiei o prompt gerado para a área de transferência.

Inicie a jornada de implementação​

Criei um novo chat clicando no botão +, alternei para o modo Agent e colei o prompt usando Ctrl+Shift+V (como texto).

Após o plano ser gerado, digitei please, implement this plan no chat para começar a implementação.

nota

Incluí apenas o ponto de partida, pois não registrei todos os prompts usados. Havia muitos deles.

Notas

  • Alguns modelos podem ficar presos ao corrigir bugs. "claude-3.5" e "claude-4" geralmente são melhores, mas às vezes você precisa tentar outro modelo (GPT, Gemini, etc.). Para bugs ou erros complexos, use um prompt para analisar possíveis causas do erro em vez de simplesmente pedir para corrigi-lo.
  • Ao fazer modificações complexas, use um prompt para criar um plano e depois peça ao agente de IA para implementá-lo. Isso sempre funciona melhor.
  • Seja específico ao alterar o código-fonte. Se possível, selecione a parte relevante do código no editor e pressione Ctrl+L para incluí-lo no chat como contexto.
  • Também inclua uma referência ao arquivo que você está mencionando no chat para ajudar o agente de IA a focar na parte relevante do código e evitar fazer alterações em outras partes do código.
  • Tenho a tendência de antropomorfizar o agente de IA dado que ele persistentemente usa 'nós', 'nosso código' e 'gostaria que eu...'. Isso também é para melhorar minhas chances de sobrevivência no caso (ou quando) Skynet se tornar senciente e o Exterminador for inventado.
  • Às vezes, use Gemini, Deepseek, ChatGPT, Manus... para gerar prompts com instruções melhores para o agente de IA.