feat: revamp portfolio with case studies, curriculo page, and local SEO

Adds dynamic case study and curriculo routes, project health monitoring
for live demo status, and strengthens local SEO (structured data,
service-area targeting for Garuva/Joinville/Curitiba, a dedicated
"criação de sites" service page) so search results better match the
professional title (Engenheiro da Computação) and experience (5 anos).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
Evandro Fonseca JuniorandClaude Sonnet 5 committed 2026-07-15 01:31:46 -03:00
1 parent 9236fdd685
commit d76bbf5974
41 files changed
+1359 -492

No files matched your search

+23
View File
@@ -0,0 +1,23 @@
# Verificação automática de projetos na VPS
A lista pública de projetos só exibe demos cujo snapshot atual tenha resposta final HTTP `200` e `Content-Type: text/html`. O snapshot vence após 15 minutos; se não houver uma verificação atual, nenhum projeto é exibido.
## Pré-requisito
O cron deve executar no mesmo diretório de release que contém `data/project-health.json` consumido pelo processo Next.js. Em deploys com diretório versionado, aponte o cron para o symlink `current`.
```cron
*/10 * * * * cd /var/www/evandro.dev.br/current && /usr/bin/node scripts/check-projects.mjs >> /var/log/evandro-project-health.log 2>&1
```
Para validar manualmente:
```bash
cd /var/www/evandro.dev.br/current
npm run check:projects
cat data/project-health.json
```
O script segue redirecionamentos, limita cada requisição a 10 segundos, não aceita `3xx`, `4xx`, `5xx`, DNS/TLS inválido nem conteúdo não HTML. Ele grava em arquivo temporário e renomeia ao final, evitando que o Next.js leia JSON parcial.
Após a primeira instalação, rode `npm run check:projects` antes de iniciar a aplicação. O ISR da home é de 5 minutos; portanto, uma alteração de disponibilidade pode levar até esse intervalo adicional para aparecer no HTML público.
@@ -0,0 +1,82 @@
# Portfolio Growth Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Make the portfolio fast, indexable, regionally relevant, and limited to live project demos.
**Architecture:** Project metadata remains static and is read on the server. A VPS cron runs a small Node script that writes an atomic health snapshot; server rendering filters featured projects by final HTTP 200 HTML results. Interactive motion is isolated from semantic server-rendered content, and SEO is represented by Next metadata plus visible resume/case content and matching schema.org.
**Tech Stack:** Next.js 16 App Router, React 19, TypeScript, Jest, Node.js fetch, cron.
---
### Task 1: Project-health domain
**Files:**
- Create: `lib/project-health.ts`
- Create: `lib/project-health.test.ts`
- Create: `scripts/check-projects.mjs`
- Create: `data/project-health.json`
- [ ] Write a failing test: only current, final-200 HTML project IDs are accepted.
- [ ] Run `npm test -- lib/project-health.test.ts --runInBand`; expect failure because the module is absent.
- [ ] Implement pure snapshot parsing/filtering and seed a safe empty snapshot.
- [ ] Run the focused test; expect pass.
- [ ] Implement the cron script with bounded concurrent GET checks, 10-second timeout, HTML content-type test, atomic JSON rename and nonzero exit only for configuration failures.
### Task 2: Render data on the server
**Files:**
- Create: `lib/portfolio-data.ts`
- Modify: `app/components/Projects.tsx`
- Modify: `app/components/Experience.tsx`
- Modify: `app/components/Skills.tsx`
- Modify: `app/components/cinematic/CinematicHome.tsx`
- [ ] Write failing tests for project filtering and server data adapters.
- [ ] Move static portfolio JSON parsing into a typed server module.
- [ ] Pass filtered projects, experiences and skills as props; retain client animation only within components.
- [ ] Run focused tests and build.
### Task 3: Indexable professional content and regional SEO
**Files:**
- Modify: `app/layout.tsx`
- Modify: `app/page.tsx`
- Modify: `lib/site-content.ts`
- Modify: `app/robots.ts`
- Modify: `app/sitemap.ts`
- Create: `app/curriculo/page.tsx`
- Create: `app/cases/[slug]/page.tsx`
- [ ] Add profile/curriculum and case-study routes with visible text, internal links and static params.
- [ ] Add regional titles/descriptions and ProfilePage/Person schema that matches visible text.
- [ ] Add only canonical generated by Next, remove stale static metadata files that conflict with generated routes.
- [ ] Test static generation and inspect route output.
### Task 4: Measured front-end fixes
**Files:**
- Modify: `app/layout.tsx`
- Modify: `app/components/Hero.tsx`
- Modify: `app/components/cinematic/HeroScene.tsx`
- Modify: `app/components/cinematic/CinematicHome.tsx`
- Modify: `app/globals.css`
- Modify: `app/icon.svg`
- [ ] Write or update tests for semantics where behavior changes.
- [ ] Remove hydration blocker; reserve hero layout to stop CLS.
- [ ] Defer the 3D canvas until browser idle and omit it with reduced motion or narrow/coarse pointers.
- [ ] Replace gradient text/glass defaults, repair contrast, list structure and accessible labels.
- [ ] Run Lighthouse again and compare baseline.
### Task 5: Operations and verification
**Files:**
- Create: `docs/project-health-cron.md`
- Modify: relevant failing component tests only when the implementation intentionally changed their contractual UI.
- [ ] Document the exact cron command and expected snapshot behavior.
- [ ] Run `npm test -- --runInBand`, `npm run lint`, and `npm run build`.
- [ ] Run the health script against actual project URLs and confirm rendered project IDs match final 200 responses.
- [ ] Run a fresh Lighthouse audit and report measured deltas.
@@ -0,0 +1,27 @@
# Portfolio Growth Design
## Objetivo
Posicionar Evandro Fonseca Junior para contratação em engenharia de software no Norte de Santa Catarina e Curitiba, mantendo consultoria como conversão secundária. O portfólio deve servir conteúdo profissional indexável, rápido e verificável.
## Decisões
- A validação de projetos usa um snapshot gerado na VPS. Um script executado pelo cron testa as demos com `GET`, redirecionamentos, timeout e limite de corpo; somente resposta final HTTP 200 com HTML é aprovada.
- O snapshot é gravado de forma atômica. Se estiver ausente ou vencido, nenhum projeto é mostrado em vez de exibir links potencialmente quebrados.
- Dados profissionais e projetos passam a ser renderizados no servidor, deixando animações como ilhas client-side.
- O posicionamento textual prioriza Garuva, Joinville, Norte de Santa Catarina, Curitiba e região, com contratação como CTA principal.
- SEO para mecanismos de IA segue SEO convencional: conteúdo textual rastreável, links internos, dados estruturados fiéis ao conteúdo e boa experiência de página. Não haverá markup ou arquivo específico prometendo ranking em IA.
## Escopo
1. Snapshot de saúde, script de validação, testes e instrução de cron.
2. Projetos e currículo visíveis no HTML inicial.
3. Metadados e JSON-LD regionais, ProfilePage, cases e currículo.
4. Correções mensuráveis de Lighthouse: cena 3D diferida, remoção do bloqueador de hidratação, ícone enxuto, contraste e listas semânticas.
5. Correção dos testes afetados pela arquitetura atual.
## Fora do escopo
- Garantia de posição em buscadores.
- Integração com APIs externas de Google Jobs ou Google Business Profile.
- Verificação de repositórios GitHub; a regra solicitada cobre demos públicas.