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
package/test-aplicacion.con-logisession/controllers/tracking/TrackingControllerWithLoadModel.js
DELETED
|
@@ -1,437 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Controlador de Tracking para OTrack (versión con loadModel)
|
|
3
|
-
* TrackingControllerWithLoadModel.js
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const { ControllerBase } = require('insitu-js');
|
|
7
|
-
|
|
8
|
-
class TrackingControllerWithLoadModel extends ControllerBase {
|
|
9
|
-
constructor(options = {}) {
|
|
10
|
-
super(options);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Endpoint para registrar sesiones
|
|
14
|
-
async registerSession(req, res) {
|
|
15
|
-
// Verificar si la respuesta ya ha sido enviada
|
|
16
|
-
if (res.headersSent) {
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
// Cargar el modelo con el adaptador desde la solicitud
|
|
22
|
-
const adapter = req.modelManager?.getAdapter('memory') || null;
|
|
23
|
-
const sessionModel = await this.loadModel('SessionModel', {
|
|
24
|
-
adapter: adapter,
|
|
25
|
-
modelDir: './models/tracking'
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
const { session_id, user_id, device, country, ip, user, wtf_session, site_url, token } = req.body;
|
|
29
|
-
|
|
30
|
-
// Llamar al modelo para registrar la sesión
|
|
31
|
-
const result = await sessionModel.registerSession({
|
|
32
|
-
session_id,
|
|
33
|
-
user_id,
|
|
34
|
-
device,
|
|
35
|
-
country,
|
|
36
|
-
ip,
|
|
37
|
-
user,
|
|
38
|
-
wtf_session,
|
|
39
|
-
site_url,
|
|
40
|
-
token
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
44
|
-
res.end(JSON.stringify(result));
|
|
45
|
-
} catch (error) {
|
|
46
|
-
console.error('[ERROR] registerSession:', error);
|
|
47
|
-
|
|
48
|
-
// Verificar si la respuesta ya ha sido enviada
|
|
49
|
-
if (res.headersSent) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Determinar el código de estado HTTP según el error
|
|
54
|
-
let statusCode = 500;
|
|
55
|
-
let errorMessage = 'Error interno del servidor';
|
|
56
|
-
|
|
57
|
-
if (error.message === 'Token inválido') {
|
|
58
|
-
statusCode = 401;
|
|
59
|
-
errorMessage = 'Token inválido';
|
|
60
|
-
} else if (error.message === 'session_id es requerido') {
|
|
61
|
-
statusCode = 400;
|
|
62
|
-
errorMessage = 'session_id es requerido';
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
res.writeHead(statusCode, { 'Content-Type': 'application/json' });
|
|
66
|
-
res.end(JSON.stringify({ error: errorMessage }));
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Endpoint para registrar eventos
|
|
71
|
-
async registerEventA(req, res) {
|
|
72
|
-
// Verificar si la respuesta ya ha sido enviada
|
|
73
|
-
if (res.headersSent) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
try {
|
|
78
|
-
// Cargar el modelo con el adaptador desde la solicitud
|
|
79
|
-
const adapter = req.modelManager?.getAdapter('memory') || null;
|
|
80
|
-
const eventModel = await this.loadModel('EventModel', {
|
|
81
|
-
adapter: adapter,
|
|
82
|
-
modelDir: './models/tracking'
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
const {
|
|
86
|
-
session_header_id, event_type, qty, product_id, sku, product_name,
|
|
87
|
-
url, price, old_qty, new_qty, compressed_data, data_hash,
|
|
88
|
-
event_timestamp, session_id, wtf_session, site_url, token
|
|
89
|
-
} = req.body;
|
|
90
|
-
|
|
91
|
-
// Llamar al modelo para registrar el evento
|
|
92
|
-
const result = await eventModel.registerEvent({
|
|
93
|
-
session_header_id, event_type, qty, product_id, sku, product_name,
|
|
94
|
-
url, price, old_qty, new_qty, compressed_data, data_hash,
|
|
95
|
-
event_timestamp, session_id, wtf_session, site_url, token
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
99
|
-
res.end(JSON.stringify(result));
|
|
100
|
-
} catch (error) {
|
|
101
|
-
console.error('[ERROR] registerEventA:', error);
|
|
102
|
-
|
|
103
|
-
// Verificar si la respuesta ya ha sido enviada
|
|
104
|
-
if (res.headersSent) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Determinar el código de estado HTTP según el error
|
|
109
|
-
let statusCode = 500;
|
|
110
|
-
let errorMessage = 'Error interno del servidor';
|
|
111
|
-
|
|
112
|
-
if (error.message === 'Token inválido') {
|
|
113
|
-
statusCode = 401;
|
|
114
|
-
errorMessage = 'Token inválido';
|
|
115
|
-
} else if (error.message === 'event_type es requerido') {
|
|
116
|
-
statusCode = 400;
|
|
117
|
-
errorMessage = 'event_type es requerido';
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
res.writeHead(statusCode, { 'Content-Type': 'application/json' });
|
|
121
|
-
res.end(JSON.stringify({ error: errorMessage }));
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Endpoint para insertar flujos de sitio
|
|
126
|
-
async insertSiteFlow(req, res) {
|
|
127
|
-
// Verificar si la respuesta ya ha sido enviada
|
|
128
|
-
if (res.headersSent) {
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
try {
|
|
133
|
-
// Cargar el modelo con el adaptador desde la solicitud
|
|
134
|
-
const adapter = req.modelManager?.getAdapter('memory') || null;
|
|
135
|
-
const siteFlowModel = await this.loadModel('SiteFlowModel', {
|
|
136
|
-
adapter: adapter,
|
|
137
|
-
modelDir: './models/tracking'
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
const {
|
|
141
|
-
session_header_id, event_type, qty, product_id, sku, product_name,
|
|
142
|
-
url, price, old_qty, new_qty, compressed_data, data_hash,
|
|
143
|
-
event_timestamp, session_id, wtf_session, site_url, token
|
|
144
|
-
} = req.body;
|
|
145
|
-
|
|
146
|
-
// Llamar al modelo para insertar el flujo de sitio
|
|
147
|
-
const result = await siteFlowModel.insertSiteFlow({
|
|
148
|
-
session_header_id, event_type, qty, product_id, sku, product_name,
|
|
149
|
-
url, price, old_qty, new_qty, compressed_data, data_hash,
|
|
150
|
-
event_timestamp, session_id, wtf_session, site_url, token
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
154
|
-
res.end(JSON.stringify(result));
|
|
155
|
-
} catch (error) {
|
|
156
|
-
console.error('[ERROR] insertSiteFlow:', error);
|
|
157
|
-
|
|
158
|
-
// Verificar si la respuesta ya ha sido enviada
|
|
159
|
-
if (res.headersSent) {
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Determinar el código de estado HTTP según el error
|
|
164
|
-
let statusCode = 500;
|
|
165
|
-
let errorMessage = 'Error interno del servidor';
|
|
166
|
-
|
|
167
|
-
if (error.message === 'Token inválido') {
|
|
168
|
-
statusCode = 401;
|
|
169
|
-
errorMessage = 'Token inválido';
|
|
170
|
-
} else if (error.message === 'event_type es requerido') {
|
|
171
|
-
statusCode = 400;
|
|
172
|
-
errorMessage = 'event_type es requerido';
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
res.writeHead(statusCode, { 'Content-Type': 'application/json' });
|
|
176
|
-
res.end(JSON.stringify({ error: errorMessage }));
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Endpoint para obtener sesiones
|
|
181
|
-
async getSessions(req, res) {
|
|
182
|
-
// Verificar si la respuesta ya ha sido enviada
|
|
183
|
-
if (res.headersSent) {
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
try {
|
|
188
|
-
// Obtener parámetros de consulta
|
|
189
|
-
const queryParams = { ...req.query };
|
|
190
|
-
|
|
191
|
-
// Extraer parámetros de paginación
|
|
192
|
-
const offset = parseInt(queryParams.offset) || 0;
|
|
193
|
-
const limit = parseInt(queryParams.limit) || 10;
|
|
194
|
-
const pagination = { offset, limit };
|
|
195
|
-
|
|
196
|
-
// Obtener otros parámetros de filtro excluyendo los de paginación
|
|
197
|
-
const filters = {};
|
|
198
|
-
for (const [key, value] of Object.entries(queryParams)) {
|
|
199
|
-
if (!['offset', 'limit', 'sort', 'order'].includes(key)) {
|
|
200
|
-
if (value !== '') { // Solo añadir filtros que no estén vacíos
|
|
201
|
-
filters[key] = value;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Cargar el modelo con el adaptador desde la solicitud
|
|
207
|
-
const adapter = req.modelManager?.getAdapter('memory') || null;
|
|
208
|
-
const sessionModel = await this.loadModel('SessionModel', {
|
|
209
|
-
adapter: adapter,
|
|
210
|
-
modelDir: './models/tracking'
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
// Obtener los resultados usando el modelo
|
|
214
|
-
const result = await sessionModel.queryWithFilters(filters, pagination);
|
|
215
|
-
|
|
216
|
-
// Convertir BigInt a string para evitar problemas de serialización
|
|
217
|
-
const serializedResult = JSON.parse(JSON.stringify(result, (key, value) =>
|
|
218
|
-
typeof value === 'bigint' ? value.toString() : value
|
|
219
|
-
));
|
|
220
|
-
|
|
221
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
222
|
-
res.end(JSON.stringify(serializedResult));
|
|
223
|
-
} catch (error) {
|
|
224
|
-
console.error('[ERROR] getSessions:', error);
|
|
225
|
-
if (!res.headersSent) {
|
|
226
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
227
|
-
res.end(JSON.stringify({
|
|
228
|
-
total: 0,
|
|
229
|
-
rows: [],
|
|
230
|
-
error: error.message
|
|
231
|
-
}));
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// Endpoint para obtener eventos
|
|
237
|
-
async getEvents(req, res) {
|
|
238
|
-
// Verificar si la respuesta ya ha sido enviada
|
|
239
|
-
if (res.headersSent) {
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
try {
|
|
244
|
-
// Obtener parámetros de consulta
|
|
245
|
-
const queryParams = { ...req.query };
|
|
246
|
-
|
|
247
|
-
// Extraer parámetros de paginación
|
|
248
|
-
const offset = parseInt(queryParams.offset) || 0;
|
|
249
|
-
const limit = parseInt(queryParams.limit) || 10;
|
|
250
|
-
const pagination = { offset, limit };
|
|
251
|
-
|
|
252
|
-
// Obtener otros parámetros de filtro excluyendo los de paginación
|
|
253
|
-
const filters = {};
|
|
254
|
-
for (const [key, value] of Object.entries(queryParams)) {
|
|
255
|
-
if (!['offset', 'limit', 'sort', 'order'].includes(key)) {
|
|
256
|
-
if (value !== '') { // Solo añadir filtros que no estén vacíos
|
|
257
|
-
filters[key] = value;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// Cargar el modelo con el adaptador desde la solicitud
|
|
263
|
-
const adapter = req.modelManager?.getAdapter('memory') || null;
|
|
264
|
-
const eventModel = await this.loadModel('EventModel', {
|
|
265
|
-
adapter: adapter,
|
|
266
|
-
modelDir: './models/tracking'
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
// Obtener los resultados usando el modelo
|
|
270
|
-
const result = await eventModel.queryWithFilters(filters, pagination);
|
|
271
|
-
|
|
272
|
-
// Convertir BigInt a string para evitar problemas de serialización
|
|
273
|
-
const serializedResult = JSON.parse(JSON.stringify(result, (key, value) =>
|
|
274
|
-
typeof value === 'bigint' ? value.toString() : value
|
|
275
|
-
));
|
|
276
|
-
|
|
277
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
278
|
-
res.end(JSON.stringify(serializedResult));
|
|
279
|
-
} catch (error) {
|
|
280
|
-
console.error('[ERROR] getEvents:', error);
|
|
281
|
-
if (!res.headersSent) {
|
|
282
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
283
|
-
res.end(JSON.stringify({
|
|
284
|
-
total: 0,
|
|
285
|
-
rows: [],
|
|
286
|
-
error: error.message
|
|
287
|
-
}));
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// Endpoint para obtener flujos de sitio
|
|
293
|
-
async getSiteFlow(req, res) {
|
|
294
|
-
// Verificar si la respuesta ya ha sido enviada
|
|
295
|
-
if (res.headersSent) {
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
try {
|
|
300
|
-
// Obtener parámetros de consulta
|
|
301
|
-
const queryParams = { ...req.query };
|
|
302
|
-
|
|
303
|
-
// Extraer parámetros de paginación
|
|
304
|
-
const offset = parseInt(queryParams.offset) || 0;
|
|
305
|
-
const limit = parseInt(queryParams.limit) || 10;
|
|
306
|
-
const pagination = { offset, limit };
|
|
307
|
-
|
|
308
|
-
// Obtener otros parámetros de filtro excluyendo los de paginación
|
|
309
|
-
const filters = {};
|
|
310
|
-
for (const [key, value] of Object.entries(queryParams)) {
|
|
311
|
-
if (!['offset', 'limit', 'sort', 'order'].includes(key)) {
|
|
312
|
-
if (value !== '') { // Solo añadir filtros que no estén vacíos
|
|
313
|
-
filters[key] = value;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// Cargar el modelo con el adaptador desde la solicitud
|
|
319
|
-
const adapter = req.modelManager?.getAdapter('memory') || null;
|
|
320
|
-
const siteFlowModel = await this.loadModel('SiteFlowModel', {
|
|
321
|
-
adapter: adapter,
|
|
322
|
-
modelDir: './models/tracking'
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
// Obtener los resultados usando el modelo
|
|
326
|
-
const result = await siteFlowModel.queryWithFilters(filters, pagination);
|
|
327
|
-
|
|
328
|
-
// Convertir BigInt a string para evitar problemas de serialización
|
|
329
|
-
const serializedResult = JSON.parse(JSON.stringify(result, (key, value) =>
|
|
330
|
-
typeof value === 'bigint' ? value.toString() : value
|
|
331
|
-
));
|
|
332
|
-
|
|
333
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
334
|
-
res.end(JSON.stringify(serializedResult));
|
|
335
|
-
} catch (error) {
|
|
336
|
-
console.error('[ERROR] getSiteFlow:', error);
|
|
337
|
-
if (!res.headersSent) {
|
|
338
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
339
|
-
res.end(JSON.stringify({
|
|
340
|
-
total: 0,
|
|
341
|
-
rows: [],
|
|
342
|
-
error: error.message
|
|
343
|
-
}));
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
// Endpoint para obtener carritos completados
|
|
349
|
-
async getCompletedCarts(req, res) {
|
|
350
|
-
// Verificar si la respuesta ya ha sido enviada
|
|
351
|
-
if (res.headersSent) {
|
|
352
|
-
return;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
try {
|
|
356
|
-
// Cargar el modelo con el adaptador desde la solicitud
|
|
357
|
-
const adapter = req.modelManager?.getAdapter('memory') || null;
|
|
358
|
-
const completedCartModel = await this.loadModel('CompletedCartModel', {
|
|
359
|
-
adapter: adapter,
|
|
360
|
-
modelDir: './models/tracking'
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
// Obtener parámetros de consulta
|
|
364
|
-
const queryParams = { ...req.query };
|
|
365
|
-
|
|
366
|
-
// Extraer parámetros de paginación
|
|
367
|
-
const offset = parseInt(queryParams.offset) || 0;
|
|
368
|
-
const limit = parseInt(queryParams.limit) || 10;
|
|
369
|
-
const pagination = { offset, limit };
|
|
370
|
-
|
|
371
|
-
// Obtener otros parámetros de filtro excluyendo los de paginación
|
|
372
|
-
const filters = {};
|
|
373
|
-
for (const [key, value] of Object.entries(queryParams)) {
|
|
374
|
-
if (!['offset', 'limit', 'sort', 'order'].includes(key)) {
|
|
375
|
-
if (value !== '') { // Solo añadir filtros que no estén vacíos
|
|
376
|
-
filters[key] = value;
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
// Obtener los resultados usando el modelo
|
|
382
|
-
const result = await completedCartModel.queryWithFilters(filters, pagination);
|
|
383
|
-
|
|
384
|
-
// Convertir BigInt a string para evitar problemas de serialización
|
|
385
|
-
const serializedResult = JSON.parse(JSON.stringify(result, (key, value) =>
|
|
386
|
-
typeof value === 'bigint' ? value.toString() : value
|
|
387
|
-
));
|
|
388
|
-
|
|
389
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
390
|
-
res.end(JSON.stringify(serializedResult));
|
|
391
|
-
} catch (error) {
|
|
392
|
-
console.error('[ERROR] getCompletedCarts:', error);
|
|
393
|
-
if (!res.headersSent) {
|
|
394
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
395
|
-
res.end(JSON.stringify({
|
|
396
|
-
total: 0,
|
|
397
|
-
rows: [],
|
|
398
|
-
error: error.message
|
|
399
|
-
}));
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
// Exportar métodos individualmente para que RouteLoader pueda acceder a ellos
|
|
406
|
-
const controllerInstance = new TrackingControllerWithLoadModel();
|
|
407
|
-
|
|
408
|
-
module.exports = {
|
|
409
|
-
registerSession: (req, res) => {
|
|
410
|
-
controllerInstance.setRequestResponse(req, res);
|
|
411
|
-
controllerInstance.registerSession(req, res);
|
|
412
|
-
},
|
|
413
|
-
registerEventA: (req, res) => {
|
|
414
|
-
controllerInstance.setRequestResponse(req, res);
|
|
415
|
-
controllerInstance.registerEventA(req, res);
|
|
416
|
-
},
|
|
417
|
-
insertSiteFlow: (req, res) => {
|
|
418
|
-
controllerInstance.setRequestResponse(req, res);
|
|
419
|
-
controllerInstance.insertSiteFlow(req, res);
|
|
420
|
-
},
|
|
421
|
-
getSessions: (req, res) => {
|
|
422
|
-
controllerInstance.setRequestResponse(req, res);
|
|
423
|
-
controllerInstance.getSessions(req, res);
|
|
424
|
-
},
|
|
425
|
-
getEvents: (req, res) => {
|
|
426
|
-
controllerInstance.setRequestResponse(req, res);
|
|
427
|
-
controllerInstance.getEvents(req, res);
|
|
428
|
-
},
|
|
429
|
-
getSiteFlow: (req, res) => {
|
|
430
|
-
controllerInstance.setRequestResponse(req, res);
|
|
431
|
-
controllerInstance.getSiteFlow(req, res);
|
|
432
|
-
},
|
|
433
|
-
getCompletedCarts: (req, res) => {
|
|
434
|
-
controllerInstance.setRequestResponse(req, res);
|
|
435
|
-
controllerInstance.getCompletedCarts(req, res);
|
|
436
|
-
}
|
|
437
|
-
};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hooks relacionados con la administración del sistema
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
function registerAdminHooks(hooks) {
|
|
6
|
-
// Registrar un listener para el hook de inicialización de extensiones
|
|
7
|
-
hooks.addAction('admin_extensions_initialize', (server) => {
|
|
8
|
-
console.log('Inicializando extensión de administración...');
|
|
9
|
-
|
|
10
|
-
// Inicializar la extensión de administración
|
|
11
|
-
server.initializeAdminExtension({
|
|
12
|
-
port: 9998,
|
|
13
|
-
host: '127.0.0.1'
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
console.log('Extensión de administración inicializada.');
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
module.exports = { registerAdminHooks };
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hooks generales del sistema BlackCoffee
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
function registerGeneralHooks(hooks, logger, availableControllers) {
|
|
6
|
-
// Hook que se ejecuta cuando se carga un controlador
|
|
7
|
-
hooks.addAction('post_controller_load', (controllerModule, absolutePath) => {
|
|
8
|
-
logger.info(`[[HOOK]] - Controlador cargado: ${absolutePath}`);
|
|
9
|
-
|
|
10
|
-
const controllerName = absolutePath.split('/').pop().replace('.js', '');
|
|
11
|
-
let handlerNames = Object.keys(controllerModule).filter(key =>
|
|
12
|
-
typeof controllerModule[key] === 'function'
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
availableControllers.push({
|
|
16
|
-
name: controllerName,
|
|
17
|
-
path: absolutePath,
|
|
18
|
-
handlers: handlerNames
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
logger.info(`[[HOOK]] - Handlers disponibles en ${controllerName}:`, handlerNames);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// Hook que se ejecuta antes de cargar rutas
|
|
26
|
-
hooks.addAction('pre_route_load', (filePath, serverInstance) => {
|
|
27
|
-
logger.info(`[[HOOK]] - A punto de cargar rutas desde: ${filePath}`);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
// Map global para almacenar información de endpoints
|
|
31
|
-
global.registeredEndpoints = new Map();
|
|
32
|
-
|
|
33
|
-
// Hook que se ejecuta después de cargar rutas (para RouteLoader)
|
|
34
|
-
hooks.addAction('post_route_load', (routes, serverInstance) => {
|
|
35
|
-
logger.info(`[[HOOK]] - Rutas cargadas exitosamente: ${routes.length} rutas`);
|
|
36
|
-
routes.forEach((route, index) => {
|
|
37
|
-
const handlerInfo = route.handler ? ` -> ${route.handler}` : '';
|
|
38
|
-
logger.info(`[[HOOK]] - Ruta ${index + 1}: ${route.method} ${route.path}${handlerInfo}`);
|
|
39
|
-
// Almacenar la información de la ruta en el Map global
|
|
40
|
-
const routeKey = `${route.method.toUpperCase()}_${route.path}`;
|
|
41
|
-
global.registeredEndpoints.set(routeKey, {
|
|
42
|
-
method: route.method,
|
|
43
|
-
path: route.path,
|
|
44
|
-
controller: route.controller,
|
|
45
|
-
handler: route.handler,
|
|
46
|
-
auth: route.auth || 'none',
|
|
47
|
-
description: route.description || `Endpoint para ${route.path}`,
|
|
48
|
-
createdAt: new Date().toISOString()
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
logger.info(`[[HOOK]] - ${global.registeredEndpoints.size} endpoints almacenados en el registro global`);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
// Hook que se ejecuta después de cargar rutas desde directorio (for RouteDirectoryLoader)
|
|
55
|
-
hooks.addAction('post_directory_route_load', (data) => {
|
|
56
|
-
logger.info(`[[HOOK]] - Rutas desde directorio cargadas exitosamente: ${data.routesCount} rutas`);
|
|
57
|
-
// Extraer solo las rutas del objeto data (quitando sourceFile)
|
|
58
|
-
const routes = data.map(item => {
|
|
59
|
-
const { sourceFile, ...route } = item;
|
|
60
|
-
return route;
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
routes.forEach((route, index) => {
|
|
64
|
-
const handlerInfo = route.handler ? ` -> ${route.handler}` : '';
|
|
65
|
-
logger.info(`[[HOOK]] - Ruta ${index + 1}: ${route.method} ${route.path}${handlerInfo}`);
|
|
66
|
-
// Almacenar la información de la ruta en el Map global
|
|
67
|
-
const routeKey = `${route.method.toUpperCase()}_${route.path}`;
|
|
68
|
-
|
|
69
|
-
// Determinar si la ruta es estática basada en la presencia de la propiedad 'static'
|
|
70
|
-
const isStaticRoute = route.hasOwnProperty('static');
|
|
71
|
-
|
|
72
|
-
global.registeredEndpoints.set(routeKey, {
|
|
73
|
-
method: route.method,
|
|
74
|
-
path: route.path,
|
|
75
|
-
controller: isStaticRoute ? 'STATIC_ROUTE' : (route.controller || 'N/A'),
|
|
76
|
-
handler: isStaticRoute ? 'StaticFileHandler' : (route.handler || 'N/A'),
|
|
77
|
-
isStatic: isStaticRoute,
|
|
78
|
-
auth: route.auth || 'none',
|
|
79
|
-
description: route.description || `Endpoint para ${route.path}`,
|
|
80
|
-
createdAt: new Date().toISOString()
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
logger.info(`[[HOOK]] - ${global.registeredEndpoints.size} endpoints almacenados en el registro global`);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
// Hook para registrar accesos al servidor
|
|
87
|
-
hooks.addAction('request_received', (req, res) => {
|
|
88
|
-
logger.info(`[[ACCESS]] - Nuevo acceso recibido: ${req.method} ${req.url} desde ${req.connection.remoteAddress || 'unknown'}`);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// Hook para registrar descargas o finalización de solicitudes
|
|
92
|
-
hooks.addAction('request_completed', (req, res) => {
|
|
93
|
-
logger.info(`[[DOWNLOAD/COMPLETED]] - Solicitud completada: ${req.method} ${req.url}`);
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
module.exports = { registerGeneralHooks };
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hooks del sistema de colas
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
function registerQueueHooks(hooks, logger) {
|
|
6
|
-
// Hooks para el sistema de colas
|
|
7
|
-
hooks.addAction('queue_processor_before_start', () => {
|
|
8
|
-
logger.info('[[QUEUE_SYSTEM]] - Iniciando procesador de colas...');
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
hooks.addAction('queue_processor_after_start', () => {
|
|
12
|
-
logger.info('[[QUEUE_SYSTEM]] - Procesador de colas iniciado exitosamente');
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
hooks.addAction('queue_processor_before_stop_on_error', () => {
|
|
16
|
-
logger.info('[[QUEUE_SYSTEM]] - Deteniendo procesador de colas debido a un error...');
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
hooks.addAction('queue_processor_after_stop_on_error', () => {
|
|
20
|
-
logger.info('[[QUEUE_SYSTEM]] - Procesador de colas detenido por error');
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
hooks.addAction('queue_job_created', async (job) => {
|
|
24
|
-
logger.info(`[[QUEUE_JOB]] - Nuevo trabajo creado: ${job.id} en cola ${job.queue}`);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
hooks.addAction('queue_job_processing', async (job) => {
|
|
28
|
-
logger.info(`[[QUEUE_JOB]] - Procesando trabajo: ${job.id} en cola ${job.queue}`);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
hooks.addAction('queue_job_completed', async (job) => {
|
|
32
|
-
logger.info(`[[QUEUE_JOB]] - Trabajo completado: ${job.id} en cola ${job.queue}`);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
hooks.addAction('queue_job_failed', async (job, error) => {
|
|
36
|
-
logger.error(`[[QUEUE_JOB]] - Trabajo fallido: ${job.id} en cola ${job.queue}. Error: ${error}`);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
hooks.addAction('queue_processor_iteration_start', async () => {
|
|
40
|
-
//logger.debug('[[QUEUE_PROCESSOR]] - Iniciando iteración de procesamiento de colas');
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
hooks.addAction('queue_processor_iteration_end', async () => {
|
|
44
|
-
//logger.debug('[[QUEUE_PROCESSOR]] - Finalizando iteración de procesamiento de colas');
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
hooks.addAction('qwen_queue_api_process_start', async (req, res) => {
|
|
48
|
-
logger.info('[[QWEN_QUEUE]] - Nueva solicitud a la cola de Qwen recibida');
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
hooks.addAction('qwen_queue_api_process_end', async (job, req, res) => {
|
|
52
|
-
logger.info(`[[QWEN_QUEUE]] - Solicitud a la cola de Qwen procesada. Job ID: ${job.id}`);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
hooks.addAction('qwen_queue_before_security_check', async (payload) => {
|
|
56
|
-
//logger.debug('[[QWEN_SECURITY]] - Verificando seguridad del prompt');
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
hooks.addAction('qwen_queue_after_command_execution', async (result, qwenCommand) => {
|
|
60
|
-
logger.info('[[QWEN_QUEUE]] - Comando Qwen ejecutado exitosamente');
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
module.exports = { registerQueueHooks };
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hooks específicos para RouteDirectoryLoader
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
function registerRouteDirectoryHooks(hooks, logger) {
|
|
6
|
-
// Hooks específicos para RouteDirectoryLoader
|
|
7
|
-
hooks.addAction('pre_directory_route_load', (data) => {
|
|
8
|
-
logger.info(`[[DIRECTORY_ROUTE_LOAD]] - Iniciando carga de rutas desde directorio: ${data.directoryPath}`);
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
hooks.addAction('pre_file_route_load', (data) => {
|
|
12
|
-
logger.info(`[[FILE_ROUTE_LOAD]] - Cargando rutas desde archivo: ${data.filePath}`);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
hooks.addAction('route_duplicate_detected', (data) => {
|
|
16
|
-
logger.warn(`[[ROUTE_DUPLICATE]] - Ruta duplicada detectada:`);
|
|
17
|
-
logger.warn(`Ruta sobreescrita: ${JSON.stringify(data.overwrittenRoute)}`);
|
|
18
|
-
logger.warn(`Nueva ruta: ${JSON.stringify(data.newRoute)}`);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
hooks.addAction('_route_loaded_from_directory', (data) => {
|
|
22
|
-
logger.info(`[[ROUTE_LOADED]] - Ruta cargada: ${data.route.method} ${data.route.path} desde ${data.sourceFile}`);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
hooks.addAction('post_directory_route_load', (data) => {
|
|
26
|
-
logger.info(`[[DIRECTORY_ROUTE_LOAD]] - Finalizada carga de rutas desde directorio. Total rutas: ${data.routesCount}`);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
hooks.addAction('pre_directory_routes_reload', (data) => {
|
|
30
|
-
logger.info(`[[DIRECTORY_ROUTE_RELOAD]] - Iniciando recarga de rutas desde directorio: ${data.directoryPath}`);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
hooks.addAction('post_directory_routes_reload', (data) => {
|
|
34
|
-
logger.info(`[[DIRECTORY_ROUTE_RELOAD]] - Finalizada recarga de rutas desde directorio. Total rutas: ${data.routesCount}`);
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
module.exports = { registerRouteDirectoryHooks };
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hooks relacionados con seguridad y tokens
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
function registerSecurityHooks(hooks, logger) {
|
|
6
|
-
// Hooks para seguimiento de validación de tokens
|
|
7
|
-
hooks.addAction('token_validation_start', (validationData) => {
|
|
8
|
-
logger.info(`[[TOKEN_VALIDATION_START]] - Inicio de validación de token: ${validationData.token}`);
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
hooks.addAction('token_validation_success', (validationData) => {
|
|
12
|
-
logger.info(`[[TOKEN_VALIDATION_SUCCESS]] - Token válido: ${validationData.token}, ID: ${validationData.tokenRecord.id}`);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
hooks.addAction('token_validation_failed', (validationData) => {
|
|
16
|
-
logger.info(`[[TOKEN_VALIDATION_FAILED]] - Token inválido: ${validationData.token}, Razón: ${validationData.reason}`);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
hooks.addAction('token_validation_error', (validationData) => {
|
|
20
|
-
logger.info(`[[TOKEN_VALIDATION_ERROR]] - Error validando token: ${validationData.token}, Error: ${validationData.error}`);
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
module.exports = { registerSecurityHooks };
|