Corrige tablas faltantes en producción y bug de listado en Entidades

- AutoMigrate migraba ~50 modelos en un solo llamado que se detiene en
  el primer error, dejando todo lo posterior (plantillas_documento,
  tarifas, documentos_generados, arquitecturas, telegram_staff_tokens)
  sin tabla, en silencio. Ahora se migra modelo por modelo: uno roto
  ya no bloquea al resto.
- /app/contabilidad/entidades pedía datos a la misma URL de la página
  (devuelve HTML) en vez de /list (JSON) — el listado nunca traía nada.
- Mensaje de bienvenida del asistente: estaba generado por la IA cada
  vez con calidad variable; ahora es determinístico para /ayuda y
  /start, con redacción revisada, y el system prompt pide el mismo
  formato cuando el usuario solo saluda.
This commit is contained in:
Lizandro GD
2026-08-07 03:00:02 +00:00
parent 25cde836f1
commit 0eef3f80a3
4 changed files with 47 additions and 20 deletions
+12 -6
View File
@@ -61,8 +61,13 @@ func main() {
migrations.MigratePortal()
// Crear tabla de Landing Generator
migrations.MigrateLanding()
// Crear tablas de integraciones y pasarelas si no existen
if err := app.Http.Database.DB.AutoMigrate(
// Crear tablas de integraciones y pasarelas si no existen.
// AutoMigrate(a, b, c...) se detiene en el primer modelo que falle: todo lo
// que viene después en la lista se queda sin tabla, en silencio (fue la
// causa real de que plantillas_documento/tarifas desaparecieran de
// producción — un modelo antes en la lista falló y todo lo posterior no se
// llegó a crear). Migrando uno por uno, un modelo roto no bloquea al resto.
modelosBase := []interface{}{
// Tablas base del sistema (columnas nuevas)
&models.Users{},
&models.Roles{},
@@ -141,10 +146,11 @@ func main() {
&models.Arquitectura{},
// Vinculación de Telegram para staff interno
&models.TelegramStaffToken{},
); err != nil {
// AutoMigrate se detiene en el primer error: si esto falla, todos los
// modelos que venían después en la lista se quedan sin crear en silencio.
log.Printf("[MIGRATE] Error en AutoMigrate: %v", err)
}
for _, m := range modelosBase {
if err := app.Http.Database.DB.AutoMigrate(m); err != nil {
log.Printf("[MIGRATE] Error migrando %T: %v", m, err)
}
}
// Seed automático (idempotente) de módulos del sistema
migrations.SeedRenovaciones()
+10 -4
View File
@@ -25,8 +25,11 @@ type Session struct {
func Migrate() {
log.Println("Initiating migration...")
// Migrate the main application models
if err := app.Http.Database.DB.Migrator().AutoMigrate(
// Migrate the main application models.
// Un solo AutoMigrate(a, b, c...) se detiene en el primer modelo que falle:
// todo lo que viene después en la lista se queda sin tabla. Migrando uno por
// uno, un modelo roto no bloquea al resto (mismo fix que en main.go).
modelosPrincipales := []interface{}{
&models.Roles{},
&models.Users{},
&models.Modules{},
@@ -114,8 +117,11 @@ func Migrate() {
&models.Arquitectura{},
// Vinculación de Telegram para staff interno
&models.TelegramStaffToken{},
); err != nil {
log.Fatalf("Error during main migration: %v", err)
}
for _, m := range modelosPrincipales {
if err := app.Http.Database.DB.Migrator().AutoMigrate(m); err != nil {
log.Printf("[MIGRATE] Error migrando %T: %v", m, err)
}
}
// Open (or create) a SQLite database for sessions
+24 -9
View File
@@ -1505,6 +1505,7 @@ COMPORTAMIENTO:
- Para listar datos, muestra los más relevantes en formato legible
- Los valores monetarios son en COP (pesos colombianos)
- Si una herramienta falla, explica el error y sugiere alternativas
- Si el usuario solo saluda o pregunta qué puedes hacer (sin pedir una acción concreta), responde igual que el comando /ayuda: breve, organizado por categoría, sin inventar capacidades que no tienes
- En Coolify: si solo hay una instancia activa se usa automáticamente, no hace falta preguntar por config_id; si hay varias, consulta coolify_instancias y pregunta cuál. Para actuar sobre algo necesitas su UUID: búscalo con coolify_listar por nombre antes de llamar a coolify_accion. Reiniciar/desplegar es rutinario, hazlo directo; detener algo en producción sí confírmalo antes. Si un despliegue falla, revisa coolify_logs y coolify_deployments para explicar la causa concreta
- Cuando el mensaje empiece con "[Documento adjunto recibido: ...]", el usuario acaba de enviar un archivo por Telegram (puede ser cualquier formato: PDF, foto, Word, Excel, etc.). Si es PDF o foto, viene adjunto a este mismo mensaje y puedes leerlo directamente. Si es otro formato (Word, Excel, zip, etc.) no puedes ver su contenido, solo el nombre — de todas formas guárdalo con la herramienta que corresponda usando lo que el usuario haya escrito como contexto, no rechaces el archivo por el formato. Decide primero de qué se trata el archivo antes de guardarlo:
· Si es una factura → primero determina la dirección leyendo quién emite y quién recibe: si el emisor/vendedor es "U-Site S.A.S BIC" (o similar) y el destinatario es un cliente, es una factura de VENTA → identifica cliente, monto y número, resuelve el cliente_id con listar_clientes, y llama a adjuntar_factura. Si es al revés — un proveedor (AWS, Coolify, un hosting, cualquier tercero) le está facturando A U-Site — es una factura de COMPRA → llama a adjuntar_factura_compra con el nombre de ese proveedor, no busques cliente_id. Ante la duda, mira a nombre de quién sale la plata: si U-Site cobra, es venta; si U-Site paga, es compra
@@ -1532,21 +1533,35 @@ func ProcessAgentMessage(chatID int64, userText string, ai *models.AiConfig) (st
}
return "Historial borrado. ¿En qué puedo ayudarte?", nil
case "/ayuda", "/start":
return `Soy el agente administrador de U-Site. Puedo ayudarte con:
return `¡Hola! 👋 Soy el asistente de administración de U-Site S.A.S BIC. Esto es lo que puedo hacer por ti:
Clientes y contratos
• Contabilidad (ingresos, egresos, cuentas por cobrar/pagar)
• Proyectos y tickets
• Tareas del equipo
• Deploy y gestión de apps en Coolify
• Monitoreo de servidores y URLs
Clientes y facturación
Listar y crear clientes · facturas de venta y compra · cuentas por cobrar y pagar
Escríbeme en lenguaje natural, por ejemplo:
✅ Contratos y cotizaciones
Crear, renovar y gestionar contratos · generar cotizaciones y propuestas técnicas
✅ Proyectos y soporte
Crear proyectos y fases · gestionar tickets · adjuntar documentos (PDF, fotos, Word, Excel, etc.)
✅ Tareas del equipo
Crear y asignar tareas · ver el tablero Kanban
✅ Coolify (deploy y control)
Listar apps, servicios y bases de datos · deploy, reinicio y detención · logs y despliegues
✅ Contabilidad
Dashboard de ingresos/egresos · transacciones · tarifas
✅ Monitoreo
Servidores y URLs vigiladas
¿Qué necesitas? Escríbeme en lenguaje natural, por ejemplo:
"muéstrame los clientes de esta semana"
"haz deploy de la app abc123 en coolify 1"
"¿cuánto ingresamos este mes?"
Comandos: /reset /instancias /ayuda`, nil
Comandos: /reset · /instancias · /ayuda`, nil
case "/instancias":
cfgs, err := models.GetAllCoolifyConfigs()
if err != nil {
+1 -1
View File
@@ -138,7 +138,7 @@ function entidadesApp() {
async load(){
this.loading=true;
try {
const r=await axios.get(`/app/contabilidad/entidades?page=${this.page}&search=${encodeURIComponent(this.search)}`);
const r=await axios.get(`/app/contabilidad/entidades/list?page=${this.page}&search=${encodeURIComponent(this.search)}`);
this.items=r.data.items; this.total=r.data.total; this.totalPages=r.data.totalPages;
} finally{ this.loading=false; }
},