feat(studio): muestra el cupo de agentes del plan en pantalla

Se podían crear 2 agentes con un plan de 1 sin que nada lo explicara. El
límite del backend sí funciona, pero solo aplica si el tenant tiene un
plan asignado — y hasta 115f167 los campos Cliente y Plan no aparecían en
el formulario del tenant, así que en la práctica quedaban todos sin plan
y sin límite.

El problema de fondo era que ese estado no se veía por ningún lado: un
tenant sin plan se comportaba igual que un límite roto.

- La lista de agentes devuelve también el plan y cuántos hay usados.
- La pantalla muestra "Básico · 1 de 1", "Pro · ilimitado" o "sin plan ·
  sin límite", y en este último caso explica que hay que asignarle uno.
- El botón + Nuevo agente se deshabilita al llegar al tope, en vez de
  dejar que el límite aparezca recién como un error al guardar.

El backend sigue siendo la autoridad: esto es feedback, no la validación.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-08-14 22:05:32 -05:00
co-authored by Claude Sonnet 5
parent 5c931c9400
commit 45f773fb62
7 changed files with 73 additions and 32 deletions
+10 -1
View File
@@ -171,7 +171,16 @@ func GetUmindAgentesHandler(c *fiber.Ctx) error {
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"items": items})
// El cupo viaja con la lista para que la pantalla pueda mostrar "1 de 1"
// en vez de dejar que el límite aparezca recién como un error al guardar.
// Sin plan no hay límite (ver verificarCupoAgentes), y eso también hay que
// poder verlo: si no, un tenant sin plan parece un límite que no funciona.
resp := fiber.Map{"items": items, "usados": len(items)}
if plan := models.GetPlanDeTenant(uint(tenantID)); plan != nil {
resp["plan"] = fiber.Map{"nombre": plan.Nombre, "max_agentes": plan.MaxAgentes}
}
return c.JSON(resp)
}
type umindAgenteReq struct {