feat: implement market page with QueryProvider and dynamic listings

- wrap root layout with QueryProvider for React Query
- replace market UnderConstruction placeholder with MarketClient and real data fetching
- implement search, pagination, and sort via search params using getActiveListings
- add necessary client components and queries
- update dependencies (e.g., prisma, pkg-types)
This commit is contained in:
Evandro Fonseca Junior committed 2025-11-05 01:58:03 -03:00
1 parent 55eebde0ba
commit ab37b477df
106 files changed
+15261 -301

No files matched your search

@@ -0,0 +1,96 @@
/**
* Background Jobs para Telemetria
* Agregação de métricas e expiração de anúncios
*/
import { aggregateHourlyMetrics } from "@/lib/db/queries/telemetry";
import { query } from "@/lib/db/index";
import { secureLogger } from "@/lib/secure-logger";
/**
* Agrega eventos de telemetria em métricas
* Executar a cada 1 hora via cron ou scheduler
*/
export async function aggregateTelemetry(): Promise<void> {
try {
secureLogger.info("🔄 Iniciando agregação de telemetria...");
await aggregateHourlyMetrics();
secureLogger.info("✅ Agregação de telemetria concluída");
} catch (error) {
secureLogger.error("❌ Erro ao agregar telemetria", error);
throw error;
}
}
/**
* Expira anúncios antigos (30 dias)
* Executar diariamente
*/
export async function expireOldListings(): Promise<void> {
try {
secureLogger.info("🔄 Iniciando expiração de anúncios antigos...");
const result = await query(
`
UPDATE listings
SET listing_status = 'expired',
updated_at = CURRENT_TIMESTAMP
WHERE listing_status = 'active'
AND (
expires_at IS NOT NULL AND expires_at < CURRENT_TIMESTAMP
OR
(expires_at IS NULL AND created_at < CURRENT_TIMESTAMP - INTERVAL '30 days')
)
RETURNING listing_id
`,
[]
);
const expiredCount = result.rowCount || 0;
secureLogger.info(`✅ ${expiredCount} anúncios expirados`);
} catch (error) {
secureLogger.error("❌ Erro ao expirar anúncios", error);
throw error;
}
}
/**
* Atualiza histórico de preços quando mudar
* (Já implementado via trigger, mas pode ser chamado manualmente)
*/
export async function updatePriceHistory(): Promise<void> {
try {
secureLogger.info("🔄 Verificando histórico de preços...");
// O trigger já faz isso automaticamente, mas podemos adicionar lógica adicional aqui
// Por exemplo, verificar se há inconsistências ou limpar históricos muito antigos
secureLogger.info("✅ Histórico de preços verificado");
} catch (error) {
secureLogger.error("❌ Erro ao atualizar histórico de preços", error);
throw error;
}
}
/**
* Executa todos os background jobs
*/
export async function runBackgroundJobs(): Promise<void> {
try {
secureLogger.info("🚀 Iniciando background jobs...");
await Promise.all([
aggregateTelemetry(),
expireOldListings(),
updatePriceHistory(),
]);
secureLogger.info("✅ Todos os background jobs concluídos");
} catch (error) {
secureLogger.error("❌ Erro ao executar background jobs", error);
throw error;
}
}