blackcoffee2 2.1.0
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/CHANGELOG.md +664 -0
- package/LICENSE +201 -0
- package/NOTICE +25 -0
- package/README.md +246 -0
- package/apps.zip +0 -0
- package/bin/adminclient +105 -0
- package/bin/blackcoffee +133 -0
- package/cli/admin-users.js +282 -0
- package/cli/commands/app.js +561 -0
- package/cli/commands/config.js +182 -0
- package/cli/commands/db.js +257 -0
- package/cli/commands/server.js +200 -0
- package/config/applications.json +5 -0
- package/config/database.json +28 -0
- package/config/database.json.example +23 -0
- package/config/server.json +32 -0
- package/controllers/admin/AdminController.js +529 -0
- package/controllers/admin/AdminViewController.js +90 -0
- package/controllers/admin/AuthController.js +293 -0
- package/controllers/admin/DatabaseAdminController.js +218 -0
- package/core/SQLiteAdapter.js +333 -0
- package/core/appLoader.js +385 -0
- package/core/databasePoolManager.js +431 -0
- package/core/hotReload.js +363 -0
- package/data/ADMIN-README.md +145 -0
- package/data/CHANGELOG.md +48 -0
- package/data/GTK3-NODE-PROPOSALS.md +410 -0
- package/data/admin-db.js +150 -0
- package/data/admin-gui.js +452 -0
- package/data/blackcoffee_admin.db-shm +0 -0
- package/data/blackcoffee_admin.db-wal +0 -0
- package/data/migrations/001_create_admin_users.sql +33 -0
- package/docs/APP_HOOKS_HANDLER.md +432 -0
- package/docs/APP_HOOKS_REQUIREMENTS.md +588 -0
- package/docs/ARCHITECTURE.md +435 -0
- package/docs/CREAR_APP_Y_USAR_POOLS.md +1595 -0
- package/docs/EVENTS_APP_MANUAL.md +289 -0
- package/docs/INSITU_BINARY_UPLOAD_PROPOSAL.md +186 -0
- package/docs/INSITU_FIREWALL_EXCEPTION.md +187 -0
- package/docs/ROADMAP.md +242 -0
- package/docs/ROADMAP.md.backup +243 -0
- package/includes/404-hooks.js +423 -0
- package/includes/adminAuth.js +214 -0
- package/includes/adminExtension.js +53 -0
- package/includes/appHooks.js +302 -0
- package/includes/initAdminDb.js +115 -0
- package/includes/routeLoader.js +67 -0
- package/includes/sessions.js +223 -0
- package/issues/001-duplicate-module-loading.md +92 -0
- package/manuales/ADMIN_EXTENSION_COMMANDS_MANUAL.md +261 -0
- package/manuales/ADMIN_EXTENSION_HOOK_EXAMPLE.md +28 -0
- package/manuales/ADMIN_EXTENSION_INTEGRATION_MANUAL.md +232 -0
- package/manuales/CACHE_REGEX_COMMANDS.md +136 -0
- package/manuales/CACHE_SYSTEM_MAP.md +206 -0
- package/manuales/CREACION_DE_CONTROLADORES_INSITU.md +383 -0
- package/manuales/QUEUE_CLI_MODULE_MANUAL.md +289 -0
- package/manuales/QUEUE_SYSTEM_MANUAL.md +320 -0
- package/manuales/ROUTE_CACHE_MODULE_MANUAL.md +205 -0
- package/manuales/SESSION_MANAGER_GUIDE.md +529 -0
- package/manuales/SESSION_SECURITY_FLAGS.md +174 -0
- package/manuales/WAF_MODULE_MANUAL.md +229 -0
- package/manuales/after_route_handler_filter_example.md +116 -0
- package/manuales/after_route_handler_usage.md +130 -0
- package/manuales/an/303/241lisis-completo-insitu-framework.md +213 -0
- package/manuales/async_hooks_promises_guide.md +325 -0
- package/manuales/before_route_handler_filter_example.md +97 -0
- package/manuales/before_route_handler_usage.md +122 -0
- package/manuales/hooks_chaining_conditions_guide.md +261 -0
- package/manuales/hooks_filters_documentation.md +493 -0
- package/manuales/hooks_filters_documentation_en.md +493 -0
- package/manuales/hooks_vs_middlewares_comparison.md +87 -0
- package/manuales/manual-mvc-completo.md +934 -0
- package/manuales/modulos_administracion.md +89 -0
- package/manuales/router_execution_points.md +74 -0
- package/manuales/static_file_hooks_usage.md +222 -0
- package/models/AdminUserModel.js +132 -0
- package/package.json +45 -0
- package/programatically/PRoutes.js +89 -0
- package/programatically/initFlow.js +211 -0
- package/public/admin/css/db-pools.css +336 -0
- package/public/admin/css/styles.css +310 -0
- package/public/admin/database.html +312 -0
- package/public/admin/index.html +116 -0
- package/public/admin/js/app.js +470 -0
- package/public/admin/js/db-pools.js +253 -0
- package/public/admin/login.html +278 -0
- package/public/assets/css/styles.css +477 -0
- package/public/assets/js/main.js +89 -0
- package/public/index.html +136 -0
- package/public/templates/404.html +158 -0
- package/routes/admin-views.json +20 -0
- package/routes/admin.json +38 -0
- package/routes/auth.json +32 -0
- package/routes/static.json +18 -0
- package/server.js +299 -0
- package/test-aplicacion.con-logisession/BlackCoffee.js +226 -0
- package/test-aplicacion.con-logisession/SSL_SETUP.md +53 -0
- package/test-aplicacion.con-logisession/certs/ca-certificate.pem +32 -0
- package/test-aplicacion.con-logisession/certs/ca-private-key.pem +52 -0
- package/test-aplicacion.con-logisession/certs/certificate-2048.pem +22 -0
- package/test-aplicacion.con-logisession/certs/certificate.pem +32 -0
- package/test-aplicacion.con-logisession/certs/private-key-2048.pem +28 -0
- package/test-aplicacion.con-logisession/certs/private-key.pem +52 -0
- package/test-aplicacion.con-logisession/config/iaQueueSetup.js +84 -0
- package/test-aplicacion.con-logisession/config/qwen-rules.json +39 -0
- package/test-aplicacion.con-logisession/controllers/analyticsController.js +117 -0
- package/test-aplicacion.con-logisession/controllers/auth/AdminAuthController.js +142 -0
- package/test-aplicacion.con-logisession/controllers/auth/AuthController.js +439 -0
- package/test-aplicacion.con-logisession/controllers/auth/AuthViewController.js +223 -0
- package/test-aplicacion.con-logisession/controllers/endpointController.js +66 -0
- package/test-aplicacion.con-logisession/controllers/example.js +183 -0
- package/test-aplicacion.con-logisession/controllers/iaQueueController.js +367 -0
- package/test-aplicacion.con-logisession/controllers/queueController.js +206 -0
- package/test-aplicacion.con-logisession/controllers/qwenQueueController.js +197 -0
- package/test-aplicacion.con-logisession/controllers/test.js +0 -0
- package/test-aplicacion.con-logisession/controllers/tracking/EventsNoFinishController.js +78 -0
- package/test-aplicacion.con-logisession/controllers/tracking/TrackingController.js +412 -0
- package/test-aplicacion.con-logisession/controllers/tracking/TrackingControllerWithLoadModel.js +437 -0
- package/test-aplicacion.con-logisession/hooks/admin-hooks.js +20 -0
- package/test-aplicacion.con-logisession/hooks/general-hooks.js +97 -0
- package/test-aplicacion.con-logisession/hooks/queue-hooks.js +64 -0
- package/test-aplicacion.con-logisession/hooks/route-directory-hooks.js +38 -0
- package/test-aplicacion.con-logisession/hooks/security-hooks.js +24 -0
- package/test-aplicacion.con-logisession/insitu-admin-client/README.md +69 -0
- package/test-aplicacion.con-logisession/insitu-admin-client/package.json +23 -0
- package/test-aplicacion.con-logisession/insitu-admin-client.js +257 -0
- package/test-aplicacion.con-logisession/models/ExampleModel.js +88 -0
- package/test-aplicacion.con-logisession/models/QueueJobModel.js +263 -0
- package/test-aplicacion.con-logisession/models/TokenModel.js +207 -0
- package/test-aplicacion.con-logisession/models/auth/AuthModel.js +66 -0
- package/test-aplicacion.con-logisession/models/auth/UserModel.js +189 -0
- package/test-aplicacion.con-logisession/models/tracking/CompletedCartModel.js +213 -0
- package/test-aplicacion.con-logisession/models/tracking/EventModel.js +366 -0
- package/test-aplicacion.con-logisession/models/tracking/EventsNoFinishModel.js +131 -0
- package/test-aplicacion.con-logisession/models/tracking/SessionModel.js +360 -0
- package/test-aplicacion.con-logisession/models/tracking/SiteFlowModel.js +286 -0
- package/test-aplicacion.con-logisession/models/tracking/TokenModel.js +207 -0
- package/test-aplicacion.con-logisession/package-lock.json +3313 -0
- package/test-aplicacion.con-logisession/package.json +32 -0
- package/test-aplicacion.con-logisession/public/blackcoffee-welcome/index.html +1339 -0
- package/test-aplicacion.con-logisession/public/css/style.css +64 -0
- package/test-aplicacion.con-logisession/public/ejemplo-estatica/index.html +18 -0
- package/test-aplicacion.con-logisession/public/ejemplo-estatica/script.js +16 -0
- package/test-aplicacion.con-logisession/public/ejemplo-estatica/styles.css +43 -0
- package/test-aplicacion.con-logisession/public/images/logo.svg +7 -0
- package/test-aplicacion.con-logisession/public/js/main.js +67 -0
- package/test-aplicacion.con-logisession/routes/analytics-routes.json +8 -0
- package/test-aplicacion.con-logisession/routes/auth-routes.json +98 -0
- package/test-aplicacion.con-logisession/routes/blackcoffee-welcome-routes.json +20 -0
- package/test-aplicacion.con-logisession/routes/duplicate-test-routes.json.disabled +16 -0
- package/test-aplicacion.con-logisession/routes/ejemplo-estatica-routes.json +11 -0
- package/test-aplicacion.con-logisession/routes/endpoints-routes.json +8 -0
- package/test-aplicacion.con-logisession/routes/ia-queue-routes.json +26 -0
- package/test-aplicacion.con-logisession/routes/product-routes.json.disabled +20 -0
- package/test-aplicacion.con-logisession/routes/queue-routes.json +32 -0
- package/test-aplicacion.con-logisession/routes/qwen-routes.json +14 -0
- package/test-aplicacion.con-logisession/routes/static-routes.json +29 -0
- package/test-aplicacion.con-logisession/routes/tracking-routes.json +58 -0
- package/test-aplicacion.con-logisession/routes/tracking-with-loadmodel-routes.json +51 -0
- package/test-aplicacion.con-logisession/utils/dbAdapter.js +88 -0
- package/test-aplicacion.con-logisession/utils/qbWrapper.js +4 -0
- package/test-aplicacion.con-logisession/utils/queueProcessor.js +305 -0
- package/test-aplicacion.con-logisession/utils/qwenRulesService.js +131 -0
- package/test-aplicacion.con-logisession/utils/tokenHelper.js +22 -0
- package/test-aplicacion.con-logisession/views/auth/dashboard.html +443 -0
- package/test-aplicacion.con-logisession/views/auth/forgot-password.html +200 -0
- package/test-aplicacion.con-logisession/views/auth/login.html +213 -0
- package/test-aplicacion.con-logisession/views/auth/register.html +294 -0
- package/test-aplicacion.con-logisession/views/contact/form.html +47 -0
- package/test-aplicacion.con-logisession/views/products/index.html +39 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
# Guía para Crear Controladores en el Framework Insitu
|
|
2
|
+
|
|
3
|
+
## Introducción
|
|
4
|
+
|
|
5
|
+
Los controladores en el framework Insitu son componentes fundamentales que forman parte del patrón MVC (Modelo-Vista-Controlador). Son responsables de manejar las solicitudes HTTP, interactuar con los modelos para obtener o manipular datos, y devolver respuestas apropiadas al cliente.
|
|
6
|
+
|
|
7
|
+
## Estructura Básica de un Controlador
|
|
8
|
+
|
|
9
|
+
Un controlador en Insitu debe extender la clase `ControllerBase` que proporciona funcionalidades comunes como:
|
|
10
|
+
|
|
11
|
+
- Manejo de vistas y motores de plantillas
|
|
12
|
+
- Acceso a datos de solicitud (query, body, params)
|
|
13
|
+
- Métodos para respuesta (JSON, vistas, redirecciones)
|
|
14
|
+
- Carga y manejo de modelos
|
|
15
|
+
|
|
16
|
+
### Ejemplo Básico de Controlador
|
|
17
|
+
|
|
18
|
+
```javascript
|
|
19
|
+
const { ControllerBase } = require('insitu');
|
|
20
|
+
|
|
21
|
+
class EjemploController extends ControllerBase {
|
|
22
|
+
constructor() {
|
|
23
|
+
super();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Método para manejar una solicitud GET
|
|
27
|
+
async index(req, res) {
|
|
28
|
+
// Establecer variables para la vista
|
|
29
|
+
this.set('titulo', 'Página de Inicio');
|
|
30
|
+
this.set('mensaje', '¡Bienvenido al framework Insitu!');
|
|
31
|
+
|
|
32
|
+
// Renderizar una vista
|
|
33
|
+
this.render(res, 'inicio', {
|
|
34
|
+
usuario: 'Desarrollador',
|
|
35
|
+
fecha: new Date().toISOString()
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Método para manejar una solicitud POST
|
|
40
|
+
async crear(req, res) {
|
|
41
|
+
const datos = req.body;
|
|
42
|
+
|
|
43
|
+
// Aquí iría la lógica para crear un recurso
|
|
44
|
+
// Por ejemplo, usando un modelo
|
|
45
|
+
|
|
46
|
+
this.json(res, {
|
|
47
|
+
success: true,
|
|
48
|
+
message: 'Recurso creado exitosamente',
|
|
49
|
+
data: datos
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module.exports = EjemploController;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Componentes Importantes
|
|
58
|
+
|
|
59
|
+
### ControllerBase
|
|
60
|
+
|
|
61
|
+
La clase base `ControllerBase` proporciona varios métodos útiles:
|
|
62
|
+
|
|
63
|
+
- `set(key, value)` - Establece variables para la vista
|
|
64
|
+
- `view(viewName, data, options)` - Renderiza una vista sin enviarla como respuesta
|
|
65
|
+
- `render(res, viewName, data, options)` - Renderiza una vista y la envía como respuesta HTTP
|
|
66
|
+
- `partial(viewName, data)` - Renderiza una vista parcial (sin layout)
|
|
67
|
+
- `redirect(res, url)` - Redirecciona a otra URL
|
|
68
|
+
- `json(res, data, statusCode)` - Envía una respuesta JSON
|
|
69
|
+
- `input(key, defaultValue)` - Obtiene un valor de la solicitud (query, body o params)
|
|
70
|
+
- `loadModel(modelName, options)` - Carga un modelo para su uso en el controlador
|
|
71
|
+
|
|
72
|
+
### Interacción con Modelos
|
|
73
|
+
|
|
74
|
+
Los controladores pueden interactuar con modelos para gestionar datos:
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
const { ControllerBase } = require('insitu');
|
|
78
|
+
|
|
79
|
+
class UsuarioController extends ControllerBase {
|
|
80
|
+
constructor() {
|
|
81
|
+
super();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async listar(req, res) {
|
|
85
|
+
try {
|
|
86
|
+
// Cargar el modelo de usuario
|
|
87
|
+
const userModel = this.loadModel('User');
|
|
88
|
+
|
|
89
|
+
// Obtener todos los usuarios
|
|
90
|
+
const usuarios = await userModel.find({});
|
|
91
|
+
|
|
92
|
+
// Pasar los usuarios a la vista
|
|
93
|
+
this.set('usuarios', usuarios);
|
|
94
|
+
this.render(res, 'usuarios/lista');
|
|
95
|
+
} catch (error) {
|
|
96
|
+
this.json(res, { error: error.message }, 500);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async crear(req, res) {
|
|
101
|
+
try {
|
|
102
|
+
const userData = req.body;
|
|
103
|
+
|
|
104
|
+
// Cargar el modelo de usuario
|
|
105
|
+
const userModel = this.loadModel('User');
|
|
106
|
+
|
|
107
|
+
// Crear un nuevo usuario
|
|
108
|
+
const nuevoUsuario = await userModel.create(userData);
|
|
109
|
+
|
|
110
|
+
this.json(res, {
|
|
111
|
+
success: true,
|
|
112
|
+
data: nuevoUsuario
|
|
113
|
+
}, 201);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
this.json(res, { error: error.message }, 500);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
module.exports = UsuarioController;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Definición de Rutas
|
|
124
|
+
|
|
125
|
+
Para conectar tus controladores con rutas, puedes usar el sistema de enrutamiento de Insitu:
|
|
126
|
+
|
|
127
|
+
### En un archivo de rutas (por ejemplo, routes.json):
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"routes": [
|
|
132
|
+
{
|
|
133
|
+
"method": "GET",
|
|
134
|
+
"path": "/usuarios",
|
|
135
|
+
"handler": "./controllers/UsuarioController.listar"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"method": "POST",
|
|
139
|
+
"path": "/usuarios",
|
|
140
|
+
"handler": "./controllers/UsuarioController.crear"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"method": "GET",
|
|
144
|
+
"path": "/usuarios/:id",
|
|
145
|
+
"handler": "./controllers/UsuarioController.obtenerPorId"
|
|
146
|
+
}
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### O directamente en tu código de inicialización:
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
const { Insitu, Router } = require('insitu');
|
|
155
|
+
const UsuarioController = require('./controllers/UsuarioController');
|
|
156
|
+
|
|
157
|
+
const app = new Insitu();
|
|
158
|
+
const router = new Router();
|
|
159
|
+
|
|
160
|
+
const usuarioController = new UsuarioController();
|
|
161
|
+
|
|
162
|
+
router.get('/usuarios', (req, res) => {
|
|
163
|
+
usuarioController.listar(req, res);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
router.post('/usuarios', (req, res) => {
|
|
167
|
+
usuarioController.crear(req, res);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
app.use(router);
|
|
171
|
+
|
|
172
|
+
app.listen(3000, () => {
|
|
173
|
+
console.log('Servidor corriendo en puerto 3000');
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Importante: Manejo de Contexto de los Métodos
|
|
178
|
+
|
|
179
|
+
Cuando se exportan métodos de un controlador para ser usados como handlers de rutas, es crítico mantener el contexto `this` correcto. Si no se hace correctamente, métodos como `this.json()`, `this.set()`, `this.input()`, etc., no funcionarán.
|
|
180
|
+
|
|
181
|
+
**Forma Incorrecta:**
|
|
182
|
+
```javascript
|
|
183
|
+
// Esto causará un error "Cannot read property 'json' of undefined"
|
|
184
|
+
module.exports = new UsuarioController();
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Forma Correcta:**
|
|
188
|
+
```javascript
|
|
189
|
+
// Crear una instancia del controlador
|
|
190
|
+
const usuarioController = new UsuarioController();
|
|
191
|
+
|
|
192
|
+
// Asegurar que todos los métodos tengan el contexto correcto
|
|
193
|
+
module.exports = {
|
|
194
|
+
listar: usuarioController.listar.bind(usuarioController),
|
|
195
|
+
crear: usuarioController.crear.bind(usuarioController),
|
|
196
|
+
obtenerPorId: usuarioController.obtenerPorId.bind(usuarioController)
|
|
197
|
+
};
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Esto es necesario porque cuando el cargador de rutas obtiene una función específica de un objeto y la llama directamente, pierde el contexto `this`. Usando `.bind()`, nos aseguramos de que `this` siempre se refiera a la instancia correcta del controlador.
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Buenas Prácticas
|
|
204
|
+
|
|
205
|
+
### 1. Organización de Archivos
|
|
206
|
+
|
|
207
|
+
Organiza tus controladores en una estructura de directorios clara:
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
proyecto/
|
|
211
|
+
├── controllers/
|
|
212
|
+
│ ├── UsuarioController.js
|
|
213
|
+
│ ├── ProductoController.js
|
|
214
|
+
│ └── HomeController.js
|
|
215
|
+
├── models/
|
|
216
|
+
│ ├── User.js
|
|
217
|
+
│ └── Product.js
|
|
218
|
+
├── views/
|
|
219
|
+
│ ├── home/
|
|
220
|
+
│ │ └── index.html
|
|
221
|
+
│ └── usuarios/
|
|
222
|
+
│ ├── lista.html
|
|
223
|
+
│ └── detalle.html
|
|
224
|
+
└── routes/
|
|
225
|
+
└── routes.json
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### 2. Manejo de Errores
|
|
229
|
+
|
|
230
|
+
Siempre implementa manejo de errores adecuado:
|
|
231
|
+
|
|
232
|
+
```javascript
|
|
233
|
+
async listar(req, res) {
|
|
234
|
+
try {
|
|
235
|
+
const modelo = this.loadModel('MiModelo');
|
|
236
|
+
const datos = await modelo.find({});
|
|
237
|
+
this.json(res, { success: true, data: datos });
|
|
238
|
+
} catch (error) {
|
|
239
|
+
console.error('Error en listar:', error);
|
|
240
|
+
this.json(res, {
|
|
241
|
+
success: false,
|
|
242
|
+
error: 'Ocurrió un error al procesar la solicitud'
|
|
243
|
+
}, 500);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### 3. Validación de Datos
|
|
249
|
+
|
|
250
|
+
Utiliza el middleware de validación de Insitu para validar entradas:
|
|
251
|
+
|
|
252
|
+
```javascript
|
|
253
|
+
const { Validator } = require('insitu');
|
|
254
|
+
|
|
255
|
+
// En tu archivo de rutas
|
|
256
|
+
router.post('/usuarios',
|
|
257
|
+
Validator.validate({
|
|
258
|
+
body: {
|
|
259
|
+
nombre: { type: 'string', required: true, minLength: 2 },
|
|
260
|
+
email: { type: 'string', required: true, format: 'email' },
|
|
261
|
+
edad: { type: 'number', min: 0, max: 120 }
|
|
262
|
+
}
|
|
263
|
+
}),
|
|
264
|
+
(req, res) => {
|
|
265
|
+
usuarioController.crear(req, res);
|
|
266
|
+
}
|
|
267
|
+
);
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### 4. Uso de Métodos HTTP Apropiados
|
|
271
|
+
|
|
272
|
+
Sigue las convenciones REST para el uso de métodos HTTP:
|
|
273
|
+
|
|
274
|
+
- `GET` - Obtener recursos
|
|
275
|
+
- `POST` - Crear nuevos recursos
|
|
276
|
+
- `PUT/PATCH` - Actualizar recursos existentes
|
|
277
|
+
- `DELETE` - Eliminar recursos
|
|
278
|
+
|
|
279
|
+
## Ejemplo Completo
|
|
280
|
+
|
|
281
|
+
Aquí tienes un ejemplo completo de un controlador para gestionar productos:
|
|
282
|
+
|
|
283
|
+
```javascript
|
|
284
|
+
const { ControllerBase } = require('insitu');
|
|
285
|
+
|
|
286
|
+
class ProductoController extends ControllerBase {
|
|
287
|
+
constructor() {
|
|
288
|
+
super();
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Obtener todos los productos
|
|
292
|
+
async listar(req, res) {
|
|
293
|
+
try {
|
|
294
|
+
const productoModel = this.loadModel('Producto');
|
|
295
|
+
const productos = await productoModel.find({});
|
|
296
|
+
|
|
297
|
+
this.set('productos', productos);
|
|
298
|
+
this.set('titulo', 'Lista de Productos');
|
|
299
|
+
this.render(res, 'productos/lista');
|
|
300
|
+
} catch (error) {
|
|
301
|
+
this.json(res, { error: error.message }, 500);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Obtener un producto por ID
|
|
306
|
+
async obtenerPorId(req, res) {
|
|
307
|
+
try {
|
|
308
|
+
const id = this.input('id');
|
|
309
|
+
const productoModel = this.loadModel('Producto');
|
|
310
|
+
const producto = await productoModel.findOne({ id: parseInt(id) });
|
|
311
|
+
|
|
312
|
+
if (!producto) {
|
|
313
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
314
|
+
res.end(JSON.stringify({ error: 'Producto no encontrado' }));
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
this.json(res, { success: true, data: producto });
|
|
319
|
+
} catch (error) {
|
|
320
|
+
this.json(res, { error: error.message }, 500);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Crear un nuevo producto
|
|
325
|
+
async crear(req, res) {
|
|
326
|
+
try {
|
|
327
|
+
const productoData = this.allInput();
|
|
328
|
+
const productoModel = this.loadModel('Producto');
|
|
329
|
+
const nuevoProducto = await productoModel.create(productoData);
|
|
330
|
+
|
|
331
|
+
this.json(res, {
|
|
332
|
+
success: true,
|
|
333
|
+
data: nuevoProducto
|
|
334
|
+
}, 201);
|
|
335
|
+
} catch (error) {
|
|
336
|
+
this.json(res, { error: error.message }, 500);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Actualizar un producto
|
|
341
|
+
async actualizar(req, res) {
|
|
342
|
+
try {
|
|
343
|
+
const id = this.input('id');
|
|
344
|
+
const productoData = this.allInput();
|
|
345
|
+
const productoModel = this.loadModel('Producto');
|
|
346
|
+
|
|
347
|
+
const resultado = await productoModel.update({ id: parseInt(id) }, productoData);
|
|
348
|
+
|
|
349
|
+
this.json(res, {
|
|
350
|
+
success: true,
|
|
351
|
+
message: 'Producto actualizado',
|
|
352
|
+
affectedRows: resultado
|
|
353
|
+
});
|
|
354
|
+
} catch (error) {
|
|
355
|
+
this.json(res, { error: error.message }, 500);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Eliminar un producto
|
|
360
|
+
async eliminar(req, res) {
|
|
361
|
+
try {
|
|
362
|
+
const id = this.input('id');
|
|
363
|
+
const productoModel = this.loadModel('Producto');
|
|
364
|
+
|
|
365
|
+
const resultado = await productoModel.delete({ id: parseInt(id) });
|
|
366
|
+
|
|
367
|
+
this.json(res, {
|
|
368
|
+
success: true,
|
|
369
|
+
message: 'Producto eliminado',
|
|
370
|
+
deletedRows: resultado
|
|
371
|
+
});
|
|
372
|
+
} catch (error) {
|
|
373
|
+
this.json(res, { error: error.message }, 500);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
module.exports = ProductoController;
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
## Conclusión
|
|
382
|
+
|
|
383
|
+
Crear controladores en el framework Insitu es sencillo gracias a la clase `ControllerBase` que proporciona funcionalidades comunes. Recuerda seguir las buenas prácticas para mantener tu código limpio, seguro y mantenible. La arquitectura MVC del framework te permite separar claramente la lógica de negocio (modelos), la presentación (vistas) y el flujo de control (controladores).
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# Manual del Módulo CLI de Gestión de Colas para Insitu Framework
|
|
2
|
+
|
|
3
|
+
## Tabla de Contenidos
|
|
4
|
+
1. [Introducción](#introducción)
|
|
5
|
+
2. [Comandos Disponibles](#comandos-disponibles)
|
|
6
|
+
3. [Uso Básico](#uso-básico)
|
|
7
|
+
4. [Uso Avanzado](#uso-avanzado)
|
|
8
|
+
5. [Ejemplos de Uso](#ejemplos-de-uso)
|
|
9
|
+
6. [Solución de Problemas](#solución-de-problemas)
|
|
10
|
+
|
|
11
|
+
## Introducción
|
|
12
|
+
|
|
13
|
+
El módulo de Gestión de Colas es una extensión del sistema de administración CLI de Insitu Framework que permite monitorear y gestionar las colas de tareas del sistema. Proporciona comandos para ver el estado de las colas, pausarlas, reanudarlas, limpiarlas y gestionar tareas fallidas.
|
|
14
|
+
|
|
15
|
+
## Comandos Disponibles
|
|
16
|
+
|
|
17
|
+
### Comandos Generales de Colas
|
|
18
|
+
- `queues`: Muestra el estado de todas las colas del sistema
|
|
19
|
+
- `queue-info`: Muestra información detallada de una cola específica
|
|
20
|
+
- `queue-pause`: Pausa una cola específica
|
|
21
|
+
- `queue-resume`: Reanuda una cola específica
|
|
22
|
+
- `queue-clear`: Limpia las tareas pendientes de una cola específica
|
|
23
|
+
- `queue-retry-failed`: Reintenta las tareas fallidas de una cola específica
|
|
24
|
+
|
|
25
|
+
## Uso Básico
|
|
26
|
+
|
|
27
|
+
### Conectar al Sistema de Administración
|
|
28
|
+
|
|
29
|
+
Para acceder al módulo de gestión de colas, primero debes conectarte al sistema de administración:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
telnet localhost 9999
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
O alternativamente:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
nc localhost 9999
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Ver el estado de todas las colas
|
|
42
|
+
|
|
43
|
+
Comando: `queues`
|
|
44
|
+
|
|
45
|
+
Este comando muestra el estado de todas las colas registradas en el sistema:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
> queues
|
|
49
|
+
|
|
50
|
+
=== Colas del Sistema ===
|
|
51
|
+
imagenes:
|
|
52
|
+
Concurrencia: 3/3
|
|
53
|
+
Tareas pendientes: 0
|
|
54
|
+
Tareas en proceso: 0
|
|
55
|
+
Tareas fallidas: 0
|
|
56
|
+
Estado: INACTIVO
|
|
57
|
+
Reintentos: 2
|
|
58
|
+
Retraso de reintento: 1000ms
|
|
59
|
+
|
|
60
|
+
correos:
|
|
61
|
+
Concurrencia: 2/2
|
|
62
|
+
Tareas pendientes: 1
|
|
63
|
+
Tareas en proceso: 1
|
|
64
|
+
Tareas fallidas: 0
|
|
65
|
+
Estado: PROCESANDO
|
|
66
|
+
Reintentos: 3
|
|
67
|
+
Retraso de reintento: 2000ms
|
|
68
|
+
|
|
69
|
+
pagos:
|
|
70
|
+
Concurrencia: 1/1
|
|
71
|
+
Tareas pendientes: 0
|
|
72
|
+
Tareas en proceso: 0
|
|
73
|
+
Tareas fallidas: 2
|
|
74
|
+
Estado: INACTIVO
|
|
75
|
+
Reintentos: 5
|
|
76
|
+
Retraso de reintento: 3000ms
|
|
77
|
+
|
|
78
|
+
backups:
|
|
79
|
+
Concurrencia: 1/1
|
|
80
|
+
Tareas pendientes: 0
|
|
81
|
+
Tareas en proceso: 0
|
|
82
|
+
Tareas fallidas: 0
|
|
83
|
+
Estado: INACTIVO
|
|
84
|
+
Reintentos: 3
|
|
85
|
+
Retraso de reintento: 5000ms
|
|
86
|
+
|
|
87
|
+
>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Ver información detallada de una cola específica
|
|
91
|
+
|
|
92
|
+
Comando: `queue-info`
|
|
93
|
+
|
|
94
|
+
Este comando solicita el nombre de una cola y muestra información detallada:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
> queue-info
|
|
98
|
+
|
|
99
|
+
Introduce el nombre de la cola:
|
|
100
|
+
> pagos
|
|
101
|
+
|
|
102
|
+
=== Información de la Cola: pagos ===
|
|
103
|
+
Concurrencia: 1/1
|
|
104
|
+
Tareas pendientes: 0
|
|
105
|
+
Tareas en proceso: 0
|
|
106
|
+
Tareas fallidas: 2
|
|
107
|
+
Estado: INACTIVO
|
|
108
|
+
Reintentos: 5
|
|
109
|
+
Retraso de reintento: 3000ms
|
|
110
|
+
Total de workers: 0
|
|
111
|
+
|
|
112
|
+
>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Uso Avanzado
|
|
116
|
+
|
|
117
|
+
### Pausar una cola
|
|
118
|
+
|
|
119
|
+
Comando: `queue-pause`
|
|
120
|
+
|
|
121
|
+
Pausa temporalmente el procesamiento de tareas en una cola específica:
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
> queue-pause
|
|
125
|
+
|
|
126
|
+
Introduce el nombre de la cola:
|
|
127
|
+
> correos
|
|
128
|
+
|
|
129
|
+
✅ Cola 'correos' pausada exitosamente.
|
|
130
|
+
|
|
131
|
+
>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Cuando una cola está pausada, no procesará nuevas tareas, pero las tareas que ya estaban en proceso se completarán normalmente.
|
|
135
|
+
|
|
136
|
+
### Reanudar una cola
|
|
137
|
+
|
|
138
|
+
Comando: `queue-resume`
|
|
139
|
+
|
|
140
|
+
Reanuda el procesamiento de tareas en una cola específica:
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
> queue-resume
|
|
144
|
+
|
|
145
|
+
Introduce el nombre de la cola:
|
|
146
|
+
> correos
|
|
147
|
+
|
|
148
|
+
✅ Cola 'correos' reanudada exitosamente.
|
|
149
|
+
|
|
150
|
+
>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Limpiar una cola
|
|
154
|
+
|
|
155
|
+
Comando: `queue-clear`
|
|
156
|
+
|
|
157
|
+
Elimina todas las tareas pendientes de una cola específica (no afecta a las tareas que ya están en proceso):
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
> queue-clear
|
|
161
|
+
|
|
162
|
+
Introduce el nombre de la cola:
|
|
163
|
+
> imagenes
|
|
164
|
+
|
|
165
|
+
✅ Cola 'imagenes' limpiada exitosamente (tareas pendientes eliminadas).
|
|
166
|
+
|
|
167
|
+
>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Reintentar tareas fallidas
|
|
171
|
+
|
|
172
|
+
Comando: `queue-retry-failed`
|
|
173
|
+
|
|
174
|
+
Reintenta todas las tareas que han fallado definitivamente en una cola específica:
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
> queue-retry-failed
|
|
178
|
+
|
|
179
|
+
Introduce el nombre de la cola:
|
|
180
|
+
> pagos
|
|
181
|
+
|
|
182
|
+
✅ Reintento de tareas fallidas iniciado para la cola 'pagos'.
|
|
183
|
+
|
|
184
|
+
>
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Ejemplos de Uso
|
|
188
|
+
|
|
189
|
+
### Ejemplo 1: Monitoreo de colas
|
|
190
|
+
|
|
191
|
+
Para monitorear constantemente el estado de las colas, puedes usar el comando `queues` repetidamente:
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
> queues
|
|
195
|
+
imagenes: Pendientes=0, En proceso=2, Fallidas=0, Pausada=false
|
|
196
|
+
correos: Pendientes=5, En proceso=1, Fallidas=0, Pausada=false
|
|
197
|
+
pagos: Pendientes=0, En proceso=0, Fallidas=1, Pausada=false
|
|
198
|
+
backups: Pendientes=0, En proceso=0, Fallidas=0, Pausada=false
|
|
199
|
+
>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Ejemplo 2: Gestión de alta carga
|
|
203
|
+
|
|
204
|
+
Si una cola está recibiendo demasiadas tareas y necesitas detener temporalmente el procesamiento:
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
> queue-pause
|
|
208
|
+
Introduce el nombre de la cola:
|
|
209
|
+
> correos
|
|
210
|
+
✅ Cola 'correos' pausada exitosamente.
|
|
211
|
+
|
|
212
|
+
> queues
|
|
213
|
+
correos: Pendientes=50, En proceso=0, Fallidas=0, Pausada=true
|
|
214
|
+
>
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Luego, cuando la carga disminuya, puedes reanudar:
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
> queue-resume
|
|
221
|
+
Introduce el nombre de la cola:
|
|
222
|
+
> correos
|
|
223
|
+
✅ Cola 'correos' reanudada exitosamente.
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Ejemplo 3: Manejo de tareas fallidas
|
|
227
|
+
|
|
228
|
+
Si una cola tiene tareas fallidas que deseas reintentar:
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
> queues
|
|
232
|
+
pagos: Pendientes=0, En proceso=0, Fallidas=3, Pausada=false
|
|
233
|
+
|
|
234
|
+
> queue-retry-failed
|
|
235
|
+
Introduce el nombre de la cola:
|
|
236
|
+
> pagos
|
|
237
|
+
✅ Reintento de tareas fallidas iniciado para la cola 'pagos'.
|
|
238
|
+
|
|
239
|
+
> queues
|
|
240
|
+
pagos: Pendientes=3, En proceso=0, Fallidas=0, Pausada=false
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Solución de Problemas
|
|
244
|
+
|
|
245
|
+
### Problema: Comando no reconocido
|
|
246
|
+
|
|
247
|
+
**Síntoma**: El sistema responde con "Comando desconocido para el módulo de gestión de colas"
|
|
248
|
+
|
|
249
|
+
**Solución**: Verifica que estás usando uno de los comandos válidos: `queues`, `queue-info`, `queue-pause`, `queue-resume`, `queue-clear`, `queue-retry-failed`
|
|
250
|
+
|
|
251
|
+
### Problema: Cola no encontrada
|
|
252
|
+
|
|
253
|
+
**Síntoma**: El sistema responde con "❌ Cola 'nombre' no encontrada."
|
|
254
|
+
|
|
255
|
+
**Solución**: Verifica que el nombre de la cola es correcto. Puedes usar el comando `queues` para ver la lista de colas disponibles.
|
|
256
|
+
|
|
257
|
+
### Problema: Cola no responde
|
|
258
|
+
|
|
259
|
+
**Síntoma**: Las tareas no se procesan aunque la cola esté activa
|
|
260
|
+
|
|
261
|
+
**Solución**:
|
|
262
|
+
1. Verifica el estado con `queues`
|
|
263
|
+
2. Comprueba si la cola está pausada
|
|
264
|
+
3. Verifica que el sistema de colas esté iniciado en la aplicación
|
|
265
|
+
4. Revisa los logs de la aplicación para posibles errores
|
|
266
|
+
|
|
267
|
+
### Problema: Tareas acumulándose
|
|
268
|
+
|
|
269
|
+
**Síntoma**: La cola tiene muchas tareas pendientes que no se procesan
|
|
270
|
+
|
|
271
|
+
**Soluciones posibles**:
|
|
272
|
+
1. Aumenta la concurrencia de la cola en la configuración de la aplicación
|
|
273
|
+
2. Pausa temporalmente la cola si hay sobrecarga: `queue-pause`
|
|
274
|
+
3. Verifica que las tareas no estén fallando continuamente
|
|
275
|
+
|
|
276
|
+
## Compatibilidad
|
|
277
|
+
|
|
278
|
+
- **Versión mínima del framework**: Insitu 1.0.0
|
|
279
|
+
- **Puerto de administración**: Por defecto 9999 (configurable)
|
|
280
|
+
- **Acceso**: Solo desde localhost por razones de seguridad
|
|
281
|
+
- **Protocolo**: Conexión TCP con interfaz de línea de comandos
|
|
282
|
+
|
|
283
|
+
## Autor
|
|
284
|
+
|
|
285
|
+
Insitu Framework Team
|
|
286
|
+
|
|
287
|
+
## Versión
|
|
288
|
+
|
|
289
|
+
v1.0.0
|