Skip to content

Rdemora2/Portifolio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

167 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Roberto Moraes — Portfólio

CI

Portfólio profissional multilíngue em Next.js 16 e React 19. A aplicação combina conteúdo pré-renderizado, uma experiência editorial imersiva e efeitos progressivos com limites explícitos de acessibilidade, segurança e performance.

Este README é a porta de entrada operacional. O desenho completo, os fluxos, contratos, decisões e procedimentos de manutenção estão em docs/TECHNICAL_CONTEXT.md.

Características principais

  • Home e artigo localizados e pré-renderizados para português, inglês e espanhol.
  • Prefixo de idioma somente quando necessário: /, /en e /es.
  • Metadata localizada com canonical, hreflang, Open Graph, Twitter Cards, sitemap e JSON-LD.
  • Server Components por padrão e ilhas client-side somente para interação.
  • Vitrine de sites publicados com screenshots locais, links externos seguros e conteúdo integralmente localizado.
  • Artigo legível sem JavaScript, com experiência de scroll aprimorada quando o navegador e as preferências do usuário permitem.
  • WebGL, GSAP e formulário carregados sob demanda, com fallbacks estáticos ou nativos.
  • API de contato com validação estrita, proteção de origem, limites de corpo, rate limiting, honeypot, timeout e idempotência.
  • Build standalone e imagem de produção distroless, não-root e com filesystem somente leitura via Compose.
  • Gates automatizados para testes, lint, tipos, build, bundle, navegadores, dependências e imagem Docker.

Stack

Área Implementação atual
Aplicação Next.js 16.2.10, React 19.2.4, TypeScript 5
Interface Tailwind CSS 4, CSS Modules, CSS nativo e Web Animations API
Motion opcional GSAP 3.15.0 e OGL 1.0.11
Formulário React Hook Form 7.74.0, Zod 4.4.1 e Resend 6.17.2
Internacionalização next-intl 4.12
Qualidade ESLint 9, Vitest 4.1, Playwright 1.61 e axe-core
Entrega GitHub Actions, Docker e Docker Compose

Requisitos

  • Node.js >=24.0.0, sem teto de major.
  • npm 11.16.0 como versão de referência reproduzível.
  • Docker 24+ somente para os fluxos em container.

O projeto usa Node.js 24.18.0 em .nvmrc, CI e Docker. Essa versão é referência, não limite: engines, devEngines e engine-strict=true rejeitam Node anterior à versão 24, mas aceitam versões posteriores. O campo packageManager declara npm 11.16.0 como referência reproduzível, sem impor uma faixa adicional de compatibilidade.

Scripts de lifecycle de dependências ficam desabilitados por .npmrc. Os scripts do próprio projeto, executados explicitamente com npm run, continuam habilitados.

Execução local

Node.js

Use nvm use para a toolchain de referência ou qualquer Node.js 24+:

nvm use
node --version
npm --version
npm ci
cp .env.example .env.development.local
npm run dev

A aplicação fica em http://localhost:3000.

Use especificamente .env.development.local para o desenvolvimento. O template contém apenas placeholders locais e nunca deve ser promovido para produção. As credenciais do Resend só são necessárias para validar um envio real; os demais conteúdos e links funcionam sem elas.

O fluxo padrão usa explicitamente Webpack, limita o old space do V8 a 1.536 MiB e, no macOS e Linux, monitora o RSS de toda a árvore do servidor. Se ela ultrapassar 2.048 MiB, o processo é encerrado com uma mensagem explícita em vez de pressionar a memória da máquina. Os limites podem ser ajustados por NEXT_DEV_OLD_SPACE_MB e NEXT_DEV_MEMORY_LIMIT_MB; ambos aceitam de 512 a 4.096 MiB e o old space deve deixar ao menos 256 MiB para o restante do heap, memória nativa e processos filhos. No Windows, o old space continua limitado, mas o teto rígido de memória exige o fluxo Docker. O wrapper lê os dois valores com a mesma precedência de arquivos .env do Next.js sem repassar o estado do loader ao processo filho.

Se o Node 24 do Homebrew estiver keg-only:

export PATH="$(brew --prefix node@24)/bin:$PATH"

Docker de desenvolvimento

O Compose de desenvolvimento monta o repositório, preserva node_modules e .next em volumes nomeados e usa eventos nativos para o hot reload. Além do watchdog da aplicação, o container tem limite rígido padrão de 2.560 MiB e reserva de 1.024 MiB:

cp .env.example .env.development.local
docker compose --env-file .env.development.local -f docker-compose.dev.yml up --build

O parâmetro --env-file também alimenta a interpolação do Compose; assim, valores server-side definidos no arquivo chegam ao container em vez de serem substituídos pelos defaults do YAML.

O template deriva NEXT_PUBLIC_SITE_URL e CONTACT_ALLOWED_ORIGINS de PORT. Portanto, alterar PORT no arquivo muda em conjunto a porta publicada e as duas origens browser-facing.

Os volumes de dependências e cache são reconciliados por um fingerprint de package-lock.json, package.json, .npmrc, Node.js, plataforma e arquitetura. Ao detectar uma runtime incompatível, o container executa uma instalação limpa com verificação de assinaturas e descarta apenas o cache Next obsoleto; um volume antigo nunca é reutilizado silenciosamente.

Para encerrar e remover os containers:

docker compose --env-file .env.development.local -f docker-compose.dev.yml down --remove-orphans

Configuração

As configurações públicas são incorporadas ao bundle. Segredos permanecem exclusivamente no runtime do servidor.

Variável Fase Obrigatoriedade
NEXT_PUBLIC_SITE_URL build e runtime Origem pública; em produção deve ser HTTPS e pública
NEXT_PUBLIC_WEB_VITALS_ENDPOINT build Caminho first-party opcional para telemetria
RESEND_API_KEY runtime Obrigatória no bootstrap de produção
CONTACT_FROM_EMAIL runtime Remetente com domínio público; deve estar verificado para envio real
CONTACT_TO_EMAIL runtime Destino das mensagens
CONTACT_IDEMPOTENCY_SECRET runtime Segredo de alta entropia com pelo menos 32 caracteres
CONTACT_ALLOWED_ORIGINS runtime Lista de origens HTTPS; deve conter a origem pública
CONTACT_TRUST_PROXY runtime Decisão explícita: true ou false

Limites de request, timeout, rate limiting e proxy estão documentados e exemplificados em .env.example. O contrato completo, incluindo faixas aceitas e defaults, está no contexto técnico.

Regras importantes:

  • Nunca exponha segredos com prefixo NEXT_PUBLIC_.
  • Alterar uma variável pública exige novo build.
  • Habilite CONTACT_TRUST_PROXY somente se o proxy confiável sobrescrever o header configurado.
  • O endpoint de Web Vitals deve ser um caminho relativo à origem. Este repositório não implementa o coletor; ele precisa existir na mesma origem antes de a variável ser habilitada.

Comandos

Comando Finalidade
npm run dev Servidor de desenvolvimento com Webpack e limites de memória
npm run dev:turbo Turbopack opt-in, protegido pelos mesmos limites
npm test Vitest e regressão do quality hook
npm run test:watch Vitest em modo interativo
npm run lint ESLint com regras Next.js, Core Web Vitals e TypeScript
npm run typecheck Gera tipos de rotas e executa TypeScript sem emitir arquivos
npm run build Build standalone e cópia validada dos assets
npm run check:bundle Gate de transferência inicial e chunks diferidos
npm run test:e2e:install Instala Chromium, Firefox e WebKit
npm run test:e2e Playwright em todos os projetos configurados
npm run analyze Analyzer oficial do Turbopack
npm run start Executa .next/standalone/server.js

As validações de ambiente não dependem de um comando manual separado: os gates reais são executados pelo next build para variáveis públicas e pelo bootstrap Node.js ao iniciar em produção.

Validação completa

Instale os browsers uma vez:

npm run test:e2e:install

Em uma instalação Linux mínima, instale também as bibliotecas do sistema com npx playwright install --with-deps chromium firefox webkit. A CI já usa essa variante.

Depois execute, nesta ordem:

npm test
npm run lint
npm run typecheck
npm run build
npm run check:bundle
npm run test:e2e

O Playwright inicia o standalone em http://localhost:3100 por padrão, portanto o build é pré-requisito. O projeto principal faz a regressão detalhada em Chromium; há um cenário dedicado sem WebGL e smokes adicionais em Firefox e WebKit. Falhas preservam trace, screenshot e vídeo conforme a configuração.

Para testar uma instância já iniciada:

PLAYWRIGHT_TEST_BASE_URL=http://localhost:3000 npm run test:e2e

Use essa opção apenas contra um ambiente descartável ou autorizado: os testes exercitam rotas, navegação e a API de contato.

Budgets de bundle

npm run check:bundle mede HTML, JS e CSS com gzip nível 9; WOFF2 é medido pelo tamanho bruto, pois já é comprimido. Preloads de fonte e inventário alcançável pelo CSS são gates separados.

Superfície Limite padrão
Home JS 260 KiB
Artigo JS 250 KiB
Home CSS / artigo CSS 25 KiB cada
Home HTML 60 KiB
Artigo HTML 35 KiB
Fontes preloadadas da home / artigo 120 KiB cada
Inventário WOFF2 da home / artigo 210 KiB cada
Cada entry lazy 100 KiB
Maior chunk diferido 90 KiB
Total diferido único 165 KiB

Os nomes das variáveis de override e o fallback que captura pelo standalone qualquer rota medida sem HTML pré-renderizado estão detalhados no contexto técnico. Manifestos vazios, rotas sem assets iniciais e ausência de chunks diferidos são tratados como erro.

O analyzer grava uma interface estática em .next/diagnostics/analyze:

npm run analyze

Produção

Standalone local

O build copia public quando existente e .next/static para o artefato standalone. Injete um ambiente de produção válido antes de iniciar:

set -a
. ./.env.production
set +a
npm run build
npm run start

.env.production é ignorado pelo Git. Use valores reais para validar o formulário; fixtures apenas sintaticamente válidas servem para smoke de páginas, mas não para entrega de email.

Ao carregar o arquivo com o shell, mantenha-o compatível com POSIX e coloque entre aspas valores que contenham espaços. O Compose também aceita esses valores entre aspas.

Docker Compose

Crie um .env.production exclusivo para o ambiente. Não copie .env.example: seus valores sensíveis são deliberadamente inválidos em produção.

docker compose --env-file .env.production config --quiet
docker compose --env-file .env.production up --build --detach
docker compose --env-file .env.production ps
curl --fail http://127.0.0.1:3000/robots.txt

A porta é publicada somente em loopback por padrão. Um proxy reverso deve terminar HTTPS e encaminhar o tráfego público. Se PORT for alterada no arquivo de ambiente, ajuste o URL do smoke.

Para acompanhar logs e encerrar:

docker compose --env-file .env.production logs --follow portfolio
docker compose --env-file .env.production down --remove-orphans

O runner usa Node.js 24.18.0 em uma imagem distroless Debian 13, sem shell, package manager ou toolchain. Ele executa como UID/GID 65532:65532; o Compose remove capabilities, proíbe privilege escalation, aplica limites de processo/CPU/memória e disponibiliza somente dois tmpfs graváveis.

Segurança e limites deliberados

  • A CSP e os headers defensivos são centralizados em next.config.ts.
  • A API não retorna segredos nem inclui dados pessoais nos logs de erro.
  • Instalações bloqueiam lifecycle scripts e a CI verifica assinaturas e vulnerabilidades.
  • Actions e imagens-base são fixadas por commit ou digest; o Trivy rejeita vulnerabilidades High e Critical da imagem final.
  • A política estática ainda usa unsafe-inline para scripts e estilos exigidos pelo bootstrap atual do App Router. Migrar para nonce por request tornaria as superfícies hoje estáticas dinâmicas; a decisão deve ser reavaliada se surgir autenticação ou requisito formal de compliance.
  • O rate limiter é local ao processo e reinicia com a instância. Múltiplas réplicas exigem Redis/Upstash, WAF ou mecanismo distribuído equivalente.
  • Com CONTACT_TRUST_PROXY=false, nenhum header de IP é confiado e os clientes compartilham o bucket por cliente. Isso é seguro contra spoofing, mas pode gerar contenção sob tráfego real.

Veja o modelo de segurança completo, inclusive a ordem dos controles da API e os gaps operacionais conhecidos.

Estrutura

src/
├── app/                 rotas, layouts, metadata, imagens sociais e API
├── components/          layout, seções, componentes compartilhados e artigo
├── content/             modelos editoriais localizados
├── data/                projetos, sites publicados, experiência, métricas e links
├── hooks/               observação de viewport e navegação
├── lib/                 constantes, validações, WebGL e gates de produção
├── messages/            catálogos pt, en e es
└── types/               contratos compartilhados
e2e/                     regressão Playwright
scripts/                 bundle gate, standalone e quality hook
docs/                    contexto técnico versionado
public/images/sites/     thumbnails locais dos sites publicados

docs/portifolio/ permanece intencionalmente ignorado e não faz parte da documentação versionada.

Política de conteúdo

Casos, métricas e experiências publicados devem ser verificáveis e autorizados. Logos, screenshots, depoimentos e informações confidenciais de terceiros não devem entrar no portfólio sem aprovação explícita.

Ao alterar conteúdo localizado, arquitetura, ambiente, budgets ou comandos, atualize o README e docs/TECHNICAL_CONTEXT.md no mesmo conjunto de mudanças.

About

Next.js / React / Tailwind / Gsap / Three.js

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Contributors