
Portfólio Pessoal
Open SourcePortfólio full-stack construído com Next.js, DDD e Arquitetura Limpa em um monorepo Turborepo.
- TypeScript
- React
- Next.js
- Node.js
- PostgreSQL
- Tailwind CSS
- CI/CD
- Prisma
- Supabase
Após seis anos em engenharia de software, este portfólio foi a primeira oportunidade de ser dono de um produto inteiro — da arquitetura ao deploy. Construído para ir além do LinkedIn e alcançar um público internacional, para buscar oportunidades no exterior e para demonstrar que Domain-Driven Design e Arquitetura Limpa se sustentam em um projeto solo do zero — não apenas em times onde o processo é imposto.
As Restrições
A arquitetura foi autoimposta. Sem equipe, sem prazo e sem pressão externa, a restrição veio de uma decisão deliberada: tratar o projeto como um produto real com escopo de MVP, um roadmap pós-MVP e nenhum atalho na camada de domínio.
Três requisitos moldaram cada decisão técnica:
- Performance — o site precisava pontuar bem no Lighthouse; um portfólio lento passa a mensagem errada
- Conteúdo sem alterar código — atualizar entradas de projetos ou experiências não poderia exigir um deploy; todo o conteúdo é orientado por um banco de dados seedado e renderizado como markdown
- i18n em todas as camadas — suportar inglês, português e espanhol significava resolver internacionalização na camada de domínio, não apenas remendá-la na UI
O design visual foi criado inteiramente no Figma por Milena Kawai, uma amiga designer que entregou a especificação completa do zero.
Processo de Engenharia
O backlog foi gerenciado com Task Master, dividido em sprints rastreadas como milestones do GitHub. O GitHub Projects forneceu um quadro Kanban para acompanhamento; cada issue seguia um template estruturado com contexto, critérios de aceitação, arquivos relevantes e dependências. Labels customizadas organizaram o trabalho por sprint, prioridade e tipo.
O projeto foi estruturado em cinco PRDs numerados — um por camada de arquitetura:
- Sprint 0 — fundação do domínio (
core): padrão Either, Value Objects, entidades, interfaces de repositório - Sprint 1 — camada de aplicação: use cases, ports, DTOs
- Sprint 2 — infraestrutura: repositórios Prisma, gateway Supabase, contêiner de DI
- Sprint 3 — site público: Next.js App Router, SSG, roteamento i18n, componentes de UI
- Sprint 4 — CI/CD: verificação de tipos, lint e suite de testes no GitHub Actions
Uma sprint dedicada à acessibilidade resolveu 88 problemas de WCAG, seguida por uma passagem orientada pelo Lighthouse que focou no bundle crítico, hints de preload de RSC e carregamento da imagem LCP.
A pasta docs/ contém 12 documentos de arquitetura numerados — contextos delimitados, estratégia de validação, abordagem de i18n, estratégia de testes, padrões de código e glossário de domínio.
Arquitetura
O domínio é organizado em três contextos delimitados — portfolio (projetos, experiências, skills, perfil), identity (autenticação e usuário) e contact (envio de mensagens) — cada um com suas próprias entidades, value objects e interfaces de repositório, compartilhando apenas o Shared Kernel.
Cada pacote tem uma única responsabilidade aplicada mecanicamente:
core— modelo de domínio; zero dependências de framework; entidades, value objects, padrão Either, interfaces de repositórioapplication— use cases e ports; depende apenas decore; sem Prisma, sem HTTPinfra— implementações concretas; única camada que importa Prisma e Supabaseui— biblioteca de componentes React; dividida emView(exibição) eControl(interatividade)utils— utilitários TypeScript puros:Validator, formatadores, hooks de browser; sem dependência de React
Site do Portfólio
Server Components chamam use cases diretamente no build time — não existe nenhuma camada REST entre o domínio e o HTML gerado. Para um site estático orientado a conteúdo, uma fronteira HTTP seria overhead puro.
A internacionalização é uma preocupação de domínio: LocalizedText é um value object em core. O site renderiza em inglês, português e espanhol — resolvido na camada de domínio antes que qualquer componente React toque os dados.
Cada página exporta generateMetadata com title, description e campos openGraph localizados. Páginas de projetos derivam os dados de OG diretamente das entidades de domínio — título, caption e imagem de capa — garantindo que os metadados nunca fiquem fora de sincronia com o conteúdo. Uma rota de imagem OG personalizada, construída com next/og no Edge Runtime, gera cards 1200×630 com identidade visual por página, locale e projeto.
As rotas de detalhe de projeto são orientadas pelo Slug — um value object em core — com generateStaticParams resolvendo cada slug de projeto publicado nas três locales no build time. Sem slug, sem rota.
O formulário de contato passa por rate limiting via Upstash Redis e entrega e-mail pelo Resend — ambos por trás de interfaces de porta, substituíveis e testáveis sem tocar a infraestrutura.
Este portfólio é a primeira presença técnica pública que construí e possuo por completo — do modelo de domínio ao pipeline de deploy. O app admin para gerenciamento de conteúdo e o blog estão escopados como pós-MVP, mantendo o site atual focado e publicável.
Destaques Técnicos
- Sem camada de API — Server Components consomem use cases no build time; um site estático não precisa de uma fronteira HTTP entre domínio e HTML
- Direção de dependência aplicada pelo ESLint — violações de camada são detectadas no lint time, não no code review; a fronteira é mecânica, não uma convenção
- Padrão Either — nenhuma exceção lançada para erros de domínio;
Left<ValidationError>propaga pelos use cases até a UI, tornando todos os caminhos de erro explícitos e testáveis - LocalizedText como VO — i18n é uma preocupação de domínio; componentes recebem strings já resolvidas, não chaves de tradução
- Acessibilidade como sprint — 88 problemas de WCAG rastreados, escopados e entregues como issues individuais com critérios de aceitação
- Performance orientada pelo Lighthouse — bundle crítico enxugado com lazy-loading de formulários pesados, remoção de
'use client'desnecessários e preload da imagem LCP comfetchpriority=high - SEO e Open Graph — cada página exporta
generateMetadatalocalizado; uma rota/ogno Edge Runtime gera cards 1200×630 por página, locale e projeto usandonext/og; os dados de OG são derivados das entidades de domínio, nunca de strings estáticas
Tecnologias
- Next.js — App Router com SSG;
generateStaticParamsgera todas as rotas localizadas no build time - Turborepo — orquestração de monorepo com cinco pacotes compartilhados e cache remoto no Vercel
- TypeScript — modo strict em todos os pacotes;
anyé proibido - Prisma — ORM e camada de migrations, isolado em
packages/infra - Supabase — banco de dados PostgreSQL e autenticação baseada em JWT
- Tailwind CSS — tokens de design compartilhados via
packages/tailwind-config - next-intl — roteamento de locale e resolução de mensagens para EN, PT-BR e ES
- Vitest — testes unitários e de integração em todos os pacotes; ~100 arquivos de teste
- Upstash Redis — rate limiting serverless no formulário de contato
- Resend — e-mail transacional para envios do formulário de contato
- Vercel — deployment com cache remoto do Turborepo
Outros projetos

Plataforma B2B de E-Commerce
Plataforma B2B full-stack para materiais de construção com Arquitetura Limpa, React e Node.js — do zero à produção.
- TypeScript
- React