Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ jobs:
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '16.x'
node-version: '18.x'
- run: npm ci
- run: cp config.private.ts.example config.private.ts
- run: npm run lint
- run: npm run tsc
- run: NODE_OPTIONS=--max-old-space-size=4096 npm run tsc
- run: npm run test
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# TypeScript build
*.tsbuildinfo

# Archivos de configuración
config.private.ts

Expand All @@ -10,6 +13,8 @@ logs
**/*.map
*.js
**.js
!__mocks__/
!__mocks__/**/*.js
*.map
**.map

Expand All @@ -20,3 +25,4 @@ node_modules
typings
typings/*
.vscode
.nvmrc
40 changes: 40 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Migration: Node.js 14 → 18

## Fecha
19-12-2025

## Resumen
Migración del runtime de Node.js 14 a Node.js 18.
Incluye ajustes en dependencias, tests y configuración de CI.

## Cambios principales

### Runtime
- Node.js >=18 <19
- Actualización de GitHub Actions a Node 18

### TypeScript
- Ajustes de tipado en `req.query` y `req.params`
- Uso de cast explícito en métodos de schemas (`this as DocType`)
- `skipLibCheck: true` mantenido

### Jest / Tests
- Se agregó `testTimeout` para soportar `mongodb-memory-server`
- Eliminado uso de `jasmine.DEFAULT_TIMEOUT_INTERVAL`

### Dependencias problemáticas
- `mongoose-gridfs`
- `@lykmapipo/common`
- Downgrade de `mime` y `flat` para compatibilidad CommonJS (overrides)
- Rebuild de módulos nativos (`libxmljs2`)

### MongoDB
- Warnings conocidos:
- `collection.update` (deprecated)
- `ensureIndex` (deprecated)
- No afectan funcionamiento actual

## Estado final
- ✅ Build OK
- ✅ Tests OK
- ✅ API funcional en Node 18
8 changes: 8 additions & 0 deletions __mocks__/mongoose-gridfs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
createBucket: () => ({
readFile: jest.fn(),
writeFile: jest.fn(),
deleteFile: jest.fn(),
find: jest.fn(),
}),
};
2 changes: 1 addition & 1 deletion auth/auth.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ export class Auth {
try {
let tokenSettings;
if (req.query.hudsToken) {
tokenSettings = Auth.decode(req.query.hudsToken);
tokenSettings = Auth.decode(String(req.query.hudsToken));
return (String(tokenSettings.paciente) === String(paciente));
}
} catch (e) {
Expand Down
4 changes: 2 additions & 2 deletions connect/fhir/routes/organization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ router.get('/organization/([\$])match', async (req, res, next) => {
RegExp('^.*' + req.query.name + '.*$', 'i');
}

if (req.query.identifier) {
opciones['codigo.sisa'] = utils.makePattern(req.query.identifier);
if (req.query.identifier as any) {
opciones['codigo.sisa'] = utils.makePattern(req.query.identifier as any);
}

const organizacionesFHIR = [];
Expand Down
6 changes: 3 additions & 3 deletions connect/fhir/routes/practitioner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ router.get('/practitioner/([\$])match', async (req, res, next) => {

if (req.query.family) {
opciones['apellido'] =
RegExp('^.*' + req.query.family + '.*$', 'i');
RegExp('^.*' + req.query.family as any + '.*$', 'i');
}

if (req.query.identifier) {
opciones['documento'] = utils.makePattern(req.query.identifier);
if (req.query.identifier as any) {
opciones['documento'] = utils.makePattern(req.query.identifier as any);
}

const profesionalesFHIR = [];
Expand Down
2 changes: 1 addition & 1 deletion core-v2/mpi/paciente/paciente.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ export const updateGeoreferencia = async (paciente: IPacienteDoc) => {
// georeferencia exitosa?
if (geoRef && Object.keys(geoRef).length) {
direccion[0].geoReferencia = [geoRef.lat, geoRef.lng];
const nombreBarrio = await getBarrio(geoRef, configPrivate.geoNode.host, configPrivate.geoNode.auth.user, configPrivate.geoNode.auth.password);
const nombreBarrio = await getBarrio(geoRef, configPrivate.geoNode.host, configPrivate.geoNode.auth.user, configPrivate.geoNode.auth.password, null);
// consulta exitosa?
if (nombreBarrio) {
const barrioPaciente = await Barrio.findOne().where('nombre').equals(RegExp('^.*' + nombreBarrio + '.*$', 'i'));
Expand Down
2 changes: 1 addition & 1 deletion core-v2/mpi/paciente/paciente.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export const get = async (req: Request, res: Response) => {
const conditions = { ...req.query };
delete conditions.search;
Object.keys(options).map(opt => delete conditions[opt]);
const pacientes = await multimatch(req.query.search, conditions, options);
const pacientes = await multimatch(req.query.search as any, conditions, options);
return res.json(pacientes);
} else {
if (Object.keys(req.query).length) {
Expand Down
22 changes: 12 additions & 10 deletions core-v2/mpi/paciente/paciente.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ export const PacienteSchema: mongoose.Schema = new mongoose.Schema({
id: mongoose.Schema.Types.ObjectId,
nombre: String,
apellido: String,
documento: Number },
documento: Number
},
registradoEn: Date
},
estadoCivil: ESTADOCIVIL,
Expand Down Expand Up @@ -302,16 +303,17 @@ PacienteSubSchema.virtual('edadReal').get(function () {
});

PacienteSchema.methods.basicos = function () {
const doc = this as IPacienteDoc;
return {
id: this._id,
nombre: this.nombre,
alias: this.alias,
apellido: this.apellido,
documento: this.documento,
numeroIdentificacion: this.numeroIdentificacion,
fechaNacimiento: this.fechaNacimiento,
sexo: this.sexo,
genero: this.genero
id: doc._id,
nombre: doc.nombre,
alias: doc.alias,
apellido: doc.apellido,
documento: doc.documento,
numeroIdentificacion: doc.numeroIdentificacion,
fechaNacimiento: doc.fechaNacimiento,
sexo: doc.sexo,
genero: doc.genero
};
};

Expand Down
14 changes: 7 additions & 7 deletions core/log.v2/routes/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ router.get('/', async (req, res, next) => {
// if (!Auth.check(req, 'log:get')) {
// return next(403);
// }
if (!req.query.key && !req.query.keyRegEx && !req.query.paciente) {
if (!req.query.key as any && !req.query.keyRegEx as any && !req.query.paciente as any) {
return next(400);
}

// Paginado
const skip = parseInt(req.query.skip || 0, 10);
const limit = Math.min(parseInt(req.query.limit || config.defaultLimit, 15), config.maxLimit);
const skip = parseInt(req.query.skip as any || 0, 10);
const limit = Math.min(parseInt(req.query.limit as any || config.defaultLimit, 15), config.maxLimit);
// Ejecuta la consulta
try {
const data = await logger.query(req.query.key || (req.query.keyRegEx && new RegExp(req.query.key, 'g')),
req.query.paciente && mongoose.Types.ObjectId(req.query.paciente),
req.query.desde,
req.query.hasta,
const data = await logger.query(req.query.key as any || (req.query.keyRegEx as any && new RegExp(req.query.key as any, 'g')),
req.query.paciente as any && mongoose.Types.ObjectId(req.query.paciente as any),
req.query.desde as any,
req.query.hasta as any,
skip,
limit);
res.json(data);
Expand Down
10 changes: 5 additions & 5 deletions core/log/routes/logPaciente.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ const router = express.Router();

router.get('/paciente', (req, res, next) => {
let query;
if (req.params.id) {
if (Types.ObjectId.isValid(req.params.id)) {
query = logPaciente.findById(req.params.id, (err, data) => {
if ((req.params as any).id) {
if (Types.ObjectId.isValid((req.params as any).id)) {
query = logPaciente.findById((req.params as any).id, (err, data) => {
if (err) {
return next(err);
}
Expand All @@ -19,8 +19,8 @@ router.get('/paciente', (req, res, next) => {
}
} else {
query = logPaciente.find({}); // Trae todos
if (req.query.idPaciente) {
query.where('paciente').equals(Types.ObjectId(req.query.idPaciente));
if (req.query.idPaciente as any) {
query.where('paciente').equals(Types.ObjectId(req.query.idPaciente as any));
}
if (req.query.operacion) {
query.where('operacion').equals(req.query.operacion);
Expand Down
6 changes: 3 additions & 3 deletions core/term/routes/cie10.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ router.get('/cie10', async (req, res, next) => {
whereConditions['$and'] = [];
const orRango = {};
orRango['$or'] = [];
const filtroRango = JSON.parse(req.query.filtroRango);
const filtroRango = JSON.parse(req.query.filtroRango as any);
for (const rango of filtroRango) {
orRango['$or'].push({ codigo: { $gt: rango.desde, $lt: rango.hasta } });
}
Expand All @@ -41,8 +41,8 @@ router.get('/cie10', async (req, res, next) => {
whereConditions = conditions;
}
const query = cie10.model.find(whereConditions);
const skip = parseInt(req.query.skip || 0, 10);
const limit = Math.min(parseInt(req.query.limit || defaultLimit, 15), maxLimit);
const skip = parseInt(req.query.skip as any || 0, 10);
const limit = Math.min(parseInt(req.query.limit as any || defaultLimit, 15), maxLimit);
query.skip(skip);
query.limit(limit);
try {
Expand Down
27 changes: 16 additions & 11 deletions core/term/routes/configuracionPrestacion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ router.get('/configuracionPrestaciones/:id*?', (req, res, next) => {
// return next(403);
// }

if (req.params.id) {
configuracionPrestacion.configuracionPrestacionModel.findById(req.params.id
if ((req.params as any).id) {
configuracionPrestacion.configuracionPrestacionModel.findById((req.params as any).id
, (err, data) => {
if (err) {
return next(err);
Expand Down Expand Up @@ -47,13 +47,15 @@ Elimina un 'mapeo' (Elemento del arreglo 'organizaciones') de tipoPrestacion - E
router.put('/configuracionPrestaciones', (req, res, next) => {
if (req.body.idTipoPrestacion && req.body.idOrganizacion) {
// busca por especialidad
configuracionPrestacion.configuracionPrestacionModel.update(
{ _id: req.body.idTipoPrestacion }, { $pull: { organizaciones: { _id: req.body.idOrganizacion } } }, (err, data) => {
if (err) {
return next(err);
}
res.json(data);
});
configuracionPrestacion.configuracionPrestacionModel.updateOne(
{ _id: req.body.idTipoPrestacion },
{ $pull: { organizaciones: { _id: req.body.idOrganizacion } } } as any
).exec((err: Error | null, data: any) => {
if (err) {
return next(err);
}
res.json(data);
});
} else {
res.status(404).send('Error, parámetros incorrectos.');
}
Expand Down Expand Up @@ -84,11 +86,14 @@ router.post('/configuracionPrestaciones', async (req, res, next) => {
nombreEspecialidad: req.body.prestacionLegacy.nombreEspecialidad,
codigo: req.body.prestacionLegacy.codigo
}];
configuracionPrestacion.configuracionPrestacionModel.update({ 'snomed.conceptId': idSnomed }, { $push: { organizaciones: newOrganizacion } }, (err, resultado) => {
configuracionPrestacion.configuracionPrestacionModel.updateOne(
{ 'snomed.conceptId': idSnomed },
{ $push: { organizaciones: newOrganizacion } } as any
).exec((err: Error | null, data: any) => {
if (err) {
return next(err);
} else {
res.json(resultado);
res.json(data);
}
});
}
Expand Down
8 changes: 4 additions & 4 deletions core/term/routes/snomed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ router.get('/snomed', async (req, res, next) => {
return next('Debe ingresar un parámetro de búsqueda');
}

const semanticTags = asArray(req.query.semanticTag);
const search = req.query.search;
const expression = req.query.expression;
const languageCode = req.query.languageCode || 'es';
const semanticTags = asArray(req.query.semanticTag as any);
const search = req.query.search as any;
const expression = req.query.expression as any;
const languageCode = req.query.languageCode as any || 'es';
if (isNaN(search) || expression) {
const conceptos = await SnomedCtr.searchTerms(search, { semanticTags, languageCode, expression });
const conceptoFiltrado = conceptos.filter(c => c.term !== c.fsn);
Expand Down
20 changes: 10 additions & 10 deletions core/term/routes/snomedv2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ router.get('/snomed/concepts/:sctid', async (req, res, next) => {
*/

router.get('/snomed/concepts', async (req, res, next) => {
const sctids = Array.isArray(req.query.sctids) ? req.query.sctids : [req.query.sctids];
const sctids = Array.isArray(req.query.sctids as any) ? req.query.sctids as any : [req.query.sctids as any];
try {
const concepts = await SnomedCtr.getConcepts(sctids);
return res.json(concepts);
Expand Down Expand Up @@ -74,9 +74,9 @@ router.get('/snomed/concepts/:sctid/parents', async (req, res, next) => {
*/

router.get('/snomed/concepts/:sctid/childs', async (req, res, next) => {
const sctid = req.params.sctid;
const all = req.query.all || false;
const leaf = req.query.leaf || false;
const sctid = req.params.sctid as any;
const all = req.query.all as any || false;
const leaf = req.query.leaf as any || false;
try {
const childs: any = await SnomedCtr.getChildren(sctid, { all, leaf });
return res.json(childs);
Expand All @@ -87,18 +87,18 @@ router.get('/snomed/concepts/:sctid/childs', async (req, res, next) => {
});

router.get('/snomed/expression', async (req, res, next) => {
const form = req.query.type || 'stated';
const words = req.query.words;
const expression = req.query.expression;
const languageCode = req.query.languageCode ? req.query.languageCode : 'es';
const form = req.query.type as any || 'stated';
const words = req.query.words as any;
const expression = req.query.expression as any;
const languageCode = req.query.languageCode as any ? req.query.languageCode as any : 'es';

const concepts = await SnomedCtr.getConceptByExpression(expression, words, form, languageCode);
return res.json(concepts);
});

router.get('/snomed/relationships', async (req, res, next) => {
const sctids = req.query.expression;
const types = req.query.type;
const sctids = req.query.expression as any;
const types = req.query.type as any;
try {
const concepts = await SnomedCtr.getValuesByRelationships(sctids, types);
return res.json(concepts);
Expand Down
3 changes: 2 additions & 1 deletion core/tm/controller/profesional.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ export async function matriculaCero() {


export async function formacionCero() {
const profesionales: any = await Profesional.find({ $where: 'this.formacionGrado.length > 1 && this.formacionGrado[0].matriculacion == null' }, (data: any) => { return data; });
const filter = { $where: 'this.formacionGrado.length > 1 && this.formacionGrado[0].matriculacion == null' } as any;
const profesionales = await Profesional.find(filter).exec();
return profesionales;
}

Expand Down
4 changes: 4 additions & 0 deletions core/tm/interfaces/profesional.interface.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { Mixed } from 'mongoose';

export interface IProfesional {
nombre: string;
apellido: string;
documento: string;
fechaNacimiento: Date;
sexo: string;
genero: string;
formacionGrado?: any[];
formacionPosgrado?: any[];
}
4 changes: 2 additions & 2 deletions core/tm/routes/barrio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ const router = express.Router();
*/
router.get('/barrios/:id*?', (req, res, next) => {

if (req.params.id) {
barrio.findById(req.params.id, (err, data) => {
if ((req.params as any).id) {
barrio.findById((req.params as any).id, (err, data) => {
if (err) {
return next(err);
}
Expand Down
Loading