feat(cases): Reddit Posts Explorer e MinGW GCC Installer com resposta, desafio, implementacao, limites e fontes fixadas em commit
- textos reescritos a partir do codigo e do README dos repositorios publicos (SHA ff76e08 e bab64fc); remove afirmacoes que o codigo nao sustenta (SSG, rate limiting/cache, busca em tempo real, download assincrono, monitoramento) - public/portfolio-data.json alinhado (descricao, tecnologias, recursos e selos) - testes: cinco cases detalhados, limite sourced + escopo editorial, guardas contra afirmacoes sem fonte Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
1 parent
2c032b68af
commit
02ecba73f8
5 files changed
+173
-50
No files matched your search
@@ -209,7 +209,7 @@ it("renders the authorized detailed case in order with traceable sources", async
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("keeps the fallback concise and links its declared services", async () => {
|
it("keeps the fallback concise and links its declared services", async () => {
|
||||||
const caseStudy = getCase("gcc-installer");
|
const caseStudy = getCase("sc-plus");
|
||||||
expect(caseStudy.detail).toBeUndefined();
|
expect(caseStudy.detail).toBeUndefined();
|
||||||
const ui = await CasePage({
|
const ui = await CasePage({
|
||||||
params: Promise.resolve({ slug: caseStudy.id }),
|
params: Promise.resolve({ slug: caseStudy.id }),
|
||||||
@@ -222,7 +222,9 @@ it("keeps the fallback concise and links its declared services", async () => {
|
|||||||
for (const technology of caseStudy.stack) {
|
for (const technology of caseStudy.stack) {
|
||||||
expect(screen.getByText(technology)).toBeVisible();
|
expect(screen.getByText(technology)).toBeVisible();
|
||||||
}
|
}
|
||||||
expect(screen.queryByRole("link", { name: "Abrir demonstração" })).toBeNull();
|
expect(
|
||||||
|
screen.getByRole("link", { name: "Abrir demonstração" }),
|
||||||
|
).toHaveAttribute("href", caseStudy.demoUrl);
|
||||||
expect(screen.getByRole("link", { name: "Ver código" })).toHaveAttribute(
|
expect(screen.getByRole("link", { name: "Ver código" })).toHaveAttribute(
|
||||||
"href",
|
"href",
|
||||||
caseStudy.githubUrl,
|
caseStudy.githubUrl,
|
||||||
|
|||||||
@@ -86,6 +86,20 @@ describe("factual portfolio records", () => {
|
|||||||
/produç|clientes?|leads?|ranking|performance|resultado comercial|anime\.js|shadcn/i,
|
/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 publish the unavailable Twins Lab demo", () => {
|
it("does not publish the unavailable Twins Lab demo", () => {
|
||||||
expect(
|
expect(
|
||||||
portfolio.projects.find((item) => item.id === "twins-lab")?.demoUrl,
|
portfolio.projects.find((item) => item.id === "twins-lab")?.demoUrl,
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
import { caseStudies, getRelatedServices, servicePages } from "./site-content";
|
import { caseStudies, getRelatedServices, servicePages } from "./site-content";
|
||||||
|
|
||||||
const detailedIds = ["as-servicos", "nutriscan", "twins-lab"] as const;
|
const detailedIds = [
|
||||||
|
"as-servicos",
|
||||||
|
"gcc-installer",
|
||||||
|
"nutriscan",
|
||||||
|
"reddit-explorer",
|
||||||
|
"twins-lab",
|
||||||
|
] as const;
|
||||||
const immutableGitHubBlobUrl =
|
const immutableGitHubBlobUrl =
|
||||||
/^https:\/\/github\.com\/[^/]+\/[^/]+\/blob\/[0-9a-f]{40}\/.+$/;
|
/^https:\/\/github\.com\/[^/]+\/[^/]+\/blob\/[0-9a-f]{40}\/.+$/;
|
||||||
|
|
||||||
@@ -11,7 +17,7 @@ function getDetail(id: (typeof detailedIds)[number]) {
|
|||||||
return detail;
|
return detail;
|
||||||
}
|
}
|
||||||
|
|
||||||
it("limits detailed content to the three evidenced cases", () => {
|
it("limits detailed content to the evidenced cases (public repositories pinned to a commit)", () => {
|
||||||
expect(
|
expect(
|
||||||
caseStudies
|
caseStudies
|
||||||
.filter(({ detail }) => detail !== undefined)
|
.filter(({ detail }) => detail !== undefined)
|
||||||
@@ -64,6 +70,13 @@ it("requires sources for factual statements and resolves every source ID", () =>
|
|||||||
expect(getDetail("nutriscan").boundaries[0]?.sourceIds).toContain(
|
expect(getDetail("nutriscan").boundaries[0]?.sourceIds).toContain(
|
||||||
"nutri-readme",
|
"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", () => {
|
it("derives the exact related service set from the existing relationship", () => {
|
||||||
|
|||||||
+120
-9
@@ -620,13 +620,74 @@ export const caseStudies: CaseStudyContent[] = [
|
|||||||
{
|
{
|
||||||
id: "reddit-explorer",
|
id: "reddit-explorer",
|
||||||
title: "Reddit Posts Explorer",
|
title: "Reddit Posts Explorer",
|
||||||
subtitle: "Aplicação orientada a dados com API, cache e busca",
|
subtitle: "Posts do r/artificial em MongoDB, filtrados por período",
|
||||||
summary:
|
summary:
|
||||||
"Projeto em Astro e MongoDB para explorar conteúdo com filtros, ordenação e cache, mantendo boa experiência em consultas frequentes.",
|
"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.",
|
||||||
impact:
|
impact:
|
||||||
"Mostra capacidade de desenhar consumo de API, camada de persistência e experiência de busca sem sobrecarregar a aplicação.",
|
"Atualizar a coleta sem duplicar posts e consultar o histórico por intervalo de datas e ordenação.",
|
||||||
stack: ["Astro.js", "MongoDB", "Mongoose", "TypeScript", "Reddit API"],
|
stack: ["Astro", "MongoDB", "Mongoose", "TypeScript", "Reddit API"],
|
||||||
githubUrl: "https://github.com/evandrodevbr/reddit-search",
|
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",
|
id: "sc-plus",
|
||||||
@@ -643,14 +704,64 @@ export const caseStudies: CaseStudyContent[] = [
|
|||||||
{
|
{
|
||||||
id: "gcc-installer",
|
id: "gcc-installer",
|
||||||
title: "MinGW GCC Installer",
|
title: "MinGW GCC Installer",
|
||||||
subtitle:
|
subtitle: "Instalador gráfico de MinGW-w64/GCC para Windows",
|
||||||
"Ferramenta desktop para automação de ambiente de desenvolvimento",
|
|
||||||
summary:
|
summary:
|
||||||
"Aplicação em Python para simplificar setup local no Windows, com download assíncrono, checagem de compatibilidade e integração com PATH.",
|
"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.",
|
||||||
impact:
|
impact:
|
||||||
"Mostra familiaridade com software desktop, integração com sistema operacional e automação de setup técnico.",
|
"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", "Threading", "7-Zip"],
|
stack: ["Python", "Tkinter", "Win32 API", "GitHub API", "7-Zip"],
|
||||||
githubUrl: "https://github.com/evandrodevbr/gcc-installer",
|
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",
|
id: "as-servicos",
|
||||||
|
|||||||
+20
-37
@@ -152,31 +152,23 @@
|
|||||||
{
|
{
|
||||||
"id": "reddit-explorer",
|
"id": "reddit-explorer",
|
||||||
"title": "Reddit Posts Explorer",
|
"title": "Reddit Posts Explorer",
|
||||||
"subtitle": "Análise de Conteúdo IA",
|
"subtitle": "Posts do r/artificial em MongoDB, filtrados por período",
|
||||||
"description": "Aplicação Astro.js com arquitetura SSG otimizada para consumo de Reddit API. Resolve problema de rate limiting através de cache estratégico em MongoDB com Mongoose. Sistema de filtragem por data e ordenação, API REST própria e busca em tempo real com otimização de queries.",
|
"description": "Aplicação Astro 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.",
|
||||||
"longDescription": "Aplicação web que consome a API do Reddit para buscar, filtrar e analisar posts relacionados à Inteligência Artificial, oferecendo interface intuitiva para descoberta de conteúdo relevante.",
|
"longDescription": "O serviço consulta r/artificial/hot.json e grava os posts em lote, atualizando os existentes em vez de duplicar. O endpoint de filtro valida as datas e o campo de ordenação. O projeto não tem paginação, busca textual, autenticação, testes automatizados nem CI.",
|
||||||
"technologies": [
|
"technologies": ["Astro", "MongoDB", "Mongoose", "TypeScript", "Reddit API"],
|
||||||
"Astro.js",
|
|
||||||
"MongoDB",
|
|
||||||
"Mongoose",
|
|
||||||
"TypeScript",
|
|
||||||
"TailwindCSS",
|
|
||||||
"Reddit API"
|
|
||||||
],
|
|
||||||
"features": [
|
"features": [
|
||||||
"Integração com Reddit API",
|
"Coleta dos posts em alta do r/artificial",
|
||||||
"Sistema de cache com MongoDB",
|
"Upsert por id no MongoDB",
|
||||||
"Filtragem por data e ordenação",
|
"Filtro por período",
|
||||||
"Interface responsiva",
|
"Ordenação por upvotes ou comentários",
|
||||||
"API REST própria",
|
"API própria com validação de parâmetros"
|
||||||
"Busca em tempo real"
|
|
||||||
],
|
],
|
||||||
"category": "api",
|
"category": "api",
|
||||||
"level": "pleno",
|
"level": "pleno",
|
||||||
"status": "Concluído",
|
"status": "Concluído",
|
||||||
"demoUrl": null,
|
"demoUrl": null,
|
||||||
"githubUrl": "https://github.com/evandrodevbr/reddit-search",
|
"githubUrl": "https://github.com/evandrodevbr/reddit-search",
|
||||||
"badges": ["API Integration", "MongoDB", "Real-time"],
|
"badges": ["API Integration", "MongoDB", "Código público"],
|
||||||
"featured": true,
|
"featured": true,
|
||||||
"metrics": {
|
"metrics": {
|
||||||
"complexity": 3,
|
"complexity": 3,
|
||||||
@@ -217,32 +209,23 @@
|
|||||||
{
|
{
|
||||||
"id": "gcc-installer",
|
"id": "gcc-installer",
|
||||||
"title": "MinGW GCC Installer",
|
"title": "MinGW GCC Installer",
|
||||||
"subtitle": "Ferramenta de Desenvolvimento",
|
"subtitle": "Instalador gráfico de MinGW-w64/GCC para Windows",
|
||||||
"description": "Aplicação desktop Python com Tkinter para automação de setup de ambiente GCC no Windows. Resolve problema de configuração manual complexa através de download assíncrono com threading, verificação de compatibilidade via Win32 API e integração automática com PATH do sistema. Utiliza 7-Zip para extração e Watchdog para monitoramento.",
|
"description": "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.",
|
||||||
"longDescription": "Ferramenta automatizada que simplifica drasticamente o processo de configuração de ambiente de desenvolvimento GCC no Windows, incluindo verificação de compatibilidade, download automático e integração com o sistema.",
|
"longDescription": "A lista de versões vem da API de releases do niXman/mingw-builds-binaries, com as builds ucrt e posix destacadas. A instalação extrai o pacote com o 7-Zip, move para C:\\mingw64 e renomeia mingw32-make.exe para make.exe. Funciona só no Windows e o caminho do 7-Zip é fixo.",
|
||||||
"technologies": [
|
"technologies": ["Python", "Tkinter", "Win32 API", "GitHub API", "7-Zip"],
|
||||||
"Python",
|
|
||||||
"Tkinter",
|
|
||||||
"Requests",
|
|
||||||
"Watchdog",
|
|
||||||
"Win32 API",
|
|
||||||
"7-Zip",
|
|
||||||
"Threading"
|
|
||||||
],
|
|
||||||
"features": [
|
"features": [
|
||||||
"Interface gráfica intuitiva",
|
"Lista as builds publicadas do MinGW-w64",
|
||||||
"Download assíncrono com progresso",
|
"Destaca builds ucrt e posix",
|
||||||
"Verificação de compatibilidade",
|
"Baixa e instala em C:\\mingw64",
|
||||||
"Integração automática com PATH",
|
"Adiciona o toolchain ao PATH do usuário",
|
||||||
"Monitoramento em tempo real",
|
"Testes do núcleo (23)"
|
||||||
"Instalação automática de dependências"
|
|
||||||
],
|
],
|
||||||
"category": "desktop",
|
"category": "desktop",
|
||||||
"level": "pleno",
|
"level": "pleno",
|
||||||
"status": "Concluído",
|
"status": "Concluído",
|
||||||
"demoUrl": null,
|
"demoUrl": null,
|
||||||
"githubUrl": "https://github.com/evandrodevbr/gcc-installer",
|
"githubUrl": "https://github.com/evandrodevbr/gcc-installer",
|
||||||
"badges": ["Desktop", "Automation", "System Integration"],
|
"badges": ["Desktop", "Windows", "Código público"],
|
||||||
"featured": true,
|
"featured": true,
|
||||||
"metrics": {
|
"metrics": {
|
||||||
"complexity": 4,
|
"complexity": 4,
|
||||||
|
|||||||
Reference in new issue
Block a user