Initial commit: LexMind - Plataforma Jurídica Inteligente

This commit is contained in:
bigtux
2026-02-10 15:46:26 -03:00
commit 08bd4f039d
108 changed files with 75782 additions and 0 deletions

View File

@@ -0,0 +1,169 @@
#!/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)
})