Projetos de estudo em desenvolvimento de software. Cada pasta é um projeto independente,
com o próprio package.json e o próprio README explicando por que cada decisão de
arquitetura foi tomada — inclusive as que foram descartadas.
O repositório existe porque, separados, esses projetos parecem exercícios soltos. Em sequência, eles são uma coisa só: o mesmo tipo de problema atacado com ferramentas cada vez mais capazes, para que a diferença entre elas fique visível.
Nenhuma linha que eu não consiga explicar em voz alta. Consulta na documentação, escrita do zero, previsão do output antes de rodar. Nestes projetos a IA entra como crítica e revisora, nunca como autora — código gerado que eu não sei defender não me ensina nada, e é justamente o que este repositório existe para evitar.
Os dados de exemplo são todos fictícios. Não há dado de pessoa ou empresa real em nenhum lugar deste repositório.
Em ordem de evolução. Cada projeto assume o anterior resolvido.
| # | Projeto | O que a etapa introduz |
|---|---|---|
| 01 | painel-pulsos | JavaScript e DOM sem build e sem framework. A fronteira entre cálculo e tela: o domínio não sabe que existe interface |
| 02 | buscador-repositories | A borda assíncrona. Consumo de API externa e as quatro telas de uma requisição — carregando, resultado, vazio e erro |
| 03 | painel-aprendiz | TypeScript de verdade: o dado chega como unknown e é estreitado por guardas antes de virar entidade. Zero any |
| 04 | painel-aprendiz-react | O mesmo domínio do 03, com a camada de tela trocada por React — e as camadas de dados congeladas |
| 05 | painel-despesas | Modelagem por tipos: quanto do domínio dá para tornar impossível antes de escrever validação |
| 06 | api-notas | Backend completo. Express, Postgres com Drizzle, validação com Zod, autenticação por token e migrations versionadas |
painel-aprendiz e painel-aprendiz-react resolvem o mesmo problema, com as mesmas
cinco camadas de dados, byte a byte. Só a camada de tela muda: DOM imperativo de um
lado, componentes declarativos do outro.
Isso torna duas coisas verificáveis em vez de afirmáveis. Primeiro, o que o React de fato faz — dá para apontar linha a linha o que ele substitui, e o que ele não toca. Segundo, se a fronteira entre dados e interface foi desenhada no lugar certo: se trocar o framework tivesse exigido mexer no repositório ou no use case, não tinha.
Projeto daqui que ganha ciclo próprio — releases, guia de contribuição, deploy — sai para um repositório separado. Já aconteceu duas vezes:
| Projeto | Nasceu como | Virou |
|---|---|---|
| api-contatos-express | exercício de Express e Drizzle | repositório próprio, com as decisões de arquitetura documentadas |
| indica-app | protótipo de produto | aplicação Next.js com versionamento, CONTRIBUTING e roadmap |
O critério é simples: enquanto o projeto serve para aprender, ele fica aqui e o valor está na sequência. Quando ele passa a ter usuário, versão e ciclo de release, o histórico compartilhado atrapalha mais do que ajuda.
Todos seguem a mesma forma, e ela vale mais que o código:
- o que o projeto é e o que ele demonstra
- Decisões — cada escolha de arquitetura com o motivo, e o que foi rejeitado
- Dívidas conhecidas, quando existem — o que ainda está errado é parte do valor
- Horizonte — o que deliberadamente não existe, e qual dor concreta justificaria criar. Documentar o gatilho é o que evita abstração prematura
Cada projeto se instala sozinho. Não há workspace nem instalação na raiz:
cd <projeto>
npm install
npm run devOs projetos 01 e 02 não têm build — abrir o index.html no navegador basta. O 06 precisa
de Docker para subir o Postgres; as instruções estão no README dele.