inicializacion del proyecto.
This commit is contained in:
10
README.md
10
README.md
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
### Modulos Requeridos para el funcionamiento
|
### Modulos Requeridos para el funcionamiento
|
||||||
ejs
|
ejs
|
||||||
mysql : se cambiara a mysql2
|
mysql2
|
||||||
express-myconnection
|
express-myconnection
|
||||||
express
|
express
|
||||||
express-session: necesario para controlar las ssiones
|
express-session: necesario para controlar las ssiones
|
||||||
@@ -16,18 +16,16 @@ nodemon
|
|||||||
express-fileupload
|
express-fileupload
|
||||||
cors
|
cors
|
||||||
jsonwebtoken
|
jsonwebtoken
|
||||||
|
uuid
|
||||||
npm install mysql2
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### recomendaciones previas
|
### recomendaciones previas
|
||||||
npm install -s //-s para guardar los datos
|
npm install -s //-s para guardar los datos
|
||||||
|
|
||||||
|
|
||||||
### instalacion de modulos
|
### instalacion de modulos
|
||||||
|
Se recomienda usar `mysql2` en lugar de `mysql` por su soporte a Promises y mejor rendimiento.
|
||||||
```bash
|
```bash
|
||||||
npm install -s mysql express-myconnection express morgan telegraf nodemon ejs express-fileupload axios jsonwebtoken
|
npm install -s mysql2 express-myconnection express morgan telegraf nodemon ejs express-fileupload axios jsonwebtoken cors express-session uuid
|
||||||
```
|
```
|
||||||
|
|
||||||
### Modulo control de origenes
|
### Modulo control de origenes
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ app.use(session({
|
|||||||
resave: false,//no se guarde cada vez que se hace un cambio
|
resave: false,//no se guarde cada vez que se hace un cambio
|
||||||
saveUninitialized: true,//guardar sesion aunque no haya datos
|
saveUninitialized: true,//guardar sesion aunque no haya datos
|
||||||
cookie: { secure: global.config.sessionStorage.cookie }//true solo se envia por https
|
cookie: { secure: global.config.sessionStorage.cookie }//true solo se envia por https
|
||||||
|
// FIX: La cookie de sesión debe ser segura en producción.
|
||||||
|
// Se establece dinámicamente en 'true' si el entorno es 'production'.
|
||||||
|
// Esto requiere que la app en producción se sirva sobre HTTPS.
|
||||||
|
//cookie: { secure: process.env.NODE_ENV === 'production' }
|
||||||
}));
|
}));
|
||||||
|
|
||||||
//middlewares
|
//middlewares
|
||||||
|
|||||||
106
src/controladores/controlador_sincronizacion_docs.js
Normal file
106
src/controladores/controlador_sincronizacion_docs.js
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
// src/controladores/controlador_sincronizacion_docs.js
|
||||||
|
const mysql = require('mysql2/promise'); // Usamos la versión con promesas para async/await
|
||||||
|
|
||||||
|
const controlador = {};
|
||||||
|
|
||||||
|
// Pool de conexión específico para la base de datos 'webControl'
|
||||||
|
const poolWebControl = mysql.createPool({
|
||||||
|
host: process.env.DB_WEBCTRL_HOST || '192.168.10.150', // Asumiendo variables de entorno
|
||||||
|
user: process.env.DB_WEBCTRL_USER || 'admin',
|
||||||
|
password: process.env.DB_WEBCTRL_PASSWORD || 'Dx.1706%',
|
||||||
|
database: process.env.DB_WEBCTRL_NAME || 'webControl', // Nombre de la BD
|
||||||
|
waitForConnections: true,
|
||||||
|
connectionLimit: 10,
|
||||||
|
queueLimit: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Crea un nuevo registro de documento electrónico.
|
||||||
|
* Espera los datos del documento en el cuerpo de la solicitud.
|
||||||
|
*/
|
||||||
|
controlador.crearDocumento = async (req, res) => {
|
||||||
|
const {
|
||||||
|
tipo_documento,
|
||||||
|
entidad_emisora,
|
||||||
|
entidad_receptora,
|
||||||
|
numero_autorizacion,
|
||||||
|
fecha_registrada
|
||||||
|
} = req.body;
|
||||||
|
|
||||||
|
if (!tipo_documento || !entidad_emisora || !entidad_receptora || !numero_autorizacion || !fecha_registrada) {
|
||||||
|
return res.status(400).json({ error: 'Todos los campos son obligatorios: tipo_documento, entidad_emisora, entidad_receptora, numero_autorizacion, fecha_registrada.' });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const sql = 'INSERT INTO ia_sincronizacion_documentos_electronicos SET ?';
|
||||||
|
const nuevoDocumento = {
|
||||||
|
tipo_documento,
|
||||||
|
entidad_emisora,
|
||||||
|
entidad_receptora,
|
||||||
|
numero_autorizacion,
|
||||||
|
fecha_registrada,
|
||||||
|
estado_sincronizacion: 'pendiente' // Por defecto al crear
|
||||||
|
};
|
||||||
|
|
||||||
|
const [result] = await poolWebControl.query(sql, nuevoDocumento);
|
||||||
|
res.status(201).json({ message: 'Documento registrado para sincronización.', id: result.insertId });
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error al insertar el documento:", error);
|
||||||
|
if (error.code === 'ER_DUP_ENTRY') {
|
||||||
|
return res.status(409).json({ error: `El documento con autorización '${numero_autorizacion}' ya existe.` });
|
||||||
|
}
|
||||||
|
return res.status(500).json({ error: 'Error al guardar el registro del documento.' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Obtiene una lista de documentos, con opción de filtrar por estado.
|
||||||
|
*/
|
||||||
|
controlador.listarDocumentos = async (req, res) => {
|
||||||
|
const { estado } = req.query; // Filtrar por ej: /api/documentos-electronicos?estado=pendiente
|
||||||
|
|
||||||
|
try {
|
||||||
|
let sql = 'SELECT * FROM ia_sincronizacion_documentos_electronicos';
|
||||||
|
const params = [];
|
||||||
|
|
||||||
|
if (estado) {
|
||||||
|
sql += ' WHERE estado_sincronizacion = ?';
|
||||||
|
params.push(estado);
|
||||||
|
}
|
||||||
|
sql += ' ORDER BY fecha_registrada DESC';
|
||||||
|
|
||||||
|
const [rows] = await poolWebControl.query(sql, params);
|
||||||
|
res.status(200).json(rows);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error al consultar documentos:", error);
|
||||||
|
return res.status(500).json({ error: 'Error al obtener los documentos.' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Actualiza el estado de un documento electrónico por su ID.
|
||||||
|
*/
|
||||||
|
controlador.actualizarEstadoDocumento = async (req, res) => {
|
||||||
|
const { id } = req.params;
|
||||||
|
const { estado_sincronizacion } = req.body;
|
||||||
|
|
||||||
|
if (!estado_sincronizacion || !['pendiente', 'procesado', 'error'].includes(estado_sincronizacion)) {
|
||||||
|
return res.status(400).json({ error: "El campo 'estado_sincronizacion' es obligatorio y debe ser 'pendiente', 'procesado' o 'error'." });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const sql = 'UPDATE ia_sincronizacion_documentos_electronicos SET estado_sincronizacion = ? WHERE id = ?';
|
||||||
|
const [result] = await poolWebControl.query(sql, [estado_sincronizacion, id]);
|
||||||
|
|
||||||
|
if (result.affectedRows === 0) {
|
||||||
|
return res.status(404).json({ error: `No se encontró ningún documento con el ID ${id}.` });
|
||||||
|
}
|
||||||
|
res.status(200).json({ message: 'Estado del documento actualizado correctamente.' });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error al actualizar el estado:", error);
|
||||||
|
return res.status(500).json({ error: 'Error al actualizar el estado del documento.' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = controlador;
|
||||||
@@ -148,6 +148,102 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"response": []
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Sincronización Documentos Electrónicos",
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "Crear Documento",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\n \"tipo_documento\": \"01\",\n \"entidad_emisora\": \"0992222222001\",\n \"entidad_receptora\": \"0701637498001\",\n \"numero_autorizacion\": \"1234567890123456789012345678901234567890123456789\",\n \"fecha_registrada\": \"2023-11-15T14:30:00Z\"\n}"
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://localhost:3001/api/documentos-electronicos",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"localhost"
|
||||||
|
],
|
||||||
|
"port": "3001",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"documentos-electronicos"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"description": "Registra un nuevo documento electrónico para ser procesado por el sistema. Ideal para ser llamado desde n8n."
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Listar Documentos",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "http://localhost:3001/api/documentos-electronicos?estado=pendiente",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"localhost"
|
||||||
|
],
|
||||||
|
"port": "3001",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"documentos-electronicos"
|
||||||
|
],
|
||||||
|
"query": [
|
||||||
|
{
|
||||||
|
"key": "estado",
|
||||||
|
"value": "pendiente",
|
||||||
|
"description": "Filtra por 'pendiente', 'procesado' o 'error'. Omitir para ver todos."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"description": "Obtiene una lista de todos los documentos electrónicos, con la opción de filtrar por su estado de sincronización."
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Actualizar Estado de Documento",
|
||||||
|
"request": {
|
||||||
|
"method": "PUT",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\n \"estado_sincronizacion\": \"procesado\"\n}"
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://localhost:3001/api/documentos-electronicos/1/estado",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"localhost"
|
||||||
|
],
|
||||||
|
"port": "3001",
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"documentos-electronicos",
|
||||||
|
"1",
|
||||||
|
"estado"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"description": "Actualiza el estado de un documento específico por su ID. El estado puede ser 'procesado' o 'error'."
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Endpoints para la gestión de documentos electrónicos sincronizados desde n8n."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@ const rutas = express.Router();
|
|||||||
|
|
||||||
const controlador_init = require('../controladores/controlador_Apps');
|
const controlador_init = require('../controladores/controlador_Apps');
|
||||||
const controlador_videos = require('../controladores/controlador_videos'); // Controlador para videos
|
const controlador_videos = require('../controladores/controlador_videos'); // Controlador para videos
|
||||||
|
const controlador_sinc_docs = require('../controladores/controlador_sincronizacion_docs'); // NUEVO: Controlador para documentos electrónicos
|
||||||
|
|
||||||
rutas.get('/app_restaurant', controlador_init.app_restaurant);//login testing css / dev
|
rutas.get('/app_restaurant', controlador_init.app_restaurant);//login testing css / dev
|
||||||
//rutas.get('/usuarios', controlador_init.user);//
|
//rutas.get('/usuarios', controlador_init.user);//
|
||||||
@@ -24,4 +25,75 @@ rutas.get('/videos', controlador_videos.videos_v2);//videos sigma server
|
|||||||
rutas.get('/videos_upload', controlador_videos.upload_v2);//videos sigma server (version nueva)
|
rutas.get('/videos_upload', controlador_videos.upload_v2);//videos sigma server (version nueva)
|
||||||
rutas.post('/videos_upload', controlador_videos.uploadVideo); // Nueva ruta para manejar la subida
|
rutas.post('/videos_upload', controlador_videos.uploadVideo); // Nueva ruta para manejar la subida
|
||||||
|
|
||||||
|
// --- API para Sincronización de Documentos Electrónicos (desde n8n) ---
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/documentos-electronicos:
|
||||||
|
* post:
|
||||||
|
* summary: Registra un nuevo documento electrónico para ser procesado.
|
||||||
|
* tags: [Sincronización Documentos]
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* required: [tipo_documento, entidad_emisora, entidad_receptora, numero_autorizacion, fecha_registrada]
|
||||||
|
* properties:
|
||||||
|
* tipo_documento: { type: string, example: "01" }
|
||||||
|
* entidad_emisora: { type: string, example: "RUC_EMISOR" }
|
||||||
|
* entidad_receptora: { type: string, example: "RUC_RECEPTOR" }
|
||||||
|
* numero_autorizacion: { type: string, example: "1234567890123456789012345678901234567890123456789" }
|
||||||
|
* fecha_registrada: { type: string, format: date-time, example: "2023-10-27T10:00:00Z" }
|
||||||
|
* responses:
|
||||||
|
* 201: { description: Documento registrado exitosamente. }
|
||||||
|
* 400: { description: Datos de entrada inválidos. }
|
||||||
|
* 409: { description: El documento ya existe (conflicto). }
|
||||||
|
* 500: { description: Error del servidor. }
|
||||||
|
* get:
|
||||||
|
* summary: Lista todos los documentos electrónicos registrados.
|
||||||
|
* tags: [Sincronización Documentos]
|
||||||
|
* parameters:
|
||||||
|
* - in: query
|
||||||
|
* name: estado
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* enum: [pendiente, procesado, error]
|
||||||
|
* description: Filtra los documentos por su estado de sincronización.
|
||||||
|
* responses:
|
||||||
|
* 200: { description: Lista de documentos. }
|
||||||
|
* 500: { description: Error del servidor. }
|
||||||
|
*/
|
||||||
|
rutas.post('/api/documentos-electronicos', controlador_sinc_docs.crearDocumento);
|
||||||
|
rutas.get('/api/documentos-electronicos', controlador_sinc_docs.listarDocumentos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/documentos-electronicos/{id}/estado:
|
||||||
|
* put:
|
||||||
|
* summary: Actualiza el estado de sincronización de un documento.
|
||||||
|
* tags: [Sincronización Documentos]
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: id
|
||||||
|
* required: true
|
||||||
|
* schema: { type: integer }
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* required: [estado_sincronizacion]
|
||||||
|
* properties:
|
||||||
|
* estado_sincronizacion: { type: string, enum: [pendiente, procesado, error], example: "procesado" }
|
||||||
|
* responses:
|
||||||
|
* 200: { description: Estado actualizado correctamente. }
|
||||||
|
* 400: { description: Estado inválido. }
|
||||||
|
* 404: { description: Documento no encontrado. }
|
||||||
|
* 500: { description: Error del servidor. }
|
||||||
|
*/
|
||||||
|
rutas.put('/api/documentos-electronicos/:id/estado', controlador_sinc_docs.actualizarEstadoDocumento);
|
||||||
|
|
||||||
module.exports = rutas;
|
module.exports = rutas;
|
||||||
@@ -512,8 +512,8 @@ router.post('/api/proyectos/memorias-tecnicas/:memoriaId/mantenimiento', control
|
|||||||
* type: integer
|
* type: integer
|
||||||
* description: ID del plan de mantenimiento a eliminar.
|
* description: ID del plan de mantenimiento a eliminar.
|
||||||
* responses:
|
* responses:
|
||||||
* 200:
|
* 204:
|
||||||
* description: Plan de mantenimiento eliminado exitosamente.
|
* description: Plan de mantenimiento eliminado exitosamente. No devuelve contenido.
|
||||||
* 404:
|
* 404:
|
||||||
* description: Plan de mantenimiento no encontrado.
|
* description: Plan de mantenimiento no encontrado.
|
||||||
* 500:
|
* 500:
|
||||||
|
|||||||
Reference in New Issue
Block a user