feat(studio): la puesta en marcha guiada y una bandeja de conversaciones que informa
Dos mitades de la misma experiencia: el primer día y todos los días después. El primer día. Un agente recién creado mostraba tres avisos ámbar sueltos —"no atiende", "no sabe nada"— sin ningún orden: el dueño sabía que faltaban cosas pero no cuál iba primero. Ahora hay una guía de tres pasos (contale de tu negocio → hacele una pregunta → ponelo a atender) donde solo el siguiente paso pendiente se resalta, porque una guía donde todo grita a la vez no guía nada. Mientras falte algo, la guía reemplaza al estado — una sola voz por etapa; con los pasos hechos desaparece para siempre y el estado operativo toma su lugar. Todos los días. La bandeja de conversaciones mostraba el último mensaje de cada sesión —casi siempre la respuesta del bot, "¡Hola! ¿En qué te ayudo?" cincuenta veces— y el session_id crudo (tg:8812). Ahora cada conversación muestra lo que el visitante preguntó al abrir, que es el dato que le importa al dueño: qué le preguntan de verdad a su negocio. Con canal deducido del prefijo de la sesión (WhatsApp, Telegram, Tu web, Prueba), cantidad de mensajes, y fecha relativa. Las pruebas propias se separan detrás de un filtro: mezcladas inflan la lista y el dueño no distingue cuáles son clientes reales. El contador del estado cuenta solo las reales, por lo mismo — si arriba dice 4 y la lista muestra 3, el número parece roto. El hilo muestra la hora de cada mensaje, y el backend gana una consulta que agrupa por sesión con el primer mensaje del visitante en vez de mandar filas crudas; la vieja quedó sin usos y se fue. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
22158a10a7
commit
be01d95631
+30
-17
@@ -326,23 +326,6 @@ func GetUmindHistorial(agenteID uint, sessionID string, n int) ([]UmindMensaje,
|
||||
return items, err
|
||||
}
|
||||
|
||||
// GetUmindSesiones lista las sesiones de conversación recientes de un agente
|
||||
// (para el panel admin), con el último mensaje como resumen.
|
||||
func GetUmindSesiones(agenteID uint, limit int) ([]UmindMensaje, error) {
|
||||
var items []UmindMensaje
|
||||
err := app.Http.Database.DB.Raw(`
|
||||
SELECT * FROM (
|
||||
SELECT DISTINCT ON (session_id) *
|
||||
FROM umind_mensajes
|
||||
WHERE agente_id = ? AND deleted_at IS NULL
|
||||
ORDER BY session_id, created_at DESC
|
||||
) ultimos
|
||||
ORDER BY created_at DESC
|
||||
LIMIT ?
|
||||
`, agenteID, limit).Scan(&items).Error
|
||||
return items, err
|
||||
}
|
||||
|
||||
// SesionResumen es una conversación vista desde el reporte: cuándo empezó,
|
||||
// cuántos mensajes tuvo y con qué la abrió el visitante. El primer mensaje es
|
||||
// lo más útil del conjunto — muestra qué le preguntan de verdad al negocio.
|
||||
@@ -351,6 +334,36 @@ type SesionResumen struct {
|
||||
Inicio time.Time `json:"inicio"`
|
||||
Mensajes int64 `json:"mensajes"`
|
||||
PrimerMensaje string `json:"primer_mensaje"`
|
||||
// Ultimo es la última actividad: es lo que ordena la bandeja del panel.
|
||||
// El reporte mensual no lo usa (ordena por inicio) y ahí queda en cero.
|
||||
Ultimo time.Time `json:"ultimo"`
|
||||
}
|
||||
|
||||
// GetUmindSesionesPanel es la bandeja de conversaciones del panel: las más
|
||||
// recientes primero, con lo que el visitante preguntó al abrir — no con la
|
||||
// última respuesta del bot, que era lo que se mostraba antes y no decía nada
|
||||
// ("¡Hola! ¿En qué te ayudo?" cincuenta veces).
|
||||
func GetUmindSesionesPanel(agenteID uint, limit int) ([]SesionResumen, error) {
|
||||
var items []SesionResumen
|
||||
err := app.Http.Database.DB.Raw(`
|
||||
SELECT
|
||||
m.session_id,
|
||||
MIN(m.created_at) AS inicio,
|
||||
MAX(m.created_at) AS ultimo,
|
||||
COUNT(*) AS mensajes,
|
||||
COALESCE((
|
||||
SELECT p.content FROM umind_mensajes p
|
||||
WHERE p.session_id = m.session_id AND p.agente_id = m.agente_id
|
||||
AND p.role = 'user' AND p.deleted_at IS NULL
|
||||
ORDER BY p.created_at ASC LIMIT 1
|
||||
), '') AS primer_mensaje
|
||||
FROM umind_mensajes m
|
||||
WHERE m.agente_id = ? AND m.deleted_at IS NULL
|
||||
GROUP BY m.session_id, m.agente_id
|
||||
ORDER BY ultimo DESC
|
||||
LIMIT ?
|
||||
`, agenteID, limit).Scan(&items).Error
|
||||
return items, err
|
||||
}
|
||||
|
||||
// GetUmindSesionesRango agrupa los mensajes en conversaciones dentro de un
|
||||
|
||||
Reference in New Issue
Block a user