Spaces:
Running
Running
| """Funciones de lógica de negocio""" | |
| import logging | |
| from datetime import datetime | |
| from connection import get_connection | |
| from models import RegistroRequest, RegistroResponse, ActionRequest | |
| # Configurar logging | |
| logger = logging.getLogger(__name__) | |
| def crear_registro(datos: RegistroRequest) -> dict: | |
| """ | |
| Crea un nuevo registro en la base de datos. | |
| Args: | |
| datos: Objeto RegistroRequest con los datos del usuario | |
| Returns: | |
| dict: Información del registro creado o error | |
| """ | |
| conn = get_connection() | |
| if not conn: | |
| logger.error("❌ No se pudo conectar a la base de datos") | |
| return { | |
| "success": False, | |
| "error": "No se pudo conectar a la base de datos" | |
| } | |
| try: | |
| logger.info(f"🔗 Conexión establecida a BD") | |
| # Preparar datos | |
| uid = datos.uid | |
| display_name = datos.display_name | |
| pais = datos.pais | |
| correo = datos.correo | |
| fecha_registro = datos.fecha_registro or datetime.now() | |
| usos = datos.usos or 0 | |
| prompt = datos.prompt | |
| prompt_type = datos.prompt_type | |
| prompt_eval = datos.prompt_eval | |
| estilo = datos.estilo | |
| estilo_agregado = datos.estilo_agregado | |
| calificacion = datos.calificacion | |
| proveedor = datos.proveedor | |
| seed = datos.seed | |
| logger.info(f"📊 Datos a insertar - UID: {uid}, Usuario: {display_name}, País: {pais}, Email: {correo}, Prompt: {prompt}, Tipo: {prompt_type}, Eval: {prompt_eval}, Estilo: {estilo}, Estilo Agregado: {estilo_agregado}, Calificación: {calificacion}, Proveedor: {proveedor}") | |
| # Insertar en la BD | |
| cursor = conn.cursor() | |
| sql = """ | |
| INSERT INTO `creacion` | |
| (uid, display_name, pais, correo, fecha_registro, usos, prompt, prompt_type, prompt_eval, estilo, estilo_agregado, calificacion, proveedor, seed) | |
| VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) | |
| """ | |
| valores = ( | |
| uid, display_name, pais, correo, fecha_registro, | |
| usos, prompt, prompt_type, prompt_eval, estilo, estilo_agregado, calificacion, proveedor, seed | |
| ) | |
| cursor.execute(sql, valores) | |
| conn.commit() | |
| logger.info(f"✅ Registro insertado en BD") | |
| # Obtener el ID del registro recién creado | |
| nuevo_id = cursor.lastrowid | |
| logger.info(f"🔑 ID generado: {nuevo_id}") | |
| # Recuperar el registro creado | |
| cursor.execute( | |
| """ | |
| SELECT id, uid, display_name, pais, correo, fecha_registro, | |
| usos, prompt, prompt_type, prompt_eval, estilo, estilo_agregado, calificacion, proveedor, seed, created_at | |
| FROM `creacion` | |
| WHERE id = %s | |
| """, | |
| (nuevo_id,) | |
| ) | |
| registro = cursor.fetchone() | |
| cursor.close() | |
| conn.close() | |
| if registro: | |
| logger.info(f"✅ Registro recuperado exitosamente - ID: {registro[0]}") | |
| return { | |
| "success": True, | |
| "data": { | |
| "id": registro[0], | |
| "uid": registro[1], | |
| "display_name": registro[2], | |
| "pais": registro[3], | |
| "correo": registro[4], | |
| "fecha_registro": registro[5], | |
| "usos": registro[6], | |
| "prompt": registro[7], | |
| "prompt_type": registro[8], | |
| "prompt_eval": registro[9], | |
| "estilo": registro[10], | |
| "estilo_agregado": registro[11], | |
| "calificacion": registro[12], | |
| "proveedor": registro[13], | |
| "seed": registro[14], | |
| "created_at": registro[15] | |
| } | |
| } | |
| else: | |
| logger.error("❌ No se pudo recuperar el registro creado") | |
| return { | |
| "success": False, | |
| "error": "No se pudo recuperar el registro creado" | |
| } | |
| except Exception as e: | |
| logger.error(f"❌ Error al crear registro: {str(e)}") | |
| return { | |
| "success": False, | |
| "error": f"Error al crear registro: {str(e)}" | |
| } | |
| def obtener_registros(limit: int = 10, offset: int = 0) -> dict: | |
| """ | |
| Obtiene registros de la base de datos con paginación. | |
| Args: | |
| limit: Cantidad máxima de registros | |
| offset: Desplazamiento para paginación | |
| Returns: | |
| dict: Lista de registros o error | |
| """ | |
| conn = get_connection() | |
| if not conn: | |
| logger.error("❌ No se pudo conectar a la base de datos") | |
| return { | |
| "success": False, | |
| "error": "No se pudo conectar a la base de datos" | |
| } | |
| try: | |
| logger.info(f"🔗 Obteniendo registros - Limit: {limit}, Offset: {offset}") | |
| cursor = conn.cursor() | |
| # Obtener total de registros | |
| cursor.execute("SELECT COUNT(*) FROM `creacion`") | |
| total = cursor.fetchone()[0] | |
| logger.info(f"📊 Total de registros en BD: {total}") | |
| # Obtener registros con paginación | |
| cursor.execute( | |
| """ | |
| SELECT id, uid, display_name, pais, correo, fecha_registro, | |
| usos, prompt, prompt_type, prompt_eval, estilo, estilo_agregado, calificacion, proveedor, seed, created_at | |
| FROM `creacion` | |
| ORDER BY created_at DESC | |
| LIMIT %s OFFSET %s | |
| """, | |
| (limit, offset) | |
| ) | |
| registros = cursor.fetchall() | |
| logger.info(f"✅ Se obtuvieron {len(registros)} registros de la BD") | |
| cursor.close() | |
| conn.close() | |
| # Convertir resultados | |
| datos = [] | |
| for reg in registros: | |
| datos.append({ | |
| "id": reg[0], | |
| "uid": reg[1], | |
| "display_name": reg[2], | |
| "pais": reg[3], | |
| "correo": reg[4], | |
| "fecha_registro": reg[5], | |
| "usos": reg[6], | |
| "prompt": reg[7], | |
| "prompt_type": reg[8], | |
| "prompt_eval": reg[9], | |
| "estilo": reg[10], | |
| "estilo_agregado": reg[11], | |
| "calificacion": reg[12], | |
| "proveedor": reg[13], | |
| "seed": reg[14], | |
| "created_at": reg[15] | |
| }) | |
| logger.info(f"📈 Retornando {len(datos)} registros") | |
| return { | |
| "success": True, | |
| "data": datos, | |
| "total": total, | |
| "limit": limit, | |
| "offset": offset | |
| } | |
| except Exception as e: | |
| logger.error(f"❌ Error al obtener registros: {str(e)}") | |
| return { | |
| "success": False, | |
| "error": f"Error al obtener registros: {str(e)}" | |
| } | |
| def actualizar_calificacion(id_registro: int, calificacion: int) -> dict: | |
| """ | |
| Actualiza la calificación de un registro existente. | |
| Args: | |
| id_registro: ID del registro a actualizar | |
| calificacion: Nueva calificación | |
| Returns: | |
| dict: Información del registro actualizado o error | |
| """ | |
| conn = get_connection() | |
| if not conn: | |
| logger.error("❌ No se pudo conectar a la base de datos") | |
| return { | |
| "success": False, | |
| "error": "No se pudo conectar a la base de datos" | |
| } | |
| try: | |
| logger.info(f"🔗 Actualizando calificación - ID: {id_registro}, Calificación: {calificacion}") | |
| cursor = conn.cursor() | |
| # Actualizar la calificación | |
| cursor.execute( | |
| "UPDATE `creacion` SET calificacion = %s WHERE id = %s", | |
| (calificacion, id_registro) | |
| ) | |
| conn.commit() | |
| if cursor.rowcount == 0: | |
| logger.error(f"❌ No se encontró registro con ID: {id_registro}") | |
| cursor.close() | |
| conn.close() | |
| return { | |
| "success": False, | |
| "error": f"No se encontró registro con ID: {id_registro}" | |
| } | |
| logger.info(f"✅ Calificación actualizada para ID: {id_registro}") | |
| # Recuperar el registro actualizado | |
| cursor.execute( | |
| """ | |
| SELECT id, uid, display_name, pais, correo, fecha_registro, | |
| usos, prompt, prompt_type, prompt_eval, estilo, estilo_agregado, calificacion, proveedor, seed, created_at | |
| FROM `creacion` | |
| WHERE id = %s | |
| """, | |
| (id_registro,) | |
| ) | |
| registro = cursor.fetchone() | |
| cursor.close() | |
| conn.close() | |
| if registro: | |
| logger.info(f"✅ Registro recuperado - ID: {registro[0]}") | |
| return { | |
| "success": True, | |
| "data": { | |
| "id": registro[0], | |
| "uid": registro[1], | |
| "display_name": registro[2], | |
| "pais": registro[3], | |
| "correo": registro[4], | |
| "fecha_registro": registro[5], | |
| "usos": registro[6], | |
| "prompt": registro[7], | |
| "prompt_type": registro[8], | |
| "prompt_eval": registro[9], | |
| "estilo": registro[10], | |
| "estilo_agregado": registro[11], | |
| "calificacion": registro[12], | |
| "proveedor": registro[13], | |
| "seed": registro[14], | |
| "created_at": registro[15] | |
| } | |
| } | |
| else: | |
| logger.error("❌ No se pudo recuperar el registro actualizado") | |
| return { | |
| "success": False, | |
| "error": "No se pudo recuperar el registro actualizado" | |
| } | |
| except Exception as e: | |
| logger.error(f"❌ Error al actualizar calificación: {str(e)}") | |
| return { | |
| "success": False, | |
| "error": f"Error al actualizar calificación: {str(e)}" | |
| } | |
| def crear_o_actualizar_action(datos: ActionRequest) -> dict: | |
| """ | |
| Crea o actualiza un registro en la tabla action_call. | |
| Args: | |
| datos: Objeto ActionRequest con los datos del usuario | |
| Returns: | |
| dict: Información del action creado/actualizado o error | |
| """ | |
| conn = get_connection() | |
| if not conn: | |
| logger.error("❌ No se pudo conectar a la base de datos") | |
| return { | |
| "success": False, | |
| "error": "No se pudo conectar a la base de datos" | |
| } | |
| try: | |
| logger.info(f"🔗 Conexión establecida a BD") | |
| cursor = conn.cursor() | |
| # Preparar los valores | |
| valores = ( | |
| datos.usuario, datos.uid, datos.displayName, datos.email, | |
| datos.action_call, datos.trigger_action, datos.country_header, datos.country_ip, | |
| datos.creditos, datos.esta_hora, datos.explicit_counter, | |
| datos.fecha_registro, datos.gaClient, datos.open_use, | |
| datos.ritmo, datos.streak, datos.ultima_generacion_hora, | |
| datos.ultimo_uso, datos.usos | |
| ) | |
| logger.info(f"📊 Datos a insertar/actualizar - Usuario: {datos.usuario}, Email: {datos.email}, Usos: {datos.usos}") | |
| # Usar INSERT ... ON DUPLICATE KEY UPDATE para crear o actualizar | |
| sql = """ | |
| INSERT INTO `action_call` | |
| (usuario, uid, displayName, email, action_call, trigger_action, country_header, country_ip, | |
| creditos, esta_hora, explicit_counter, fecha_registro, gaClient, open_use, | |
| ritmo, streak, ultima_generacion_hora, ultimo_uso, usos) | |
| VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) | |
| ON DUPLICATE KEY UPDATE | |
| uid = VALUES(uid), | |
| displayName = VALUES(displayName), | |
| email = VALUES(email), | |
| action_call = VALUES(action_call), | |
| trigger_action = VALUES(trigger_action), | |
| country_header = VALUES(country_header), | |
| country_ip = VALUES(country_ip), | |
| creditos = VALUES(creditos), | |
| esta_hora = VALUES(esta_hora), | |
| explicit_counter = VALUES(explicit_counter), | |
| fecha_registro = VALUES(fecha_registro), | |
| gaClient = VALUES(gaClient), | |
| open_use = VALUES(open_use), | |
| ritmo = VALUES(ritmo), | |
| streak = VALUES(streak), | |
| ultima_generacion_hora = VALUES(ultima_generacion_hora), | |
| ultimo_uso = VALUES(ultimo_uso), | |
| usos = VALUES(usos) | |
| """ | |
| cursor.execute(sql, valores) | |
| conn.commit() | |
| logger.info(f"✅ Action insertado/actualizado en BD") | |
| # Recuperar el action | |
| cursor.execute( | |
| "SELECT * FROM `action_call` WHERE usuario = %s", | |
| (datos.usuario,) | |
| ) | |
| action = cursor.fetchone() | |
| cursor.close() | |
| conn.close() | |
| if action: | |
| logger.info(f"✅ Action recuperado - Usuario: {action[1]}") | |
| return { | |
| "success": True, | |
| "data": { | |
| "id": action[0], | |
| "usuario": action[1], | |
| "uid": action[2], | |
| "displayName": action[3], | |
| "email": action[4], | |
| "action_call": action[5], | |
| "trigger_action": action[6], | |
| "country_header": action[7], | |
| "country_ip": action[8], | |
| "creditos": action[9], | |
| "esta_hora": action[10], | |
| "explicit_counter": action[11], | |
| "fecha_registro": action[12], | |
| "gaClient": action[13], | |
| "open_use": action[14], | |
| "ritmo": action[15], | |
| "streak": action[16], | |
| "ultima_generacion_hora": action[17], | |
| "ultimo_uso": action[18], | |
| "usos": action[19], | |
| "created_at": action[20], | |
| "updated_at": action[21] | |
| } | |
| } | |
| else: | |
| logger.error("❌ No se pudo recuperar el action") | |
| return { | |
| "success": False, | |
| "error": "No se pudo recuperar el action" | |
| } | |
| except Exception as e: | |
| logger.error(f"❌ Error al crear/actualizar action: {str(e)}") | |
| return { | |
| "success": False, | |
| "error": f"Error al crear/actualizar action: {str(e)}" | |
| } | |
| def obtener_action(usuario: str) -> dict: | |
| """ | |
| Obtiene un action específico por usuario. | |
| Args: | |
| usuario: Nombre de usuario | |
| Returns: | |
| dict: Información del action o error | |
| """ | |
| conn = get_connection() | |
| if not conn: | |
| logger.error("❌ No se pudo conectar a la base de datos") | |
| return { | |
| "success": False, | |
| "error": "No se pudo conectar a la base de datos" | |
| } | |
| try: | |
| logger.info(f"🔍 Buscando action - Usuario: {usuario}") | |
| cursor = conn.cursor() | |
| cursor.execute( | |
| "SELECT * FROM `action_call` WHERE usuario = %s", | |
| (usuario,) | |
| ) | |
| action = cursor.fetchone() | |
| cursor.close() | |
| conn.close() | |
| if action: | |
| logger.info(f"✅ Action encontrado - Usuario: {usuario}") | |
| return { | |
| "success": True, | |
| "data": { | |
| "id": action[0], | |
| "usuario": action[1], | |
| "uid": action[2], | |
| "displayName": action[3], | |
| "email": action[4], | |
| "action_call": action[5], | |
| "trigger_action": action[6], | |
| "country_header": action[7], | |
| "country_ip": action[8], | |
| "creditos": action[9], | |
| "esta_hora": action[10], | |
| "explicit_counter": action[11], | |
| "fecha_registro": action[12], | |
| "gaClient": action[13], | |
| "open_use": action[14], | |
| "ritmo": action[15], | |
| "streak": action[16], | |
| "ultima_generacion_hora": action[17], | |
| "ultimo_uso": action[18], | |
| "usos": action[19], | |
| "created_at": action[20], | |
| "updated_at": action[21] | |
| } | |
| } | |
| else: | |
| logger.error(f"❌ No se encontró action - Usuario: {usuario}") | |
| return { | |
| "success": False, | |
| "error": f"No se encontró action para el usuario: {usuario}" | |
| } | |
| except Exception as e: | |
| logger.error(f"❌ Error al obtener action: {str(e)}") | |
| return { | |
| "success": False, | |
| "error": f"Error al obtener action: {str(e)}" | |
| } | |
| def obtener_todas_acciones(limit: int = 10, offset: int = 0) -> dict: | |
| """ | |
| Obtiene todas las acciones con paginación. | |
| Args: | |
| limit: Cantidad máxima de registros | |
| offset: Desplazamiento para paginación | |
| Returns: | |
| dict: Lista de acciones o error | |
| """ | |
| conn = get_connection() | |
| if not conn: | |
| logger.error("❌ No se pudo conectar a la base de datos") | |
| return { | |
| "success": False, | |
| "error": "No se pudo conectar a la base de datos" | |
| } | |
| try: | |
| logger.info(f"📚 Obteniendo todas las acciones - Limit: {limit}, Offset: {offset}") | |
| cursor = conn.cursor() | |
| # Obtener total | |
| cursor.execute("SELECT COUNT(*) FROM `action_call`") | |
| total = cursor.fetchone()[0] | |
| logger.info(f"📊 Total de acciones: {total}") | |
| # Obtener con paginación | |
| cursor.execute( | |
| "SELECT * FROM `action_call` ORDER BY updated_at DESC LIMIT %s OFFSET %s", | |
| (limit, offset) | |
| ) | |
| acciones = cursor.fetchall() | |
| logger.info(f"✅ Se obtuvieron {len(acciones)} acciones") | |
| cursor.close() | |
| conn.close() | |
| datos = [] | |
| for action in acciones: | |
| datos.append({ | |
| "id": action[0], | |
| "usuario": action[1], | |
| "uid": action[2], | |
| "displayName": action[3], | |
| "email": action[4], | |
| "action_call": action[5], | |
| "trigger_action": action[6], | |
| "country_header": action[7], | |
| "country_ip": action[8], | |
| "creditos": action[9], | |
| "esta_hora": action[10], | |
| "explicit_counter": action[11], | |
| "fecha_registro": action[12], | |
| "gaClient": action[13], | |
| "open_use": action[14], | |
| "ritmo": action[15], | |
| "streak": action[16], | |
| "ultima_generacion_hora": action[17], | |
| "ultimo_uso": action[18], | |
| "usos": action[19], | |
| "created_at": action[20], | |
| "updated_at": action[21] | |
| }) | |
| return { | |
| "success": True, | |
| "data": datos, | |
| "total": total, | |
| "limit": limit, | |
| "offset": offset | |
| } | |
| except Exception as e: | |
| logger.error(f"❌ Error al obtener acciones: {str(e)}") | |
| return { | |
| "success": False, | |
| "error": f"Error al obtener acciones: {str(e)}" | |
| } | |
| def crear_evento_funel(datos) -> dict: | |
| """ | |
| Crea un evento en el funel de compra. | |
| Args: | |
| datos: Object FunelCompraRequest con usuario, mail, accion | |
| Returns: | |
| dict: Evento creado o error | |
| """ | |
| conn = get_connection() | |
| if not conn: | |
| logger.error("❌ No se pudo conectar a la base de datos") | |
| return { | |
| "success": False, | |
| "error": "No se pudo conectar a la base de datos" | |
| } | |
| try: | |
| logger.info(f"📊 Registrando evento funel - Usuario: {datos.usuario}, Mail: {datos.mail}, Acción: {datos.accion}") | |
| cursor = conn.cursor() | |
| sql = """ | |
| INSERT INTO `funel_compra` | |
| (usuario, mail, accion) | |
| VALUES (%s, %s, %s) | |
| """ | |
| valores = (datos.usuario, datos.mail, datos.accion) | |
| cursor.execute(sql, valores) | |
| conn.commit() | |
| logger.info(f"✅ Evento funel registrado en BD - Usuario: {datos.usuario}") | |
| # Recuperar el evento creado | |
| cursor.execute( | |
| "SELECT * FROM `funel_compra` WHERE usuario = %s AND mail = %s AND accion = %s ORDER BY created_at DESC LIMIT 1", | |
| (datos.usuario, datos.mail, datos.accion) | |
| ) | |
| evento = cursor.fetchone() | |
| cursor.close() | |
| conn.close() | |
| if evento: | |
| logger.info(f"✅ Evento recuperado - ID: {evento[0]}") | |
| return { | |
| "success": True, | |
| "data": { | |
| "id": evento[0], | |
| "usuario": evento[1], | |
| "mail": evento[2], | |
| "accion": evento[3], | |
| "created_at": evento[4] | |
| } | |
| } | |
| else: | |
| logger.error("❌ No se pudo recuperar el evento creado") | |
| return { | |
| "success": False, | |
| "error": "No se pudo recuperar el evento" | |
| } | |
| except Exception as e: | |
| logger.error(f"❌ Error al crear evento funel: {str(e)}") | |
| return { | |
| "success": False, | |
| "error": f"Error al crear evento: {str(e)}" | |
| } | |
| def obtener_eventos_funel(usuario: str) -> dict: | |
| """ | |
| Obtiene todos los eventos de funel para un usuario. | |
| Args: | |
| usuario: Nombre del usuario | |
| Returns: | |
| dict: Lista de eventos o error | |
| """ | |
| conn = get_connection() | |
| if not conn: | |
| logger.error("❌ No se pudo conectar a la base de datos") | |
| return { | |
| "success": False, | |
| "error": "No se pudo conectar a la base de datos" | |
| } | |
| try: | |
| logger.info(f"🔍 Buscando eventos funel - Usuario: {usuario}") | |
| cursor = conn.cursor() | |
| cursor.execute( | |
| "SELECT * FROM `funel_compra` WHERE usuario = %s ORDER BY created_at DESC", | |
| (usuario,) | |
| ) | |
| eventos = cursor.fetchall() | |
| cursor.close() | |
| conn.close() | |
| datos = [] | |
| for evento in eventos: | |
| datos.append({ | |
| "id": evento[0], | |
| "usuario": evento[1], | |
| "mail": evento[2], | |
| "accion": evento[3], | |
| "created_at": evento[4] | |
| }) | |
| logger.info(f"✅ Se obtuvieron {len(datos)} eventos para el usuario: {usuario}") | |
| return { | |
| "success": True, | |
| "data": datos, | |
| "total": len(datos) | |
| } | |
| except Exception as e: | |
| logger.error(f"❌ Error al obtener eventos funel: {str(e)}") | |
| return { | |
| "success": False, | |
| "error": f"Error al obtener eventos: {str(e)}" | |
| } | |
| def obtener_todos_eventos_funel(limit: int = 10, offset: int = 0) -> dict: | |
| """ | |
| Obtiene todos los eventos del funel con paginación. | |
| Args: | |
| limit: Cantidad máxima de registros | |
| offset: Desplazamiento para paginación | |
| Returns: | |
| dict: Lista de eventos paginada o error | |
| """ | |
| conn = get_connection() | |
| if not conn: | |
| logger.error("❌ No se pudo conectar a la base de datos") | |
| return { | |
| "success": False, | |
| "error": "No se pudo conectar a la base de datos" | |
| } | |
| try: | |
| logger.info(f"📚 Obteniendo todos los eventos funel - Limit: {limit}, Offset: {offset}") | |
| cursor = conn.cursor() | |
| # Obtener total | |
| cursor.execute("SELECT COUNT(*) FROM `funel_compra`") | |
| total = cursor.fetchone()[0] | |
| logger.info(f"📊 Total de eventos: {total}") | |
| # Obtener con paginación | |
| cursor.execute( | |
| "SELECT * FROM `funel_compra` ORDER BY created_at DESC LIMIT %s OFFSET %s", | |
| (limit, offset) | |
| ) | |
| eventos = cursor.fetchall() | |
| logger.info(f"✅ Se obtuvieron {len(eventos)} eventos") | |
| cursor.close() | |
| conn.close() | |
| datos = [] | |
| for evento in eventos: | |
| datos.append({ | |
| "id": evento[0], | |
| "usuario": evento[1], | |
| "mail": evento[2], | |
| "accion": evento[3], | |
| "created_at": evento[4] | |
| }) | |
| return { | |
| "success": True, | |
| "data": datos, | |
| "total": total, | |
| "limit": limit, | |
| "offset": offset | |
| } | |
| except Exception as e: | |
| logger.error(f"❌ Error al obtener eventos funel: {str(e)}") | |
| return { | |
| "success": False, | |
| "error": f"Error al obtener eventos: {str(e)}" | |
| } | |