feat: log de auditoría técnica por agente
Nueva tabla umind_eventos_log + tab "Auditoría" en el panel: errores y eventos que hasta ahora solo se podían ver pidiendo los logs del servidor (fallos al llamar al AI, respuestas sin texto usable, tools/webhooks que fallan, tokens de correo que no se pueden refrescar, firmas de WhatsApp inválidas, errores procesando mensajes de Telegram/WhatsApp) quedan registrados por agente, visibles directo en el panel con el JSON crudo expandible para diagnosticar sin acceso al servidor. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
5febbd24d5
commit
997e3cc790
@@ -273,11 +273,33 @@ const tabs = [
|
||||
['conexiones', 'Conexiones'],
|
||||
['chat', 'Chat de prueba'],
|
||||
['conversaciones', 'Conversaciones'],
|
||||
['auditoria', 'Auditoría'],
|
||||
]
|
||||
|
||||
// ─── Auditoría ────────────────────────────────────────────────────────────────
|
||||
const eventos = ref([])
|
||||
|
||||
async function cargarEventos() {
|
||||
const r = await api.get(`/app/umind/eventos?agente_id=${props.agenteId}`)
|
||||
eventos.value = r.items || []
|
||||
}
|
||||
|
||||
const nivelColor = computed(() => (nivel) => ({
|
||||
error: 'bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-400',
|
||||
warn: 'bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-400',
|
||||
}[nivel] || 'bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400'))
|
||||
|
||||
function formatearFecha(iso) {
|
||||
try {
|
||||
return new Date(iso).toLocaleString()
|
||||
} catch {
|
||||
return iso
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
await Promise.all([cargarAgente(), cargarDocumentos(), cargarSesiones(), cargarTools(), cargarCanales(), cargarConexiones()])
|
||||
await Promise.all([cargarAgente(), cargarDocumentos(), cargarSesiones(), cargarTools(), cargarCanales(), cargarConexiones(), cargarEventos()])
|
||||
} catch (e) {
|
||||
error.value = e.message
|
||||
}
|
||||
@@ -583,7 +605,7 @@ onMounted(async () => {
|
||||
</div>
|
||||
|
||||
<!-- Conversaciones -->
|
||||
<div v-else class="grid grid-cols-3 gap-4">
|
||||
<div v-else-if="tab === 'conversaciones'" class="grid grid-cols-3 gap-4">
|
||||
<div class="col-span-1 bg-white dark:bg-gray-900 rounded-xl border border-gray-200 dark:border-gray-800 divide-y divide-gray-100 dark:divide-gray-800 max-h-[28rem] overflow-y-auto">
|
||||
<div v-if="sesiones.length === 0" class="p-4 text-sm text-gray-500 dark:text-gray-400">Sin conversaciones.</div>
|
||||
<button
|
||||
@@ -609,5 +631,24 @@ onMounted(async () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Auditoría -->
|
||||
<div v-else>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400 mb-4">
|
||||
Errores y eventos técnicos de este agente — fallos al llamar al AI, a tools, a correo o a los canales. Últimos 100.
|
||||
</p>
|
||||
<div class="bg-white dark:bg-gray-900 rounded-xl border border-gray-200 dark:border-gray-800 divide-y divide-gray-100 dark:divide-gray-800 max-h-[32rem] overflow-y-auto">
|
||||
<div v-if="eventos.length === 0" class="p-6 text-sm text-gray-500 dark:text-gray-400">Sin eventos registrados — buena señal.</div>
|
||||
<details v-for="e in eventos" :key="e.ID" class="p-3">
|
||||
<summary class="cursor-pointer flex items-center gap-2 text-sm">
|
||||
<span class="px-1.5 py-0.5 rounded text-xs shrink-0" :class="nivelColor(e.nivel)">{{ e.nivel }}</span>
|
||||
<span class="text-gray-400 dark:text-gray-500 text-xs shrink-0">{{ e.origen }}</span>
|
||||
<span class="text-gray-800 dark:text-gray-200 truncate">{{ e.mensaje }}</span>
|
||||
<span class="text-gray-400 dark:text-gray-500 text-xs ml-auto shrink-0">{{ formatearFecha(e.CreatedAt) }}</span>
|
||||
</summary>
|
||||
<pre v-if="e.detalle" class="mt-2 bg-gray-50 dark:bg-gray-950 border border-gray-200 dark:border-gray-800 rounded-lg p-2 text-xs text-gray-600 dark:text-gray-400 overflow-x-auto whitespace-pre-wrap">{{ e.detalle }}</pre>
|
||||
</details>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user