170 lines
4.9 KiB
TypeScript
170 lines
4.9 KiB
TypeScript
#!/usr/bin/env npx ts-node
|
||
|
||
/**
|
||
* Script de Busca Diária de Publicações
|
||
*
|
||
* Executa busca de publicações em todos os processos ativos de todos os usuários.
|
||
* Pode ser executado via cron ou manualmente.
|
||
*
|
||
* Uso: npx ts-node scripts/buscar-publicacoes.ts
|
||
* Ou: node dist/scripts/buscar-publicacoes.js (se compilado)
|
||
*/
|
||
|
||
import { PrismaClient } from '@prisma/client'
|
||
import { buscarPublicacoesReais, buscarPublicacoesEmLote, PublicacaoEncontrada } from '../src/lib/diarios-service'
|
||
|
||
const prisma = new PrismaClient()
|
||
|
||
interface BuscaStats {
|
||
totalProcessos: number
|
||
processosComNovas: number
|
||
totalPublicacoes: number
|
||
erros: string[]
|
||
inicioEm: Date
|
||
fimEm?: Date
|
||
}
|
||
|
||
async function buscarPublicacoesDiarias(): Promise<BuscaStats> {
|
||
const stats: BuscaStats = {
|
||
totalProcessos: 0,
|
||
processosComNovas: 0,
|
||
totalPublicacoes: 0,
|
||
erros: [],
|
||
inicioEm: new Date(),
|
||
}
|
||
|
||
console.log('='.repeat(60))
|
||
console.log(`[${new Date().toISOString()}] Iniciando busca diária de publicações`)
|
||
console.log('='.repeat(60))
|
||
|
||
try {
|
||
// Busca todos os processos ativos
|
||
const processos = await prisma.processoMonitorado.findMany({
|
||
where: { status: 'ATIVO' },
|
||
select: {
|
||
id: true,
|
||
numeroProcesso: true,
|
||
tribunal: true,
|
||
userId: true,
|
||
user: {
|
||
select: { email: true }
|
||
}
|
||
},
|
||
})
|
||
|
||
stats.totalProcessos = processos.length
|
||
console.log(`\n📋 Total de processos ativos: ${processos.length}`)
|
||
|
||
if (processos.length === 0) {
|
||
console.log('Nenhum processo ativo encontrado.')
|
||
return stats
|
||
}
|
||
|
||
// Busca publicações em lote com rate limiting (500ms entre requisições)
|
||
console.log('\n🔍 Buscando publicações nos diários oficiais...\n')
|
||
|
||
const resultados = await buscarPublicacoesEmLote(
|
||
processos.map(p => ({
|
||
id: p.id,
|
||
numeroProcesso: p.numeroProcesso,
|
||
tribunal: p.tribunal,
|
||
})),
|
||
500 // delay entre requisições
|
||
)
|
||
|
||
// Processa resultados
|
||
for (const processo of processos) {
|
||
const resultado = resultados.get(processo.id)
|
||
|
||
if (!resultado) {
|
||
stats.erros.push(`${processo.numeroProcesso}: Sem resultado`)
|
||
continue
|
||
}
|
||
|
||
if (!resultado.sucesso) {
|
||
stats.erros.push(`${processo.numeroProcesso}: ${resultado.erro}`)
|
||
continue
|
||
}
|
||
|
||
let novasDoProcesso = 0
|
||
|
||
for (const pub of resultado.publicacoes) {
|
||
// Verifica duplicata
|
||
const existing = await prisma.publicacao.findFirst({
|
||
where: {
|
||
processoId: processo.id,
|
||
dataPublicacao: {
|
||
gte: new Date(pub.dataPublicacao.toDateString()),
|
||
lt: new Date(new Date(pub.dataPublicacao).setDate(pub.dataPublicacao.getDate() + 1)),
|
||
},
|
||
tipo: pub.tipo,
|
||
},
|
||
})
|
||
|
||
if (!existing) {
|
||
await prisma.publicacao.create({
|
||
data: {
|
||
processoId: processo.id,
|
||
dataPublicacao: pub.dataPublicacao,
|
||
diario: pub.diario,
|
||
conteudo: pub.conteudo,
|
||
tipo: pub.tipo,
|
||
prazoCalculado: pub.prazoCalculado,
|
||
prazoTipo: pub.prazoTipo,
|
||
visualizado: false,
|
||
},
|
||
})
|
||
novasDoProcesso++
|
||
stats.totalPublicacoes++
|
||
}
|
||
}
|
||
|
||
if (novasDoProcesso > 0) {
|
||
stats.processosComNovas++
|
||
console.log(` ✅ ${processo.numeroProcesso}: ${novasDoProcesso} nova(s) publicação(ões)`)
|
||
} else {
|
||
console.log(` ➖ ${processo.numeroProcesso}: sem novas publicações`)
|
||
}
|
||
}
|
||
|
||
} catch (error) {
|
||
const msg = error instanceof Error ? error.message : 'Erro desconhecido'
|
||
stats.erros.push(`Erro geral: ${msg}`)
|
||
console.error('\n❌ Erro durante execução:', error)
|
||
} finally {
|
||
await prisma.$disconnect()
|
||
}
|
||
|
||
stats.fimEm = new Date()
|
||
|
||
// Resumo final
|
||
console.log('\n' + '='.repeat(60))
|
||
console.log('📊 RESUMO DA BUSCA')
|
||
console.log('='.repeat(60))
|
||
console.log(`Processos verificados: ${stats.totalProcessos}`)
|
||
console.log(`Processos com novas publicações: ${stats.processosComNovas}`)
|
||
console.log(`Total de novas publicações: ${stats.totalPublicacoes}`)
|
||
console.log(`Erros: ${stats.erros.length}`)
|
||
|
||
if (stats.erros.length > 0) {
|
||
console.log('\n⚠️ Erros encontrados:')
|
||
stats.erros.forEach(e => console.log(` - ${e}`))
|
||
}
|
||
|
||
const duracao = ((stats.fimEm.getTime() - stats.inicioEm.getTime()) / 1000).toFixed(1)
|
||
console.log(`\n⏱️ Tempo de execução: ${duracao}s`)
|
||
console.log(`[${stats.fimEm.toISOString()}] Busca finalizada\n`)
|
||
|
||
return stats
|
||
}
|
||
|
||
// Executar
|
||
buscarPublicacoesDiarias()
|
||
.then(stats => {
|
||
process.exit(stats.erros.length > 0 ? 1 : 0)
|
||
})
|
||
.catch(error => {
|
||
console.error('Erro fatal:', error)
|
||
process.exit(1)
|
||
})
|