inicializacion del proyecto.

This commit is contained in:
Pablinux
2025-09-28 15:02:50 -05:00
parent bb424ce537
commit 972749cee2
6 changed files with 284 additions and 8 deletions

View File

@@ -6,7 +6,7 @@
### Modulos Requeridos para el funcionamiento
ejs
mysql : se cambiara a mysql2
mysql2
express-myconnection
express
express-session: necesario para controlar las ssiones
@@ -16,18 +16,16 @@ nodemon
express-fileupload
cors
jsonwebtoken
npm install mysql2
uuid
### recomendaciones previas
npm install -s //-s para guardar los datos
### instalacion de modulos
Se recomienda usar `mysql2` en lugar de `mysql` por su soporte a Promises y mejor rendimiento.
```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

View File

@@ -47,6 +47,10 @@ app.use(session({
resave: false,//no se guarde cada vez que se hace un cambio
saveUninitialized: true,//guardar sesion aunque no haya datos
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

View 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;

View File

@@ -148,6 +148,102 @@
}
},
"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."
}
]
}

View File

@@ -3,6 +3,7 @@ const rutas = express.Router();
const controlador_init = require('../controladores/controlador_Apps');
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('/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.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;

View File

@@ -512,8 +512,8 @@ router.post('/api/proyectos/memorias-tecnicas/:memoriaId/mantenimiento', control
* type: integer
* description: ID del plan de mantenimiento a eliminar.
* responses:
* 200:
* description: Plan de mantenimiento eliminado exitosamente.
* 204:
* description: Plan de mantenimiento eliminado exitosamente. No devuelve contenido.
* 404:
* description: Plan de mantenimiento no encontrado.
* 500: