refactor(api): remove MCP marketplace cache integration
Removed dependencies on MCPCacheRepository and PulseMCPService from MCP routes to simplify installation and listing logic, avoiding reliance on potentially stale cached data and streamlining the codebase. Updated available-for-chat filter to include MCPs without explicit status.
This commit is contained in:
1 parent
4739a13458
commit
f96d4ed696
34 files changed
+260
-3775
No files matched your search
@@ -1,66 +0,0 @@
|
||||
import Database from "better-sqlite3";
|
||||
import path from "path";
|
||||
|
||||
const dbPath = path.join(process.cwd(), "database", "ollahub.db");
|
||||
const db = new Database(dbPath);
|
||||
|
||||
console.log("🔧 Adding FTS5 support to MCP cache...");
|
||||
|
||||
// Criar tabela FTS5
|
||||
db.exec(`
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS mcp_search_fts USING fts5(
|
||||
id UNINDEXED,
|
||||
content_name,
|
||||
description,
|
||||
content_tag_list,
|
||||
publisher_id,
|
||||
content=mcp_marketplace_cache,
|
||||
content_rowid=rowid
|
||||
);
|
||||
`);
|
||||
|
||||
// Popular com dados existentes
|
||||
console.log("📦 Populating FTS index...");
|
||||
db.exec(`
|
||||
INSERT INTO mcp_search_fts(rowid, id, content_name, description, content_tag_list, publisher_id)
|
||||
SELECT rowid, id, content_name, description, content_tag_list, publisher_id
|
||||
FROM mcp_marketplace_cache;
|
||||
`);
|
||||
|
||||
// Criar triggers
|
||||
console.log("⚡ Creating triggers...");
|
||||
db.exec(`
|
||||
CREATE TRIGGER IF NOT EXISTS mcp_fts_insert AFTER INSERT ON mcp_marketplace_cache BEGIN
|
||||
INSERT INTO mcp_search_fts(rowid, id, content_name, description, content_tag_list, publisher_id)
|
||||
VALUES (new.rowid, new.id, new.content_name, new.description, new.content_tag_list, new.publisher_id);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS mcp_fts_update AFTER UPDATE ON mcp_marketplace_cache BEGIN
|
||||
UPDATE mcp_search_fts
|
||||
SET content_name = new.content_name,
|
||||
description = new.description,
|
||||
content_tag_list = new.content_tag_list,
|
||||
publisher_id = new.publisher_id
|
||||
WHERE rowid = old.rowid;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS mcp_fts_delete AFTER DELETE ON mcp_marketplace_cache BEGIN
|
||||
DELETE FROM mcp_search_fts WHERE rowid = old.rowid;
|
||||
END;
|
||||
`);
|
||||
|
||||
// Criar índices compostos
|
||||
console.log("🔍 Creating composite indexes...");
|
||||
db.exec(`
|
||||
CREATE INDEX IF NOT EXISTS idx_mcp_cache_category_rating
|
||||
ON mcp_marketplace_cache(category, rating DESC);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_mcp_cache_subfield_rating
|
||||
ON mcp_marketplace_cache(subfield, rating DESC);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_mcp_cache_updated_rating
|
||||
ON mcp_marketplace_cache(updated_at DESC, rating DESC);
|
||||
`);
|
||||
|
||||
console.log("✅ FTS5 migration completed!");
|
||||
db.close();
|
||||
@@ -1,187 +0,0 @@
|
||||
import Database from "better-sqlite3";
|
||||
import path from "path";
|
||||
|
||||
const dbPath = path.join(process.cwd(), "database", "ollahub.db");
|
||||
const db = new Database(dbPath);
|
||||
|
||||
console.log("🚀 Benchmark de Performance - MCP Marketplace");
|
||||
console.log("=".repeat(50));
|
||||
|
||||
// Função para medir tempo de execução
|
||||
function measureTime<T>(name: string, fn: () => T): T {
|
||||
const start = performance.now();
|
||||
const result = fn();
|
||||
const end = performance.now();
|
||||
console.log(`⏱️ ${name}: ${(end - start).toFixed(2)}ms`);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Benchmark 1: Busca textual com FTS5
|
||||
console.log("\n📊 BENCHMARK 1: Busca Textual");
|
||||
console.log("-".repeat(30));
|
||||
|
||||
const searchTerms = ["context", "search", "browser", "map", "ai"];
|
||||
|
||||
searchTerms.forEach((term) => {
|
||||
// Busca com FTS5 (nova implementação)
|
||||
const ftsResults = measureTime(`FTS5 "${term}"`, () => {
|
||||
const stmt = db.prepare(`
|
||||
SELECT c.* FROM mcp_marketplace_cache c
|
||||
INNER JOIN mcp_search_fts f ON c.rowid = f.rowid
|
||||
WHERE mcp_search_fts MATCH ?
|
||||
ORDER BY f.rank, c.rating DESC
|
||||
LIMIT 50
|
||||
`);
|
||||
return stmt.all(`${term}*`);
|
||||
});
|
||||
|
||||
// Busca com LIKE (implementação antiga)
|
||||
const likeResults = measureTime(`LIKE "${term}"`, () => {
|
||||
const stmt = db.prepare(`
|
||||
SELECT * FROM mcp_marketplace_cache
|
||||
WHERE content_name LIKE ? OR description LIKE ? OR content_tag_list LIKE ?
|
||||
ORDER BY rating DESC
|
||||
LIMIT 50
|
||||
`);
|
||||
const searchPattern = `%${term}%`;
|
||||
return stmt.all(searchPattern, searchPattern, searchPattern);
|
||||
});
|
||||
|
||||
console.log(` 📈 Resultados FTS5: ${ftsResults.length}`);
|
||||
console.log(` 📈 Resultados LIKE: ${likeResults.length}`);
|
||||
});
|
||||
|
||||
// Benchmark 2: Queries com índices compostos
|
||||
console.log("\n📊 BENCHMARK 2: Queries com Índices Compostos");
|
||||
console.log("-".repeat(30));
|
||||
|
||||
const categories = ["search", "browser", "map", "ai"];
|
||||
|
||||
categories.forEach((category) => {
|
||||
// Query com índice composto (nova implementação)
|
||||
const indexedResults = measureTime(`Índice composto "${category}"`, () => {
|
||||
const stmt = db.prepare(`
|
||||
SELECT * FROM mcp_marketplace_cache
|
||||
WHERE category = ?
|
||||
ORDER BY rating DESC
|
||||
LIMIT 100
|
||||
`);
|
||||
return stmt.all(category);
|
||||
});
|
||||
|
||||
// Query sem índice composto (simulação)
|
||||
const nonIndexedResults = measureTime(`Sem índice "${category}"`, () => {
|
||||
const stmt = db.prepare(`
|
||||
SELECT * FROM mcp_marketplace_cache
|
||||
WHERE category = ?
|
||||
ORDER BY rating DESC
|
||||
LIMIT 100
|
||||
`);
|
||||
return stmt.all(category);
|
||||
});
|
||||
|
||||
console.log(` 📈 Resultados: ${indexedResults.length}`);
|
||||
});
|
||||
|
||||
// Benchmark 3: Contagem total
|
||||
console.log("\n📊 BENCHMARK 3: Operações de Contagem");
|
||||
console.log("-".repeat(30));
|
||||
|
||||
const totalCount = measureTime("Contagem total", () => {
|
||||
const stmt = db.prepare(
|
||||
"SELECT COUNT(*) as count FROM mcp_marketplace_cache"
|
||||
);
|
||||
return stmt.get() as { count: number };
|
||||
});
|
||||
|
||||
const categoryCount = measureTime("Contagem por categoria", () => {
|
||||
const stmt = db.prepare(`
|
||||
SELECT category, COUNT(*) as count
|
||||
FROM mcp_marketplace_cache
|
||||
GROUP BY category
|
||||
ORDER BY count DESC
|
||||
`);
|
||||
return stmt.all();
|
||||
});
|
||||
|
||||
console.log(` 📈 Total de MCPs: ${totalCount.count}`);
|
||||
console.log(` 📈 Categorias: ${categoryCount.length}`);
|
||||
|
||||
// Benchmark 4: Verificar índices criados
|
||||
console.log("\n📊 BENCHMARK 4: Verificação de Índices");
|
||||
console.log("-".repeat(30));
|
||||
|
||||
const indexes = measureTime("Listar índices", () => {
|
||||
const stmt = db.prepare(`
|
||||
SELECT name, sql FROM sqlite_master
|
||||
WHERE type = 'index' AND name LIKE '%mcp%'
|
||||
ORDER BY name
|
||||
`);
|
||||
return stmt.all();
|
||||
});
|
||||
|
||||
console.log(` 📈 Índices encontrados: ${indexes.length}`);
|
||||
indexes.forEach((idx: any) => {
|
||||
console.log(` - ${idx.name}`);
|
||||
});
|
||||
|
||||
// Benchmark 5: Verificar tabela FTS5
|
||||
console.log("\n📊 BENCHMARK 5: Verificação FTS5");
|
||||
console.log("-".repeat(30));
|
||||
|
||||
const ftsTables = measureTime("Verificar tabelas FTS5", () => {
|
||||
const stmt = db.prepare(`
|
||||
SELECT name FROM sqlite_master
|
||||
WHERE type = 'table' AND name LIKE '%fts%'
|
||||
`);
|
||||
return stmt.all();
|
||||
});
|
||||
|
||||
console.log(` 📈 Tabelas FTS5: ${ftsTables.length}`);
|
||||
ftsTables.forEach((table: any) => {
|
||||
console.log(` - ${table.name}`);
|
||||
});
|
||||
|
||||
// Benchmark 6: Teste de stress
|
||||
console.log("\n📊 BENCHMARK 6: Teste de Stress");
|
||||
console.log("-".repeat(30));
|
||||
|
||||
const stressTest = measureTime("100 buscas simultâneas", () => {
|
||||
const results = [];
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const term = `test${i % 10}`;
|
||||
const stmt = db.prepare(`
|
||||
SELECT c.* FROM mcp_marketplace_cache c
|
||||
INNER JOIN mcp_search_fts f ON c.rowid = f.rowid
|
||||
WHERE mcp_search_fts MATCH ?
|
||||
LIMIT 10
|
||||
`);
|
||||
results.push(stmt.all(`${term}*`));
|
||||
}
|
||||
return results;
|
||||
});
|
||||
|
||||
console.log(` 📈 Buscas executadas: ${stressTest.length}`);
|
||||
console.log(
|
||||
` 📈 Total de resultados: ${stressTest.reduce(
|
||||
(sum, r) => sum + r.length,
|
||||
0
|
||||
)}`
|
||||
);
|
||||
|
||||
// Resumo final
|
||||
console.log("\n🎯 RESUMO DOS GANHOS");
|
||||
console.log("=".repeat(50));
|
||||
console.log("✅ FTS5 Full-Text Search implementado");
|
||||
console.log("✅ Índices compostos criados");
|
||||
console.log("✅ React.memo aplicado aos cards");
|
||||
console.log("✅ useMemo para processamento de categorias");
|
||||
console.log("✅ Triggers automáticos para sincronização FTS5");
|
||||
console.log("\n📈 Ganhos esperados:");
|
||||
console.log(" - Busca textual: 10-100x mais rápida");
|
||||
console.log(" - Queries com categoria: 5-15x mais rápidas");
|
||||
console.log(" - Re-renders desnecessários: reduzidos em 80%");
|
||||
console.log(" - Processamento de categorias: otimizado");
|
||||
|
||||
db.close();
|
||||
console.log("\n✅ Benchmark concluído!");
|
||||
@@ -1,90 +0,0 @@
|
||||
#!/usr/bin/env tsx
|
||||
|
||||
import { MCPSyncService } from "../lib/services/mcp-sync";
|
||||
import { MCPCacheRepository } from "../database/repositories/mcp-cache";
|
||||
import { PulseMCPService } from "../lib/services/pulsemcp";
|
||||
|
||||
async function forcePulseMCPSync() {
|
||||
console.log("🔄 Forçando sincronização completa com PulseMCP...");
|
||||
|
||||
try {
|
||||
// 1. Verificar se PulseMCP API está funcionando
|
||||
console.log("🔍 Verificando conectividade com PulseMCP API...");
|
||||
const isHealthy = await PulseMCPService.checkHealth();
|
||||
|
||||
if (!isHealthy) {
|
||||
console.error("❌ PulseMCP API não está acessível");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("✅ PulseMCP API está funcionando");
|
||||
|
||||
// 2. Limpar cache antigo completamente
|
||||
console.log("🗑️ Limpando cache antigo do DeepNLP...");
|
||||
MCPCacheRepository.clearCache();
|
||||
console.log("✅ Cache antigo limpo");
|
||||
|
||||
// 3. Forçar sincronização completa
|
||||
console.log("📥 Iniciando download completo de servidores PulseMCP...");
|
||||
|
||||
const result = await MCPSyncService.syncAll((progress) => {
|
||||
const percentage =
|
||||
progress.total > 0
|
||||
? Math.round((progress.current / progress.total) * 100)
|
||||
: 0;
|
||||
console.log(
|
||||
`📊 Progresso: ${progress.current}/${progress.total} (${percentage}%) - Página ${progress.page}/${progress.totalPages}`
|
||||
);
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
console.log(`✅ Sincronização concluída com sucesso!`);
|
||||
console.log(`📊 Total de servidores baixados: ${result.totalDownloaded}`);
|
||||
console.log(`⏱️ Tempo total: ${Math.round(result.duration / 1000)}s`);
|
||||
|
||||
// 4. Verificar estatísticas do cache
|
||||
const stats = MCPCacheRepository.getStats();
|
||||
console.log(`📈 Estatísticas do cache:`);
|
||||
console.log(` - Total de itens: ${stats.totalItems}`);
|
||||
console.log(
|
||||
` - Última sincronização: ${
|
||||
stats.lastSync ? new Date(stats.lastSync).toLocaleString() : "Nunca"
|
||||
}`
|
||||
);
|
||||
console.log(` - Cache válido: ${stats.isValid ? "Sim" : "Não"}`);
|
||||
|
||||
// 5. Testar busca de alguns servidores
|
||||
console.log("🔍 Testando busca de servidores...");
|
||||
const sampleServers = MCPCacheRepository.search({ limit: 5 });
|
||||
console.log(
|
||||
`📋 Encontrados ${sampleServers.length} servidores no cache:`
|
||||
);
|
||||
|
||||
sampleServers.forEach((server, index) => {
|
||||
console.log(
|
||||
` ${index + 1}. ${server.content_name} (${server.category})`
|
||||
);
|
||||
});
|
||||
} else {
|
||||
console.error("❌ Sincronização falhou:");
|
||||
result.errors.forEach((error) => console.error(` - ${error}`));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("❌ Erro durante sincronização:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// Executar se chamado diretamente
|
||||
if (require.main === module) {
|
||||
forcePulseMCPSync()
|
||||
.then(() => {
|
||||
console.log("🎉 Script concluído");
|
||||
process.exit(0);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("💥 Erro fatal:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
export { forcePulseMCPSync };
|
||||
+1
-66
@@ -92,56 +92,7 @@ function runMigrations(db: Database.Database): void {
|
||||
console.log("✅ Migração 002_mcp_installations aplicada");
|
||||
}
|
||||
|
||||
// Aplicar migração para tabela MCP marketplace cache se não foi aplicada
|
||||
if (!appliedNames.has("003_mcp_marketplace_cache")) {
|
||||
console.log("📋 Aplicando migração: 003_mcp_marketplace_cache");
|
||||
|
||||
db.exec(`
|
||||
-- Tabela principal de cache
|
||||
CREATE TABLE IF NOT EXISTS mcp_marketplace_cache (
|
||||
id TEXT PRIMARY KEY,
|
||||
owner TEXT NOT NULL,
|
||||
repo TEXT NOT NULL,
|
||||
content_name TEXT NOT NULL,
|
||||
publisher_id TEXT NOT NULL,
|
||||
description TEXT,
|
||||
category TEXT,
|
||||
subfield TEXT,
|
||||
field TEXT,
|
||||
rating REAL DEFAULT 0,
|
||||
review_cnt INTEGER DEFAULT 0,
|
||||
content_tag_list TEXT,
|
||||
thumbnail_picture TEXT,
|
||||
website TEXT,
|
||||
detail_url TEXT,
|
||||
ext_info JSON,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Metadados
|
||||
CREATE TABLE IF NOT EXISTS mcp_cache_metadata (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Índices
|
||||
CREATE INDEX IF NOT EXISTS idx_mcp_cache_category ON mcp_marketplace_cache(category);
|
||||
CREATE INDEX IF NOT EXISTS idx_mcp_cache_subfield ON mcp_marketplace_cache(subfield);
|
||||
CREATE INDEX IF NOT EXISTS idx_mcp_cache_rating ON mcp_marketplace_cache(rating DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_mcp_cache_owner_repo ON mcp_marketplace_cache(owner, repo);
|
||||
CREATE INDEX IF NOT EXISTS idx_mcp_cache_search ON mcp_marketplace_cache(content_name, description);
|
||||
`);
|
||||
|
||||
// Registrar migração
|
||||
db.prepare("INSERT INTO _migrations (name, applied_at) VALUES (?, ?)").run(
|
||||
"003_mcp_marketplace_cache",
|
||||
Date.now()
|
||||
);
|
||||
|
||||
console.log("✅ Migração 003_mcp_marketplace_cache aplicada");
|
||||
}
|
||||
// Migração de marketplace removida
|
||||
|
||||
// Inicializar extensão vetorial se disponível
|
||||
try {
|
||||
@@ -231,22 +182,6 @@ if (require.main === module) {
|
||||
])
|
||||
.then(async () => {
|
||||
console.log("🎉 Inicialização concluída");
|
||||
|
||||
// Iniciar sincronização do marketplace se necessário
|
||||
try {
|
||||
const { MCPSyncService } = await import("@/lib/services/mcp-sync");
|
||||
const { MCPCacheRepository } = await import("@/database/repositories/mcp-cache");
|
||||
|
||||
if (MCPCacheRepository.needsSync()) {
|
||||
console.log("🔄 Iniciando sincronização inicial do marketplace...");
|
||||
MCPSyncService.backgroundSync();
|
||||
} else {
|
||||
console.log("✅ Cache do marketplace já está atualizado");
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("⚠️ Não foi possível inicializar sincronização do marketplace:", error);
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
})
|
||||
.catch((error) => {
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
#!/usr/bin/env tsx
|
||||
|
||||
async function testPulseMCPDirect() {
|
||||
console.log("🔍 Testando PulseMCP API diretamente...");
|
||||
|
||||
try {
|
||||
const url =
|
||||
"https://api.pulsemcp.com/v0beta/servers?count_per_page=5&offset=0";
|
||||
|
||||
console.log(`📡 Fazendo requisição para: ${url}`);
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
"User-Agent": "Ollahub-MCP-Client/1.0 (https://ollahub.com)",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
console.log(`📊 Status: ${response.status} ${response.statusText}`);
|
||||
console.log(`📋 Headers:`, Object.fromEntries(response.headers.entries()));
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error(`❌ Erro ${response.status}:`, errorText);
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log(`✅ Sucesso! Total de servidores: ${data.total_count}`);
|
||||
console.log(`📋 Primeiros 3 servidores:`);
|
||||
|
||||
data.servers.slice(0, 3).forEach((server: any, index: number) => {
|
||||
console.log(` ${index + 1}. ${server.name}`);
|
||||
console.log(` - Package: ${server.package_name || "N/A"}`);
|
||||
console.log(` - Registry: ${server.package_registry || "N/A"}`);
|
||||
console.log(` - Stars: ${server.github_stars || 0}`);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("❌ Erro na requisição:", error);
|
||||
}
|
||||
}
|
||||
|
||||
testPulseMCPDirect()
|
||||
.then(() => {
|
||||
console.log("🎉 Teste concluído");
|
||||
process.exit(0);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("💥 Erro fatal:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,87 +0,0 @@
|
||||
import { MCPCacheRepository } from "../database/repositories/mcp-cache";
|
||||
import { MCPSyncService } from "../lib/services/mcp-sync";
|
||||
import { PulseMCPService } from "../lib/services/pulsemcp";
|
||||
|
||||
async function testSimpleSync() {
|
||||
console.log("🔄 Testando sincronização simples com PulseMCP...");
|
||||
|
||||
try {
|
||||
// 1. Verificar se PulseMCP API está funcionando
|
||||
console.log("🔍 Verificando conectividade com PulseMCP API...");
|
||||
const isHealthy = await PulseMCPService.checkHealth();
|
||||
|
||||
if (!isHealthy) {
|
||||
console.error("❌ PulseMCP API não está acessível");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("✅ PulseMCP API está funcionando");
|
||||
|
||||
// 2. Limpar cache antigo
|
||||
console.log("🗑️ Limpando cache antigo...");
|
||||
MCPCacheRepository.clearCache();
|
||||
console.log("✅ Cache antigo limpo");
|
||||
|
||||
// 3. Testar chamada direta à API
|
||||
console.log("📡 Testando chamada direta à API PulseMCP...");
|
||||
const response = await PulseMCPService.getAllServers();
|
||||
console.log(
|
||||
`✅ API retornou ${response.servers.length} servidores (total: ${response.total_count})`
|
||||
);
|
||||
|
||||
// 4. Salvar alguns servidores no banco para teste
|
||||
console.log("💾 Salvando primeiros 10 servidores no banco...");
|
||||
const testBatch = response.servers.slice(0, 10);
|
||||
MCPCacheRepository.saveBatch(testBatch);
|
||||
console.log("✅ Servidores salvos no banco");
|
||||
|
||||
// 5. Verificar se foram salvos corretamente
|
||||
console.log("🔍 Verificando dados salvos...");
|
||||
const savedServers = MCPCacheRepository.search({ limit: 10 });
|
||||
console.log(`📋 Encontrados ${savedServers.length} servidores no banco:`);
|
||||
|
||||
savedServers.forEach((server, index) => {
|
||||
console.log(
|
||||
` ${index + 1}. ${server.content_name} (${server.category})`
|
||||
);
|
||||
});
|
||||
|
||||
// 6. Testar sincronização completa
|
||||
console.log("🚀 Iniciando sincronização completa...");
|
||||
const result = await MCPSyncService.syncAll((progress) => {
|
||||
const percentage =
|
||||
progress.total > 0
|
||||
? Math.round((progress.current / progress.total) * 100)
|
||||
: 0;
|
||||
console.log(
|
||||
`📊 Progresso: ${progress.current}/${progress.total} (${percentage}%)`
|
||||
);
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
console.log(`✅ Sincronização concluída com sucesso!`);
|
||||
console.log(`📊 Total de servidores baixados: ${result.totalDownloaded}`);
|
||||
console.log(`⏱️ Tempo total: ${Math.round(result.duration / 1000)}s`);
|
||||
|
||||
// 7. Verificar estatísticas finais
|
||||
const stats = MCPCacheRepository.getStats();
|
||||
console.log(`📈 Estatísticas finais do cache:`);
|
||||
console.log(` - Total de itens: ${stats.totalItems}`);
|
||||
console.log(
|
||||
` - Última sincronização: ${
|
||||
stats.lastSync ? new Date(stats.lastSync).toLocaleString() : "Nunca"
|
||||
}`
|
||||
);
|
||||
console.log(` - Cache válido: ${stats.isValid ? "Sim" : "Não"}`);
|
||||
} else {
|
||||
console.error("❌ Sincronização falhou:");
|
||||
result.errors.forEach((error) => console.error(` - ${error}`));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("❌ Erro durante teste:", error);
|
||||
}
|
||||
}
|
||||
|
||||
testSimpleSync();
|
||||
|
||||
export { testSimpleSync };
|
||||
Reference in new issue
Block a user