Estado do disco em 14/10/2026, sem filtrar. Inclui as copias .sync-conflict-* do Syncthing de 07/10 e os 15 arquivos que o Syncthing apagou; todo esse conteudo ja existia em outros commits. So havia fora do Git: AGENTS.md, CLAUDE.md e a alteracao em data/project-health.json.
This commit is contained in:
1 parent
b2f3899dc2
commit
dfcadc71fa
77 files changed
+6944
-2419
No files matched your search
@@ -1,10 +1,3 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
|
||||
const brandMark = `data:image/png;base64,${readFileSync(
|
||||
join(process.cwd(), "public/brand/mark-dark.png"),
|
||||
).toString("base64")}`;
|
||||
|
||||
export const OG_SIZE = { width: 1200, height: 630 } as const;
|
||||
export const OG_CONTENT_TYPE = "image/png";
|
||||
|
||||
@@ -23,7 +16,6 @@ export function OgCard({
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
position: "relative",
|
||||
flexDirection: "column",
|
||||
justifyContent: "space-between",
|
||||
background: "#050505",
|
||||
@@ -32,17 +24,9 @@ export function OgCard({
|
||||
fontFamily: "Arial, sans-serif",
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={brandMark}
|
||||
alt="Evandro.dev.br"
|
||||
width={80}
|
||||
height={80}
|
||||
style={{ position: "absolute", top: 48, right: 72 }}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
paddingRight: 112,
|
||||
color: "#ccff00",
|
||||
fontSize: 24,
|
||||
letterSpacing: "0.16em",
|
||||
|
||||
@@ -86,27 +86,6 @@ describe("factual portfolio records", () => {
|
||||
/produç|clientes?|leads?|ranking|performance|resultado comercial|anime\.js|shadcn/i,
|
||||
);
|
||||
});
|
||||
it("keeps Reddit Posts Explorer and MinGW GCC Installer within what their public repositories support", () => {
|
||||
const reddit = serializeProject("reddit-explorer");
|
||||
const gcc = serializeProject("gcc-installer");
|
||||
|
||||
expect(reddit).toContain("MongoDB");
|
||||
expect(reddit).not.toMatch(
|
||||
/SSG|rate limit|cache|tempo real|real-time|busca em|otimiza|responsiv/i,
|
||||
);
|
||||
expect(gcc).toContain("mingw64");
|
||||
expect(gcc).not.toMatch(
|
||||
/assíncron|monitoramento|drastic|Watchdog|dependências|intuitiv/i,
|
||||
);
|
||||
});
|
||||
|
||||
it("does not claim measured performance for SC Plus without a stored measurement", () => {
|
||||
// Lighthouse mobile local: LCP 3,7 s em 2026-10-05; a alegação anterior (LCP < 2,5 s) não se sustentava
|
||||
expect(serializeProject("sc-plus")).not.toMatch(
|
||||
/LCP|Core Web Vitals|otimizad|velocidade|rápid|Performance/i,
|
||||
);
|
||||
});
|
||||
|
||||
it("does not publish the unavailable Twins Lab demo", () => {
|
||||
expect(
|
||||
portfolio.projects.find((item) => item.id === "twins-lab")?.demoUrl,
|
||||
|
||||
+1
-12
@@ -37,17 +37,7 @@ it("keeps the root graph limited to verified website and person fields", () => {
|
||||
["@id", "@type", "inLanguage", "name", "publisher", "url"].sort(),
|
||||
);
|
||||
expect(Object.keys(person).sort()).toEqual(
|
||||
[
|
||||
"@id",
|
||||
"@type",
|
||||
"homeLocation",
|
||||
"image",
|
||||
"jobTitle",
|
||||
"knowsAbout",
|
||||
"name",
|
||||
"sameAs",
|
||||
"url",
|
||||
].sort(),
|
||||
["@id", "@type", "homeLocation", "image", "name", "sameAs", "url"].sort(),
|
||||
);
|
||||
expect(website).toMatchObject({
|
||||
"@type": "WebSite",
|
||||
@@ -59,7 +49,6 @@ it("keeps the root graph limited to verified website and person fields", () => {
|
||||
"@type": "Person",
|
||||
"@id": SEO_IDS.person,
|
||||
image: `${siteUrl}/edev.jpg`,
|
||||
jobTitle: "Engenheiro da Computação e Desenvolvedor de Software",
|
||||
homeLocation: { "@type": "Place", name: "Garuva, Santa Catarina, Brasil" },
|
||||
sameAs: [
|
||||
"https://github.com/evandrodevbr",
|
||||
|
||||
-12
@@ -24,18 +24,6 @@ export function buildPersonJsonLd() {
|
||||
name: "Evandro Fonseca Junior",
|
||||
url: siteUrl,
|
||||
image: `${siteUrl}/edev.jpg`,
|
||||
// cargo e áreas vêm de public/portfolio-data.json e estão visíveis em /curriculo e na seção de skills
|
||||
jobTitle: "Engenheiro da Computação e Desenvolvedor de Software",
|
||||
knowsAbout: [
|
||||
"Next.js",
|
||||
"React",
|
||||
"TypeScript",
|
||||
"Node.js",
|
||||
"Python",
|
||||
"IoT",
|
||||
"Computação em nuvem",
|
||||
"Inteligência artificial",
|
||||
],
|
||||
homeLocation: {
|
||||
"@type": "Place",
|
||||
name: "Garuva, Santa Catarina, Brasil",
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
import { caseStudies, getRelatedServices, servicePages } from "./site-content";
|
||||
|
||||
const detailedIds = [
|
||||
"as-servicos",
|
||||
"gcc-installer",
|
||||
"nutriscan",
|
||||
"reddit-explorer",
|
||||
"twins-lab",
|
||||
] as const;
|
||||
const detailedIds = ["as-servicos", "nutriscan", "twins-lab"] as const;
|
||||
const immutableGitHubBlobUrl =
|
||||
/^https:\/\/github\.com\/[^/]+\/[^/]+\/blob\/[0-9a-f]{40}\/.+$/;
|
||||
|
||||
@@ -17,7 +11,7 @@ function getDetail(id: (typeof detailedIds)[number]) {
|
||||
return detail;
|
||||
}
|
||||
|
||||
it("limits detailed content to the evidenced cases (public repositories pinned to a commit)", () => {
|
||||
it("limits detailed content to the three evidenced cases", () => {
|
||||
expect(
|
||||
caseStudies
|
||||
.filter(({ detail }) => detail !== undefined)
|
||||
@@ -70,15 +64,6 @@ it("requires sources for factual statements and resolves every source ID", () =>
|
||||
expect(getDetail("nutriscan").boundaries[0]?.sourceIds).toContain(
|
||||
"nutri-readme",
|
||||
);
|
||||
|
||||
// reddit-explorer e gcc-installer: o 1º limite vem da documentação do repositório; o 2º é o escopo editorial (sem fonte)
|
||||
for (const id of ["reddit-explorer", "gcc-installer"] as const) {
|
||||
const { boundaries } = getDetail(id);
|
||||
expect(boundaries[0]?.sourceIds.length).toBeGreaterThan(0);
|
||||
expect(
|
||||
boundaries.slice(1).every(({ sourceIds }) => sourceIds.length === 0),
|
||||
).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
it("derives the exact related service set from the existing relationship", () => {
|
||||
@@ -111,14 +96,3 @@ it("does not publish the unavailable Twins Lab demo", () => {
|
||||
caseStudies.find((item) => item.id === "twins-lab")?.demoUrl,
|
||||
).toBeUndefined();
|
||||
});
|
||||
|
||||
it("keeps AS Serviços as a project (code only) and states the author's participation", () => {
|
||||
const asServicos = caseStudies.find(({ id }) => id === "as-servicos");
|
||||
expect(asServicos?.demoUrl).toBeNull();
|
||||
expect(asServicos?.githubUrl).toBe(
|
||||
"https://github.com/evandrodevbr/as-servicos",
|
||||
);
|
||||
expect(asServicos?.role).toMatch(/primeira landing page/i);
|
||||
expect(asServicos?.role).toMatch(/animações 3D/i);
|
||||
expect(asServicos?.role).toMatch(/painel para controle de projetos/i);
|
||||
});
|
||||
+22
-136
@@ -2,13 +2,13 @@ export const siteUrl = "https://evandro.dev.br";
|
||||
export const siteName = "Evandro.dev.br";
|
||||
|
||||
export const intentCtas = {
|
||||
project: {
|
||||
label: "Conversar sobre meu projeto",
|
||||
href: "/#contact",
|
||||
hiring: {
|
||||
label: "Avaliar perfil para contratação",
|
||||
href: "/curriculo",
|
||||
},
|
||||
consulting: {
|
||||
label: "Conhecer as soluções",
|
||||
href: "/servicos",
|
||||
label: "Solicitar consultoria técnica",
|
||||
href: "/#contact",
|
||||
},
|
||||
} as const;
|
||||
|
||||
@@ -75,8 +75,6 @@ export interface CaseStudyContent {
|
||||
stack: string[];
|
||||
demoUrl?: string | null;
|
||||
githubUrl?: string | null;
|
||||
/** Papel do autor quando o projeto não é só dele (texto editorial, sem fonte pública). */
|
||||
role?: string;
|
||||
detail?: CaseStudyDetail;
|
||||
}
|
||||
|
||||
@@ -146,7 +144,7 @@ export const servicePages: ServicePageContent[] = [
|
||||
slug: "engenharia-de-software",
|
||||
navLabel: "Sistemas web e aplicativos mobile",
|
||||
eyebrow: "Engenharia de software",
|
||||
seoTitle: "Sistemas Web e Aplicativos Mobile sob Medida",
|
||||
seoTitle: "Desenvolvimento de Sistemas Web e Aplicativos Mobile",
|
||||
metaDescription:
|
||||
"Sistemas web e aplicativos mobile sob medida, integração entre ferramentas e evolução de software existente. Escopo, plataformas e entregas definidos por projeto.",
|
||||
headline: "Sistemas e apps para o seu trabalho.",
|
||||
@@ -268,7 +266,7 @@ export const servicePages: ServicePageContent[] = [
|
||||
slug: "tauri-rust",
|
||||
navLabel: "Aplicativos desktop para Windows e Linux",
|
||||
eyebrow: "Aplicativos desktop",
|
||||
seoTitle: "Aplicativos Desktop com Tauri e Rust",
|
||||
seoTitle: "Aplicativos Desktop para Windows e Linux com Tauri e Rust",
|
||||
metaDescription:
|
||||
"Desenvolvimento de aplicativos desktop para Windows e Linux com Tauri e Rust. Ferramentas locais, arquivos e integrações com compatibilidade definida por projeto.",
|
||||
headline: "Aplicativos para Windows e Linux.",
|
||||
@@ -620,83 +618,22 @@ export const caseStudies: CaseStudyContent[] = [
|
||||
{
|
||||
id: "reddit-explorer",
|
||||
title: "Reddit Posts Explorer",
|
||||
subtitle: "Posts do r/artificial em MongoDB, filtrados por período",
|
||||
subtitle: "Aplicação orientada a dados com API, cache e busca",
|
||||
summary:
|
||||
"Aplicação Astro SSR que coleta os posts em alta do r/artificial, grava no MongoDB sem duplicar e filtra por período, upvotes ou comentários.",
|
||||
"Projeto em Astro e MongoDB para explorar conteúdo com filtros, ordenação e cache, mantendo boa experiência em consultas frequentes.",
|
||||
impact:
|
||||
"Atualizar a coleta sem duplicar posts e consultar o histórico por intervalo de datas e ordenação.",
|
||||
stack: ["Astro", "MongoDB", "Mongoose", "TypeScript", "Reddit API"],
|
||||
"Mostra capacidade de desenhar consumo de API, camada de persistência e experiência de busca sem sobrecarregar a aplicação.",
|
||||
stack: ["Astro.js", "MongoDB", "Mongoose", "TypeScript", "Reddit API"],
|
||||
githubUrl: "https://github.com/evandrodevbr/reddit-search",
|
||||
detail: {
|
||||
answer: {
|
||||
text: "Aplicação Astro em modo SSR que coleta os posts em alta do r/artificial pela API pública do Reddit, grava no MongoDB com upsert por id e permite filtrar por período e ordenar por upvotes ou comentários.",
|
||||
sourceIds: ["rd-readme", "rd-service", "rd-astro"],
|
||||
},
|
||||
challenge: {
|
||||
text: "Atualizar a coleta sem duplicar posts e consultar o histórico por intervalo de datas e ordenação.",
|
||||
sourceIds: ["rd-service", "rd-filter"],
|
||||
},
|
||||
implementation: [
|
||||
{
|
||||
text: "O serviço consulta r/artificial/hot.json com User-Agent identificado e limite de 15 segundos, e grava os posts em lote com upsert pelo id; rodar a coleta de novo atualiza os existentes.",
|
||||
sourceIds: ["rd-service"],
|
||||
},
|
||||
{
|
||||
text: "O endpoint de filtro valida as datas e o campo de ordenação (ups ou num_comments) e responde 400 quando faltam parâmetros ou eles são inválidos.",
|
||||
sourceIds: ["rd-filter"],
|
||||
},
|
||||
{
|
||||
text: "O Astro roda com output server e o adapter Node em modo standalone.",
|
||||
sourceIds: ["rd-astro", "rd-package"],
|
||||
},
|
||||
],
|
||||
boundaries: [
|
||||
{
|
||||
text: "O subreddit é fixo, e o projeto não tem paginação, busca textual, autenticação, testes automatizados nem CI.",
|
||||
sourceIds: ["rd-readme"],
|
||||
},
|
||||
{
|
||||
text: "O case demonstra implementação e decisões técnicas; não atribui ganho de performance, volume de dados ou resultado comercial.",
|
||||
sourceIds: [],
|
||||
},
|
||||
],
|
||||
sources: [
|
||||
{
|
||||
id: "rd-readme",
|
||||
label: "README do projeto",
|
||||
url: "https://github.com/evandrodevbr/reddit-search/blob/ff76e08379a51fc02c3b8e4d6c415d627d8c90de/README.md",
|
||||
},
|
||||
{
|
||||
id: "rd-service",
|
||||
label: "Serviço de coleta e consulta",
|
||||
url: "https://github.com/evandrodevbr/reddit-search/blob/ff76e08379a51fc02c3b8e4d6c415d627d8c90de/src/lib/services/redditService.ts",
|
||||
},
|
||||
{
|
||||
id: "rd-filter",
|
||||
label: "Endpoint de filtro",
|
||||
url: "https://github.com/evandrodevbr/reddit-search/blob/ff76e08379a51fc02c3b8e4d6c415d627d8c90de/src/pages/api/posts/filter.ts",
|
||||
},
|
||||
{
|
||||
id: "rd-astro",
|
||||
label: "Configuração do Astro",
|
||||
url: "https://github.com/evandrodevbr/reddit-search/blob/ff76e08379a51fc02c3b8e4d6c415d627d8c90de/astro.config.mjs",
|
||||
},
|
||||
{
|
||||
id: "rd-package",
|
||||
label: "Manifesto do projeto",
|
||||
url: "https://github.com/evandrodevbr/reddit-search/blob/ff76e08379a51fc02c3b8e4d6c415d627d8c90de/package.json",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "sc-plus",
|
||||
title: "SC Plus Aquicultura",
|
||||
subtitle: "Landing page institucional em Next.js 15",
|
||||
subtitle: "Site institucional em Next.js com foco em performance e SEO",
|
||||
summary:
|
||||
"Landing page institucional em Next.js 15, React 19 e Tailwind CSS 4, com metadados e dados estruturados para indexação.",
|
||||
"Landing page em Next.js 15 otimizada para Core Web Vitals, metadata e estrutura técnica de indexação.",
|
||||
impact:
|
||||
"Dar à instituição uma página própria, com base técnica para ser encontrada em buscadores.",
|
||||
"Exemplo de projeto em que clareza de mensagem, velocidade e SEO técnico trabalham juntos.",
|
||||
stack: ["Next.js 15", "React 19", "Tailwind CSS 4", "TypeScript"],
|
||||
demoUrl: "https://scplus.evandro.dev.br",
|
||||
githubUrl: "https://github.com/evandrodevbr/scplus",
|
||||
@@ -704,80 +641,29 @@ export const caseStudies: CaseStudyContent[] = [
|
||||
{
|
||||
id: "gcc-installer",
|
||||
title: "MinGW GCC Installer",
|
||||
subtitle: "Instalador gráfico de MinGW-w64/GCC para Windows",
|
||||
subtitle:
|
||||
"Ferramenta desktop para automação de ambiente de desenvolvimento",
|
||||
summary:
|
||||
"Aplicativo Python com interface tkinter que lista as builds do MinGW-w64, baixa a escolhida, instala em C:\\mingw64 e adiciona o GCC ao PATH do usuário.",
|
||||
"Aplicação em Python para simplificar setup local no Windows, com download assíncrono, checagem de compatibilidade e integração com PATH.",
|
||||
impact:
|
||||
"Reduzir a configuração manual do GCC no Windows (escolher a build, baixar, extrair e ajustar o PATH) a uma única janela.",
|
||||
stack: ["Python", "Tkinter", "Win32 API", "GitHub API", "7-Zip"],
|
||||
"Mostra familiaridade com software desktop, integração com sistema operacional e automação de setup técnico.",
|
||||
stack: ["Python", "Tkinter", "Win32 API", "Threading", "7-Zip"],
|
||||
githubUrl: "https://github.com/evandrodevbr/gcc-installer",
|
||||
detail: {
|
||||
answer: {
|
||||
text: "Aplicativo Python com interface tkinter que lê as builds publicadas do MinGW-w64, baixa o pacote .7z escolhido, instala em C:\\mingw64 e adiciona o toolchain ao PATH do usuário no registro do Windows.",
|
||||
sourceIds: ["gcc-readme", "gcc-main"],
|
||||
},
|
||||
challenge: {
|
||||
text: "Reduzir a configuração manual do GCC no Windows (escolher a build, baixar, extrair e ajustar o PATH) a uma única janela.",
|
||||
sourceIds: ["gcc-readme"],
|
||||
},
|
||||
implementation: [
|
||||
{
|
||||
text: "A lista de versões vem da API de releases do repositório niXman/mingw-builds-binaries, e as builds com ucrt e thread model posix são destacadas na tabela.",
|
||||
sourceIds: ["gcc-main"],
|
||||
},
|
||||
{
|
||||
text: "A instalação extrai o pacote com o 7-Zip (caminho padrão fixo) em uma pasta temporária, move o resultado para C:\\mingw64 e renomeia mingw32-make.exe para make.exe.",
|
||||
sourceIds: ["gcc-main"],
|
||||
},
|
||||
{
|
||||
text: "Adicionar ao PATH grava em HKCU\\Environment e avisa o Windows com WM_SETTINGCHANGE; fora do Windows o programa encerra com um aviso.",
|
||||
sourceIds: ["gcc-main"],
|
||||
},
|
||||
],
|
||||
boundaries: [
|
||||
{
|
||||
text: "Funciona só no Windows, o caminho do 7-Zip é fixo e o fluxo da interface não foi exercitado de ponta a ponta no Windows nesta revisão; os 23 testes cobrem a lógica independente de plataforma, e não há CI.",
|
||||
sourceIds: ["gcc-readme", "gcc-tests"],
|
||||
},
|
||||
{
|
||||
text: "O case demonstra implementação e decisões técnicas; não atribui ganho de performance, número de usuários ou resultado comercial.",
|
||||
sourceIds: [],
|
||||
},
|
||||
],
|
||||
sources: [
|
||||
{
|
||||
id: "gcc-readme",
|
||||
label: "README do projeto",
|
||||
url: "https://github.com/evandrodevbr/gcc-installer/blob/bab64fc5b5c20128e7b06e1afc448c5efe71b747/README.md",
|
||||
},
|
||||
{
|
||||
id: "gcc-main",
|
||||
label: "Aplicativo (main.py)",
|
||||
url: "https://github.com/evandrodevbr/gcc-installer/blob/bab64fc5b5c20128e7b06e1afc448c5efe71b747/main.py",
|
||||
},
|
||||
{
|
||||
id: "gcc-tests",
|
||||
label: "Testes do núcleo",
|
||||
url: "https://github.com/evandrodevbr/gcc-installer/blob/bab64fc5b5c20128e7b06e1afc448c5efe71b747/tests/test_core.py",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "as-servicos",
|
||||
title: "AS Serviços",
|
||||
subtitle: "Site institucional com cena 3D procedural",
|
||||
summary:
|
||||
"Site institucional em Next.js 16 com cena Three.js gerada em código: uma casa wireframe e uma placa-mãe ligadas ao progresso da rolagem.",
|
||||
"Site institucional em Next.js 16 que representa quatro frentes de engenharia com uma cena Three.js gerada em código: uma casa wireframe e uma placa-mãe ligadas ao progresso da rolagem.",
|
||||
impact:
|
||||
"Representar engenharia física e software na mesma narrativa visual sem depender de um modelo 3D pronto.",
|
||||
stack: ["Next.js 16", "Three.js", "TypeScript"],
|
||||
demoUrl: null,
|
||||
demoUrl: "https://asservicos.com",
|
||||
githubUrl: "https://github.com/evandrodevbr/as-servicos",
|
||||
role: "Desenvolvimento da primeira landing page do site, com animações 3D, e de um painel para controle de projetos.",
|
||||
detail: {
|
||||
answer: {
|
||||
text: "Site institucional em Next.js 16 com cena Three.js gerada em código: uma casa wireframe e uma placa-mãe ligadas ao progresso da rolagem.",
|
||||
text: "Site institucional em Next.js 16 que representa quatro frentes de engenharia com uma cena Three.js gerada em código: uma casa wireframe e uma placa-mãe ligadas ao progresso da rolagem.",
|
||||
sourceIds: ["as-readme", "as-package", "as-engine"],
|
||||
},
|
||||
challenge: {
|
||||
|
||||
@@ -2,9 +2,10 @@ export const CV_URL = "/Profile.pdf";
|
||||
export const CV_DOWNLOAD_NAME = "Evandro_Fonseca_Junior_CV.pdf";
|
||||
|
||||
export const NAVIGATION_ITEMS = [
|
||||
{ href: "/#modalities", label: "Soluções" },
|
||||
{ href: "/cases", label: "Projetos" },
|
||||
{ href: "/#process", label: "Como trabalho" },
|
||||
{ href: "/#home", label: "Home" },
|
||||
{ href: "/cases", label: "Casos" },
|
||||
{ href: "/servicos", label: "Serviços" },
|
||||
{ href: "/curriculo", label: "Currículo" },
|
||||
{ href: "/#about", label: "Sobre" },
|
||||
{ href: "/#experience", label: "Experiência" },
|
||||
{ href: "/#contact", label: "Contato" },
|
||||
] as const;
|
||||
Reference in new issue
Block a user