Evandro.dev.br: portfólio
Portfólio profissional de Evandro Fonseca Junior, com projetos, cases, serviços, currículo e contato por WhatsApp.
Requisitos
- Node.js
22.x - pnpm
9.15.9, fixado empackage.json#packageManager
O projeto usa Next.js 16.3.0. Essa versão é intencional: 16.2.11 ainda mantinha três advisories transitivos de severidade alta; 16.3.0 foi a menor versão estável da mesma major que deixou as auditorias atuais sem vulnerabilidades high.
Início rápido
corepack [email protected] install --frozen-lockfile
corepack [email protected] dev
O servidor de desenvolvimento usa Turbopack. Para executar o artefato de produção:
corepack [email protected] build
corepack [email protected] start
Scripts
| Comando | Comportamento |
|---|---|
pnpm dev |
Inicia o Next.js em desenvolvimento com Turbopack. |
pnpm build |
Gera o build de produção com Turbopack. |
pnpm start |
Serve um build já gerado. |
pnpm lint |
Executa biome check. |
pnpm typecheck |
Executa TypeScript sem emitir arquivos. |
pnpm format |
Formata o repositório com Biome. |
pnpm test |
Executa a suíte Jest. |
pnpm test:watch |
Executa Jest em modo watch. |
pnpm check:projects |
Verifica URLs de demonstração e substitui atomicamente data/project-health.json. |
Stack
| Área | Pacotes usados |
|---|---|
| Aplicação | Next.js 16.3.0, React 19.1.0, React DOM 19.1.0 e TypeScript 5.9.2. |
| Estilos e composição | Tailwind CSS 4, clsx e tailwind-merge. |
| Movimento | Motion 12 e GSAP 3. |
| 3D e gráficos | Three.js, React Three Fiber, Drei e Cobe. |
| Interface | Lucide React. |
| Qualidade | Biome, Jest, Testing Library e ambiente JSDOM. |
Todas as dependências diretas estão fixadas em versões exatas no manifesto; o lockfile é instalado sem atualização implícita.
Rotas
| Rota | Conteúdo |
|---|---|
/ |
Homepage com hero, notebook de projetos, perfil, competências, experiência, projetos, modalidades de trabalho e contato. |
/cases |
Índice dos seis cases. |
/cases/nutriscan |
Case NutriScan. |
/cases/twins-lab |
Case Twins Lab. |
/cases/reddit-explorer |
Case Reddit Posts Explorer. |
/cases/sc-plus |
Case SC Plus Aquicultura. |
/cases/gcc-installer |
Case MinGW GCC Installer. |
/cases/as-servicos |
Case AS Serviços. |
/servicos |
Índice dos seis serviços. |
/servicos/criacao-de-sites |
Criação de sites. |
/servicos/engenharia-de-software |
Engenharia de software. |
/servicos/consultoria-nextjs |
Consultoria Next.js. |
/servicos/tauri-rust |
Desenvolvimento Tauri e Rust. |
/servicos/integracao-hardware-software-iot |
Integração de hardware, software e IoT. |
/servicos/arquitetura-de-software |
Arquitetura de software. |
/curriculo |
Currículo em HTML, com download de /Profile.pdf. |
O App Router também gera /manifest.webmanifest, /robots.txt, /sitemap.xml, /opengraph-image, /icon.svg e /favicon.ico. Caminhos desconhecidos usam a página 404 do projeto. Não há API route ativa.
Comportamento da aplicação
Conteúdo e project health
O conteúdo principal vem de public/portfolio-data.json e lib/site-content.ts. A seleção da homepage usa o campo featured; o snapshot de disponibilidade não remove cards. Ele apenas controla o estado do CTA de cada demo: disponível, indisponível, desconhecido ou sem demo.
Em produção, a renderização só lê o snapshot versionado e não consulta demos externas. Em desenvolvimento, um snapshot ausente ou com mais de 15 minutos é atualizado em memória. A atualização manual opcional é pnpm check:projects e grava o arquivo por rename atômico. O contrato completo está em docs/project-health.md.
3D progressivo e movimento reduzido
O hero 3D é carregado no cliente a partir de 1024px, sem prefers-reduced-motion: reduce e sem ponteiro coarse. O notebook 3D exige mais de 1024px, hover disponível e as mesmas condições de movimento e ponteiro. Nos demais casos, o notebook entrega a navegação HTML completa sem WebGL ou movimento. No notebook 3D, o loop de renderização só permanece ativo enquanto a seção cruza o viewport e a página está visível.
Contato
O formulário da homepage valida os campos nativos de nome, e-mail, tipo e contexto. Ao enviar, ele abre wa.me em uma nova aba com o briefing preenchido; não existe backend de formulário. O rodapé mantém contato direto por e-mail.
Consentimento de analytics
Google Analytics só é carregado depois de aceite explícito. A decisão fica em evandro.analytics-consent.v1; recusar não monta o loader. As preferências permanecem acessíveis e a revogação envia consentimento negado, ativa a flag de desabilitação, remove o loader e expira apenas cookies _ga/_ga_* acessíveis.
Estrutura
app/ App Router, rotas e componentes da interface
lib/ Dados derivados, navegação, JSON-LD e project health
public/ Conteúdo JSON, PDF, fontes, imagens e modelo 3D
scripts/check-projects.mjs
Atualização manual do snapshot de demos
data/project-health.json
Última observação versionada das demos
docs/project-health.md Contrato operacional do snapshot
.github/workflows/ci.yml
Gate único de integração contínua
nixpacks.toml Build e start para Nixpacks
CI e deploy
O workflow único em .github/workflows/ci.yml roda em cada push e pull_request com permissão contents: read. Ele instala Node 22 e pnpm conforme packageManager, restaura o cache do pnpm e executa, nesta ordem: frozen install, lint, typecheck, Jest serial, build e auditorias de produção e desenvolvimento com limite high.
O Nixpacks usa nodejs_22, pnpm-9_x, pnpm install --frozen-lockfile, pnpm run build e pnpm run start. Não há etapa de deploy nem secret de CI neste repositório.
Validação local
corepack [email protected] install --frozen-lockfile
corepack [email protected] lint
corepack [email protected] typecheck
corepack [email protected] test -- --runInBand
corepack [email protected] build
corepack [email protected] audit --prod --audit-level=high
corepack [email protected] audit --dev --audit-level=high