Hasta ahora la única forma de darle información a un agente era crawlear una
URL, una vez, para siempre. Tres cosas cambian:
Escribir a mano. Es la fuente más valiosa y la única que no está en ningún
documento: horarios, qué no hacen, la respuesta que dan quince veces por día.
También es la única que el dueño puede corregir en el momento en que ve al
agente contestar mal.
Subir un archivo. La lista de precios suele estar en un PDF, no en la web. Usa
el mismo extractor que los adjuntos de los canales, así que PDF, Word, texto e
imágenes entran sin código nuevo. El texto se extrae con la persona mirando la
pantalla: si el archivo no se puede leer, se dice ahí y no en un log.
Y lo importante: el conocimiento se congelaba el día que se cargaba. Si el
cliente cambiaba los precios en su sitio, el agente seguía dando los viejos con
total seguridad — sin error, sin aviso, nada. Ahora cada fuente muestra de
cuándo es ("leído hace 3 meses", en ámbar pasados dos meses), tiene botón de
actualizar, y las URLs pueden marcarse para releerse solas cada semana (cron a
las 4 AM). Reprocesar reemplaza los fragmentos en vez de sumarlos: si no,
quedaban las dos versiones compitiendo en la búsqueda y podía ganar la vieja.
De paso, el troceado dejaba fragmentos que arrancaban a mitad de palabra
("alabra…") porque el solape no se alineaba a un espacio.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Cuatro cosas que ya estaban a medio construir y no se usaban como canal.
1. El badge del widget ahora es un enlace con UTM. Cada cliente ya te
estaba dando exposición en su sitio y no se capitalizaba. El host sale
de la URL del propio script, así funciona igual en cualquier entorno.
2. Reporte del mes por agente en Excel: conversaciones atendidas, con qué
las abrió el visitante, y el consumo desglosado. Es lo que el cliente
necesita para justificar el gasto puertas adentro — un panel al que hay
que entrar no sirve para eso, un archivo que se reenvía sí. Reusa el
generador de xlsx del cronograma.
3. Aviso automático de agentes sin base de conocimiento (cron diario). Un
agente sin fuentes responde de memoria e inventa datos, el cliente
concluye que el producto no sirve y se va. Es el punto donde más gente
se cae y se detecta solo. Se avisa UNA vez por agente, usando el log de
auditoría como registro de envío para no necesitar tabla nueva ni
convertir el recordatorio en spam.
4. Tarjeta de uMind en el dashboard del portal: atajo si el cliente ya lo
tiene, oferta si no. Es el punto de contacto más barato que hay — ya
entró, ya confía, y el cobro se suma a la factura que ya recibe. El
mensaje lidera con notas de voz y fotos, que es lo más difícil de
copiar de lo que tenemos.
La consulta de conversaciones agrupa en SQL en vez de traerse el historial
entero para agrupar en Go.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Acá es donde uMind deja de ser una herramienta interna: el cliente entra
a /portal/studio con su sesión de portal y gestiona lo suyo.
- UmindScopePortal/UmindScopeStaff es el ÚNICO punto donde se decide el
alcance. El del cliente sale de GetClienteIDsForPortalUser, el mismo
que ya autoriza el resto del portal. nil = staff sin restricción,
slice vacío = no ve nada; una ruta sin scope también cae en "no ve
nada" para que olvidarse el middleware falle visible y no abra todo.
- Un solo set de handlers montado bajo /app/umind y /portal/umind
(RegistrarRutasUmind). Duplicarlos sería duplicar las chances de
olvidar un chequeo.
- Guarda de acceso en TODOS los handlers, incluidos los sub-recursos que
llegan por :id (documento, tool, canal, conexión): hay que cargarlos
para saber de quién son, si no un cliente podría borrar el canal de
otro adivinando el id. Responden 404, no 403: un 403 confirmaría que
el recurso existe.
- Cierra un bug preexistente: las lecturas GET /app/umind/* no tenían
SoloAdmin ni pasaban por MenuMiddleware, así que cualquier usuario de
staff podía leer los tenants de todos los clientes.
- Límite de agentes por plan (409 con mensaje claro). Un tenant sin plan
no tiene límite: cortarles de golpe sería peor que dejarlos como estaban.
- /umind/ai-configs reemplaza con alcance a /app/api/ai-config/select,
que devolvía TODAS las configs del sistema.
- El SPA deduce por la URL si es staff o cliente (base del router,
prefijo de API y URL de login) y oculta lo que es solo de staff.
- Test de aislamiento entre clientes: 7 casos, incluido que un scope
vacío no se confunda con staff.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>