feat(modo-local): CRM 100% local sin dependencia de Monday.com

Nuevas tablas:
- ActividadLocal (historial de llamadas, reuniones, tareas)
- AsignacionLocal (round-robin local)
- fechaLimite en LeadCaptura

Servicios nuevos:
- actividad-local.service.ts (CRUD actividades)
- local-canal.ts (canal de envío para recordatorios)
- seed-modo-local.js (activar modo local)

Mi día local mejorado:
- Mis actividades hoy (filtros usuario/fecha/estado)
- Apartados por vencer (con fechaLimite real)
- Equipo (contadores por vendedor, solo coordinador/admin)
- unidadCodigo en oportunidades desde datosJson

Automatizaciones locales:
- Round-robin: asigna leads sin vendedor + crea actividad
- Inactividad: detecta oportunidades >10 días sin update
- Escalado: alerta oportunidades >48h sin contacto

Reportes: actividadesAbiertas + parcial:false en modo local
Cron wiring: crons locales cuando Monday caído

661 tests verdes.
This commit is contained in:
2026-09-07 04:00:15 +00:00
parent aadbc6f83f
commit 388e1da338
16 changed files with 1604 additions and 37 deletions

View File

@@ -183,6 +183,8 @@ model LeadCaptura {
// Item de Monday una vez sincronizado (rows viejas: = leadId)
mondayItemId String?
// true = falta replicar a Monday (lo drena el sync worker)
// Fecha límite del apartado (para "Apartados por vencer" en Mi día)
fechaLimite DateTime?
pendienteSync Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt @default(now())
@@ -353,3 +355,35 @@ model AIMensaje {
@@index([conversacionId])
}
// ---------- Actividades locales (modo sin Monday) ----------
model ActividadLocal {
id String @id @default(uuid())
titulo String
descripcion String?
usuarioId String
leadCapturaId String?
fechaVencimiento DateTime?
fechaCierre DateTime?
estado String @default("ABIERTA") // ABIERTA | CERRADA
tipo String @default("SEGUIMIENTO") // SEGUIMIENTO | RECORDATORIO | REUNION
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([usuarioId])
@@index([estado])
@@index([fechaVencimiento])
}
// Asignaciones locales de leads (reemplaza round-robin de Monday)
model AsignacionLocal {
id String @id @default(uuid())
leadCapturaId String
usuarioId String
asignadoPor String? // round-robin | capturista | manual
createdAt DateTime @default(now())
@@unique([leadCapturaId])
@@index([usuarioId])
}