Pular para o conteúdo
Voltar para projetos

Aprender para Todos

Plataforma de estudo gratuita, da pré-escola ao ENEM, construída sem backend e sem conta: o progresso vive no dispositivo do estudante.

aprenderparatodos.cianci.com.br

Contexto

Projeto social: uma plataforma de estudo gratuita, organizada por etapa e ano escolar, cobrindo da pré-escola ao ensino médio, incluindo ENEM e redação. O público é estudante, família que quer acompanhar, vestibulando e professor ou ONG, em boa parte gente acessando pelo celular.

Desafio

Sustentar uma plataforma educacional completa com custo de operação próximo de zero, e sem coletar dado pessoal de estudante, sendo muitos deles menores de idade. Tirar o backend da equação resolve custo e privacidade de uma vez, mas deixa duas perguntas abertas: onde vive o progresso do aluno, e como se autora conteúdo sem um CMS.

Meu papel

Arquitetura, desenvolvimento, modelagem do domínio educacional, acessibilidade, testes, infraestrutura e deploy.

Responsabilidades

  • Arquitetura da aplicação e do modelo de conteúdo.
  • Modelagem do domínio educacional: etapas, anos, áreas, trilhas, módulos, lições e quizzes.
  • Camada de persistência local sobre IndexedDB.
  • Acessibilidade como preferência de primeira classe.
  • Suíte de testes e pipeline de CI.
  • Infraestrutura AWS e deploy em dois ambientes.

Restrições

  • Projeto gratuito: o custo de operação precisa caber em quem o mantém, indefinidamente.
  • Público inclui crianças: conta e cadastro significam coleta de dado pessoal de menor.
  • Mobile first, com aparelho possivelmente modesto: cada KB de JavaScript é pago pelo usuário.
  • Base de conteúdo ampla (várias etapas, anos e componentes) que precisa crescer sem virar bagunça.

Arquitetura

  • Next.js 16 com App Router e export estático: nenhum servidor de aplicação, nenhum banco em runtime.
  • Nenhuma dependência de runtime além do próprio framework: next, react e react-dom. Sem biblioteca de estado, de UI ou de acesso a IndexedDB.
  • Persistência no dispositivo: wrapper próprio sobre IndexedDB, com um repositório por domínio (progresso, quizzes, caderno de erros, plano de estudo, rascunhos, histórico).
  • Preferências pequenas e síncronas em localStorage, separadas do IndexedDB para não bloquear o primeiro render.
  • Conteúdo como código TypeScript, com IDs branded para o compilador barrar referência cruzada errada entre entidades.
  • Pipeline editorial no próprio domínio: validadores puros que retornam issues estruturados, relatório de cobertura e estados editoriais explícitos.
  • Console editorial local rodando no browser, sem CMS e sem servidor.
  • Envelope versionado de exportação e importação de dados, validado na entrada, como alternativa a sincronizar por servidor.

Principais decisões técnicas

Não ter backend: o progresso do estudante vive no dispositivo, em IndexedDB.

Por quê

Conta e banco de dados significariam coletar dado pessoal de criança, assumir a responsabilidade de guardá-lo e pagar servidor para sempre. Também colocariam uma tela de cadastro entre o aluno e a lição. Sem backend, o custo de operação de um projeto gratuito cai para hospedagem estática, e não existe dado de menor para vazar.

Trade-offs

  • O progresso não sincroniza entre aparelhos: trocar de celular começa do zero.
  • Limpar os dados do navegador apaga o histórico de estudo.
  • Sem servidor não há telemetria agregada, nenhuma visão de como o conteúdo está sendo usado.
  • Mitigação parcial: exportação e importação de dados em um envelope versionado, controlado pelo usuário.

Zero dependências de runtime além do framework.

Por quê

Cada KB de JavaScript é pago justamente pelo aparelho modesto que é o público-alvo. E cada dependência é manutenção futura que um projeto gratuito não tem como custear a longo prazo. Context do React e a API nativa de IndexedDB dão conta do que o produto precisa.

Trade-offs

  • Mais código próprio para manter. O wrapper de IndexedDB, por exemplo, é nosso.
  • Abre mão dos recursos prontos de bibliotecas maduras (devtools, cache, utilitários).
  • Em troca: bundle pequeno, superfície de supply chain praticamente nula e nenhuma quebra vinda de terceiro.

Conteúdo como código versionado, com testes guardando a própria base de conteúdo.

Por quê

Um CMS traria de volta o servidor e o banco que a primeira decisão removeu. Com o conteúdo em TypeScript, o compilador garante a forma e o CI valida cobertura e pendências antes do deploy. Erro de conteúdo vira build vermelho, não bug em produção.

Trade-offs

  • Autoria passa a exigir build e Git, o que não serve para autor não técnico.
  • Por isso existe o console editorial local: autoria no browser, com rascunho em IndexedDB e exportação, sem reintroduzir servidor.
  • Uma base de conteúdo grande vira muitos arquivos TypeScript para navegar.

Implementação

  • Trilhas por etapa, ano e componente curricular, com lição e quiz canônicos por módulo.
  • Caderno de erros, plano de estudo, progresso e métricas, tudo local.
  • Área de ENEM, incluindo redação.
  • Múltiplos perfis no mesmo dispositivo, para quando o aparelho é compartilhado.
  • Acessibilidade com três eixos (movimento reduzido, alto contraste e tamanho de texto), com padrão herdado das preferências do sistema operacional e sobrescrita persistida do usuário.
  • Exportação e importação dos dados do dispositivo, com validação e pré-visualização antes de importar.

Operação em produção

  • Export estático publicado em S3 privado, servido por CloudFront com OAC.
  • URLs limpas resolvidas na borda por uma CloudFront Function em viewer-request.
  • Infraestrutura provisionada por scripts idempotentes e versionados, com usuário IAM por ambiente.
  • Cache separado por classe de asset: HTML revalidável, assets com hash imutáveis.
  • CI roda testes, lint, build e uma validação do export antes de qualquer deploy.
  • Dois ambientes: staging automático no merge, produção só por acionamento manual com confirmação explícita.
  • Sem servidor de aplicação em produção: não há o que operar, corrigir ou escalar.

Resultados

  • Custo de operação limitado a hospedagem estática, o que torna um projeto gratuito sustentável.
  • Nenhum dado de estudante sai do dispositivo: não há conta, não há banco, não há analytics.
  • Integridade do conteúdo protegida por testes que rodam no CI, cobrindo persistência, domínio e a própria base de conteúdo.
  • Acessibilidade tratada como parte da arquitetura, e não como ajuste posterior: herda a preferência do sistema e deixa o usuário sobrescrever.
  • Cada bug de conteúdo virou um teste permanente, em vez de uma correção pontual.

Stack

  • Next.js 16
  • React 19
  • TypeScript
  • Tailwind CSS 4
  • IndexedDB
  • Vitest
  • AWS S3
  • AWS CloudFront
  • CloudFront Functions
  • GitHub Actions