From 594daecd2bb9c57680f040869ca9ad8988da0604 Mon Sep 17 00:00:00 2001 From: Evandro Fonseca Junior <1+evandro@noreply.git.evandro.dev.br> Date: Sat, 24 Oct 2026 04:13:02 +0000 Subject: [PATCH] docs(readme): padroniza README (hero, badges, quickstart, arquitetura) --- README.md | 337 +++++++++++++++++++++++++++--------------------------- 1 file changed, 168 insertions(+), 169 deletions(-) diff --git a/README.md b/README.md index 9869826..92609c8 100644 --- a/README.md +++ b/README.md @@ -2,187 +2,176 @@ Logo do Evandro.dev.br -# Evandro.dev.br — portfólio +

Evandro Fonseca Junior

-**Portfólio profissional de Evandro Fonseca Junior: projetos, cases, serviços, -currículo e contato por WhatsApp — com hero e notebook 3D progressivos que caem -para HTML puro quando o dispositivo não comporta.** +

Engenheiro da Computação em Garuva-SC: sites, sistemas web e revisão de apps feitos com IA, com contato direto pelo WhatsApp.

-![Next.js](https://img.shields.io/badge/Next.js-16.3.0-informational) -![React](https://img.shields.io/badge/React-19.1.0-informational) -![Node](https://img.shields.io/badge/Node-22.x-informational) +Site · +Cases · +Currículo · +Quickstart · +Arquitetura · +LinkedIn · +Issues -[Rotas](#o-que-o-site-entrega) · [Como funciona](#como-funciona) · [Execução local](#execu%C3%A7%C3%A3o-local) · [CI/CD](#cicd) +![Stack](https://img.shields.io/badge/Stack-Next.js_16-000000?logo=nextdotjs&logoColor=white) +![Status](https://img.shields.io/badge/status-produ%C3%A7%C3%A3o-brightgreen) +![Licença](https://img.shields.io/badge/licen%C3%A7a-todos_os_direitos_reservados-lightgrey) -> [!NOTE] -> **Estado do projeto:** em desenvolvimento ativo (último commit: "refine portfolio -> showcase, services and quality lab"); o site de produção é `https://evandro.dev.br`, -> que é o host declarado em `app/sitemap.ts` e `app/robots.ts`. As ações externas -> de SEO/GEO (Search Console, Bing, Cloudflare, CrUX) estão descritas como runbook e -> **não executadas** em [`docs/seo-geo-operations.md`](docs/seo-geo-operations.md). +
-> [!IMPORTANT] -> **Next.js `16.3.0` é intencional.** A `16.2.11` ainda mantinha três advisories -> transitivos de severidade alta; a `16.3.0` foi a menor versão estável da mesma -> major que deixou as auditorias atuais sem vulnerabilidades high. Não faça -> downgrade sem repetir `pnpm audit`. +## 📌 O problema -## O que o site entrega +Pequenos negócios costumam vender e atender por mensagem: o cliente pergunta o preço um a um, o estoque vive em planilha e qualquer mudança no site depende de um desenvolvedor. Este repositório é o site [evandro.dev.br](https://evandro.dev.br), a vitrine de quem resolve isso: projetos entregues, serviços, currículo e um botão de WhatsApp para começar a conversa. -| Rota | Conteúdo | +## ✨ O que faz + +- Apresenta três ofertas: criação de sites, sistemas web sob medida e revisão de apps feitos com IA (`/ia`). +- Publica oito cases com stack, entregas e decisões técnicas, cada um em `/cases/`. +- Detalha seis serviços em `/servicos/*`, com escopo e etapas visíveis e a parte técnica em `
`. +- Serve o currículo em HTML e o PDF em `/Profile.pdf`. +- Abre o `wa.me` com o briefing já preenchido a partir do formulário de contato; não há backend de formulário. +- Mostra o hero e o notebook de projetos em 3D (Three.js) só onde o dispositivo comporta; nos demais, entrega HTML estático. +- Carrega Google Analytics somente depois de aceite explícito, e permite revogar o consentimento depois. +- Gera `sitemap.xml`, `robots.txt`, manifest, imagens Open Graph e dados estruturados JSON-LD. + +### Cases publicados + +Fonte: `public/portfolio-data.json` e `lib/site-content.ts` (os mesmos oito ids). + +| Case | O que é | Estado | Demo | +| --- | --- | --- | --- | +| [`sev-modaintima`](https://evandro.dev.br/cases/sev-modaintima) | SEV Moda Íntima: catálogo digital e loja virtual, pedido pelo WhatsApp e painel de estoque | Em produção | [sevmodaintima.com.br](https://sevmodaintima.com.br) | +| [`lavacao-047`](https://evandro.dev.br/cases/lavacao-047) | Lavação 047: site e painel para lavação automotiva em Garuva-SC, o dono edita preços, textos e fotos | Em produção | [landing-page-lavacao047.vercel.app](https://landing-page-lavacao047.vercel.app) | +| [`nutriscan`](https://evandro.dev.br/cases/nutriscan) | NutriScan: consulta de produtos por nome e código de barras | Em produção | [nutriscan.evandro.dev.br](https://nutriscan.evandro.dev.br) | +| [`twins-lab`](https://evandro.dev.br/cases/twins-lab) | Twins Lab: painel ao vivo de um reator simulado | Protótipo | sem demo | +| [`reddit-explorer`](https://evandro.dev.br/cases/reddit-explorer) | Reddit Posts Explorer: posts de um fórum de IA, filtrados por período | Concluído | sem demo | +| [`sc-plus`](https://evandro.dev.br/cases/sc-plus) | SC Plus Aquicultura: site institucional com áreas, projetos e contato | Concluído | [scplus.evandro.dev.br](https://scplus.evandro.dev.br) | +| [`gcc-installer`](https://evandro.dev.br/cases/gcc-installer) | MinGW GCC Installer: instalador do compilador GCC para Windows | Concluído | sem demo | +| [`as-servicos`](https://evandro.dev.br/cases/as-servicos) | AS Serviços: site institucional com cena 3D | Concluído | sem demo | + +## 🖼️ Demonstração + +| SEV Moda Íntima | NutriScan | | --- | --- | -| `/` | 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, com explicações de uso e acesso ao detalhamento técnico | -| `/servicos/criacao-de-sites` | Criação de sites | -| `/servicos/engenharia-de-software` | Sistemas web e aplicativos mobile sob medida | -| `/servicos/consultoria-nextjs` | Consultoria Next.js | -| `/servicos/tauri-rust` | Aplicativos desktop para Windows e Linux, com compatibilidade definida por projeto | -| `/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` | -| `/privacidade` | Página de privacidade e consentimento de analytics | +| Site da SEV Moda Íntima | NutriScan | +| **SC Plus Aquicultura** | **AS Serviços** | +| Site da SC Plus Aquicultura | Site da AS Serviços | -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. +Capturas feitas com Chrome headless a partir de deploys de produção do próprio autor. Origem e créditos (inclusive do ícone do WhatsApp) em [`CREDITS.md`](CREDITS.md). -As páginas de serviços mantêm escopo, exemplos ilustrativos e etapas visíveis; -tecnologias e decisões de implementação ficam em um `
` nativo. Sobre e -Contato apontam para `/#about` e `/#contact`, com ajuste de chegada após a -definição do layout do notebook. +## 🚀 Quickstart -## Como funciona - -```mermaid -flowchart LR - A["public/portfolio-data.json
+ lib/site-content.ts"] --> B["lib/portfolio-data.ts
loadFeaturedProjects()"] - C["data/project-health.json
snapshot versionado"] --> B - D["scripts/check-projects.mjs
pnpm check:projects"] -->|rename atômico| C - B --> E["app/ — App Router
homepage, cases, serviços"] - E --> F["Next.js 16.3.0
build e start (Turbopack)"] -``` - -
-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`](docs/project-health.md). - -
- -
-3D progressivo e movimento reduzido - -O fundo 3D do hero (Three.js, sem React Three Fiber) só é montado a partir de -`1024px`, com ponteiro fino, sem `prefers-reduced-motion: reduce`, sem economia -de dados e com placa de vídeo real (WebGL por software mostra o hero estático). -A cena monta depois da primeira interação ou com o navegador ocioso, desenha no -máximo ~30 quadros por segundo e para quando nada se move. No celular e nos -demais casos, o hero é estático e ocupa uma tela. - -As passagens entre seções e a barra de progresso são CSS (`animation-timeline`); -a rolagem suave (Lenis) só existe com ponteiro fino. - -
- -
-Contato e consentimento de analytics - -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. - -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. - -
- -
-Stack e estrutura - -| Área | Pacotes usados | +| Ferramenta | Versão mínima | | --- | --- | -| Aplicação | Next.js 16.3.8, React 19.1.0, React DOM 19.1.0 e TypeScript 5.9.2 | -| Estilos | Tailwind CSS 4 | -| Movimento | CSS (`animation-timeline`) e Lenis | -| 3D | Three.js | -| Interface | Lucide React | -| Qualidade | Biome, Jest, Testing Library (JSDOM), Playwright e axe-core | - -Todas as dependências diretas estão fixadas em versões exatas no manifesto; o -lockfile é instalado sem atualização implícita. - -```text -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 capturas -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 -``` - -
- -## Limitações conhecidas - -- **Sem backend.** O formulário de contato não grava nada: abre `wa.me` com o - briefing preenchido. -- **Demos externas podem aparecer como indisponíveis.** O CTA de cada case reflete - o último snapshot versionado em `data/project-health.json`, não uma consulta em - tempo real (em produção o render não faz fetch externo). -- **Sem WebGL em telas pequenas, com ponteiro coarse ou movimento reduzido.** Nesses - casos o hero e o notebook entregam a versão HTML. - -## Execução local - -> [!WARNING] -> Use **Node.js `22.x`** e **pnpm `9.15.9`** (fixado em `package.json#packageManager`). -> A instalação é sempre com `--frozen-lockfile`; o CI e o Nixpacks fazem o mesmo. +| Node.js | `22.x` (`engines`) | +| pnpm | `9.15.9` (`packageManager`) | +| Chromium | só para `pnpm test:e2e` (Playwright) | ```bash corepack pnpm@9.15.9 install --frozen-lockfile -corepack pnpm@9.15.9 dev # Next.js com Turbopack -corepack pnpm@9.15.9 build # build de produção com Turbopack -corepack pnpm@9.15.9 start # serve um build já gerado +corepack pnpm@9.15.9 dev # Next.js com Turbopack +corepack pnpm@9.15.9 build # build de produção +corepack pnpm@9.15.9 start # serve um build já gerado ``` -| Script | Comportamento | +A instalação é sempre com `--frozen-lockfile`, igual ao CI e ao Nixpacks. + +Não há `.env.example` e nenhuma variável é necessária para rodar localmente. As que o código lê: + +| Variável | Obrigatória | Descrição | +| --- | --- | --- | +| `NEXT_PUBLIC_GOOGLE_ADS_CONVERSION_LABEL` | Não | Rótulo de conversão do Google Ads; sem ele, nenhum evento de conversão é enviado | +| `BASE_URL` | Não | Endereço do site testado por `pnpm test:e2e` (padrão `http://localhost:3001`) | +| `PW_CHROMIUM` | Não | Caminho de um Chromium local para o Playwright, para não baixar o navegador | + +> [!IMPORTANT] +> O Next.js (`16.3.8`) é fixado de propósito: a `16.2.11` mantinha três advisories transitivos de severidade alta, e a `16.3.0` foi a menor versão estável da mesma major que deixou as auditorias sem vulnerabilidades high. Não faça downgrade sem repetir `pnpm audit`. + +## 🧱 Arquitetura + +```mermaid +flowchart LR + A["public/portfolio-data.json"] --> B["lib/portfolio-data.server.ts"] + S["lib/site-content.ts"] --> E["app/ App Router"] + C["data/project-health.json"] --> B + D["scripts/check-projects.mjs"] -->|rename atômico| C + B --> E + E --> F["Vercel"] +``` + +- O conteúdo vem de `public/portfolio-data.json` e `lib/site-content.ts`; a homepage escolhe os projetos pelo campo `featured`. +- `data/project-health.json` é um snapshot versionado das demos. Ele só controla o CTA de cada card (disponível, indisponível, desconhecido ou sem demo) e nunca remove um card. +- Em produção, o render só lê o snapshot e não consulta demos externas. Em desenvolvimento, um snapshot ausente ou com mais de 15 minutos é atualizado em memória. +- `pnpm check:projects` atualiza o snapshot por rename atômico. Contrato completo em [`docs/project-health.md`](docs/project-health.md). +- Não há API route ativa. + +### CI/CD + +Um único workflow, [`.gitea/workflows/ci.yml`](.gitea/workflows/ci.yml), roda em `push`, `pull_request` e `workflow_dispatch`, com permissão `contents: read`. O repositório usa Gitea; por isso não há badge de GitHub Actions. + +| Job | O que roda | Bloqueia o deploy | +| --- | --- | --- | +| `verify` | Node 22, `pnpm install --frozen-lockfile`, `lint`, `typecheck`, `test -- --runInBand`, `build` | Sim | +| `audit` | `pnpm audit --prod` e `pnpm audit --dev`, ambos com `--audit-level=high` | Não | +| `e2e` | Playwright (Chromium) contra o build de produção na porta 3001; publica `test-results/` | Não | +| `deploy` | Vercel CLI `61.1.0`; só após `verify`; branch padrão vai para produção, as demais para preview; pull request não publica | n/a | + +O deploy usa o secret `VERCEL_TOKEN`; o projeto na Vercel é o nome do repositório, ou a variável `VERCEL_PROJECT`. [`nixpacks.toml`](nixpacks.toml) (`nodejs_22`, `pnpm-9_x`) e [`vercel.json`](vercel.json) (`framework: nextjs`) descrevem o build. + +
+Rotas + +| Rota | Conteúdo | | --- | --- | -| `pnpm dev` | Inicia o Next.js em desenvolvimento com Turbopack | -| `pnpm build` | Gera o build de produção com Turbopack | +| `/` | Hero, notebook de projetos, perfil, competências, experiência, projetos, modalidades de trabalho e contato | +| `/cases`, `/cases/` | Índice e página de cada um dos oito cases | +| `/servicos` | Índice dos seis serviços | +| `/servicos/criacao-de-sites` | Criação de sites | +| `/servicos/engenharia-de-software` | Sistemas web e aplicativos mobile sob medida | +| `/servicos/consultoria-nextjs` | Consultoria Next.js | +| `/servicos/tauri-rust` | Aplicativos desktop para Windows e Linux | +| `/servicos/integracao-hardware-software-iot` | Integração de hardware, software e IoT | +| `/servicos/arquitetura-de-software` | Diagnóstico de arquitetura | +| `/ia` | Revisão de sistema e de app feito com IA | +| `/curriculo` | Currículo em HTML, com download de `/Profile.pdf` | +| `/privacidade` | Privacidade e consentimento de analytics | + +
+ +## 🗂️ Estrutura + +```text +app/ rotas (App Router) e componentes +lib/ conteúdo (site-content.ts), SEO, JSON-LD, WhatsApp, project health +public/ portfolio-data.json, Profile.pdf, logos, capturas e mídias dos cases +data/ project-health.json, snapshot versionado das demos +scripts/ check-projects.mjs e utilitários de SEO e vídeo +e2e/ testes Playwright (9 specs) +docs/ SEO/GEO, project health e planos +.gitea/workflows/ ci.yml (verify, audit, e2e, deploy) +nixpacks.toml build e start via Nixpacks +CREDITS.md créditos de capturas e ícone +``` + +Stack: Next.js 16.3.8, React 19.1.0, TypeScript 5.9.2, Tailwind CSS 4, Three.js, Lenis e Lucide React. Qualidade: Biome, Jest 30 com Testing Library (150 arquivos de teste), Playwright e axe-core. Todas as dependências diretas estão fixadas em versões exatas, exceto `lenis` (`^1.3.26`). + +## 🧪 Scripts + +| Comando | O que faz | +| --- | --- | +| `pnpm dev` | Next.js em desenvolvimento com Turbopack | +| `pnpm build` | 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 typecheck` | Executa `next typegen` e `tsc --noEmit` | | `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` | +| `pnpm test:e2e` | Executa o Playwright contra um servidor já no ar (`BASE_URL`) | +| `pnpm check:projects` | Consulta as demos e substitui atomicamente `data/project-health.json` | Validação completa, na mesma ordem do CI: @@ -196,20 +185,30 @@ corepack pnpm@9.15.9 audit --prod --audit-level=high corepack pnpm@9.15.9 audit --dev --audit-level=high ``` -## CI/CD +Para os testes de ponta a ponta: `pnpm build && pnpm start -p 3001`, e em outro terminal `BASE_URL=http://localhost:3001 pnpm test:e2e`. -O workflow único [`.github/workflows/ci.yml`](.github/workflows/ci.yml) roda em -cada `push` e `pull_request`, com permissão `contents: read`. No job `verify` -(`ubuntu-latest`) 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. +## 📚 Documentação -O Nixpacks ([`nixpacks.toml`](nixpacks.toml)) 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. +- [`docs/project-health.md`](docs/project-health.md): estados do CTA das demos e atualização do snapshot. +- [`docs/seo-geo-operations.md`](docs/seo-geo-operations.md): runbook de SEO e GEO (Search Console, Bing, Cloudflare, CrUX), descrito e **não executado**. +- [`docs/seo-geo-validation.md`](docs/seo-geo-validation.md): validação de SEO e GEO. +- [`CREDITS.md`](CREDITS.md): créditos das capturas de tela e do ícone do WhatsApp. -## Avisos +## 🛣️ Limitações e próximos passos -- As capturas em `public/assets/prints/*.png` foram feitas com Chrome headless a - partir de deploys de produção do próprio autor (evandro.dev.br) e aparecem como - conteúdo da tela do notebook. Detalhes em [`CREDITS.md`](CREDITS.md). +- **Sem backend.** O formulário de contato não grava nada: abre `wa.me` com o briefing preenchido, e o rodapé mantém o contato direto por e-mail. +- **Demos externas podem aparecer como indisponíveis.** O CTA reflete o último snapshot versionado, não uma consulta em tempo real. No snapshot de 2026-07-11, só a SEV respondeu 200; `nutriscan` falhou na consulta e `sc-plus` respondeu 502. Rode `pnpm check:projects` para renová-lo. +- **Sem 3D em telas pequenas, com ponteiro `coarse` ou movimento reduzido.** O hero e o notebook entregam a versão HTML. +- **Ações externas de SEO/GEO pendentes.** Search Console, Bing, Cloudflare e CrUX estão só no runbook. + +## 🤝 Contribuindo + +Projeto pessoal (`"private": true` no `package.json`). O CI roda em `push` e `pull_request`; antes de abrir um PR, o que ele exige deve passar localmente: + +```bash +pnpm lint && pnpm typecheck && pnpm test -- --runInBand && pnpm build +``` + +## 📄 Licença + +Sem licença definida — todos os direitos reservados.