blackcoffee2 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +67 -0
- package/CHANGELOG.md +167 -0
- package/README.md +1 -3
- package/config/database.json +11 -0
- package/controllers/admin/AuthController.js +2 -1
- package/core/ViewHelper.js +75 -0
- package/core/hotReload.js +1 -1
- package/data/blackcoffee_admin.db-shm +0 -0
- package/data/blackcoffee_admin.db-wal +0 -0
- package/includes/adminAuth.js +5 -3
- package/includes/sessions.js +1 -1
- package/otrack.tar.gz +0 -0
- package/package.json +4 -2
- package/programatically/initFlow.js +2 -2
- package/test-aplicacion.con-logisession/BlackCoffee.js +0 -226
- package/test-aplicacion.con-logisession/SSL_SETUP.md +0 -53
- package/test-aplicacion.con-logisession/certs/ca-certificate.pem +0 -32
- package/test-aplicacion.con-logisession/certs/ca-private-key.pem +0 -52
- package/test-aplicacion.con-logisession/certs/certificate-2048.pem +0 -22
- package/test-aplicacion.con-logisession/certs/certificate.pem +0 -32
- package/test-aplicacion.con-logisession/certs/private-key-2048.pem +0 -28
- package/test-aplicacion.con-logisession/certs/private-key.pem +0 -52
- package/test-aplicacion.con-logisession/config/iaQueueSetup.js +0 -84
- package/test-aplicacion.con-logisession/config/qwen-rules.json +0 -39
- package/test-aplicacion.con-logisession/controllers/analyticsController.js +0 -117
- package/test-aplicacion.con-logisession/controllers/auth/AdminAuthController.js +0 -142
- package/test-aplicacion.con-logisession/controllers/auth/AuthController.js +0 -439
- package/test-aplicacion.con-logisession/controllers/auth/AuthViewController.js +0 -223
- package/test-aplicacion.con-logisession/controllers/endpointController.js +0 -66
- package/test-aplicacion.con-logisession/controllers/example.js +0 -183
- package/test-aplicacion.con-logisession/controllers/iaQueueController.js +0 -367
- package/test-aplicacion.con-logisession/controllers/queueController.js +0 -206
- package/test-aplicacion.con-logisession/controllers/qwenQueueController.js +0 -197
- package/test-aplicacion.con-logisession/controllers/test.js +0 -0
- package/test-aplicacion.con-logisession/controllers/tracking/EventsNoFinishController.js +0 -78
- package/test-aplicacion.con-logisession/controllers/tracking/TrackingController.js +0 -412
- package/test-aplicacion.con-logisession/controllers/tracking/TrackingControllerWithLoadModel.js +0 -437
- package/test-aplicacion.con-logisession/hooks/admin-hooks.js +0 -20
- package/test-aplicacion.con-logisession/hooks/general-hooks.js +0 -97
- package/test-aplicacion.con-logisession/hooks/queue-hooks.js +0 -64
- package/test-aplicacion.con-logisession/hooks/route-directory-hooks.js +0 -38
- package/test-aplicacion.con-logisession/hooks/security-hooks.js +0 -24
- package/test-aplicacion.con-logisession/insitu-admin-client/README.md +0 -69
- package/test-aplicacion.con-logisession/insitu-admin-client/package.json +0 -23
- package/test-aplicacion.con-logisession/insitu-admin-client.js +0 -257
- package/test-aplicacion.con-logisession/models/ExampleModel.js +0 -88
- package/test-aplicacion.con-logisession/models/QueueJobModel.js +0 -263
- package/test-aplicacion.con-logisession/models/TokenModel.js +0 -207
- package/test-aplicacion.con-logisession/models/auth/AuthModel.js +0 -66
- package/test-aplicacion.con-logisession/models/auth/UserModel.js +0 -189
- package/test-aplicacion.con-logisession/models/tracking/CompletedCartModel.js +0 -213
- package/test-aplicacion.con-logisession/models/tracking/EventModel.js +0 -366
- package/test-aplicacion.con-logisession/models/tracking/EventsNoFinishModel.js +0 -131
- package/test-aplicacion.con-logisession/models/tracking/SessionModel.js +0 -360
- package/test-aplicacion.con-logisession/models/tracking/SiteFlowModel.js +0 -286
- package/test-aplicacion.con-logisession/models/tracking/TokenModel.js +0 -207
- package/test-aplicacion.con-logisession/package-lock.json +0 -3313
- package/test-aplicacion.con-logisession/package.json +0 -32
- package/test-aplicacion.con-logisession/public/blackcoffee-welcome/index.html +0 -1339
- package/test-aplicacion.con-logisession/public/css/style.css +0 -64
- package/test-aplicacion.con-logisession/public/ejemplo-estatica/index.html +0 -18
- package/test-aplicacion.con-logisession/public/ejemplo-estatica/script.js +0 -16
- package/test-aplicacion.con-logisession/public/ejemplo-estatica/styles.css +0 -43
- package/test-aplicacion.con-logisession/public/images/logo.svg +0 -7
- package/test-aplicacion.con-logisession/public/js/main.js +0 -67
- package/test-aplicacion.con-logisession/routes/analytics-routes.json +0 -8
- package/test-aplicacion.con-logisession/routes/auth-routes.json +0 -98
- package/test-aplicacion.con-logisession/routes/blackcoffee-welcome-routes.json +0 -20
- package/test-aplicacion.con-logisession/routes/duplicate-test-routes.json.disabled +0 -16
- package/test-aplicacion.con-logisession/routes/ejemplo-estatica-routes.json +0 -11
- package/test-aplicacion.con-logisession/routes/endpoints-routes.json +0 -8
- package/test-aplicacion.con-logisession/routes/ia-queue-routes.json +0 -26
- package/test-aplicacion.con-logisession/routes/product-routes.json.disabled +0 -20
- package/test-aplicacion.con-logisession/routes/queue-routes.json +0 -32
- package/test-aplicacion.con-logisession/routes/qwen-routes.json +0 -14
- package/test-aplicacion.con-logisession/routes/static-routes.json +0 -29
- package/test-aplicacion.con-logisession/routes/tracking-routes.json +0 -58
- package/test-aplicacion.con-logisession/routes/tracking-with-loadmodel-routes.json +0 -51
- package/test-aplicacion.con-logisession/utils/dbAdapter.js +0 -88
- package/test-aplicacion.con-logisession/utils/qbWrapper.js +0 -4
- package/test-aplicacion.con-logisession/utils/queueProcessor.js +0 -305
- package/test-aplicacion.con-logisession/utils/qwenRulesService.js +0 -131
- package/test-aplicacion.con-logisession/utils/tokenHelper.js +0 -22
- package/test-aplicacion.con-logisession/views/auth/dashboard.html +0 -443
- package/test-aplicacion.con-logisession/views/auth/forgot-password.html +0 -200
- package/test-aplicacion.con-logisession/views/auth/login.html +0 -213
- package/test-aplicacion.con-logisession/views/auth/register.html +0 -294
- package/test-aplicacion.con-logisession/views/contact/form.html +0 -47
- package/test-aplicacion.con-logisession/views/products/index.html +0 -39
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
const { ControllerBase } = require('insitu-js');
|
|
2
|
-
|
|
3
|
-
class EndpointController extends ControllerBase {
|
|
4
|
-
constructor(options = {}) {
|
|
5
|
-
super(options);
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
// Método para listar todos los endpoints registrados
|
|
9
|
-
async listEndpoints(req, res) {
|
|
10
|
-
try {
|
|
11
|
-
let endpoints = [];
|
|
12
|
-
|
|
13
|
-
// Usar el mapa global registeredEndpoints que contiene la información completa de las rutas
|
|
14
|
-
for (const [key, endpoint] of global.registeredEndpoints) {
|
|
15
|
-
endpoints.push(endpoint);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Ordenar los endpoints por método y luego por ruta
|
|
19
|
-
endpoints.sort((a, b) => {
|
|
20
|
-
// Primero ordenar por método HTTP
|
|
21
|
-
const methodOrder = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD'];
|
|
22
|
-
const methodComparison = methodOrder.indexOf(a.method.toUpperCase()) - methodOrder.indexOf(b.method.toUpperCase());
|
|
23
|
-
|
|
24
|
-
if (methodComparison !== 0) {
|
|
25
|
-
return methodComparison;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Si tienen el mismo método, ordenar por ruta
|
|
29
|
-
return a.path.localeCompare(b.path);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
// Preparar respuesta
|
|
33
|
-
const response = {
|
|
34
|
-
success: true,
|
|
35
|
-
count: endpoints.length,
|
|
36
|
-
endpoints: endpoints
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
// Enviar respuesta JSON
|
|
40
|
-
res.writeHead(200, {
|
|
41
|
-
'Content-Type': 'application/json',
|
|
42
|
-
'Access-Control-Allow-Origin': '*',
|
|
43
|
-
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
|
44
|
-
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
|
|
45
|
-
});
|
|
46
|
-
res.end(JSON.stringify(response, null, 2));
|
|
47
|
-
} catch (error) {
|
|
48
|
-
console.error('Error al listar endpoints:', error);
|
|
49
|
-
|
|
50
|
-
this.json(res, {
|
|
51
|
-
success: false,
|
|
52
|
-
error: error.message
|
|
53
|
-
}, 500);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Exportar métodos individualmente para que RouteLoader pueda acceder a ellos
|
|
59
|
-
const controllerInstance = new EndpointController();
|
|
60
|
-
|
|
61
|
-
module.exports = {
|
|
62
|
-
listEndpoints: (req, res) => {
|
|
63
|
-
controllerInstance.setRequestResponse(req, res);
|
|
64
|
-
controllerInstance.listEndpoints(req, res);
|
|
65
|
-
}
|
|
66
|
-
};
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
const { ControllerBase } = require('insitu-js');
|
|
2
|
-
const ProductModel = require('../models/ExampleModel');
|
|
3
|
-
|
|
4
|
-
class ProductController extends ControllerBase {
|
|
5
|
-
constructor(options = {}) {
|
|
6
|
-
super(options);
|
|
7
|
-
this.model = new ProductModel();
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
// Método para mostrar la página principal con productos
|
|
11
|
-
async index(req, res) {
|
|
12
|
-
try {
|
|
13
|
-
const products = await this.model.getAllProducts();
|
|
14
|
-
|
|
15
|
-
// Preparar datos para la vista
|
|
16
|
-
this.set('title', 'Tienda de Productos');
|
|
17
|
-
this.set('products', products);
|
|
18
|
-
this.set('activePage', 'home');
|
|
19
|
-
|
|
20
|
-
// Renderizar la vista
|
|
21
|
-
const html = this.view('products/index', {
|
|
22
|
-
title: 'Tienda de Productos',
|
|
23
|
-
products: products,
|
|
24
|
-
activePage: 'home'
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
28
|
-
res.end(html);
|
|
29
|
-
} catch (error) {
|
|
30
|
-
this.json(res, {
|
|
31
|
-
success: false,
|
|
32
|
-
error: error.message
|
|
33
|
-
}, 500);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Método para obtener productos en formato JSON
|
|
38
|
-
async getAllProducts(req, res) {
|
|
39
|
-
try {
|
|
40
|
-
const products = await this.model.getAllProducts();
|
|
41
|
-
|
|
42
|
-
// Devolver directamente el array de productos para compatibilidad con el frontend
|
|
43
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
44
|
-
res.end(JSON.stringify(products));
|
|
45
|
-
} catch (error) {
|
|
46
|
-
this.json(res, {
|
|
47
|
-
success: false,
|
|
48
|
-
error: error.message
|
|
49
|
-
}, 500);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Método para obtener un producto específico por ID
|
|
54
|
-
async getProductById(req, res) {
|
|
55
|
-
try {
|
|
56
|
-
const id = this.input('id', null);
|
|
57
|
-
if (!id) {
|
|
58
|
-
return this.json(res, {
|
|
59
|
-
success: false,
|
|
60
|
-
error: 'ID de producto es requerido'
|
|
61
|
-
}, 400);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const product = await this.model.getProductById(id);
|
|
65
|
-
if (!product) {
|
|
66
|
-
return this.json(res, {
|
|
67
|
-
success: false,
|
|
68
|
-
error: 'Producto no encontrado'
|
|
69
|
-
}, 404);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
this.json(res, {
|
|
73
|
-
success: true,
|
|
74
|
-
data: product
|
|
75
|
-
});
|
|
76
|
-
} catch (error) {
|
|
77
|
-
this.json(res, {
|
|
78
|
-
success: false,
|
|
79
|
-
error: error.message
|
|
80
|
-
}, 500);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Método para crear un nuevo producto
|
|
85
|
-
async createProduct(req, res) {
|
|
86
|
-
try {
|
|
87
|
-
// En una implementación real, aquí obtendríamos los datos del cuerpo de la solicitud
|
|
88
|
-
const productData = {
|
|
89
|
-
name: this.input('name', ''),
|
|
90
|
-
description: this.input('description', ''),
|
|
91
|
-
price: parseFloat(this.input('price', 0)),
|
|
92
|
-
category: this.input('category', '')
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
const newProduct = await this.model.createProduct(productData);
|
|
96
|
-
|
|
97
|
-
this.json(res, {
|
|
98
|
-
success: true,
|
|
99
|
-
data: newProduct
|
|
100
|
-
}, 201);
|
|
101
|
-
} catch (error) {
|
|
102
|
-
this.json(res, {
|
|
103
|
-
success: false,
|
|
104
|
-
error: error.message
|
|
105
|
-
}, 500);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Método para mostrar la página de contacto
|
|
110
|
-
async showContact(req, res) {
|
|
111
|
-
try {
|
|
112
|
-
this.set('title', 'Contacto');
|
|
113
|
-
this.set('activePage', 'contact');
|
|
114
|
-
|
|
115
|
-
const html = this.view('contact/form', {
|
|
116
|
-
title: 'Contacto',
|
|
117
|
-
activePage: 'contact'
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
121
|
-
res.end(html);
|
|
122
|
-
} catch (error) {
|
|
123
|
-
this.json(res, {
|
|
124
|
-
success: false,
|
|
125
|
-
error: error.message
|
|
126
|
-
}, 500);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Método para manejar el envío del formulario de contacto
|
|
131
|
-
async handleContact(req, res) {
|
|
132
|
-
try {
|
|
133
|
-
const contactData = {
|
|
134
|
-
name: this.input('name', ''),
|
|
135
|
-
email: this.input('email', ''),
|
|
136
|
-
message: this.input('message', '')
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
// Aquí iría la lógica para procesar el formulario de contacto
|
|
140
|
-
// Por ahora, simplemente devolvemos éxito
|
|
141
|
-
|
|
142
|
-
this.json(res, {
|
|
143
|
-
success: true,
|
|
144
|
-
message: 'Mensaje recibido correctamente'
|
|
145
|
-
});
|
|
146
|
-
} catch (error) {
|
|
147
|
-
this.json(res, {
|
|
148
|
-
success: false,
|
|
149
|
-
error: error.message
|
|
150
|
-
}, 500);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Exportar métodos individualmente para que RouteLoader pueda acceder a ellos
|
|
156
|
-
const controllerInstance = new ProductController();
|
|
157
|
-
|
|
158
|
-
module.exports = {
|
|
159
|
-
index: (req, res) => {
|
|
160
|
-
controllerInstance.setRequestResponse(req, res);
|
|
161
|
-
controllerInstance.index(req, res);
|
|
162
|
-
},
|
|
163
|
-
getAllProducts: (req, res) => {
|
|
164
|
-
controllerInstance.setRequestResponse(req, res);
|
|
165
|
-
controllerInstance.getAllProducts(req, res);
|
|
166
|
-
},
|
|
167
|
-
getProductById: (req, res) => {
|
|
168
|
-
controllerInstance.setRequestResponse(req, res);
|
|
169
|
-
controllerInstance.getProductById(req, res);
|
|
170
|
-
},
|
|
171
|
-
createProduct: (req, res) => {
|
|
172
|
-
controllerInstance.setRequestResponse(req, res);
|
|
173
|
-
controllerInstance.createProduct(req, res);
|
|
174
|
-
},
|
|
175
|
-
showContact: (req, res) => {
|
|
176
|
-
controllerInstance.setRequestResponse(req, res);
|
|
177
|
-
controllerInstance.showContact(req, res);
|
|
178
|
-
},
|
|
179
|
-
handleContact: (req, res) => {
|
|
180
|
-
controllerInstance.setRequestResponse(req, res);
|
|
181
|
-
controllerInstance.handleContact(req, res);
|
|
182
|
-
}
|
|
183
|
-
};
|
|
@@ -1,367 +0,0 @@
|
|
|
1
|
-
const { ControllerBase } = require('insitu-js');
|
|
2
|
-
|
|
3
|
-
class IAQueueController extends ControllerBase {
|
|
4
|
-
constructor(options = {}) {
|
|
5
|
-
super(options);
|
|
6
|
-
|
|
7
|
-
// Inicializar el almacenamiento global para resultados si no existe
|
|
8
|
-
if (!global.iaQueueResults) {
|
|
9
|
-
global.iaQueueResults = new Map();
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
this.resultsMap = global.iaQueueResults;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Procesar una solicitud de IA a través del sistema de colas
|
|
16
|
-
async processWithIAQueue(req, res) {
|
|
17
|
-
try {
|
|
18
|
-
let requestData = {};
|
|
19
|
-
|
|
20
|
-
if (req.body) {
|
|
21
|
-
if (typeof req.body === 'string') {
|
|
22
|
-
requestData = JSON.parse(req.body);
|
|
23
|
-
} else {
|
|
24
|
-
requestData = req.body;
|
|
25
|
-
}
|
|
26
|
-
} else {
|
|
27
|
-
let body = '';
|
|
28
|
-
for await (const chunk of req) {
|
|
29
|
-
body += chunk.toString();
|
|
30
|
-
}
|
|
31
|
-
requestData = JSON.parse(body);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Validar que existan las secciones requeridas
|
|
35
|
-
if (!requestData.data && !requestData.metrics) {
|
|
36
|
-
return this.json(res, {
|
|
37
|
-
success: false,
|
|
38
|
-
error: 'Missing data or metrics section in request'
|
|
39
|
-
}, 400);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (!requestData.prompt) {
|
|
43
|
-
return this.json(res, {
|
|
44
|
-
success: false,
|
|
45
|
-
error: 'Missing prompt section in request'
|
|
46
|
-
}, 400);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Preparar el payload para el trabajo
|
|
50
|
-
const payload = {
|
|
51
|
-
data: requestData.data || requestData.metrics,
|
|
52
|
-
prompt: requestData.prompt,
|
|
53
|
-
userId: requestData.userId || null,
|
|
54
|
-
requestId: Date.now()
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
// Función que representa la tarea de IA
|
|
58
|
-
const iaTask = async (datos, taskObj) => {
|
|
59
|
-
try {
|
|
60
|
-
console.log('[IA_QUEUE_TASK] Iniciando procesamiento de tarea:', taskObj.id);
|
|
61
|
-
console.log('[IA_QUEUE_TASK] Datos recibidos:', datos);
|
|
62
|
-
|
|
63
|
-
// Importar exec aquí para evitar problemas de dependencias
|
|
64
|
-
const { exec } = require('child_process');
|
|
65
|
-
const util = require('util');
|
|
66
|
-
const execAsync = util.promisify(exec);
|
|
67
|
-
|
|
68
|
-
// Preparar el comando para Qwen con el prompt
|
|
69
|
-
const qwenCommand = `qwen -p "${datos.prompt}"`;
|
|
70
|
-
|
|
71
|
-
console.log('[IA_QUEUE_TASK] Ejecutando comando Qwen:', qwenCommand);
|
|
72
|
-
|
|
73
|
-
// Ejecutar el comando de Qwen
|
|
74
|
-
const result = await execAsync(qwenCommand);
|
|
75
|
-
|
|
76
|
-
console.log('[IA_QUEUE_TASK] Comando Qwen ejecutado exitosamente');
|
|
77
|
-
|
|
78
|
-
const response = result.stdout;
|
|
79
|
-
console.log('[IA_QUEUE_TASK] Respuesta de Qwen:', response);
|
|
80
|
-
|
|
81
|
-
const finalResult = {
|
|
82
|
-
success: true,
|
|
83
|
-
response: response,
|
|
84
|
-
command: qwenCommand,
|
|
85
|
-
userId: datos.userId,
|
|
86
|
-
requestId: datos.requestId
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
console.log('[IA_QUEUE_TASK] Resultado generado para tarea:', taskObj.id, finalResult);
|
|
90
|
-
|
|
91
|
-
// Guardar el resultado en el almacenamiento global inmediatamente después de generar el resultado
|
|
92
|
-
if (!global.iaQueueResults) {
|
|
93
|
-
global.iaQueueResults = new Map();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const resultData = {
|
|
97
|
-
job_id: taskObj.id,
|
|
98
|
-
result: typeof finalResult === 'object' ? JSON.stringify(finalResult) : finalResult,
|
|
99
|
-
created_at: new Date().toISOString()
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
global.iaQueueResults.set(taskObj.id, resultData);
|
|
103
|
-
console.log(`[IA_QUEUE_TASK] Resultado guardado inmediatamente para tarea: ${taskObj.id}`);
|
|
104
|
-
|
|
105
|
-
return finalResult;
|
|
106
|
-
} catch (error) {
|
|
107
|
-
console.error('[IA_QUEUE_TASK] Error ejecutando comando de Qwen:', error);
|
|
108
|
-
// Guardar el error también en el almacenamiento global
|
|
109
|
-
if (!global.iaQueueResults) {
|
|
110
|
-
global.iaQueueResults = new Map();
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const errorResult = {
|
|
114
|
-
success: false,
|
|
115
|
-
error: error.message,
|
|
116
|
-
command: `qwen -p "${datos.prompt}"`,
|
|
117
|
-
userId: datos.userId,
|
|
118
|
-
requestId: datos.requestId
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
const resultData = {
|
|
122
|
-
job_id: taskObj.id,
|
|
123
|
-
result: JSON.stringify(errorResult),
|
|
124
|
-
created_at: new Date().toISOString()
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
global.iaQueueResults.set(taskObj.id, resultData);
|
|
128
|
-
console.log(`[IA_QUEUE_TASK] Resultado de error guardado para tarea: ${taskObj.id}`);
|
|
129
|
-
|
|
130
|
-
throw new Error(`Qwen execution failed: ${error.message}`);
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
// Verificar que el sistema de colas esté disponible
|
|
135
|
-
if (!global.queueIntegration) {
|
|
136
|
-
return this.json(res, {
|
|
137
|
-
success: false,
|
|
138
|
-
error: 'Queue system is not available'
|
|
139
|
-
}, 500);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Agregar la tarea a la cola de IA
|
|
143
|
-
const taskId = global.queueIntegration.addTask(
|
|
144
|
-
'ia-processing', // Nombre de la cola
|
|
145
|
-
iaTask, // Función de la tarea
|
|
146
|
-
payload, // Datos para la tarea
|
|
147
|
-
requestData.priority || 0 // Prioridad (0 es la más alta)
|
|
148
|
-
);
|
|
149
|
-
|
|
150
|
-
this.json(res, {
|
|
151
|
-
success: true,
|
|
152
|
-
data: {
|
|
153
|
-
jobId: taskId,
|
|
154
|
-
queue: 'ia-processing',
|
|
155
|
-
status: 'pending',
|
|
156
|
-
message: 'IA job added to queue successfully'
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
} catch (error) {
|
|
161
|
-
this.json(res, {
|
|
162
|
-
success: false,
|
|
163
|
-
error: error.message
|
|
164
|
-
}, 500);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Obtener el estado de una tarea de IA
|
|
169
|
-
async getIAQueueResult(req, res) {
|
|
170
|
-
try {
|
|
171
|
-
const jobId = req.params?.id || this.input('id', null);
|
|
172
|
-
|
|
173
|
-
if (!jobId) {
|
|
174
|
-
return this.json(res, {
|
|
175
|
-
success: false,
|
|
176
|
-
error: 'Job ID is required'
|
|
177
|
-
}, 400);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Primero intentar obtener el resultado desde el almacenamiento global
|
|
181
|
-
try {
|
|
182
|
-
const resultData = this.resultsMap.get(jobId);
|
|
183
|
-
if (resultData) {
|
|
184
|
-
let result = resultData.result;
|
|
185
|
-
try {
|
|
186
|
-
// Intentar parsear como JSON si es posible
|
|
187
|
-
result = JSON.parse(resultData.result);
|
|
188
|
-
} catch (e) {
|
|
189
|
-
// Si no es JSON válido, usar como string
|
|
190
|
-
result = resultData.result;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
return this.json(res, {
|
|
194
|
-
success: true,
|
|
195
|
-
data: {
|
|
196
|
-
jobId: jobId,
|
|
197
|
-
status: 'completed',
|
|
198
|
-
result: result,
|
|
199
|
-
message: 'Job completed and result retrieved from storage'
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
} catch (error) {
|
|
204
|
-
console.error('[IA_QUEUE] Error retrieving stored result:', error.message);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Si no está en el almacenamiento global, verificar en el sistema de colas
|
|
208
|
-
if (!global.queueIntegration) {
|
|
209
|
-
return this.json(res, {
|
|
210
|
-
success: true,
|
|
211
|
-
data: {
|
|
212
|
-
jobId: jobId,
|
|
213
|
-
status: 'completed_or_not_found',
|
|
214
|
-
message: 'Queue system is not available',
|
|
215
|
-
queueStatus: {}
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
const queueStatus = global.queueIntegration.getStatus();
|
|
221
|
-
|
|
222
|
-
// Buscar la tarea específica
|
|
223
|
-
let jobStatus = null;
|
|
224
|
-
|
|
225
|
-
// Buscar en la cola de ia-processing
|
|
226
|
-
if (queueStatus['ia-processing']) {
|
|
227
|
-
const queueInfo = queueStatus['ia-processing'];
|
|
228
|
-
|
|
229
|
-
// La cola de tareas pendientes está en el sistema de colas
|
|
230
|
-
const pendingQueue = global.queueIntegration.getQueueSystem().pendingTasks.get('ia-processing') || [];
|
|
231
|
-
const runningTasks = global.queueIntegration.getQueueSystem().runningTasks.get('ia-processing') || new Set();
|
|
232
|
-
|
|
233
|
-
// Buscar en tareas pendientes
|
|
234
|
-
if (pendingQueue.some(task => task.id === jobId)) {
|
|
235
|
-
jobStatus = 'pending';
|
|
236
|
-
}
|
|
237
|
-
// Buscar en tareas en proceso
|
|
238
|
-
else if (runningTasks.has(jobId)) {
|
|
239
|
-
jobStatus = 'processing';
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
if (!jobStatus) {
|
|
244
|
-
// La tarea no está en colas activas y tampoco en el almacenamiento global
|
|
245
|
-
this.json(res, {
|
|
246
|
-
success: true,
|
|
247
|
-
data: {
|
|
248
|
-
jobId: jobId,
|
|
249
|
-
status: 'completed_or_not_found',
|
|
250
|
-
message: 'Job may be completed or not found in active queues',
|
|
251
|
-
queueStatus: queueStatus
|
|
252
|
-
}
|
|
253
|
-
});
|
|
254
|
-
} else {
|
|
255
|
-
this.json(res, {
|
|
256
|
-
success: true,
|
|
257
|
-
data: {
|
|
258
|
-
jobId: jobId,
|
|
259
|
-
status: jobStatus,
|
|
260
|
-
message: `Job is ${jobStatus}, please check again later`,
|
|
261
|
-
queueInfo: queueStatus['ia-processing']
|
|
262
|
-
}
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
} catch (error) {
|
|
267
|
-
this.json(res, {
|
|
268
|
-
success: false,
|
|
269
|
-
error: error.message
|
|
270
|
-
}, 500);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// Obtener historial de resultados de IA
|
|
275
|
-
async getIAQueueHistory(req, res) {
|
|
276
|
-
try {
|
|
277
|
-
const limit = parseInt(req.query.limit) || 10;
|
|
278
|
-
|
|
279
|
-
// Convertir el map a array y tomar los últimos 'limit' elementos
|
|
280
|
-
const allResults = Array.from(this.resultsMap.values())
|
|
281
|
-
.sort((a, b) => new Date(b.created_at) - new Date(a.created_at))
|
|
282
|
-
.slice(0, limit);
|
|
283
|
-
|
|
284
|
-
const results = allResults.map(result => {
|
|
285
|
-
try {
|
|
286
|
-
// Intentar parsear como JSON si es posible
|
|
287
|
-
return {
|
|
288
|
-
job_id: result.job_id,
|
|
289
|
-
result: JSON.parse(result.result),
|
|
290
|
-
created_at: result.created_at
|
|
291
|
-
};
|
|
292
|
-
} catch (e) {
|
|
293
|
-
// Si no es JSON válido, devolver como string
|
|
294
|
-
return {
|
|
295
|
-
job_id: result.job_id,
|
|
296
|
-
result: result.result,
|
|
297
|
-
created_at: result.created_at
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
this.json(res, {
|
|
303
|
-
success: true,
|
|
304
|
-
data: {
|
|
305
|
-
results: results,
|
|
306
|
-
count: results.length
|
|
307
|
-
}
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
} catch (error) {
|
|
311
|
-
this.json(res, {
|
|
312
|
-
success: false,
|
|
313
|
-
error: error.message
|
|
314
|
-
}, 500);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// Obtener estadísticas de la cola de IA
|
|
319
|
-
async getIAQueueStats(req, res) {
|
|
320
|
-
try {
|
|
321
|
-
if (!global.queueIntegration) {
|
|
322
|
-
return this.json(res, {
|
|
323
|
-
success: false,
|
|
324
|
-
error: 'Queue system is not available'
|
|
325
|
-
}, 500);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
const queueStatus = global.queueIntegration.getStatus();
|
|
329
|
-
|
|
330
|
-
this.json(res, {
|
|
331
|
-
success: true,
|
|
332
|
-
data: {
|
|
333
|
-
queueStats: queueStatus,
|
|
334
|
-
message: 'IA queue statistics retrieved successfully'
|
|
335
|
-
}
|
|
336
|
-
});
|
|
337
|
-
} catch (error) {
|
|
338
|
-
this.json(res, {
|
|
339
|
-
success: false,
|
|
340
|
-
error: error.message
|
|
341
|
-
}, 500);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
// Instanciar el controlador
|
|
347
|
-
const controllerInstance = new IAQueueController();
|
|
348
|
-
|
|
349
|
-
// Exportar métodos individualmente
|
|
350
|
-
module.exports = {
|
|
351
|
-
processWithIAQueue: (req, res) => {
|
|
352
|
-
controllerInstance.setRequestResponse(req, res);
|
|
353
|
-
controllerInstance.processWithIAQueue(req, res);
|
|
354
|
-
},
|
|
355
|
-
getIAQueueResult: (req, res) => {
|
|
356
|
-
controllerInstance.setRequestResponse(req, res);
|
|
357
|
-
controllerInstance.getIAQueueResult(req, res);
|
|
358
|
-
},
|
|
359
|
-
getIAQueueHistory: (req, res) => {
|
|
360
|
-
controllerInstance.setRequestResponse(req, res);
|
|
361
|
-
controllerInstance.getIAQueueHistory(req, res);
|
|
362
|
-
},
|
|
363
|
-
getIAQueueStats: (req, res) => {
|
|
364
|
-
controllerInstance.setRequestResponse(req, res);
|
|
365
|
-
controllerInstance.getIAQueueStats(req, res);
|
|
366
|
-
}
|
|
367
|
-
};
|