Banco de Desafios · todas as trilhas

Desafios para quem quer ir além

Todos os desafios das aulas em um só lugar, mais projetos integradores. ⭐ leva uma ou duas horas; ⭐⭐ uma tarde; ⭐⭐⭐ um fim de semana; 🔥 é o boss da unidade. Marque Feito e acompanhe: 0 concluídos neste navegador.

Nível 1Aula 01 · Apresentação, tecnologias e arquitetura da Web

Quem entregou esta página?

Toda resposta HTTP carrega cabeçalhos que contam quem a produziu — e muitos sites deixam pistas: qual servidor web, se passou por uma CDN, há quanto tempo o arquivo está em cache. Hoje você vira detetive: escolha três…

devtools http investigacao
Nível 1Aula 01 · Apresentação, tecnologias e arquitetura da Web

Linha do tempo da Web, só com HTML

A tabela da §2 resume meio século em dez linhas. Ela merece mais: crie uma página HTML com uma linha do tempo de pelo menos 10 marcos da história da Web (1969 até hoje), cada um com ano, título e um parágrafo de 2 a 3…

⭐⭐html projeto
Nível 1Aula 01 · Apresentação, tecnologias e arquitetura da Web

A rota até o servidor

Escolha um domínio real (o site de uma universidade, um jornal, uma loja). Quantos computadores um pacote atravessa entre a sua máquina e o servidor dele? A resposta está em um comando que existe em todo sistema opera…

⭐⭐terminal dns investigacao
Nível 1Aula 01 · Apresentação, tecnologias e arquitetura da Web

HTTP à mão

O navegador esconde tudo o que a §4 descreve. Hoje você faz o trabalho dele manualmente: dispara uma requisição HTTP sem navegador, lê a resposta crua e compara protocolos. A ferramenta é o curl, que já vem instalado …

⭐⭐⭐http https terminal investigacao
Nível 1Aula 02 · Introdução ao HTML: estrutura, textos, links e tabelas

Caça ao bug: oito erros escondidos

O trecho abaixo "funciona" — abre no navegador e mostra tudo. Mesmo assim, ele tem pelo menos oito problemas: alguns o validador do W3C encontra, outros só um olho humano treinado percebe. Encontre todos, classifique-…

html bug investigacao
Nível 1Aula 02 · Introdução ao HTML: estrutura, textos, links e tabelas

Sem mouse, sem CSS

Boa parte das pessoas que usam a Web não usa mouse: quem navega por teclado, quem usa leitor de tela, quem tem lesão por esforço repetitivo. E buscadores não "veem" CSS nenhum. Hoje você vai usar o site do evento (e u…

acessibilidade html investigacao
Nível 1Aula 02 · Introdução ao HTML: estrutura, textos, links e tabelas

Documentação técnica dos status HTTP

A tabela de status HTTP da Aula 01 tem cinco linhas. Um desenvolvedor consulta esses códigos toda semana — e a maioria dos sites de referência é em inglês. Produza http-referencia.html: uma página que documente os cód…

⭐⭐html http projeto
Nível 1Aula 02 · Introdução ao HTML: estrutura, textos, links e tabelas

Análise arquitetural de um sistema real

Você aprendeu camadas, MPA/SPA e APIs em teoria. Agora aplique em um sistema que você usa todo dia: escolha um (SIGAA, um e-commerce, uma rede social, um app de banco no navegador) e produza um relatório de 2 páginas …

⭐⭐investigacao devtools http
Nível 1Aula 02 · Introdução ao HTML: estrutura, textos, links e tabelas

Reproduza um artigo da Wikipédia só com HTML

A Wikipédia é um dos sites mais bem estruturados da Web: sumário com âncoras, infobox em tabela, seções hierárquicas, notas de rodapé com links de ida e volta. Escolha um artigo em português (sugestão: "HTML" ou "Tim …

⭐⭐⭐html acessibilidade projeto
Nível 1Aula 03 · Introdução aos formulários

O formulário de três campos

Todo mundo já desistiu de preencher um cadastro. Qual é o menor formulário capaz de inscrever alguém em um evento? Pegue a inscricao.html que você acabou de construir e faça o caminho inverso: corte tudo que não é ind…

html formularios acessibilidade
Nível 1Aula 03 · Introdução aos formulários

Auditoria de um formulário real

Escolha um formulário público de verdade: matrícula de uma universidade, agendamento de uma prefeitura, cadastro de uma loja, abertura de conta de um banco. Abra o DevTools e leia o HTML dele. Quantos campos têm <labe…

⭐⭐formularios acessibilidade investigacao html
Nível 1Aula 03 · Introdução aos formulários

Dado sujo: o formulário que estraga o banco

Um mesmo campo "telefone", sem restrição nenhuma, recebeu na vida real: 66999990000, (66) 99999-0000, 66 9 9999 0000, +55 66 99999-0000, 9999-0000 (falar com a Maria) e não tenho. Nenhum está errado do ponto de vista …

⭐⭐formularios html investigacao bug
Nível 1Aula 03 · Introdução aos formulários

Formulário multietapas sem JavaScript

Formulários longos assustam. A solução clássica é dividir em etapas ("Etapa 2 de 4") — e quase todo mundo faz isso com JavaScript. Mas dá para construir um formulário de várias etapas usando apenas HTML, com uma págin…

⭐⭐⭐html formularios acessibilidade projeto
Nível 1Aula 04 · Formulários, mídias e listas

Caça aos bugs na galeria

Alguém entregou a galeria abaixo dizendo que "abre normal no navegador". Abre — mas o validador do W3C acusa erros, o leitor de tela lê nomes de arquivo e o vídeo nunca mostra legenda. Há oito problemas no trecho. Enc…

html acessibilidade bug
Nível 1Aula 04 · Formulários, mídias e listas

Galeria dez vezes mais leve

Uma página de galeria com doze fotos de celular pesa em média 40 MB. Quanto tempo ela leva para abrir no 4G lento? Você vai medir. Monte uma página com doze fotos originais (sem tratamento), meça o peso e o tempo de c…

⭐⭐html performance devtools investigacao
Nível 1Aula 04 · Formulários, mídias e listas

Mídia acessível de ponta a ponta

A WCAG exige, para vídeo pré-gravado: legendas (critério 1.2.2), audiodescrição ou alternativa em texto (1.2.3) e, para áudio, transcrição (1.2.1). Quase nenhum site de evento cumpre isso — o seu vai cumprir. Pegue um…

⭐⭐⭐html acessibilidade investigacao projeto
Nível 1Aula 05 · Elementos HTML para layout e introdução ao CSS

A folha de estilo que não funciona

Alguém passou uma hora tentando descobrir por que "o CSS não pega". O arquivo está abaixo, e o HTML o referencia com <link rel="stylesheet" href="estilo.css"> — mas o arquivo está salvo em css/estilo.css. Além desse, …

css bug devtools
Nível 1Aula 05 · Elementos HTML para layout e introdução ao CSS

Reproduza o cartão de repositório do GitHub

Abra o perfil de qualquer pessoa no GitHub e olhe os cartões de "repositórios fixados" (pinned): ícone, nome em azul, descrição em cinza, etiqueta da linguagem com uma bolinha colorida, contador de estrelas. Parece si…

⭐⭐css layout investigacao
Nível 1Aula 05 · Elementos HTML para layout e introdução ao CSS

Laboratório interativo do box model

Explicar o box model para outra pessoa é a melhor forma de descobrir se você entendeu. Construa uma página didática, box-model.html, que demonstre visualmente cada conceito desta aula com exemplos vivos: a mesma caixa…

⭐⭐⭐css layout devtools investigacao
Nível 1Aula 05 · Elementos HTML para layout e introdução ao CSS

Auditoria e reconstrução de um site real

Sites institucionais brasileiros — de prefeituras, secretarias, campi — costumam ter dezenas de <div>, imagens sem alt, formulários sem <label> e tabelas usadas para layout. Você agora sabe reconhecer tudo isso. Escol…

🔥html acessibilidade projeto investigacao
Nível 1Aula 06 · CSS: sintaxe, seletores, classes, atributos e valores

Detetive de especificidade

Existe um estilo que "não pega" em praticamente todo projeto de CSS — e quase sempre a culpa é da especificidade. Neste desafio você vai treinar o olho: dada uma lista de conflitos reais, prever quem vence antes de ab…

css investigacao devtools
Nível 1Aula 06 · CSS: sintaxe, seletores, classes, atributos e valores

A paleta que ninguém consegue ler

Escolha três sites reais que você usa toda semana — um portal público, uma loja e uma rede social — e audite o contraste deles. Você vai encontrar texto cinza-claro sobre branco, botão desabilitado ilegível e link que…

⭐⭐css acessibilidade investigacao
Nível 1Aula 06 · CSS: sintaxe, seletores, classes, atributos e valores

Reconstruindo um componente só com seletores

Pegue este HTML sujo, cheio de classes que descrevem aparência, e reconstrua o mesmo visual sem tocar no HTML — usando apenas seletores de tipo, de atributo, combinadores e pseudoclasses. Depois reescreva o HTML como …

⭐⭐css html refatoracao acessibilidade
Nível 1Aula 06 · CSS: sintaxe, seletores, classes, atributos e valores

Clone visual de uma identidade real

Escolha a página inicial de um site cuja identidade visual você admira e reproduza a identidade — paleta, tipografia, escala de espaçamentos, estilo de botões, tratamento de links — em uma página com conteúdo totalmen…

⭐⭐⭐css investigacao projeto acessibilidade
Nível 1Aula 07 · Formatando o layout de um website e o menu

Flexbox Froggy e Grid Garden até o fim

Você consegue levar 24 sapos para as vitórias-régias certas usando só justify-content, align-items e flex-wrap? E regar 28 cenouras com grid-column, grid-area e grid-template-areas? Os dois jogos foram criados para fi…

css flexbox grid
Nível 1Aula 07 · Formatando o layout de um website e o menu

Caça ao bug de layout

O código abaixo era para produzir um cabeçalho fixo com menu à direita, uma página com lateral à esquerda e conteúdo à direita, e um selo "Esgotado" no canto do cartão. Nada disso acontece: o cabeçalho rola junto com …

⭐⭐css layout bug devtools
Nível 1Aula 07 · Formatando o layout de um website e o menu

Mosaico de destaques com Grid

A página inicial do site do evento precisa de um bloco de destaques em formato de revista: sete cartões de tamanhos diferentes — um grande (2 × 2), dois largos (2 × 1), um alto (1 × 2) e três pequenos (1 × 1) — encaix…

⭐⭐css grid layout projeto
Nível 1Aula 07 · Formatando o layout de um website e o menu

Recriação de um layout real

Você consegue reproduzir a página inicial de um site que usa todo dia? Escolha a home de um site conhecido (o portal da sua universidade ou escola, um jornal, uma loja, a página inicial do GitHub) e reproduza seu layo…

⭐⭐⭐css grid flexbox layout
Nível 1Aula 08 · Criando telas responsivas

Grid Garden completo

Você escreveu repeat(auto-fit, minmax()) hoje e talvez ainda não tenha certeza de por que funciona — porque decorar a linha não é o mesmo que enxergar as linhas-guia da grade. O Grid Garden é um jogo de 28 fases em qu…

grid layout responsivo
Nível 1Aula 08 · Criando telas responsivas

Caça ao bug: o site que só funciona no monitor de quem escreveu

Alguém jura que "o site está responsivo, testei no meu monitor". No celular ele aparece minúsculo, com rolagem horizontal, imagem estourando e um menu que nunca vira hambúrguer. Há seis erros entre o HTML e o CSS abai…

bug responsivo css devtools
Nível 1Aula 08 · Criando telas responsivas

Menu hambúrguer sem uma linha de JavaScript

O menu.js de hoje tem oito linhas — mas dá para ter zero. Um <input type="checkbox"> escondido, um <label> que faz papel de botão e a pseudoclasse :checked da Aula 06 conseguem abrir e fechar o menu só com CSS. Constr…

⭐⭐css responsivo acessibilidade layout
Nível 1Aula 08 · Criando telas responsivas

Nota 90 no Lighthouse Mobile

Rode o Lighthouse Mobile no index.html do seu projeto autoral agora, antes de mexer em qualquer coisa, e guarde o relatório. É comum a primeira nota de Performance ficar abaixo de 60 em um site com fotos grandes, e a …

⭐⭐⭐responsivo performance acessibilidade devtools
Nível 1Aula 09 · Animações e efeitos em CSS

Caça ao bug: quatro animações que não animam

Alguém enviou o CSS abaixo dizendo "nada anima, o CSS deve estar bugado". Não está — o navegador está fazendo exatamente o que foi pedido. Há quatro erros conceituais, cada um de um tipo diferente visto nesta aula. En…

css animacao bug devtools
Nível 1Aula 09 · Animações e efeitos em CSS

Movimento que degrada com elegância

Ative prefers-reduced-motion: reduce no sistema (ou emule no DevTools) e abra qualquer site grande: a maioria simplesmente remove tudo, e junto some o feedback — o painel que deslizava agora aparece do nada, o toast q…

css animacao acessibilidade refatoracao
Nível 1Aula 09 · Animações e efeitos em CSS

`left` contra `transform`: meça, não acredite

Esta aula afirma que animar transform é mais barato que animar left. Você vai provar isso com números, do jeito que um engenheiro de front-end faz antes de defender a escolha para outra pessoa. Implemente o mesmo pain…

⭐⭐css performance devtools investigacao
Nível 1Aula 09 · Animações e efeitos em CSS

Sua biblioteca de animações

Bibliotecas como a Animate.css têm milhões de downloads por semana — e cabem em um arquivo CSS que você já sabe ler. Crie o seu animacoes.css com no mínimo 20 animações reutilizáveis, organizadas em quatro categorias …

⭐⭐⭐css animacao refatoracao projeto
Nível 1Aula 09 · Animações e efeitos em CSS

Projeto pronto para o Marco 2

Quatro aulas atrás o seu projeto autoral era HTML puro. Hoje ele tem um sistema de design, um layout de verdade, responde a qualquer tela e se move com propósito. O Boss desta unidade é fechar tudo isso em um site que…

🔥css layout responsivo animacao
Nível 1Aula 10 · Introdução ao JavaScript

Adivinhe a saída: a coerção posta à prova

Você acabou de ver que "5" + 3 é "53" e "5" - 3 é 2. Alguém afirma que "com prática dá para prever qualquer coerção sem testar". Vamos ver. Abaixo estão doze expressões; escreva a sua previsão para cada uma antes de d…

javascript investigacao
Nível 1Aula 10 · Introdução ao JavaScript

Caça ao bug: cinco erros em um script de 20 linhas

O script abaixo deveria mostrar, na página de inscrição, o nome do evento e as vagas restantes. Ele tem cinco defeitos: um impede o arquivo inteiro de rodar, um faz a página quebrar antes de o HTML existir, um produz …

⭐⭐javascript bug devtools
Nível 1Aula 10 · Introdução ao JavaScript

Dinheiro não cabe em ponto flutuante

Um sistema de inscrição cobra R$ 0,10 de taxa por SMS e envia três. No Console, 0.1 3 dá 0.30000000000000004; o cliente vê "R$ 0,30000000000000004" no boleto e liga furioso. Bancos, lojas e sistemas de ingressos não …

⭐⭐⭐javascript investigacao bug
Nível 1Aula 11 · Variáveis, operações aritméticas e estruturas de controle

O sorteio honesto

Quantas vezes você precisa sortear um número de 1 a 6 até que os seis valores tenham saído pelo menos uma vez? A intuição diz "umas dez"; a matemática diz 14,7 em média; e o seu computador pode dizer a verdade em três…

javascript investigacao projeto
Nível 1Aula 11 · Variáveis, operações aritméticas e estruturas de controle

Caça ao bug: o script que decide errado

O script abaixo deveria classificar as inscrições do evento e mostrar o preço final. Ele roda sem nenhuma linha vermelha no Console — e mesmo assim está errado em cinco pontos: uma faixa nunca é alcançada, um desconto…

⭐⭐javascript bug devtools refatoracao
Nível 1Aula 11 · Variáveis, operações aritméticas e estruturas de controle

A calculadora de cronograma do evento

A organização da Semana Acadêmica precisa saber, a qualquer momento, em que fase está: falta mais de um mês, está na reta final, é hoje, ou já acabou? E precisa que a página inicial diga isso em português correto — "f…

⭐⭐⭐javascript investigacao projeto acessibilidade
Nível 1Aula 12 · Estruturas sequenciais, condicionais e de repetição

O relatório que ninguém pediu

Todo conjunto de dados esconde uma informação que ninguém tinha pensado em perguntar. Com os arrays palestras e palestrantes da Mão na massa, quantas perguntas interessantes você consegue responder em uma linha cada? …

javascript investigacao projeto
Nível 1Aula 12 · Estruturas sequenciais, condicionais e de repetição

Caça ao bug: o laço que conta errado

O script abaixo deveria montar o resumo da programação. Ele roda, imprime números — e todos estão errados. São seis defeitos: um erro "por um", um for…in usado onde deveria ser for…of, um sort que ordena como texto, u…

⭐⭐javascript bug devtools refatoracao
Nível 1Aula 12 · Estruturas sequenciais, condicionais e de repetição

O agrupador genérico

Você já agrupou atividades por dia e contou por área. Agora repare: os dois códigos são quase idênticos — muda apenas a propriedade usada como chave. Programadores experientes sentem coceira ao ver isso e escrevem uma…

⭐⭐⭐javascript refatoracao investigacao projeto
Nível 1Aula 13 · Funções e eventos

O botão que só funciona uma vez

Alguém enviou o código abaixo dizendo que "o contador funciona uma vez e depois para, e às vezes nem começa". Rode-o, reproduza os dois sintomas e encontre os quatro bugs plantados — sem reescrever do zero. Cada um é …

javascript eventos bug devtools
Nível 1Aula 13 · Funções e eventos

Lista de tarefas interativa

Uma lista de tarefas é o "olá, mundo" das interfaces dinâmicas — e o exercício que mais revela se você entendeu o fluxo estado → renderização → eventos. Construa a sua, do zero, seguindo a arquitetura da seção 18, sem…

⭐⭐javascript dom eventos projeto
Nível 1Aula 13 · Funções e eventos

Quiz com pontuação e cronômetro

Sites de evento costumam ter um "quiz de conhecimentos" para engajar quem se inscreve. Construa um quiz de 10 perguntas de múltipla escolha sobre a Unidade 3 (você escreve as perguntas), com uma pergunta por tela, cro…

⭐⭐⭐javascript dom eventos acessibilidade
Nível 1Aula 14 · JavaScript para validação de formulários e consultas dinâmicas

O formulário que aceita qualquer coisa

O arquivo abaixo deveria validar uma inscrição, mas aceita nome vazio, e-mail sem arroba e CPF com uma letra no meio — e, quando reclama, ninguém que use leitor de tela fica sabendo. São seis defeitos: quatro de lógic…

formularios javascript bug acessibilidade
Nível 1Aula 14 · JavaScript para validação de formulários e consultas dinâmicas

Busca que ignora acentos, plurais e a ordem das palavras

Digite "minicurso git" na busca da programação: nada aparece, porque nenhum título contém exatamente essa sequência. Digite "seguranças": também nada. Usuários não digitam do jeito que os seus dados foram escritos — e…

⭐⭐javascript investigacao performance dom
Nível 1Aula 14 · JavaScript para validação de formulários e consultas dinâmicas

Validação sem uma linha de `if`

O validarCampo da Mão na massa tem um switch com sete casos. Funciona, mas cada campo novo exige mexer nessa função — e, num formulário de vinte campos, ela vira um monstro. Existe uma alternativa que os frameworks us…

⭐⭐javascript refatoracao formularios
Nível 1Aula 14 · JavaScript para validação de formulários e consultas dinâmicas

O formulário mais acessível que você já fez

Um formulário pode passar em todos os testes automáticos e ainda ser impossível de preencher sem o mouse. Nesta missão você vai auditar o formulário do seu projeto autoral como um usuário que não enxerga a tela, corri…

⭐⭐⭐acessibilidade formularios investigacao projeto
Nível 1Aula 15 · Publicando seu website na internet

O site que quebrou ao subir

O repositório abaixo quase funciona no Live Server do Windows e chega ao GitHub Pages sem estilo, sem imagens e com o JavaScript morto. São cinco linhas com defeito, e nenhum defeito é erro de sintaxe: todos são conse…

deploy bug devtools investigacao
Nível 1Aula 15 · Publicando seu website na internet

Cem pontos em acessibilidade

O Lighthouse dá nota 100 em acessibilidade para páginas que um usuário de leitor de tela não consegue usar — ele testa o que é automatizável, e isso é menos da metade do problema. Neste desafio você faz as duas coisas…

⭐⭐acessibilidade performance devtools deploy
Nível 1Aula 15 · Publicando seu website na internet

Meio megabyte, no máximo

A página inicial de um site de evento não deveria pesar mais que um aplicativo de celular. Neste desafio, a meta é objetiva e medida por ferramenta: a página inicial do seu site, carregada pela primeira vez em um nave…

⭐⭐⭐performance deploy devtools refatoracao
Nível 1Aula 15 · Publicando seu website na internet

Do zero ao ar, em três horas

Este é o desafio que fecha a Unidade 3 e esta trilha. A regra é simples e desconfortável: um tema novo, do zero, publicado e auditado em três horas. Sem reaproveitar o código do site do evento nem o do seu projeto aut…

🔥projeto deploy github acessibilidade
Nível 2Aula 01 · Apresentação, arquitetura web, ambiente de desenvolvimento e Git

Um repositório que se explica sozinho

Um recrutador abre o seu GitHub e olha um repositório por, em média, alguns segundos. Nesse tempo ele decide se você sabe trabalhar ou se apenas entregou uma tarefa. A diferença raramente está no código: está no READM…

git github projeto
Nível 2Aula 01 · Apresentação, arquitetura web, ambiente de desenvolvimento e Git

A viagem de um GET

O navegador esconde tudo o que a §2.2 descreve. Hoje você faz o trabalho dele na mão: dispara requisições HTTP sem navegador, lê a resposta crua e mede onde o tempo é gasto. A ferramenta é o curl, que já vem no Window…

⭐⭐http terminal devtools investigacao
Nível 2Aula 01 · Apresentação, arquitetura web, ambiente de desenvolvimento e Git

Quem responde por este site?

Toda resposta HTTP carrega pistas sobre a infraestrutura que a produziu: qual software serviu, se passou por uma CDN, quanto tempo o arquivo pode ficar em cache. Vire detetive: escolha quatro sites (o da sua universid…

⭐⭐http devtools dns investigacao
Nível 2Aula 01 · Apresentação, arquitetura web, ambiente de desenvolvimento e Git

Volte no tempo

O valor real do Git não aparece quando tudo dá certo — aparece às 23h30 do dia da entrega, quando você apaga o arquivo errado. Este desafio é um treino de emergência: você vai quebrar o próprio projeto de quatro forma…

⭐⭐⭐git github investigacao refatoracao
Nível 2Aula 02 · Introdução ao desenvolvimento web moderno

A identidade em um bloco só

Um cliente pede: "gostei do site, mas a marca agora é verde-oliva, e queremos um modo escuro". Quanto tempo isso custa? Em um CSS bem escrito, cinco minutos; em um CSS com cores espalhadas por 300 linhas, uma tarde. D…

css layout projeto
Nível 2Aula 02 · Introdução ao desenvolvimento web moderno

O que trava a primeira pintura

Por que um site com pouquíssimo conteúdo demora dois segundos para aparecer? Quase sempre porque alguma coisa está bloqueando o caminho até a primeira pintura. Hoje você vira perito: mede, identifica o culpado e compr…

⭐⭐performance devtools css investigacao
Nível 2Aula 02 · Introdução ao desenvolvimento web moderno

O site sobrevive sem CSS?

Um teste brutal e revelador: desligue a folha de estilo do seu site e leia a página resultante. Se ela continuar fazendo sentido — títulos na ordem certa, links com texto claro, conteúdo antes do rodapé — a estrutura …

⭐⭐html acessibilidade investigacao devtools
Nível 2Aula 02 · Introdução ao desenvolvimento web moderno

Seu próprio servidor estático

O GitHub Pages e o Live Server fazem a mesma coisa que você vai programar na Unidade 3: receber um caminho, achar um arquivo, devolver com o cabeçalho certo. Antecipe o assunto. Escreva, em Node.js puro (sem Express, …

⭐⭐⭐node http terminal investigacao
Nível 2Aula 03 · Revisão de HTML: layout, links e formulários

Caça aos landmarks

Quantas regiões um leitor de tela consegue enxergar no seu site? E no site da sua faculdade? Sem instalar nada, o DevTools mostra a mesma árvore que o leitor de tela usa — e a diferença entre um site bem marcado e um …

html acessibilidade devtools investigacao
Nível 2Aula 03 · Revisão de HTML: layout, links e formulários

O formulário que não deixa você errar

Existe um formulário famoso por ser insuportável: o de cadastro que rejeita o seu telefone porque você digitou parênteses, recusa a senha porque tem um caractere "inválido" que ele não diz qual é, e apaga tudo quando …

⭐⭐html formularios acessibilidade refatoracao
Nível 2Aula 03 · Revisão de HTML: layout, links e formulários

Caça ao bug de marcação

O arquivo abaixo abre no navegador sem nenhum erro visível no console e parece funcionar. Mas ele tem sete problemas: alguns o validador do W3C aponta, outros só aparecem quando você navega por teclado ou clica nos ró…

⭐⭐html formularios bug investigacao
Nível 2Aula 03 · Revisão de HTML: layout, links e formulários

Reprodução estrutural de uma página real

Escolha uma página de um site que você usa toda semana — um portal de notícias, uma loja, o sistema acadêmico, um blog técnico — e reproduza a estrutura semântica dela: só HTML, sem uma linha de CSS, com conteúdo escr…

⭐⭐⭐html acessibilidade layout investigacao
Nível 2Aula 04 · Frameworks CSS: Bootstrap, Tailwind e Material

O framework por baixo do capô

Você usou col-md-6 a tarde inteira sem nunca ter visto o CSS que faz aquilo acontecer. Isso é confortável e é perigoso: no dia em que a coluna não obedecer, você não vai ter para onde olhar. Abra a caixa preta. O boot…

css layout devtools investigacao
Nível 2Aula 04 · Frameworks CSS: Bootstrap, Tailwind e Material

O mesmo componente, três vezes

Discussões sobre framework na internet duram anos e quase nunca têm números. Você vai encerrar a sua em uma tarde: construa o mesmo componente — um card de produto com imagem, título, texto, preço e botão — nos três f…

⭐⭐css layout responsivo performance
Nível 2Aula 04 · Frameworks CSS: Bootstrap, Tailwind e Material

Fuja da cara de Bootstrap

Existe um jogo cruel entre desenvolvedores: abrir um site e adivinhar o framework em dois segundos. Sites feitos com Bootstrap sem customização são os mais fáceis — azul #0d6efd, cantos de 6 px, a mesma sombra, a mesm…

⭐⭐css layout refatoracao projeto
Nível 2Aula 04 · Frameworks CSS: Bootstrap, Tailwind e Material

Seu micro-framework de 200 linhas

A melhor forma de entender um framework é escrever um. Não um clone do Bootstrap — um micro-framework honesto, de no máximo 200 linhas de CSS, com o mínimo necessário para montar o site do Café Cerrado sem nenhuma dep…

⭐⭐⭐css layout grid refatoracao
Nível 2Aula 05 · Animação e SVG

Caça ao bug: cinco animações que não animam

Um colega mandou o CSS abaixo dizendo "não anima nada, o navegador deve estar bugado". Não está: o navegador está fazendo exatamente o que foi pedido. Há cinco erros conceituais, cada um de um tipo diferente visto hoj…

css animacao bug devtools
Nível 2Aula 05 · Animação e SVG

O logotipo do seu projeto em menos de 2 KB

Todo projeto autoral desta trilha precisa de uma marca. É tentador baixar um PNG genérico de 80 KB que fica borrado na tela do celular. Você vai desenhar a sua — no código, com formas geométricas — e ela vai pesar men…

svg css projeto acessibilidade
Nível 2Aula 05 · Animação e SVG

Do bitmap ao vetor: meça, não acredite

"SVG é mais leve" é uma frase que todo mundo repete e quase ninguém mediu. Você vai medir — e vai descobrir que a frase tem exceções importantes. O objetivo não é provar que SVG ganha: é aprender a decidir com números.

⭐⭐svg performance devtools investigacao
Nível 2Aula 05 · Animação e SVG

Um gráfico SVG do Café Cerrado, desenhado à mão

A página inicial do Café Cerrado vai ganhar uma seção "O café em números" com três indicadores. A tentação é usar uma biblioteca de gráficos com 90 KB de JavaScript. Você não pode: a Unidade 1 é sem JavaScript. Vai de…

⭐⭐⭐svg animacao acessibilidade css
Nível 2Aula 06 · Acessibilidade e ARIA

Vinte minutos sem mouse

Desconecte o mouse. Fisicamente, do computador — ou desative o touchpad. Por vinte minutos você vai usar apenas o teclado: o seu site, o site da sua universidade ou escola, o SIGAA e um site de comércio à sua escolha.…

acessibilidade investigacao devtools
Nível 2Aula 06 · Acessibilidade e ARIA

ARIA que mente: conserte o componente

Um "desenvolvedor sênior" entregou este acordeão de perguntas frequentes para o Café Cerrado, orgulhoso do ARIA que usou. O componente é uma coleção de mentiras: os atributos afirmam coisas que o código não cumpre, e …

⭐⭐acessibilidade html refatoracao bug
Nível 2Aula 06 · Acessibilidade e ARIA

Auditoria de um serviço público brasileiro

A Lei Brasileira de Inclusão exige acessibilidade em sites de órgãos públicos desde 2015. Você vai verificar, com método, se um deles cumpre — e produzir um documento que poderia, de fato, ser protocolado. Escolha um …

⭐⭐⭐acessibilidade investigacao devtools projeto
Nível 2Aula 06 · Acessibilidade e ARIA

O seu site pronto para o Marco 1

Seis aulas atrás o seu projeto era uma pasta vazia e um repositório recém-criado. Hoje ele é um site de três páginas, semântico, responsivo, com framework CSS, identidade visual em SVG, movimento com propósito e utili…

🔥html css acessibilidade responsivo
Nível 2Aula 07 · Revisão de JavaScript: objetos, funções, eventos e DOM

O caçador de `null`

Um colega mexeu no app.js do Café Cerrado antes de sair de férias e agora o cardápio não aparece. O Console mostra Uncaught TypeError: Cannot read properties of null (reading 'content') e mais nada. Ele plantou três d…

javascript dom bug devtools
Nível 2Aula 07 · Revisão de JavaScript: objetos, funções, eventos e DOM

O cardápio que virou porta de entrada

Troque textContent por innerHTML em criarCardProduto e adicione ao array um produto chamado <img src=x onerror="document.body.style.filter='invert(1)'">. Recarregue a página. O que acontece é uma versão inofensiva de …

⭐⭐javascript dom seguranca refatoracao
Nível 2Aula 07 · Revisão de JavaScript: objetos, funções, eventos e DOM

Um ouvinte para duzentos cards

Delegação parece um detalhe de estilo até você medir. Gere 200 produtos falsos, renderize duas versões do cardápio — uma registrando addEventListener em cada card, outra com um único ouvinte no contêiner — e compare t…

⭐⭐dom eventos performance devtools
Nível 2Aula 07 · Revisão de JavaScript: objetos, funções, eventos e DOM

O cardápio que lembra de você

Quem entra no Café Cerrado toda semana sempre pede as mesmas duas coisas. Dê a essa pessoa um jeito de marcar favoritos que sobreviva ao fechamento do navegador, funcione só com teclado, seja anunciado corretamente po…

⭐⭐⭐javascript dom eventos acessibilidade
Nível 2Aula 08 · Arrow functions, callbacks e operações em vetores

O comparador mentiroso

Um colega escreveu a ordenação por preço assim e jurou que testou: produtos.sort((a, b) => a.preco > b.preco). Com três produtos, funcionou. Com os nove do Café Cerrado, a lista sai quase ordenada — mas não totalmente…

javascript bug investigacao
Nível 2Aula 08 · Arrow functions, callbacks e operações em vetores

Cinco laços viram uma passada

Este relatório do Café Cerrado funciona, mas percorre o array cinco vezes e repete a mesma estrutura em todas. Refatore-o com métodos de array, meça as duas versões e decida com dados — não com gosto — qual entra no p…

⭐⭐javascript refatoracao performance
Nível 2Aula 08 · Arrow functions, callbacks e operações em vetores

O filtro que respeita quem não vê a tela

Sua busca funciona lindamente com o mouse. Agora feche os olhos: como alguém que usa leitor de tela sabe que a lista mudou? Que 2 de 10 itens sobraram? Que a busca não achou nada? Faça o cardápio filtrado ser tão util…

⭐⭐acessibilidade eventos javascript
Nível 2Aula 08 · Arrow functions, callbacks e operações em vetores

Filtros que cabem em um link

Alguém filtra o cardápio por "Doces, ordenados por preço", acha o combo perfeito e quer mandar no grupo da família. Copia a URL, cola, e a outra pessoa abre o cardápio inteiro sem filtro nenhum — porque o estado só ex…

⭐⭐⭐javascript refatoracao spa performance
Nível 2Aula 09 · Promises e async/await

O cronômetro do cardápio

Você trocou dois await em sequência por um Promise.all e alguém disse que ficou mais rápido. Mas "mais rápido" é opinião até virar número. Meça: quanto tempo, exatamente, o seu cardápio leva para aparecer nas duas ver…

async performance devtools
Nível 2Aula 09 · Promises e async/await

A resposta que chega atrasada

Ative "Slow 4G" na aba Network, digite a, depois ca, depois café na busca do cardápio — rápido, como qualquer pessoa digita. De vez em quando a tela mostra o resultado de a embora o campo diga café. O bug não está na …

⭐⭐async javascript bug investigacao
Nível 2Aula 09 · Promises e async/await

Carregando para quem não vê

Feche os olhos e navegue no seu cardápio usando só o teclado e o leitor de tela do sistema (NVDA no Windows, Orca no Linux, VoiceOver no macOS). Enquanto os dados carregam, você provavelmente ouve silêncio — e quando …

⭐⭐acessibilidade async dom
Nível 2Aula 09 · Promises e async/await

Trinta pedidos, quatro de cada vez

Promise.all com 30 operações dispara as 30 ao mesmo tempo. Em um navegador real isso esbarra no limite de conexões simultâneas por domínio (historicamente 6 no HTTP/1.1) e, em um servidor de verdade, é um jeito rápido…

⭐⭐⭐async performance refatoracao javascript
Nível 2Aula 10 · AJAX, JSON e Single Page Application

O 404 que o fetch não viu

Um colega "simplificou" o pegarJson do projeto e agora a tela do cardápio mostra "Carregando…" para sempre quando o arquivo não existe — em vez da mensagem de erro. Pior: o console mostra um SyntaxError falando de <!D…

fetch bug devtools investigacao
Nível 2Aula 10 · AJAX, JSON e Single Page Application

O cardápio que não pergunta duas vezes

Cada vez que alguém entra na tela do cardápio, você busca produtos.json de novo. Hoje isso é rápido porque o arquivo é seu e pequeno. Amanhã será uma API na internet, e a mesma resposta viajará dezenas de vezes por se…

⭐⭐fetch performance json devtools
Nível 2Aula 10 · AJAX, JSON e Single Page Application

Um roteador de verdade

O roteador da aula é um Map de caminhos fixos. Frameworks reais aceitam parâmetros (/produto/:id), rota coringa para 404, e proteção de rota (entrar em /admin só se estiver logado). Escreva o seu, genérico o suficient…

⭐⭐⭐spa rotas javascript refatoracao
Nível 2Aula 10 · AJAX, JSON e Single Page Application

Pedido do Café Cerrado, do cardápio à confirmação

Este é o Boss da Unidade 2: um fluxo completo de pedido, em quatro telas, usando tudo o que você aprendeu desde a Aula 07 — DOM e eventos, map/filter/reduce, assíncrono com estados, fetch de arquivo e de API, POST, fo…

🔥spa fetch json projeto
Nível 2Aula 11 · Introdução ao Node.js e Express

O endpoint que ainda falta

O front-end do Café Cerrado precisa montar os botões de filtro por categoria, mas hoje ele só sabe pedir a lista inteira de produtos e deduzir as categorias no navegador — o que significa baixar seis produtos completo…

node express api json
Nível 2Aula 11 · Introdução ao Node.js e Express

A API que não morre com um arquivo quebrado

Abra data/produtos.json, apague uma vírgula qualquer no meio e salve. Agora recarregue o site. O que você vê? Provavelmente a página em branco, um erro feio no terminal e um usuário que nunca vai saber o que aconteceu…

⭐⭐node express bug json
Nível 2Aula 11 · Introdução ao Node.js e Express

Express contra o módulo `http`, com números

"Por que instalar um framework se o Node já tem um servidor embutido?" É uma pergunta legítima, e a resposta "porque todo mundo usa" não vale nada em uma prova ou em uma entrevista. Reimplemente a sua API inteira — as…

⭐⭐node http refatoracao investigacao
Nível 2Aula 11 · Introdução ao Node.js e Express

O 304 que ninguém vê

Abra o DevTools na aba Network, recarregue o site e olhe a coluna Size do estilo.css: em vez do tamanho em kB, aparece (disk cache) ou o status 304. O Express fez isso sozinho para os arquivos estáticos — mas a sua ro…

⭐⭐⭐performance http express devtools
Nível 2Aula 12 · Express estruturado e middlewares

O crachá de cada requisição

Duas pessoas abrem o cardápio ao mesmo tempo e o seu terminal cospe seis linhas de log embaralhadas: não dá para saber quais linhas pertencem a qual visita. Serviços de verdade resolvem isso dando um identificador úni…

express middleware node investigacao
Nível 2Aula 12 · Express estruturado e middlewares

O `next()` que ninguém chamou

Um colega mexeu no server.js sem avisar e agora o site "não abre mais": a aba do navegador fica girando indefinidamente, o terminal não mostra erro nenhum e o processo Node continua vivo, sem consumir CPU. O curl tamb…

⭐⭐express middleware bug devtools
Nível 2Aula 12 · Express estruturado e middlewares

Validar sem repetir

Hoje a validação do POST /api/produtos são vinte linhas de if dentro do handler. Na próxima aula chega o PUT, que precisa das mesmas regras. Na aula seguinte, o recurso de categorias. Copiar e colar esses if três veze…

⭐⭐express middleware refatoracao api
Nível 2Aula 12 · Express estruturado e middlewares

Escreva o seu próprio `express.json()`

app.use(express.json()) parece uma linha mágica: o corpo cru vira objeto e ninguém pergunta como. Não é mágica — é um stream. O corpo de uma requisição HTTP chega em pedaços, e alguém precisa juntá-los, decidir quando…

⭐⭐⭐node express middleware http
Nível 2Aula 13 · Rotas e controladores

A rota que engoliu a palavra

O Café Cerrado quer uma vitrine de destaques na página inicial. Você acrescenta router.get('/destaques', controlador.destaques) no fim do arquivo de rotas, sobe o servidor, abre http://localhost:3000/api/produtos/dest…

express rotas bug investigacao
Nível 2Aula 13 · Rotas e controladores

PUT que substitui, PATCH que remenda

O PUT que você escreveu hoje mente: pelo RFC 9110, PUT substitui o recurso inteiro, então mandar {"preco": 12.9} deveria apagar nome, categoria e descrição. O nosso preserva — comportamento de PATCH usando o nome erra…

⭐⭐api http rotas refatoracao
Nível 2Aula 13 · Rotas e controladores

O gerente que quer saber o que vende

A dona do Café Cerrado pediu um resumo do cardápio: quantos produtos existem, quanto custa o mais caro e o mais barato, qual o preço médio por categoria. Ela não sabe o que é JSON, mas o seu front vai saber. Construa …

⭐⭐api express json crud
Nível 2Aula 13 · Rotas e controladores

Dois pedidos ao mesmo tempo, um produto perdido

Seu criar faz três coisas em sequência: lê o arquivo, acrescenta um item, grava o arquivo. Entre a leitura e a gravação existe uma janela de alguns milissegundos. Se duas requisições entrarem nessa janela juntas, as d…

⭐⭐⭐node api bug performance
Nível 2Aula 14 · Autenticação com Google (OAuth 2.0)

O botão que não quer aparecer

Abra o site do Café Cerrado pelo Live Server do VS Code, em http://127.0.0.1:5500, em vez de pelo seu servidor Express. O botão do Google some, e o console solta uma mensagem que menciona origin. Antes de consertar, e…

oauth autenticacao devtools bug
Nível 2Aula 14 · Autenticação com Google (OAuth 2.0)

Só quem é da casa entra

Hoje qualquer pessoa com uma conta Google — o planeta inteiro — vira um usuário capaz de mexer no cardápio do Café Cerrado. Isso está certo para um blog e errado para um sistema interno. Implemente autorização de verd…

⭐⭐autenticacao seguranca express middleware
Nível 2Aula 14 · Autenticação com Google (OAuth 2.0)

Quanto tempo dura a sua identidade

O ID token do Google e o token de sessão que você emitiu têm prazos de validade diferentes, definidos por gente diferente, por motivos diferentes. Poucos desenvolvedores sabem dizer quais são. Descubra os dois experim…

⭐⭐autenticacao oauth investigacao http
Nível 2Aula 14 · Autenticação com Google (OAuth 2.0)

Tirando o token das mãos do JavaScript

Se um único script malicioso rodar na sua página, ele lê o sessionStorage e leva a sessão embora. É assim que contas são roubadas de verdade. A defesa padrão da indústria é entregar a sessão em um cookie httpOnly: o n…

⭐⭐⭐seguranca autenticacao express http
Nível 2Aula 15 · CRUD com front-end assíncrono

O card que morre errado

Um colega "otimizou" a exclusão para não precisar buscar a lista de novo no servidor: em vez de recarregar, ele remove o item direto do array local. Funciona lindamente — até você digitar algo na busca. Com o filtro b…

javascript dom bug crud
Nível 2Aula 15 · CRUD com front-end assíncrono

A busca que corre atrás de si mesma

Ligue o throttling "Slow 3G" na aba Network, digite cafe rápido no campo de busca e observe: a resposta de caf pode chegar depois da resposta de cafe, e a tela termina mostrando o resultado errado, para um termo que j…

⭐⭐fetch async performance devtools
Nível 2Aula 15 · CRUD com front-end assíncrono

Erro 400 no campo certo

O servidor já faz a parte dele: desde a Aula 13, o 400 devolve detalhes como lista de objetos { "campo": "preco", "mensagem": "…" }. A tela é que desperdiça essa informação — ela junta tudo num parágrafo só: "Dados in…

⭐⭐formularios acessibilidade api fetch
Nível 2Aula 15 · CRUD com front-end assíncrono

Adeus, `confirm()`

O confirm() do navegador congela a aba inteira, não pode ser estilizado, não cabe na identidade visual do Café Cerrado e some sem deixar rastro em capturas de tela. Toda aplicação séria usa um diálogo próprio — e a pl…

⭐⭐⭐acessibilidade dom refatoracao javascript
Nível 2Aula 16 · CRUD completo com autenticação e entrega final

A prova dos três status

Dizer "minha API está protegida" é fácil; provar é outra coisa. Monte a evidência: um único arquivo com as requisições que demonstram, sem margem de dúvida, que a sua API distingue os três casos — visitante (401), pes…

seguranca autenticacao http investigacao
Nível 2Aula 16 · CRUD completo com autenticação e entrega final

O crachá de administrador

O Café Cerrado cresceu e agora tem um gerente, que precisa corrigir o preço de qualquer produto — inclusive os cadastrados por outras pessoas. Sem inventar um sistema de cadastro de usuários: uma lista de e-mails admi…

⭐⭐autenticacao express middleware seguranca
Nível 2Aula 16 · CRUD completo com autenticação e entrega final

Quem mexeu no cardápio?

Todo sistema sério registra quem fez o quê. Sem isso, quando um preço aparecer errado, ninguém consegue dizer se foi engano, sabotagem ou bug. Construa uma trilha de auditoria para o Café Cerrado: cada criação, altera…

⭐⭐⭐express seguranca node crud
Nível 2Aula 16 · CRUD completo com autenticação e entrega final

O Café Cerrado recebe pedidos

Este é o mini-projeto que fecha a Unidade 3 e usa tudo: rotas, controladores, middlewares, autenticação, autorização, persistência e front assíncrono. O cardápio está no ar e as pessoas querem pedir. Crie um segundo r…

🔥projeto crud autenticacao express
Nível 3Aula 01 · Apresentação da trilha e revisão de JavaScript

O evento com zero vagas que "ganha" 10

Um colega escreveu vagasParaExibir(evento) para mostrar o número de vagas no card do evento, usando o padrão que a Seção 3.7 alertou ser perigoso: evento.vagasDisponiveis || 10. Um evento com exatamente zero vagas est…

javascript bug investigacao
Nível 3Aula 01 · Apresentação da trilha e revisão de JavaScript

Quanto custa recriar a lista inteira a cada tecla?

O código da Seção 2.1 (DOM manual) apaga listaEl.innerHTML e reconstrói tudo a cada tecla digitada na busca — funciona bem com 4 eventos, mas e com mil? Gere uma lista grande, meça o custo real de renderizar() a cada …

⭐⭐performance dom javascript devtools
Nível 3Aula 01 · Apresentação da trilha e revisão de JavaScript

O módulo de dados do seu projeto autoral

Toda a Seção 3 revisou ferramentas de JavaScript moderno usando eventos como exemplo — mas o seu projeto autoral (Seção 1.6) tem outro domínio. Construa o dominio.js real do seu projeto, aplicando classes, módulos, os…

⭐⭐⭐javascript projeto api async
Nível 3Aula 02 · Introdução ao Vue: instância, ciclo de vida e diretivas

Vagas restantes: NaN

O formulário de criação de evento do UniEventos usa <input v-model.number="vagas" type="text"> para o campo de vagas. Um colega testou digitando "quarenta" em vez de 40 — e o card passou a mostrar "NaN vaga(s) restant…

vue bug investigacao
Nível 3Aula 02 · Introdução ao Vue: instância, ciclo de vida e diretivas

O UniEventos funciona sem mouse?

Guarde o mouse. Navegue pela tela de eventos construída hoje usando só Tab, Shift+Tab, Enter e as setas. Encontre pelo menos três barreiras de acessibilidade por teclado — foco que desaparece visualmente, campo sem ró…

⭐⭐acessibilidade vue devtools
Nível 3Aula 02 · Introdução ao Vue: instância, ciclo de vida e diretivas

A primeira tela navegável do seu projeto autoral

Aplique tudo desta aula — ref/reactive, v-bind/v-on/v-model, v-if/v-show, v-for com :key estável e um hook de ciclo de vida real — na entidade principal do seu projeto autoral, com a mesma profundidade da Seção "Mão n…

⭐⭐⭐vue projeto javascript
Nível 3Aula 03 · Vue: listas, computed e ciclo de vida

O `watch` que finge que está funcionando

A store de filtros do seu colega usa um objeto reactive com busca, categoria e apenasComVaga, observado por um único watch(filtros, callback) (sem a opção da Seção 4.2). Ele jura que testou e "funcionava" — mas agora,…

vue bug investigacao
Nível 3Aula 03 · Vue: listas, computed e ciclo de vida

Quanto o `computed` realmente economiza?

A Seção 3 provou, com um console.log, que um computed roda uma vez só, mesmo usado três vezes no template. Mas quanto tempo isso realmente economiza quando a lista é grande? Meça com 5.000 eventos e descubra a partir …

⭐⭐performance vue refatoracao
Nível 3Aula 03 · Vue: listas, computed e ciclo de vida

Estados de carregamento no seu projeto autoral

Leve todo o padrão desta aula — computed encadeadas, watch persistindo uma preferência, e os três estados de tela (carregando/erro/vazio) — para o domínio do seu projeto autoral.

⭐⭐⭐vue projeto async
Nível 3Aula 04 · Introdução a Vuetify e Vue Router

O tema que esquece toda vez

O botão de sol/lua da seção 5 troca o tema na hora — mas dê um F5: a aplicação volta para 'light', mesmo que você tenha deixado no escuro há dois segundos. Ninguém espera reconfigurar a aparência do site toda vez que …

vuetify vue javascript
Nível 3Aula 04 · Introdução a Vuetify e Vue Router

Menu que só existe para quem usa mouse

Desconecte o mouse (ou apenas prometa a si mesmo não tocar nele) e tente abrir o menu lateral do UniEventos só com o teclado: Tab até o ícone de hambúrguer, Enter para abrir, Tab pelos itens, Esc para fechar. Em quant…

⭐⭐acessibilidade vuetify devtools
Nível 3Aula 04 · Introdução a Vuetify e Vue Router

Quanto custa carregar tudo de uma vez

A seção 7 recomenda lazy loading (() => import(...)) para toda view, "porque o padrão é esse". Mas quanto isso realmente economiza no UniEventos, hoje, com só quatro views? Meça de verdade antes de confiar na recomend…

⭐⭐⭐performance vue router
Nível 3Aula 04 · Introdução a Vuetify e Vue Router

Painel de favoritos do UniEventos

A Unidade 1 terminou: você tem uma SPA com Vuetify, rotas, tema e grid responsivo. Antes de a Unidade 2 trazer componentização séria e a Unidade 3 trazer um back-end de verdade, prove que consegue montar uma funcional…

🔥vue vuetify router projeto
Nível 3Aula 05 · Componentes, Vue Router e Vuetify avançado

O emit que ninguém escuta

Um colega criou DialogoConfirmacao.vue reaproveitando o desta aula, mas trocou um detalhe sem perceber. Ao clicar em "Excluir" no diálogo, nada acontece — o evento aparentemente nunca chega ao componente pai. Este é o…

vue bug investigacao
Nível 3Aula 05 · Componentes, Vue Router e Vuetify avançado

Menu de contexto sem mouse

O v-menu de ações rápidas do Laboratório B4 funciona perfeitamente no mouse. Agora teste só com teclado: Tab até o botão de três pontinhos, Enter para abrir, Tab/setas para navegar pelas opções, Enter para escolher, E…

⭐⭐acessibilidade vuetify vue
Nível 3Aula 05 · Componentes, Vue Router e Vuetify avançado

Prop drilling até o neto

O código abaixo passa o usuário logado por três componentes até chegar a quem realmente precisa dele — clássico prop drilling. PainelAdmin e CabecalhoSecao não usam usuarioLogado para nada além de repassar adiante:

⭐⭐⭐vue refatoracao padroes-de-projeto
Nível 3Aula 06 · Axios e Pinia

Token fantasma

Um colega "simplificou" o interceptor de request removendo a checagem, para deixar o código mais enxuto:

axios javascript bug
Nível 3Aula 06 · Axios e Pinia

Persistência sem repetir código

inscricoesStore (e, se você fez o Laboratório B4, preferenciasStore também) implementam persistência em localStorage cada uma com sua própria lógica de leitura/escrita repetida. Extraia isso para uma função reutilizáv…

⭐⭐pinia refatoracao padroes-de-projeto
Nível 3Aula 06 · Axios e Pinia

Cache de 30 segundos para não repetir a mesma pergunta

Toda vez que o usuário volta para a Home vindo do detalhe de um evento, carregarEventos() dispara um novo GET /eventos — mesmo que a lista não tenha mudado nos últimos segundos. Em uma API de verdade (não o json-serve…

⭐⭐⭐performance axios javascript
Nível 3Aula 06 · Axios e Pinia

Painel de inscrições com filtros persistentes na URL

A Unidade 2 terminou. Você sabe componentizar de verdade, sincronizar filtros com a URL (Aula 05), e agora consumir uma API real com Axios e Pinia (hoje). Prove que tudo isso funciona junto, numa única funcionalidade …

🔥vue pinia axios projeto
Nível 3Aula 07 · Introdução ao Firebase, Node.js e Express

Onde seu segredo mora

Abra o DevTools (F12) no seu unieventos-web rodando com npm run dev, vá na aba Sources e procure pelo valor de uma das variáveis VITEFIREBASE que você configurou no .env. Ela aparece ali, legível, para qualquer pessoa…

javascript devtools seguranca investigacao
Nível 3Aula 07 · Introdução ao Firebase, Node.js e Express

A rota que existe duas vezes

Um colega registrou duas rotas parecidas sem perceber a colisão: GET /api/eventos/:id e, mais abaixo no arquivo, GET /api/eventos/destaque (pensada para devolver o evento em destaque do momento). Toda chamada para /ap…

⭐⭐express rotas bug refatoracao
Nível 3Aula 07 · Introdução ao Firebase, Node.js e Express

Quanto tempo o event loop aguenta

A seção 2 desta aula prometeu que o Node atende milhares de conexões com uma única thread — desde que o trabalho seja I/O, não cálculo. Prove isso (e o limite disso) na prática: meça quanto uma rota "pesada" de CPU (s…

⭐⭐⭐node performance investigacao terminal
Nível 3Aula 08 · Definindo endpoints e middlewares

O 404 que na verdade é um 200

Teste no seu unieventos-api: GET /api/eventos/abc (um id que não é número). O que a rota devolve? Compare com o que a tabela de status codes desta aula promete para "recurso inexistente". Investigue por que Number('ab…

express http bug investigacao
Nível 3Aula 08 · Definindo endpoints e middlewares

Um middleware, duas versões

O medidorDeTempo desta aula usa process.hrtime.bigint() e o evento 'finish' do objeto res. Implemente uma segunda versão que, além de logar o tempo no console, guarda em um array em memória as últimas 100 durações de …

⭐⭐middleware performance refatoracao node
Nível 3Aula 08 · Definindo endpoints e middlewares

Envelope de erro, ponta a ponta

O envelope { "erro": { "mensagem", "codigo" } } desta aula não chega pronto ao usuário final — alguém no front precisa transformá-lo em algo visível. Implemente, no front-end do seu projeto autoral, um interceptor de …

⭐⭐⭐api express refatoracao projeto
Nível 3Aula 09 · Integrando com SGBD MySQL

O índice que ninguém usa

Toda tabela do schema.sql desta aula tem pelo menos um índice — mas nem toda consulta que você vai escrever no seu projeto autoral necessariamente usa esses índices do jeito que você espera. Rode EXPLAIN numa consulta…

mysql performance investigacao banco-de-dados
Nível 3Aula 09 · Integrando com SGBD MySQL

Duas inscrições, uma vaga

A transação desta aula usa FOR UPDATE para travar a linha do evento — mas o que acontece se você remover essa trava de propósito e disparar duas inscrições simultâneas para um evento com exatamente 1 vaga? Reproduza a…

⭐⭐mysql banco-de-dados bug investigacao
Nível 3Aula 09 · Integrando com SGBD MySQL

Migrando sem quebrar nada

A promessa central desta aula é que migrar de memória para MySQL não deveria quebrar nenhum contrato de API. Prove isso formalmente no seu projeto autoral: grave as respostas de todo o requests.http rodando contra a v…

⭐⭐⭐mysql api refatoracao projeto
Nível 3Aula 10 · Requisições autenticadas com Firebase

Onde o Firebase guarda sua sessão

Você já viu que dar F5 não desloga o usuário — mas onde exatamente o SDK guarda essa informação para sobreviver ao recarregamento da página? Abra o DevTools no UniEventos já logado e investigue, sem ler a documentação…

firebase autenticacao devtools investigacao
Nível 3Aula 10 · Requisições autenticadas com Firebase

O menu pisca errado no F5

Ao dar F5 numa página do UniEventos com o usuário já logado, por uma fração de segundo aparecem os botões "Entrar"/"Cadastrar" antes de trocarem para o menu de usuário logado. É rápido demais para notar em conexão boa…

⭐⭐vue firebase bug investigacao
Nível 3Aula 10 · Requisições autenticadas com Firebase

Ninguém publica sem confirmar o e-mail

Hoje, qualquer conta criada por e-mail/senha pode criar um evento imediatamente — mesmo com um e-mail inventado (fulano@empresa-que-nao-existe.com) que a pessoa nem é dona de verdade. Ainda não confirmamos que o e-mai…

⭐⭐⭐firebase autenticacao seguranca express
Nível 3Aula 11 · Integrando front-end com back-end: CRUD

A busca que some na página 3

Um colega "melhorou" a EventosListaView.vue e agora acontece algo estranho: navegue até a página 3 da tabela e digite "docker" na busca — a tabela mostra "Nenhum evento encontrado", mas o rodapé insiste que existem 2 …

vue devtools bug investigacao
Nível 3Aula 11 · Integrando front-end com back-end: CRUD

Otimista, mas honesto

A store desta aula é pessimista de propósito (seção 5). Mas abra o DevTools, ative o throttling "Slow 3G" na aba Network e exclua um evento: o botão gira por três segundos antes de a linha sumir. Gmail e Trello remove…

⭐⭐pinia vue performance refatoracao
Nível 3Aula 11 · Integrando front-end com back-end: CRUD

O que o curl faz que a tela não deixa

O botão de editar só aparece para quem está logado, e o de excluir só para admin. Mas botão escondido não é permissão: qualquer pessoa com um token válido consegue montar um PUT /api/eventos/3 no curl e editar o event…

⭐⭐seguranca express crud autenticacao
Nível 3Aula 11 · Integrando front-end com back-end: CRUD

Paginação que aguenta 100 mil eventos

LIMIT 10 OFFSET 99990 obriga o MySQL a ler e descartar 99.990 linhas antes de devolver 10 — a última página é sempre a mais lenta. Gere 100 mil eventos falsos, meça o tempo das primeiras e das últimas páginas e depois…

⭐⭐⭐mysql performance api banco-de-dados
Nível 3Aula 12 · CRUD com banco em nuvem (Supabase)

A tabela que parecia vazia

Um colega criou a tabela de comentários de eventos com o SQL abaixo e reclamou de dois "bugs do Supabase": visitantes deslogados não veem comentário nenhum (a página fica vazia, sem erro), e um usuário conseguiu "roub…

supabase seguranca bug investigacao
Nível 3Aula 12 · CRUD com banco em nuvem (Supabase)

O que dá para fazer só com a chave pública

Rode npm run build e procure eyJ dentro de dist/assets/.js: a sua chave anon está lá, legível para qualquer pessoa que abrir o site. Isso é esperado — mas o que exatamente alguém consegue fazer com ela e um terminal? …

⭐⭐supabase seguranca http investigacao
Nível 3Aula 12 · CRUD com banco em nuvem (Supabase)

Vagas ao vivo: inscrições com join, contagem e Realtime

O card de evento mostra vagas, mas não quantas já foram ocupadas — e o botão "Inscrever-se" nem existe na versão Supabase. Construa o fluxo completo usando só o que a aula ensinou: contagem de relacionados no select, …

⭐⭐supabase crud vue banco-de-dados
Nível 3Aula 12 · CRUD com banco em nuvem (Supabase)

A última vaga, sem condição de corrida — dentro do banco

Na Aula 11, a última vaga foi protegida com uma transação e FOR UPDATE dentro do Express. Com Supabase não existe "seu servidor" para colocar essa lógica — e um select de contagem seguido de insert no front deixa a po…

⭐⭐⭐supabase banco-de-dados seguranca api
Nível 3Aula 13 · Desenvolvimento do back-end em camadas

A ordem que quebra tudo

Um colega reorganizou o app.js "para ficar mais legível" e agora os testes de rota falham de um jeito curioso: POST /api/eventos válido devolve 422 dizendo que todos os campos são obrigatórios, e GET /api/eventos/999 …

express middleware bug testes
Nível 3Aula 13 · Desenvolvimento do back-end em camadas

Rate limit que não pune todo mundo por igual

Em uma rede compartilhada — um laboratório, um escritório, ou até um provedor com NAT/CGNAT — várias pessoas saem para a internet pelo mesmo IP. Com limit: 100 por IP a cada 15 minutos, bastam quatro pessoas testando …

⭐⭐express middleware seguranca testes
Nível 3Aula 13 · Desenvolvimento do back-end em camadas

Supabase como repositório — do lado certo da chave

Na Aula 12 a servicerole era proibida porque o código rodava no navegador. Aqui é diferente: o back-end é um ambiente de servidor, e a chave pode ficar no .env. Implemente criarRepositorioDeEventosSupabase() com a mes…

⭐⭐supabase padroes-de-projeto node refatoracao
Nível 3Aula 13 · Desenvolvimento do back-end em camadas

Cobertura que aponta o que falta

Sete testes dão confiança — mas confiança em quê, exatamente? Meça: instale @vitest/coverage-v8, rode npx vitest run --coverage e olhe o relatório linha a linha. Você vai descobrir que remover, atualizar, o 413 do lim…

⭐⭐⭐testes express seguranca refatoracao
Nível 3Aula 14 · Documentação com Swagger

As tags sumidas

Um colega documentou um novo endpoint PATCH /api/eventos/{id}/destaque (marca um evento como destaque na home) com uma anotação @openapi completa — mas o Swagger UI insiste em mostrar essa operação isolada, fora dos g…

swagger api bug investigacao
Nível 3Aula 14 · Documentação com Swagger

O schema que não bate mais

Reproduza no seu repositório uma divergência que acontece o tempo todo em projeto real. Renomeie, só no linhaParaEvento do repositório, o campo imagemUrl para urlDaImagem, e ajuste a anotação Swagger de GET /api/event…

⭐⭐swagger refatoracao api json
Nível 3Aula 14 · Documentação com Swagger

Documentação como teste de contrato

Na Seção 1 você leu que "documentação vira uma fonte de verdade verificável" quando existe uma ferramenta de teste de contrato comparando a resposta real com o que foi documentado. Hoje isso ainda é só teoria no UniEv…

⭐⭐⭐testes api swagger ci-cd
Nível 3Aula 15 · Deploy, apresentação e finalização

Quanto custa acordar o servidor

Planos gratuitos de hospedagem "dormem" o processo depois de um tempo sem tráfego (Seção 3.2) — mas quanto tempo, exatamente, uma requisição demora para acordar um serviço adormecido, comparado com uma requisição norm…

deploy devtools investigacao performance
Nível 3Aula 15 · Deploy, apresentação e finalização

O F5 que só quebra em produção

Um colega jura que testou tudo: npm run preview local funciona perfeitamente, F5 em qualquer rota interna funciona. Mas depois de publicado, o mesmo F5 em /eventos/3 devolve uma página de erro genérica do provedor de …

⭐⭐deploy spa bug investigacao
Nível 3Aula 15 · Deploy, apresentação e finalização

Um deploy que se testa sozinho

Hoje, se um deploy quebrar (uma variável de ambiente errada, uma migration esquecida), você só descobre quando alguém tenta usar a aplicação e encontra um erro. Implemente um smoke test pós-deploy: um passo automático…

⭐⭐⭐ci-cd deploy testes terminal
Nível 3Aula 15 · Deploy, apresentação e finalização

Seu projeto autoral, no ar e à prova de F5

Chegamos ao fim das três unidades. Este é o desafio que fecha a trilha: seu projeto autoral publicado, de ponta a ponta, com todas as camadas construídas ao longo das aulas funcionando juntas em produção — e não só "f…

🔥deploy ci-cd projeto testes
DeployCap. 01 · Caixa de ferramentas do dev web

Quanto pesa uma dependência?

Você instalou um pacote — prettier — e a pasta nodemodules apareceu. Quantos arquivos ela tem? E se instalar vite? A resposta explica, melhor do que qualquer regra, por que nodemodules nunca entra em um .zip, em um e-…

terminal node investigacao
DeployCap. 01 · Caixa de ferramentas do dev web

Dotfiles: seu VS Code em um comando

Formatou o computador? Vai usar a máquina do laboratório? Profissionais guardam suas configurações em um repositório de dotfiles e reinstalam tudo com um script. Monte o seu: uma pasta bancada com um instalar.sh que, …

⭐⭐terminal projeto
DeployCap. 01 · Caixa de ferramentas do dev web

Detetive de performance

Por que um site de notícias demora oito segundos no 4G e o WebLab demora um? Hoje você deixa de adivinhar. Escolha três sites reais (um portal de notícias, uma loja online e um site de universidade), audite cada um no…

⭐⭐⭐devtools performance investigacao
DeployCap. 02 · Git e GitHub do zero ao pull request

O que o `.git` guarda

O git status diz que a pasta está limpa, mas a .git tem centenas de arquivos. O que exatamente está lá dentro, e por que um repositório com 20 commits de um site de 200 KB pode ocupar menos espaço do que os próprios a…

git terminal investigacao
DeployCap. 02 · Git e GitHub do zero ao pull request

Um histórico que conta a história

Pegue o repositório mais bagunçado que você tem (aquele com commits chamados "alteracoes", "update2" e "agora vai") e transforme-o em um repositório que você mostraria numa entrevista. O objetivo não é maquiar: é apre…

⭐⭐git github refatoracao
DeployCap. 02 · Git e GitHub do zero ao pull request

Caçada ao commit culpado

Um site que funcionava parou de funcionar, e ninguém sabe quando. Em vez de ler cinquenta commits, o Git faz uma busca binária: você diz um ponto bom e um ruim, e ele te leva ao commit exato em oito passos. Hoje você …

⭐⭐⭐git bug investigacao
DeployCap. 02 · Git e GitHub do zero ao pull request

A bancada inteira, versionada e publicada

Este é o Boss da Unidade 1: ele junta tudo o que os Capítulos 01 e 02 ensinaram. A ideia é simples de enunciar e trabalhosa de executar bem: uma máquina nova deve ficar pronta para trabalhar rodando um comando do seu …

🔥git github terminal projeto
DeployCap. 03 · Publicando sites estáticos

A autópsia do site quebrado

É comum alguém publicar o site e receber de volta uma página de texto sem estilo, sem imagem e sem menu — e concluir que "o GitHub Pages não funciona". Ele funciona. O que não funciona é um caminho que começa com barr…

deploy github investigacao
DeployCap. 03 · Publicando sites estáticos

Quatro hospedagens, um site, um veredicto

As quatro plataformas deste capítulo prometem a mesma coisa: seu site no ar, de graça, em uma CDN. Elas entregam a mesma coisa? Descubra medindo, e não lendo página de marketing. O mesmo site, publicado quatro vezes, …

⭐⭐deploy performance http
DeployCap. 03 · Publicando sites estáticos

De 60 a 95 no Lighthouse, com prova

Nota de Lighthouse é fácil de melhorar quando você sabe o que ela mede — e impossível quando você chuta. O trabalho aqui é científico: medir, mudar uma coisa, medir de novo, registrar o efeito. No fim, você vai saber …

⭐⭐⭐performance deploy devtools
DeployCap. 04 · Domínios, DNS e HTTPS

O caminho completo de um nome

Quantos servidores diferentes precisam ser consultados para que o seu navegador descubra o IP de weblab.aprendabit.com? E de www.uol.com.br? A resposta muda de um nome para outro — e o dig +trace mostra cada parada, c…

dns terminal investigacao
DeployCap. 04 · Domínios, DNS e HTTPS

Um domínio, três hospedagens

Um único domínio é suficiente para o portfólio inteiro do semestre: o apex para a sua página pessoal, um subdomínio para cada projeto, cada um em uma plataforma diferente. Monte essa estrutura de verdade: apex (seudom…

⭐⭐dns deploy github https
DeployCap. 04 · Domínios, DNS e HTTPS

Certificado curinga com desafio DNS

Você tem dez subdomínios de projetos e não quer emitir dez certificados. Um certificado curinga .seudominio.dev cobre todos — mas a Let's Encrypt só o emite pelo desafio DNS-01, porque não existe como "servir um arqui…

⭐⭐⭐https dns terminal seguranca
DeployCap. 05 · Publicando o back-end Node

Health check que diz a verdade

O /api/saude do Passo a passo responde ok mesmo que o arquivo de dados tenha sumido, que o disco esteja cheio ou que a API não consiga mais ler o cardápio. Ele diz apenas "o processo está vivo" — o que é útil, mas é p…

node express api investigacao
DeployCap. 05 · Publicando o back-end Node

Uma API, três ambientes

Todo time profissional trabalha com três ambientes: local (a sua máquina), homologação (onde se testa sem medo) e produção (onde os usuários estão). Hoje a sua API tem local e produção, e cada push na main vai direto …

⭐⭐deploy node seguranca projeto
DeployCap. 05 · Publicando o back-end Node

Sobreviva ao disco efêmero

Faça o teste que ninguém faz antes de entregar: crie três produtos pela API publicada, force um novo deploy e recarregue o cardápio. Eles sumiram. O dados/produtos.json voltou ao estado do repositório, porque o disco …

⭐⭐⭐deploy node api banco-de-dados
DeployCap. 06 · Servidor próprio (VPS) com nginx

O diário do servidor

O seu VPS tem poucas horas de vida e já é alvo de milhares de tentativas de acesso. Elas vêm de robôs que varrem faixas inteiras de IP procurando senhas fracas — e ficam todas registradas. Faça a auditoria: descubra q…

seguranca terminal investigacao deploy
DeployCap. 06 · Servidor próprio (VPS) com nginx

Nota A no SSL Labs

O certbot deixa o seu site funcionando, mas com a configuração TLS padrão. Submeta https://eventos.seudominio.dev ao teste do SSL Labs (<https://www.ssllabs.com/ssltest/>) e veja a nota. Depois melhore a configuração …

⭐⭐https nginx seguranca performance
DeployCap. 06 · Servidor próprio (VPS) com nginx

Publicação sem derrubar o site

Hoje o seu deploy é uma sequência de comandos digitados à mão que deixa o site fora do ar por alguns segundos — e, se algo falhar no meio, deixa o servidor num estado híbrido, com o front novo e a API antiga. Escreva …

⭐⭐⭐deploy nginx node terminal
DeployCap. 06 · Servidor próprio (VPS) com nginx

Os três projetos no ar, com HTTPS, em subdomínios

Um servidor. Um domínio. Três projetos do semestre, cada um em um subdomínio, todos com cadeado — e um README.md que qualquer pessoa consegue seguir para reconstruir tudo do zero em uma máquina nova. É o fechamento da…

🔥deploy nginx https dns
DeployCap. 07 · Docker para desenvolvedores web

Imagem abaixo de 150 MB

A imagem da API construída no Passo a passo pesa quanto? docker images ghcr.io/seu-usuario/unieventos-api responde. Se passou de 150 MB, algo desnecessário entrou: devDependencies, cache do npm, arquivos que o .docker…

docker performance investigacao
DeployCap. 07 · Docker para desenvolvedores web

Café Cerrado em contêiner

A cafe-cerrado-api do Nível 2 é mais simples que a do UniEventos: um Express 5 que serve a pasta public/ e expõe /api/produtos, gravando em um arquivo JSON. Justamente por gravar em arquivo ela tem um problema que a u…

⭐⭐docker express projeto
DeployCap. 07 · Docker para desenvolvedores web

Três contêineres, um comando, zero CORS

Hoje o site chama a API em outra origem e o CORS precisa liberar o domínio do front. Se o mesmo nginx que serve o site fizer proxy de /api/ para a API, front e back passam a ter a mesma origem — e o CORS deixa de exis…

⭐⭐⭐docker nginx vue express
DeployCap. 08 · Bancos de dados na nuvem

O banco que responde em 20 ms — ou em 200

Sua tela de eventos parece rápida no npm run dev, com o banco em Docker na mesma máquina, e fica arrastada com o banco na nuvem. Nada no código mudou — mudou a distância. Descubra exatamente quanto da lentidão é rede …

banco-de-dados performance investigacao
DeployCap. 08 · Bancos de dados na nuvem

O backup que você provou que funciona

Todo mundo tem backup até precisar restaurar. Monte a rotina completa do seu projeto autoral — gerar, guardar fora do servidor, restaurar em um banco descartável e comparar — e execute-a até o fim pelo menos uma vez, …

⭐⭐banco-de-dados deploy seguranca
DeployCap. 08 · Bancos de dados na nuvem

Do MySQL para o Postgres sem perder um evento

O projeto nasceu em MySQL (Aula 09 do Nível 3) e agora vai para um Postgres gerenciado. O schema muda, os tipos mudam, as consultas mudam — e os dados que já existem precisam chegar do outro lado inteiros, com as chav…

⭐⭐⭐banco-de-dados mysql supabase refatoracao
DeployCap. 09 · CI/CD com GitHub Actions

A esteira que reprova

Uma CI que nunca ficou vermelha não provou nada — talvez ela não esteja rodando o que você pensa. Comprove que a sua esteira reprova de verdade, nas três formas de errar que mais acontecem, e documente o que cada uma …

ci-cd github testes
DeployCap. 09 · CI/CD com GitHub Actions

Ambiente de revisão para cada pull request

Revisar um PR lendo o diff é uma coisa; abrir o site do PR no navegador é outra. Faça com que todo pull request do unieventos-web publique uma versão temporária e comente no próprio PR o endereço onde ela pode ser vista.

⭐⭐ci-cd deploy github projeto
DeployCap. 09 · CI/CD com GitHub Actions

Banco de verdade em cada pull request

Testes com repositório falso não pegam erro de SQL. Faça a CI validar as consultas contra um Postgres real, aplicando as migrations do zero a cada execução — e, de quebra, provar que toda migration nova também desfaz …

⭐⭐⭐ci-cd banco-de-dados testes investigacao
DeployCap. 09 · CI/CD com GitHub Actions

A esteira completa, com rollback automático

Você tem CI, imagem publicada e deploy por SSH. Falta o que separa um pipeline de aula de um pipeline de produção: saber que o deploy deu errado e desfazê-lo sozinho. Monte a esteira completa do UniEventos (front e ba…

🔥ci-cd docker deploy nginx
DeployCap. 10 · Qualidade, performance e observabilidade

O relatório antes e depois

Todo mundo diz que "otimizou o site". Quase ninguém consegue mostrar o número. Hoje você mostra. Pegue o seu projeto autoral publicado, meça, aplique exatamente três correções de performance e meça de novo — provando …

performance deploy investigacao
DeployCap. 10 · Qualidade, performance e observabilidade

A rede de segurança do projeto autoral

O seu projeto autoral não termina no primeiro deploy: se der certo, você (ou outra pessoa) vai voltar a mexer nele daqui a alguns meses. Sem testes, cada mudança futura é uma aposta. Construa a rede de segurança: uma …

⭐⭐testes ci-cd node
DeployCap. 10 · Qualidade, performance e observabilidade

Painel de saúde do seu sistema

Sistemas profissionais têm uma página que responde, em cinco segundos de olhada, "está tudo bem?". Construa a sua para o projeto autoral: uma página /status que reúne disponibilidade, desempenho e erros — e que você c…

⭐⭐⭐performance deploy seguranca
DeployCap. 11 · IA como ferramenta de desenvolvimento

Caderno de bordo da IA

Você provavelmente não faz ideia de quanto do seu código vem de sugestão aceita sem leitura. Ninguém faz — e é justamente por isso que a conta assusta quando aparece. Durante uma semana de trabalho no projeto autoral,…

ia projeto investigacao
DeployCap. 11 · IA como ferramenta de desenvolvimento

Placar do caça-alucinação

Quem consegue medir uma ferramenta para de discutir sobre ela. Monte uma bateria de perguntas cuja resposta certa está na documentação oficial das versões que usamos, aplique em dois assistentes diferentes e publique …

⭐⭐ia investigacao testes
DeployCap. 11 · IA como ferramenta de desenvolvimento

Revisor de segurança do seu projeto

Toda API construída nesta trilha tem pelo menos uma falha de segurança real. A sua também. Use o assistente como um revisor incansável, mas prove cada coisa: aqui, um problema só conta depois que você escreveu o teste…

⭐⭐⭐ia seguranca testes projeto
DeployCap. 11 · IA como ferramenta de desenvolvimento

Tudo no ar, medido e defensável

Este é o encerramento da trilha, e ele é simples de enunciar: o seu projeto autoral, inteiro, funcionando na internet, com tudo o que os onze capítulos ensinaram — e você capaz de defender cada decisão em dez minutos,…

🔥deploy ci-cd ia seguranca
ProjetoProjeto integrador

Página de perfil profissional

Um recrutador abre o link do seu perfil antes de abrir o currículo e decide em trinta segundos se continua lendo. Uma página de uma tela só, feita por você, diz mais do que dez linhas de "conhecimentos em HTML" num PD…

html css flexbox responsivo
ProjetoProjeto integrador

Cardápio digital de restaurante

O QR code na mesa do restaurante abre um PDF de 8 MB que não cabe na tela do celular — você já passou por isso. O dono da lanchonete perto do campus sofre com o mesmo problema e não sabe que a solução são três arquivo…

html css grid responsivo
ProjetoProjeto integrador

Lista de tarefas

Todo desenvolvedor já fez uma lista de tarefas, e é exatamente por isso que ela é um bom projeto: você vai comparar a sua com centenas de outras e descobrir o que separa uma lista de brinquedo de uma que você usaria d…

⭐⭐javascript dom eventos formularios
ProjetoProjeto integrador

Calculadora de notas acadêmicas

Fim de semestre, três notas lançadas no SIGAA e a mesma pergunta em todo grupo da turma: "quanto eu preciso tirar na última pra passar?". Responda de uma vez por todas com uma calculadora que o colega consegue usar no…

⭐⭐javascript formularios dom projeto
ProjetoProjeto integrador

Quiz de conhecimentos

Um quiz é um jogo de estado: qual pergunta está na tela, o que já foi respondido, quantos pontos, se acabou. Todo bug de quiz ("a pergunta 3 apareceu duas vezes", "o botão continuou clicável depois da resposta") é um …

⭐⭐javascript dom eventos projeto
ProjetoProjeto integrador

Sistema de cadastro de eventos

O centro acadêmico anuncia palestras num grupo de WhatsApp, e ninguém acha a da semana passada nem sabe se a de amanhã é às 19h ou às 19h30. Uma agenda no navegador — sem servidor, sem login — já resolve a maior parte…

⭐⭐javascript formularios crud dom
ProjetoProjeto integrador

Catálogo de produtos com carrinho

Por que o total do carrinho nunca está escrito no HTML? Porque o carrinho é dado, e a tela é só um reflexo dele. Construa a vitrine de uma loja fictícia — o brechó, a livraria, a Café Cerrado — e um carrinho que sobre…

⭐⭐javascript grid dom eventos
ProjetoProjeto integrador

Controle de despesas pessoais

Some 0,1 com 0,2 no console do navegador. O resultado não é 0,3 — e é por isso que todo sistema financeiro sério guarda dinheiro em centavos inteiros. Neste projeto você vai controlar receitas e despesas de verdade (a…

⭐⭐⭐javascript formularios dom responsivo
ProjetoProjeto integrador

Sistema de reservas de equipamentos

O laboratório tem três projetores e cinco kits de Arduino, e a "reserva" é um caderno na secretaria. Duas turmas chegam com o mesmo projetor reservado, e o caderno não diz quem está com o kit que não voltou. Este é o …

⭐⭐⭐javascript crud formularios dom
ProjetoProjeto integrador

Painel com dados de uma API pública

Até aqui todos os dados estavam no seu arquivo. Agora eles estão em outro computador, chegam quando querem, às vezes não chegam e às vezes chegam num formato diferente do que a documentação prometia. Escolha uma API p…

⭐⭐⭐fetch async json api
ProjetoProjeto integrador

Sistema de reservas com API e login

O sistema de reservas em localStorage funciona só no navegador de quem cadastrou; no dia em que duas pessoas precisam ver a mesma agenda, ele vira um caderno digital. Este Boss leva o projeto anterior para onde ele pe…

🔥express autenticacao banco-de-dados deploy
ProjetoProjeto integrador

Painel de dados com cache, gráficos e CI

O painel do projeto de API pública chama a fonte direto do navegador; com duzentos usuários abrindo a página, a fonte bloqueia o IP e o painel morre. Este Boss coloca um servidor seu no meio: uma API Express que consu…

🔥api testes ci-cd performance

Projetos integradores

Projetos maiores, para juntar tudo o que você aprendeu em uma trilha. Cada um tem critérios de pronto e evoluções sugeridas — escolha um, publique e coloque no portfólio.

Os desafios das aulas treinam um músculo de cada vez; os projetos desta página pedem o corpo inteiro. Cada um parte de um problema que existe fora da sala e exige que você modele os dados, implemente as regras e explique as decisões. Estão em ordem crescente de complexidade: os dez primeiros cabem em três arquivos (index.html, style.css e script.js), sem framework e sem back-end; os dois últimos são o passo seguinte, com API, login, banco, testes e deploy. Entregue sempre a versão mínima funcionando mais uma evolução da sua escolha, acompanhadas de uma demonstração de três minutos e de um texto curto explicando a estrutura do HTML, a estratégia de CSS e a lógica do JavaScript. A trilha sugerida diz a partir de qual aula você já tem o que precisa para começar.

⭐ Página de perfil profissional

htmlcssflexboxresponsivoprojeto

Trilha sugerida: Nível 1 (a partir da aula 08) · Tempo estimado: 4–6 h

Um recrutador abre o link do seu perfil antes de abrir o currículo e decide em trinta segundos se continua lendo. Uma página de uma tela só, feita por você, diz mais do que dez linhas de "conhecimentos em HTML" num PDF. Construa a sua: quem você é, o que estuda, o que sabe fazer, o que já construiu e como falar com você. É o cartão de visitas que cresce junto com o curso — cada projeto desta lista vira um item novo na sua seção de projetos.

Funcionalidades mínimas

  • Cabeçalho com foto (ou avatar), nome, curso e uma frase de apresentação.
  • Seções de formação, habilidades (lista) e projetos, com pelo menos um card com link real (pode ser o site do evento da trilha).
  • Contatos com links funcionais: e-mail, GitHub e LinkedIn; links externos abrem em nova aba.
  • Navegação interna por âncoras entre as seções.
  • Layout em Flexbox que vira uma coluna no celular.

Critérios de pronto

  • HTML válido no validador do W3C, usando header, nav, main, section e footer (nenhum div fazendo papel de seção).
  • Toda imagem tem alt descritivo; a foto de perfil tem width e height declarados.
  • Abre em 360 px de largura sem rolagem horizontal e sem texto cortado.
  • Contraste entre texto e fundo de pelo menos 4.5:1 (verifique no DevTools).
  • Lighthouse Acessibilidade ≥ 90 e Performance ≥ 90 no modo celular.
  • Publicado em URL pública (GitHub Pages ou Netlify; a aula 15 do Nível 1 e o capítulo 03 de Deploy ensinam como).

Evolução (escolha pelo menos uma)

  • Alternância entre tema claro e escuro com um botão, guardando a preferência no localStorage (a partir da aula 13 do Nível 1) e respeitando prefers-color-scheme na primeira visita.
  • Seção de projetos gerada a partir de um array de objetos em JavaScript, em vez de HTML fixo.
  • Versão para impressão (@media print) que vira um currículo de uma página em PDF.
Pistas
  1. Desenhe no papel antes de abrir o editor: três caixas (cabeçalho, conteúdo, rodapé) e o que entra em cada uma. A aula 05 do Nível 1 explica por que a estrutura vem antes do estilo.
  2. Use flex-direction: column como padrão e mude para row a partir de 720 px com uma @media; celular primeiro dá menos código do que o contrário (aula 08).
  3. Variáveis CSS (--cor-fundo, --cor-texto) no :root deixam o tema escuro da evolução em cinco linhas: basta trocar os valores dentro de um seletor [data-tema="escuro"].
  4. Para a preferência salva, localStorage.setItem e getItem guardam uma string; leia-a no início do script, antes de pintar a página, para não piscar o tema errado.

⭐ Cardápio digital de restaurante

htmlcssgridresponsivoprojeto

Trilha sugerida: Nível 1 (a partir da aula 08; evolução a partir da aula 13) · Tempo estimado: 5–8 h

O QR code na mesa do restaurante abre um PDF de 8 MB que não cabe na tela do celular — você já passou por isso. O dono da lanchonete perto do campus sofre com o mesmo problema e não sabe que a solução são três arquivos. Monte um cardápio que carrega rápido, organiza os produtos por categoria e funciona com uma mão só, enquanto a outra segura o celular na fila.

Funcionalidades mínimas

  • Pelo menos três categorias (lanches, bebidas, sobremesas), cada uma com título e pelo menos quatro produtos.
  • Cada produto em um card com imagem, nome, descrição curta e preço em reais.
  • Menu fixo no topo com links para cada categoria.
  • Grade de cards com CSS Grid: uma coluna no celular, duas no tablet, três ou mais no desktop.
  • Destaque visual para itens "do dia" ou "mais pedidos".

Critérios de pronto

  • A grade se reorganiza de uma a três ou mais colunas conforme a largura da tela, sem quebrar os cards.
  • Todas as imagens têm alt, loading="lazy" e dimensões declaradas; nenhuma passa de 200 KB.
  • A página inteira pesa menos de 1 MB (aba Rede do DevTools) e abre em menos de 2 s com "3G rápido" simulado.
  • Todos os preços aparecem com R$ e duas casas decimais.
  • Abre em 360 px sem rolagem horizontal; o menu do topo continua utilizável.
  • Lighthouse Acessibilidade ≥ 90.

Evolução (escolha pelo menos uma)

  • Busca por nome que filtra os cards enquanto você digita (aula 14 do Nível 1).
  • Botões de categoria que mostram só os produtos daquela categoria, com o botão ativo destacado.
  • Favoritos marcados com um ícone de coração e persistidos no localStorage.
  • Modo "cozinha": versão de alto contraste com fonte maior, ativada por um botão.
Pistas
  1. Escreva cada produto como um article dentro de uma section por categoria; a estrutura semântica é o que vai facilitar os filtros depois (aula 05 do Nível 1).
  2. grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)) resolve a responsividade da grade sem uma única media query — leia sobre auto-fill e auto-fit na MDN (aula 08).
  3. Para a busca, dê a cada card um atributo data-nome e compare com includes() em minúsculas; esconder é adicionar uma classe, não remover o elemento (aula 14).
  4. Favoritos são só uma lista de ids: guarde-a como JSON no localStorage e, ao carregar a página, aplique a classe favorito nos cards cujo id está na lista.
⭐⭐

⭐⭐ Lista de tarefas

javascriptdomeventosformulariosprojeto

Trilha sugerida: Nível 1 (a partir da aula 14) ou Nível 2 (a partir da aula 07) · Tempo estimado: 6–8 h

Todo desenvolvedor já fez uma lista de tarefas, e é exatamente por isso que ela é um bom projeto: você vai comparar a sua com centenas de outras e descobrir o que separa uma lista de brinquedo de uma que você usaria de verdade. Ela parece trivial até você precisar decidir o que acontece com uma tarefa vazia, com duas iguais, com a página recarregada, com o Enter pressionado no lugar do clique.

Funcionalidades mínimas

  • Formulário para adicionar tarefa com título obrigatório, por Enter ou por botão.
  • Lista renderizada a partir de um array de objetos em JavaScript — nunca editando o HTML na mão.
  • Marcar como concluída (com estilo diferente), editar o título e excluir.
  • Contador de pendentes e botão para limpar as concluídas.
  • Filtro: todas, pendentes e concluídas.

Critérios de pronto

  • Enviar o formulário vazio ou só com espaços não cria tarefa e mostra uma mensagem na tela — sem alert().
  • Recarregar a página mantém todas as tarefas e o estado de cada uma (persistência em localStorage).
  • A lista inteira é operável só pelo teclado: Tab alcança cada botão, Enter ou Espaço aciona, e o foco fica visível.
  • Nenhum id duplicado no DOM; cada tarefa tem um identificador único que não é a posição no array.
  • Console do DevTools sem erros ao adicionar, editar, concluir, filtrar e excluir.

Evolução (escolha pelo menos uma)

  • Data limite com destaque para tarefas atrasadas.
  • Arrastar e soltar para reordenar, com a API nativa de drag and drop.
  • Etiquetas coloridas com filtro combinado ao filtro de estado.
  • Desfazer a última exclusão por cinco segundos, como o Gmail faz.
Pistas
  1. Comece pelo modelo, não pela tela: { id, titulo, concluida, criadaEm }. Uma função renderizar() que esvazia a lista e desenha o array inteiro é mais simples do que atualizar item por item (aula 14 do Nível 1 ou aula 07 do Nível 2).
  2. Um único ouvinte de clique na ul, lendo event.target.closest('button') e um atributo data-acao, substitui um ouvinte por botão — pesquise "event delegation" na MDN.
  3. crypto.randomUUID() gera ids únicos sem biblioteca; Date.now() também serve enquanto ninguém cria duas tarefas no mesmo milissegundo.
  4. localStorage só guarda strings: JSON.stringify ao salvar, JSON.parse ao carregar, com um try/catch para o caso de o conteúdo estar corrompido.
⭐⭐

⭐⭐ Calculadora de notas acadêmicas

javascriptformulariosdomprojeto

Trilha sugerida: Nível 1 (a partir da aula 14) · Tempo estimado: 6–8 h

Fim de semestre, três notas lançadas no SIGAA e a mesma pergunta em todo grupo da turma: "quanto eu preciso tirar na última pra passar?". Responda de uma vez por todas com uma calculadora que o colega consegue usar no celular, no corredor, antes da prova. A conta é fácil; o difícil é não deixar ninguém digitar 15, deixar um campo em branco ou ler "aprovado" em verde quando a média foi 4,9.

Funcionalidades mínimas

  • Campos numéricos para pelo menos três notas, com pesos configuráveis.
  • Cálculo de média simples ou ponderada, conforme a escolha.
  • Situação (aprovado, exame ou reprovado) com a regra e os limites visíveis na tela.
  • "Quanto falta": a nota mínima necessária na próxima avaliação para atingir a média.
  • Feedback por cor e por texto, nunca só por cor.

Critérios de pronto

  • Notas fora do intervalo de 0 a 10, vazias ou não numéricas são rejeitadas com mensagem ao lado do campo, sem alert().
  • Pesos que não fecham 100 % (ou 10) geram aviso antes do cálculo.
  • Resultado com uma casa decimal; 6,95 aparece como 7,0 e a situação corresponde ao valor mostrado (nada de arredondar para um lado e classificar pelo outro).
  • Funciona com Tab e Enter; o resultado é anunciado pelo leitor de tela (região com aria-live).
  • Lógica de cálculo em funções puras, testáveis no console: media([7, 8, 9], [1, 1, 2]) devolve o valor sem tocar no DOM.

Evolução (escolha pelo menos uma)

  • Várias disciplinas em uma tabela, com média por disciplina e resumo do semestre (quantas aprovadas, coeficiente médio).
  • Disciplinas salvas no localStorage e resumo exportado em CSV.
  • Gráfico de barras em CSS puro comparando as médias.
  • Regras de aprovação selecionáveis (média 6,0 com exame, média 7,0 sem exame, outra combinação), definidas em um objeto de configuração.
Pistas
  1. Separe em duas camadas desde o início: funções que calculam (recebem números, devolvem números) e funções que leem e escrevem na tela. É a aula 13 do Nível 1 aplicada.
  2. input.valueAsNumber devolve NaN para campo vazio — use Number.isNaN na validação, e min, max e step no HTML como primeira linha de defesa (aula 03).
  3. Para o "quanto falta", isole a incógnita na fórmula da média ponderada: nota necessária = (média alvo × soma dos pesos − pontos já obtidos) ÷ peso da próxima. Se der acima de 10, diga com todas as letras que não é mais possível.
  4. Arredonde uma única vez, no fim, com toFixed(1), e classifique usando o mesmo número arredondado que você mostra.
⭐⭐

⭐⭐ Quiz de conhecimentos

javascriptdomeventosprojeto

Trilha sugerida: Nível 2 (a partir da aula 08) · Tempo estimado: 8–10 h

Um quiz é um jogo de estado: qual pergunta está na tela, o que já foi respondido, quantos pontos, se acabou. Todo bug de quiz ("a pergunta 3 apareceu duas vezes", "o botão continuou clicável depois da resposta") é um estado que alguém esqueceu de controlar. Faça um quiz sobre o tema que quiser — a disciplina, o Pantanal, futebol — e aprenda a pensar a interface como uma função do estado.

Funcionalidades mínimas

  • Pelo menos dez perguntas de múltipla escolha em um array de objetos (enunciado, alternativas, índice da correta, explicação).
  • Uma pergunta por vez, com indicador de progresso ("3 de 10").
  • Ao responder, marca certo ou errado, mostra a explicação e trava as alternativas até "Próxima".
  • Tela final com pontuação, percentual e botão para recomeçar.
  • Estado da aplicação em um único objeto estado, nunca espalhado em variáveis soltas.

Critérios de pronto

  • Depois de responder, clicar em outra alternativa não muda nada (verificável na tela e no console).
  • Recomeçar zera tudo, inclusive o progresso e as perguntas já vistas, sem recarregar a página.
  • Cada pergunta aparece exatamente uma vez por rodada.
  • As alternativas são button de verdade, focáveis e acionáveis por teclado; a resposta correta não é identificável no HTML antes de responder.
  • As perguntas ficam em um arquivo separado (perguntas.js), sem lógica dentro dele.

Evolução (escolha pelo menos uma)

  • Cronômetro por pergunta, com penalidade por tempo esgotado.
  • Ordem aleatória de perguntas e de alternativas a cada rodada, sem repetição.
  • Revisão final com todas as perguntas, a sua resposta e a correta.
  • Ranking local com os cinco melhores resultados e o nome do jogador, salvo no localStorage.
  • Perguntas carregadas de um JSON externo com fetch (a partir da aula 10).
Pistas
  1. Escreva renderizar(estado) antes de qualquer evento: dado o estado, qual HTML aparece? Cada clique só altera o estado e chama renderizar de novo — é o padrão que o Vue automatiza no Nível 3.
  2. Para não denunciar a resposta, nunca coloque data-correta="true" no botão; compare o índice clicado com pergunta.correta em JavaScript (aulas 07 e 08 do Nível 2).
  3. Embaralhar é o algoritmo de Fisher–Yates: dez linhas com um for de trás para a frente e uma troca. sort(() => Math.random() - 0.5) parece funcionar, mas é enviesado.
  4. Para o cronômetro, setInterval precisa ser encerrado com clearInterval sempre que a pergunta muda — guarde o id do intervalo no estado.
⭐⭐

⭐⭐ Sistema de cadastro de eventos

javascriptformularioscruddomprojeto

Trilha sugerida: Nível 2 (a partir da aula 08) · Tempo estimado: 8–12 h

O centro acadêmico anuncia palestras num grupo de WhatsApp, e ninguém acha a da semana passada nem sabe se a de amanhã é às 19h ou às 19h30. Uma agenda no navegador — sem servidor, sem login — já resolve a maior parte do problema, e usa o mesmo modelo de dados que você vai levar para uma API no fim do Nível 2 e para o UniEventos no Nível 3. A parte traiçoeira aqui é a data: formato, fuso, comparação e ordenação.

Funcionalidades mínimas

  • Formulário com título, data, horário, local e descrição; edição e exclusão de eventos existentes.
  • Lista em ordem cronológica, agrupada por dia, com os eventos passados separados dos futuros.
  • Filtro por texto (título ou local) e por período (hoje, esta semana, todos).
  • Persistência em localStorage.
  • Confirmação antes de excluir.

Critérios de pronto

  • Data e hora aparecem em português (dia da semana, dia e mês por extenso, hora com "h") e nunca no formato ISO cru.
  • Não é possível salvar evento sem título, com data no passado ou com horário inválido; a mensagem aparece junto do campo, sem alert().
  • A ordem da lista está correta mesmo para eventos em meses e anos diferentes (teste com três datas de anos distintos).
  • Editar um evento reaproveita o mesmo formulário e preserva o id; não cria duplicata.
  • A lista se atualiza sem recarregar a página em toda operação; console sem erros.

Evolução (escolha pelo menos uma)

  • Destaque para os próximos sete dias e contagem regressiva ("em 3 dias").
  • Visão de calendário mensal em grade de sete colunas.
  • Exportar e importar a agenda em JSON; gerar um arquivo .ics para o Google Agenda.
  • Categorias com cor e filtro combinado.
Pistas
  1. Guarde a data como a string que input type="datetime-local" devolve (AAAA-MM-DDTHH:mm) e converta com new Date() só para comparar e formatar; strings nesse formato ordenam corretamente até com sort() simples.
  2. Intl.DateTimeFormat('pt-BR', { dateStyle: 'medium', timeStyle: 'short' }) formata sem biblioteca — leia as opções weekday e month na MDN.
  3. "Editar" e "criar" são a mesma função de salvar: se o objeto tem id, substitua no array (findIndex); senão, gere um id e faça push (aula 08 do Nível 2).
  4. Para agrupar por dia, use reduce sobre a lista ordenada criando um objeto cuja chave é data.slice(0, 10).
⭐⭐

⭐⭐ Catálogo de produtos com carrinho

javascriptgriddomeventosprojeto

Trilha sugerida: Nível 2 (a partir da aula 08) · Tempo estimado: 8–12 h

Por que o total do carrinho nunca está escrito no HTML? Porque o carrinho é dado, e a tela é só um reflexo dele. Construa a vitrine de uma loja fictícia — o brechó, a livraria, a Café Cerrado — e um carrinho que sobrevive ao recarregar da página. Você vai reproduzir o raciocínio das lojas reais: uma lista de produtos, uma lista de itens escolhidos e funções que juntam as duas.

Funcionalidades mínimas

  • Vitrine em grade responsiva gerada a partir de um array de produtos (nome, preço, imagem, categoria, estoque).
  • Botão "adicionar" em cada card e ícone de carrinho no cabeçalho com contador de itens.
  • Painel do carrinho (lateral ou modal) listando itens, quantidade, subtotal por item e total.
  • Alterar quantidade (mais e menos) e remover item; carrinho persistido no localStorage.
  • Filtro por categoria e ordenação por preço.

Critérios de pronto

  • Adicionar o mesmo produto duas vezes aumenta a quantidade em vez de criar duas linhas.
  • A quantidade nunca excede o estoque nem fica abaixo de 1: o botão desabilita e a lógica bloqueia.
  • Total e contador do cabeçalho batem com a soma dos itens depois de qualquer operação; valores em R$ com duas casas.
  • O carrinho guarda apenas { id, quantidade }; preço e nome vêm sempre do catálogo (mudar o preço de um produto altera o total na próxima renderização).
  • O painel do carrinho fecha com Esc e devolve o foco ao botão que o abriu.

Evolução (escolha pelo menos uma)

  • Cupom de desconto com regras (percentual, valor fixo, compra mínima, validade) e mensagem para cupom inválido.
  • Cálculo de frete por faixa de CEP ou por peso.
  • Tela de finalização com formulário validado e resumo do pedido.
  • Catálogo carregado de um JSON via fetch, com estados de carregamento e de erro (aula 10).
Pistas
  1. Duas listas, duas responsabilidades: produtos (imutável, vem do catálogo) e carrinho (muda com os cliques). Toda função do carrinho recebe as duas e devolve um número ou uma nova lista (aula 08 do Nível 2).
  2. reduce calcula o total em uma linha; find acha o produto pelo id; map e filter renderizam. Se você está escrevendo um for com índice, pare e pense.
  3. Para o R$, crie new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }) uma vez e reutilize o formatador.
  4. Um painel acessível é um dialog nativo: showModal() já cuida do Esc e do foco; pesquise "HTMLDialogElement" na MDN.
⭐⭐⭐

⭐⭐⭐ Controle de despesas pessoais

javascriptformulariosdomresponsivoprojeto

Trilha sugerida: Nível 2 (a partir da aula 08) · Tempo estimado: 12–16 h

Some 0,1 com 0,2 no console do navegador. O resultado não é 0,3 — e é por isso que todo sistema financeiro sério guarda dinheiro em centavos inteiros. Neste projeto você vai controlar receitas e despesas de verdade (as suas ou as de um personagem), com categorias, saldo e filtros por mês, e descobrir na prática por que dinheiro e datas são os dois assuntos que mais geram bugs em produção.

Funcionalidades mínimas

  • Lançamentos com descrição, valor, tipo (receita ou despesa), categoria e data; editar e excluir.
  • Saldo, total de receitas e total de despesas do período selecionado.
  • Filtros por mês e ano, por categoria e por tipo, combináveis entre si.
  • Tabela ordenável por data e por valor; persistência em localStorage.
  • Categorias gerenciáveis (criar, renomear), cada uma com cor.

Critérios de pronto

  • Valores guardados como inteiros em centavos: 0,10 + 0,20 mostra R$ 0,30, e a soma de cem lançamentos de R$ 0,10 dá exatamente R$ 10,00.
  • A entrada aceita 1.234,56 e 1234.56 e rejeita letras, valores negativos ou zero, com mensagem no campo.
  • Trocar o mês recalcula saldo e totais na hora; despesa aparece em vermelho e com sinal, não só por cor.
  • Excluir uma categoria com lançamentos é impedido ou pede para onde movê-los — nunca deixa lançamento órfão.
  • A tabela é legível em 360 px (as linhas viram cards ou as colunas secundárias se escondem) sem rolagem horizontal.
  • Console sem erros; recarregar a página preserva tudo.

Evolução (escolha pelo menos uma)

  • Resumo mensal com comparação ao mês anterior (subiu ou desceu quanto por cento).
  • Limite por categoria com barra de progresso e alerta ao ultrapassar.
  • Gráfico de pizza ou de barras da distribuição por categoria, em SVG feito por você (aula 05 do Nível 2) ou com Chart.js.
  • Lançamentos recorrentes (aluguel todo dia 5) gerados automaticamente.
  • Exportar CSV compatível com o Excel em português (ponto e vírgula como separador, vírgula decimal).
Pistas
  1. Modelo: { id, descricao, valorCentavos, tipo, categoriaId, data }. Converta na entrada (Math.round(valor * 100)) e formate na saída (Intl.NumberFormat com currency: 'BRL'); no meio, só inteiros.
  2. Para aceitar 1.234,56, remova os pontos de milhar e troque a vírgula por ponto antes do Number() — uma expressão regular de duas linhas; escreva a sua e teste com os dois formatos.
  3. Filtros combináveis são filter encadeados sobre o array original; nunca filtre em cima do resultado anterior, ou o usuário não consegue voltar.
  4. Para a tabela responsiva, display: block nas linhas com td::before { content: attr(data-rotulo) } transforma cada linha em um card no celular — pesquise "responsive tables" no CSS-Tricks.
⭐⭐⭐

⭐⭐⭐ Sistema de reservas de equipamentos

javascriptcrudformulariosdomprojeto

Trilha sugerida: Nível 2 (a partir da aula 08) · Tempo estimado: 12–16 h

O laboratório tem três projetores e cinco kits de Arduino, e a "reserva" é um caderno na secretaria. Duas turmas chegam com o mesmo projetor reservado, e o caderno não diz quem está com o kit que não voltou. Este é o projeto recomendado como fechamento dos dez: junta formulários, regras de negócio, estados, datas e persistência, e é a base direta do Boss "Sistema de reservas com API e login".

Funcionalidades mínimas

  • Cadastro de equipamentos (nome, patrimônio, categoria, quantidade, estado: disponível, reservado, em uso, manutenção).
  • Reserva com solicitante, equipamento, data e hora de início e de fim; retirada e devolução mudam o estado.
  • Lista de reservas por equipamento e por dia, com filtro por estado.
  • Persistência em localStorage e máquina de estados explícita (quais transições são permitidas).
  • Painel resumo: quantos disponíveis, quantos em uso, quantas devoluções atrasadas.

Critérios de pronto

  • É impossível criar reserva que se sobreponha a outra do mesmo equipamento; teste os quatro casos (começa antes e termina dentro, começa dentro e termina depois, engloba, está contida) e a mensagem diz com qual reserva há conflito.
  • Fim antes do início, reserva no passado e duração acima do limite configurado são rejeitados no formulário.
  • Transições inválidas (devolver o que não foi retirado, reservar equipamento em manutenção) não existem na interface e são bloqueadas na lógica.
  • Devolução com atraso é marcada e aparece no painel.
  • As regras de negócio estão em funções puras separadas do DOM (haConflito(reservas, nova), podeTransitar(de, para)), testáveis no console.
  • Um README.md descreve as regras com uma tabela de estados e transições.

Evolução (escolha pelo menos uma)

  • Histórico de movimentações por equipamento (quem, quando, o quê), que nunca é apagado.
  • Linha do tempo por dia (grade de horas por equipamento) mostrando as reservas como blocos.
  • Reserva de quantidade (três dos cinco kits) em vez de unidade única.
  • Lista de espera quando não há disponibilidade, com promoção automática ao cancelar.
  • Regras adaptadas a um usuário real, seguindo a dica no fim desta página.
Pistas
  1. Duas reservas conflitam quando inicioA < fimB && inicioB < fimA. Só isso. Desenhe os quatro casos numa linha do tempo antes de acreditar.
  2. Represente as transições como um objeto, { disponivel: ['reservado', 'manutencao'], reservado: ['em_uso', 'disponivel'] }, e uma função podeTransitar(de, para) que o consulta — é o padrão State disfarçado, que o Nível 3 apresenta.
  3. Reserva e equipamento são coleções separadas ligadas por equipamentoId; o estado atual do equipamento pode ser calculado a partir das reservas em vez de guardado — pense em qual escolha gera menos inconsistência.
  4. Datas: guarde no formato ISO, compare com getTime() e formate só na hora de mostrar (as pistas do projeto de eventos valem aqui).
⭐⭐⭐

⭐⭐⭐ Painel com dados de uma API pública

fetchasyncjsonapiprojeto

Trilha sugerida: Nível 2 (a partir da aula 10) · Tempo estimado: 10–14 h

Até aqui todos os dados estavam no seu arquivo. Agora eles estão em outro computador, chegam quando querem, às vezes não chegam e às vezes chegam num formato diferente do que a documentação prometia. Escolha uma API pública sem chave — ViaCEP, BrasilAPI, REST Countries, Open-Meteo, PokéAPI — e construa um painel que consulta, apresenta e compara resultados. O que se avalia aqui não é o dado bonito na tela: é o que acontece nos 300 ms antes de ele chegar e no dia em que a API cai.

Funcionalidades mínimas

  • Campo de busca (CEP, país, cidade, nome) que dispara a consulta com fetch e async/await.
  • Resultado em cards ou tabela, com os campos relevantes formatados, e não o JSON cru.
  • Estados visíveis: carregando (esqueleto ou spinner), vazio, erro de rede e "não encontrado".
  • Histórico das últimas consultas da sessão, clicável.
  • Componentes visuais reutilizáveis: uma função cardResultado(dado) usada em toda a página.

Critérios de pronto

  • Desligue a rede no DevTools e faça uma busca: a página mostra mensagem amigável e um botão "tentar de novo"; nada quebra no console.
  • Buscar algo inexistente (CEP 00000-000, país "Nárnia") mostra "não encontrado", diferente do erro de rede.
  • Duas buscas rápidas em sequência não mostram o resultado da primeira por cima da segunda (verifique com "3G lento" no DevTools).
  • O botão fica desabilitado enquanto a requisição está em andamento; Enter no campo também busca.
  • async/await com try/catch; resposta com response.ok === false é tratada como erro.
  • Os dados exibidos correspondem ao JSON da API (mostre a aba Rede na demonstração).

Evolução (escolha pelo menos uma)

  • Favoritos persistentes no localStorage, com página própria.
  • Cache local: a mesma consulta em menos de dez minutos não vai à rede, e a tela avisa "resultado em cache".
  • Paginação ou rolagem infinita para APIs que devolvem listas.
  • Comparação lado a lado de dois resultados (dois países, dois Pokémon, duas cidades).
  • Gráfico com Chart.js (temperatura por hora, população por país).
Pistas
  1. Abra a documentação da API e faça a primeira chamada colando a URL na barra de endereços antes de escrever uma linha de JavaScript; anote o formato exato da resposta, inclusive quando não acha nada (o ViaCEP devolve um JSON com a chave erro e status 200).
  2. fetch só rejeita em falha de rede; 404 e 500 resolvem normalmente — teste response.ok e lance um Error com o status (aulas 09 e 10 do Nível 2).
  3. Para a corrida entre buscas, guarde um contador de requisições e ignore respostas cujo número não é o mais recente — ou pesquise AbortController e cancele a anterior.
  4. Cache é um objeto { chave: { dados, em } }: a chave é o termo normalizado e em é Date.now(); antes de chamar fetch, veja se existe e se ainda é recente.
🔥

🔥 Boss — Sistema de reservas com API e login

expressautenticacaobanco-de-dadosdeployprojeto

Trilha sugerida: Nível 2 (a partir da aula 16) ou Nível 3 (a partir da aula 12), com Deploy (capítulos 04, 05 e 08) · Tempo estimado: 24–32 h

O sistema de reservas em localStorage funciona só no navegador de quem cadastrou; no dia em que duas pessoas precisam ver a mesma agenda, ele vira um caderno digital. Este Boss leva o projeto anterior para onde ele pede para ir: um front SPA que fala com uma API Express 5, usuários que entram com a conta Google (ou Firebase), dados em MySQL ou Supabase, regra de conflito verificada no servidor — porque o cliente pode ser burlado — e tudo no ar, com HTTPS, numa URL que você manda para o coordenador do laboratório.

Funcionalidades mínimas

  • API REST com Express 5: equipamentos e reservas (listar, criar, mudar estado, cancelar), respostas JSON e códigos HTTP corretos (201, 400, 401, 403, 404, 409).
  • Autenticação com Google Identity Services e verificação do ID token no back com google-auth-library, ou Firebase Auth com firebase-admin; rotas de escrita exigem token.
  • Perfis: usuário comum reserva e cancela as próprias reservas; administrador cadastra equipamentos e vê todas.
  • Banco relacional (MySQL com mysql2/promise ou Supabase com RLS) com tabelas usuarios, equipamentos e reservas.
  • Front SPA: JavaScript puro com fetch no Nível 2; Vue 3 + Vuetify + Pinia + Axios no Nível 3. Estados de carregamento e de erro em toda chamada.
  • Regra de conflito de horário verificada no servidor antes de gravar, respondendo 409 com a reserva conflitante.
  • Deploy: front em hospedagem estática, API em Render, Railway ou VPS, banco na nuvem, HTTPS válido nos dois.

Critérios de pronto

  • Via curl ou Insomnia: POST /api/reservas sem token devolve 401; usuário comum tentando cancelar reserva de outro recebe 403.
  • Duas requisições de reserva do mesmo equipamento no mesmo horário, disparadas em paralelo (script com dois fetch simultâneos), resultam em uma 201 e uma 409 — nunca duas 201.
  • Nenhum segredo no repositório: .env no .gitignore, chaves lidas de process.env; a chave service_role do Supabase nunca chega ao front.
  • A SPA funciona ao recarregar em qualquer rota (o servidor devolve o index.html), e a sessão sobrevive ao recarregar.
  • https:// em front e API, cadeado válido, sem aviso de conteúdo misto; CORS restrito à origem do front.
  • README.md com diagrama da arquitetura, instruções de instalação, variáveis de ambiente documentadas e a URL pública.
  • Lighthouse Acessibilidade ≥ 90 na tela de reservas; console sem erros.

Evolução (escolha pelo menos uma)

  • Documentação da API com swagger-jsdoc e swagger-ui-express, publicada em /docs (aula 14 do Nível 3).
  • E-mail de confirmação da reserva e lembrete de devolução.
  • Histórico de movimentações imutável, com quem fez o quê (auditoria).
  • Testes automatizados das regras de conflito e das permissões, rodando no GitHub Actions (capítulo 09 de Deploy).
  • Contêiner Docker para a API e docker compose com banco local (capítulo 07 de Deploy).
Pistas
  1. Comece pela API, sem front: modele as tabelas, escreva as rotas e teste tudo com Insomnia ou curl. Só depois monte a tela — o front do projeto anterior é reaproveitável trocando localStorage por chamadas HTTP (aulas 11 a 13 do Nível 2 ou 08 e 09 do Nível 3).
  2. A verificação de conflito precisa ser atômica: uma transação (BEGIN, SELECT das reservas sobrepostas, INSERT, COMMIT) ou uma restrição no banco. Um if em JavaScript antes do INSERT deixa a janela aberta para a corrida.
  3. Middleware de autenticação: lê Authorization: Bearer, verifica o token, coloca req.usuario e chama next(); um segundo middleware exigirAdmin compara o perfil (aula 14 do Nível 2 ou aula 10 do Nível 3). Em Express 5, erros em handlers async caem sozinhos no tratador de erros.
  4. Para o deploy, siga os capítulos 04 e 05 de Deploy na ordem: primeiro a API no ar com HTTPS e variáveis de ambiente configuradas na plataforma, depois o front apontando para a URL da API. A maior parte dos problemas é CORS e URL errada.
🔥

🔥 Boss — Painel de dados com cache, gráficos e CI

apitestesci-cdperformanceprojeto

Trilha sugerida: Nível 3 (a partir da aula 08), com Deploy (capítulos 09 e 10) · Tempo estimado: 24–32 h

O painel do projeto de API pública chama a fonte direto do navegador; com duzentos usuários abrindo a página, a fonte bloqueia o IP e o painel morre. Este Boss coloca um servidor seu no meio: uma API Express que consulta a fonte, guarda em cache, expõe endpoints limpos e é testada, publicada e monitorada por um pipeline que roda sozinho a cada git push. É o ciclo completo do trabalho profissional: código, teste, integração contínua, deploy e observação.

Funcionalidades mínimas

  • API Express 5 que consome uma fonte pública (Open-Meteo, BrasilAPI, IBGE, dados.gov.br) e expõe endpoints próprios (/api/clima/:cidade, /api/indicadores) com resposta normalizada.
  • Cache no servidor (memória com tempo de vida, ou tabela no banco) e cache no cliente (localStorage ou Cache API), com indicação na resposta (cabeçalho X-Cache: HIT ou MISS).
  • Front em Vue 3 + Vuetify + Pinia + Axios com pelo menos três gráficos em Chart.js (linha, barras e um terceiro), filtros por período ou região e estados de carregamento, vazio e erro.
  • Testes automatizados: unitários das funções de transformação e de integração dos endpoints (node --test ou Vitest, com Supertest).
  • GitHub Actions: a cada push, instala, roda lint e testes; na main, publica front e API.
  • Monitoramento: endpoint /health, verificação externa (UptimeRobot ou similar) e log estruturado de erros.

Critérios de pronto

  • Duas chamadas seguidas ao mesmo endpoint: a primeira responde X-Cache: MISS; a segunda responde HIT em menos de 50 ms (mostre no Insomnia ou com curl -w '%{time_total}').
  • Fonte pública indisponível (simule trocando a URL): a API devolve o último dado em cache com aviso, ou 503 com mensagem clara — nunca 500 genérico nem travamento.
  • Cobertura de testes ≥ 70 % nas funções de transformação; pelo menos um teste falha de propósito quando você quebra uma regra (mostre na demonstração).
  • Badge do GitHub Actions verde no README.md; um pull request com teste quebrado fica vermelho e não é publicado.
  • Gráficos com título, eixos rotulados, unidade e alternativa textual (tabela ou resumo) para leitor de tela; prefers-reduced-motion desativa a animação do Chart.js.
  • Lighthouse Performance ≥ 90 e Acessibilidade ≥ 90 na página principal; vite build sem aviso de tamanho de bundle.
  • /health público e monitorado, com alerta configurado; URL pública com HTTPS.

Evolução (escolha pelo menos uma)

  • Documentação com Swagger e limite de requisições por IP.
  • Cache com invalidação seletiva e atualização em segundo plano (stale-while-revalidate).
  • Exportar os dados filtrados em CSV e o gráfico em PNG.
  • Docker para a API e deploy em VPS com nginx como proxy reverso (capítulos 06 e 07 de Deploy).
  • Comparação entre duas regiões ou períodos no mesmo gráfico, com URL compartilhável (estado nos parâmetros da rota).
Pistas
  1. Separe o back em três camadas: fontes/ (fala com a API externa), servicos/ (normaliza e cacheia) e rotas/ (HTTP). Os testes unitários cobrem servicos/ sem rede; os de integração usam Supertest com uma fonte falsa (aula 13 do Nível 3).
  2. Cache em memória é um Map de chave para { dados, expiraEm }; antes de ir à fonte, verifique Date.now() < expiraEm. Comece assim e só troque por algo externo se precisar de mais de uma instância.
  3. Chart.js: um componente Vue por gráfico, recebendo labels e datasets por props e destruindo a instância em onUnmounted — senão o gráfico duplica ao trocar de filtro (aulas 05 e 06 do Nível 3).
  4. O workflow do GitHub Actions começa com três passos (checkout, setup-node com cache do npm, npm ci && npm test); faça-o ficar verde antes de adicionar o deploy (capítulo 09 de Deploy). Segredos entram em Settings → Secrets do repositório, nunca no YAML.

💡 Dica Desafio final, válido para qualquer projeto desta página: escolha um contexto real — o laboratório da sua faculdade, a biblioteca do bairro, uma escola, o comércio da família — e entreviste ao menos uma pessoa que usaria o sistema. Pergunte o que ela faz hoje, onde dói, o que é proibido e o que acontece quando dá errado. Depois adapte as regras do projeto ao que ouviu: talvez a reserva precise de aprovação, talvez o cardápio mude por turno, talvez a nota mínima seja outra. Nesse momento você deixa de reproduzir uma interface e passa a resolver um problema, que é o que se paga a um desenvolvedor.

📌 Vale gravar Qualquer projeto desta página pode ser o seu projeto autoral — aquele que você constrói em paralelo às aulas e leva para o portfólio —, desde que siga a mesma arquitetura do projeto fio-condutor da trilha (Nível 1: site estático de várias páginas; Nível 2: SPA com API Express e login; Nível 3: Vue, Pinia, Express, banco e Firebase). Se você cursa a disciplina, combine a escolha com o professor antes de começar a unidade. Para saber se o projeto está no ponto, use o marco da unidade, na aula que a fecha: ele lista os requisitos e o checklist de qualidade.

WebLab — Laboratório de Desenvolvimento Web
Conteúdo sob CC BY 4.0; o gerador do site, sob licença MIT. Reuso livre com atribuição.
Início · Autoria e créditos · Banco de Desafios · Links úteis · Fontes no GitHub