perf(logos): pré-resolver mapeamentos Logo.dev no servidor

Cada EstablishmentLogo dispara um GET para /api/logo/mapping por
nome único (deduplicado pelo React Query, mas ainda N requests por
página). Em /dashboard, /transactions e /payers/[payerId] agora
fazemos uma única query SQL em batch (fetchEstablishmentLogoMap) e
semeamos o cache do React Query antes do primeiro render via novo
LogoPrefetchProvider — eliminando os requests da rede.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Felipe Coutinho
2026-04-25 14:45:54 +00:00
parent 7f05d2a681
commit b453b432ed
8 changed files with 257 additions and 125 deletions

View File

@@ -0,0 +1,31 @@
import "server-only";
import { fetchEstablishmentLogoMap } from "./establishment-logo-queries";
import { toNameKey } from "./index";
import { buildLogoDevUrl } from "./server";
import type { LogoPrefetchEntry } from "./types";
export async function prefetchLogoMappings(
userId: string,
names: string[],
): Promise<LogoPrefetchEntry[]> {
const uniqueNames = [
...new Set(
names.filter((n) => typeof n === "string" && n.trim().length > 0),
),
];
if (uniqueNames.length === 0) return [];
const map = await fetchEstablishmentLogoMap(userId, uniqueNames);
const seen = new Set<string>();
const entries: LogoPrefetchEntry[] = [];
for (const name of uniqueNames) {
const nameKey = toNameKey(name);
if (seen.has(nameKey)) continue;
seen.add(nameKey);
const domain = map.get(nameKey) ?? null;
entries.push({ nameKey, domain, logoUrl: buildLogoDevUrl(domain) });
}
return entries;
}

View File

@@ -0,0 +1,5 @@
export type LogoPrefetchEntry = {
nameKey: string;
domain: string | null;
logoUrl: string | null;
};