feat(cases): mídia no topo, títulos de busca curtos e CreativeWork

Case com mídia ao lado do título e play acessível; problema de cada cliente reescrito com base nos dados; serviços relacionados em 2 cards; FAQ antes do próximo passo e bloco 'Onde já apliquei isso'; Apolo citada em IoT e arquitetura. metaTitle até 43 caracteres e descrições até 155 com teste; JSON-LD CreativeWork; imagens de compartilhamento abaixo de 100 KB; 404 e robots corrigidos; server-only nos módulos com node:.
This commit is contained in:
Evandro Fonseca Junior committed 2026-10-14 14:15:25 -03:00
1 parent c9a0b80656
commit e80f73d075
52 files changed
+2593 -439

No files matched your search

+36
View File
@@ -0,0 +1,36 @@
import { readFileSync } from "node:fs";
import { join } from "node:path";
const root = join(__dirname, "..");
describe("fronteira entre servidor e cliente", () => {
it.each([
"app/cases/_components/case-media.ts",
"lib/og-card.tsx",
"lib/portfolio-data.server.ts",
])("%s só pode ser importado no servidor", (file) => {
const source = readFileSync(join(root, file), "utf8");
expect(source).toMatch(/^import "server-only";$/m);
});
it("declara server-only como dependência", () => {
const manifest = JSON.parse(
readFileSync(join(root, "package.json"), "utf8"),
) as { dependencies: Record<string, string> };
expect(manifest.dependencies["server-only"]).toBeDefined();
});
it("não deixa nenhum componente de cliente importar um módulo só de servidor", () => {
const serverOnly =
/from "(?:@\/lib\/og-card|@\/lib\/portfolio-data\.server|(?:\.{1,2}\/)+(?:[\w-]+\/)*case-media)"/;
const clientFiles = [
"app/cases/_components/CasePlayer.tsx",
"app/curriculo/CvDownloadLink.tsx",
];
for (const file of clientFiles) {
const source = readFileSync(join(root, file), "utf8");
expect(source).toMatch(/^"use client";/);
expect(source).not.toMatch(serverOnly);
}
});
});