UNPKG

tuain-ecosystem-lib

Version:

Servicio de gestión mensajería instantanea de la plataforma Tuain

308 lines (293 loc) 13.1 kB
const { ObjectId } = require('mongodb'); const { v4: uuidv4 } = require('uuid'); const forge = require('node-forge'); const { dbQueries: { groups: groupQueries }, collections: { genericGroups: groupsColl, genericGroupMembers: groupMembersColl, stores: storesColl }, } = require('../../config'); const modErrs = { createGroup: { alreadyExist: ['01', 'Ya existe grupo con parámetros similares'], }, getGroup: { missingData: ['01', 'Información insuficiente para localizar grupo'], missingOwner: ['02', 'Propietario y tipo necesario para localizar grupo'], notFound: ['03', 'No se encontro grupo con los ids especificados'], }, getGroups: { missingIds: ['01', 'Se requiere listado de identificadores para localizar grupos'], notFound: ['02', 'No se encontraron grupos con los ids especificados'], }, getMemberGroups: { missingData: ['01', 'Datos insuficientes para localizar los grupos de un miembro'], }, }; class GroupManager { constructor(getDb, logger, errMgr, options) { this.options = options; this.getDb = getDb; this.logger = logger; this.errMgr = errMgr; this.errMgr.addModuleSet('lib-groups', modErrs); } async createGroup(groupData) { const { ownerType, memberType, groupType, name, ownerId } = groupData; const groupCol = this.getDb().collection(groupsColl); const groupDetail = await groupCol.findOne(groupQueries.findGroup(null, ownerType, memberType, groupType, name, ownerId)); if (groupDetail) { const errorDetail = `Grupo ${name} de tipo ${groupType} entre ${ownerType} y ${memberType} ya existe para el propietario ${ownerId}`; const errorObj = this.errMgr.get(modErrs.createGroup.alreadyExist, errorDetail); return [errorObj, null]; } const newGroupData = groupQueries.newGroup(ownerType, memberType, groupType, name, ownerId); const actionResult = await groupCol.insertOne(newGroupData); const groupId = actionResult?.insertedId; this.logger.debug(`Grupo ${name} de tipo ${groupType} entre ${ownerType} y ${memberType} creado con id ${groupId}`); return [null, { groupId }]; } async getGroup(reqData) { const { groupId, ownerType, memberType, groupType, name, ownerId } = reqData; if (!groupId && !(ownerType && memberType && groupType && name && ownerId)) { const errorObj = this.errMgr.get(modErrs.getGroup.missingData); return [errorObj, null]; } const groupCol = this.getDb().collection(groupsColl); const groupDetail = await groupCol.findOne(groupQueries.findGroup(groupId, ownerType, memberType, groupType, name, ownerId)); if (!groupDetail) { const errorDetail = groupId ? `Grupo ${groupId} no fue encontrado` : `Grupo ${name} de tipo ${groupType} entre ${ownerType} y ${memberType} perteneciente a ${ownerId} no encontrato`; const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail); return [errorObj, null]; } return [null, groupDetail]; } async getGroupsByOwner(groupData) { const { ownerId, ownerType, memberType, groupType, name } = groupData; if (!ownerId || !ownerType) { const errorObj = this.errMgr.get(modErrs.getGroup.missingOwner); return [errorObj, null]; } const groupCol = this.getDb().collection(groupsColl); const groups = await groupCol.find(groupQueries.findGroupByParams(ownerId, ownerType, memberType, groupType, name)).toArray(); if (!groups || groups.length < 1) { const errorDetail = `No se encontraron grupos con dueño ${ownerId}`; const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail); return [errorObj, null]; } return [null, { groups }]; } async getGroupsByIds(groupIdsData) { const { groupIds } = groupIdsData; if (!groupIds || !Array.isArray(groupIds) || groupIds.length < 1) { const errorObj = this.errMgr.get(modErrs.getGroups.missingIds); return [errorObj, null]; } const groupCol = this.getDb().collection(groupsColl); const groups = await groupCol.find(groupQueries.findGroupByIds(groupIds)).toArray(); if (!groups || groups.length < 1) { const errorObj = this.errMgr.get(modErrs.getGroups.notFound); return [errorObj, null]; } return [null, { groups }]; } async obtainGroupMember(reqData) { const { groupId, ownerType, memberType, groupType, name, ownerId, memberId } = reqData; if (!groupId && !(ownerType && memberType && groupType && name && ownerId)) { const errorObj = this.errMgr.get(modErrs.getGroup.missingData); return [errorObj, null]; } const groupCol = this.getDb().collection(groupsColl); const groupDetail = await groupCol.findOne(groupQueries.findGroup(groupId, ownerType, memberType, groupType, name, ownerId)); if (!groupDetail) { const errorDetail = groupId ? `Grupo ${groupId} no fue encontrado` : `Grupo ${name} de tipo ${groupType} entre ${ownerType} y ${memberType} perteneciente a ${ownerId} no encontrato`; const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail); return [errorObj, null]; } const { _id: foundGroupId, ownerType: foundOwnerType, memberType: foundMemberType, groupType: foundGroupType, name: foundName, ownerId: foundOwnerId, } = groupDetail ?? {}; const membersCol = this.getDb().collection(groupMembersColl); const membership = await membersCol.findOne(groupQueries.findGroupMember(foundGroupId, memberId)); return [ null, { _id: foundGroupId, ownerType: foundOwnerType, memberType: foundMemberType, groupType: foundGroupType, name: foundName, ownerId: foundOwnerId, membership, }, ]; } async addGroupMember(reqData) { const { groupId, ownerType, memberType, groupType, name, ownerId, memberId } = reqData; const [memberErrorObj, groupMember] = await this.obtainGroupMember({ groupId, ownerType, memberType, groupType, name, ownerId, memberId, }); if (memberErrorObj) { return [memberErrorObj, null]; } const { _id: foundGroupId, ownerType: foundOwnerType, memberType: foundMemberType, groupType: foundGroupType, name: foundName, ownerId: foundOwnerId, membership, } = groupMember ?? {}; if (membership) { const errorDetail = `Grupo ${foundName} de tipo ${foundGroupType} entre ${foundOwnerType} y ${foundMemberType} para el propietario ${foundOwnerId} ya contiene a ${memberId}`; const errorObj = this.errMgr.get(modErrs.createGroup.alreadyExist, errorDetail); return [errorObj, null]; } const newMembershipData = groupQueries.newMembership(foundGroupId, memberId); const membersCol = this.getDb().collection(groupMembersColl); const actionResult = await membersCol.insertOne(newMembershipData); const membershipId = actionResult?.insertedId; this.logger.debug(`Grupo ${name} de tipo ${groupType} entre ${ownerType} y ${memberType} creado con id ${foundGroupId}`); return [null, { membershipId }]; } async addGroupMembers(reqData) { const { groupId, ownerType, memberType, groupType, name, ownerId, memberIds } = reqData; if (!groupId && !(ownerType && memberType && groupType && name && ownerId)) { const errorObj = this.errMgr.get(modErrs.getGroup.missingData); return [errorObj, null]; } const groupCol = this.getDb().collection(groupsColl); const groupDetail = await groupCol.findOne(groupQueries.findGroup(groupId, ownerType, memberType, groupType, name, ownerId)); if (!groupDetail) { const errorDetail = groupId ? `Grupo ${groupId} no fue encontrado` : `Grupo ${name} de tipo ${groupType} entre ${ownerType} y ${memberType} perteneciente a ${ownerId} no encontrato`; const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail); return [errorObj, null]; } const { _id: foundGroupId, ownerType: foundOwnerType, memberType: foundMemberType, groupType: foundGroupType, name: foundName, ownerId: foundOwnerId, } = groupDetail ?? {}; const membersCol = this.getDb().collection(groupMembersColl); const memberships = await membersCol.find(groupQueries.checkGroupMembers(foundGroupId, memberIds)).toArray(); if (memberships?.length > 0) { const foundMemberList = memberships.map((membership) => `${membership.memberId}`).join(', '); const errorDetail = `Grupo ${foundName} de tipo ${foundGroupType} entre ${foundOwnerType} y ${foundMemberType} para el propietario ${foundOwnerId} ya contiene algunos miembros: ${foundMemberList}`; const errorObj = this.errMgr.get(modErrs.createGroup.alreadyExist, errorDetail); return [errorObj, null]; } const membershipArray = groupQueries.newMemberships(foundGroupId, memberIds); const actionResult = await membersCol.insertMany(membershipArray); console.log('addGroupMembers'); console.log(actionResult); return [null, { membersAdded: memberIds.length }]; } async removeAllMemberships(reqData) { const { memberId } = reqData; if (memberId) { const membersCol = this.getDb().collection(groupMembersColl); const actionResult = await membersCol.deleteMany({ memberId: ObjectId(memberId) }); const result = actionResult?.result?.n > 0; return [null, { result }]; } return [null, null]; } async removeMemberFromGroup(reqData) { const { groupId, ownerType, memberType, groupType, name, ownerId, memberId } = reqData; const [memberErrorObj, groupMember] = await this.obtainGroupMember({ groupId, ownerType, memberType, groupType, name, ownerId, memberId, }); if (memberErrorObj) { return [memberErrorObj, null]; } const { // _id: foundGroupId, ownerType: foundOwnerType, memberType: foundMemberType, groupType: foundGroupType, name: foundName, ownerId: foundOwnerId, membership, } = groupMember ?? {}; if (!membership) { const errorDetail = `Grupo ${foundName} de tipo ${foundGroupType} entre ${foundOwnerType} y ${foundMemberType} para el propietario ${foundOwnerId} NO contiene a ${memberId}`; const errorObj = this.errMgr.get(modErrs.createGroup.alreadyExist, errorDetail); return [errorObj, null]; } const membershipId = membership?._id; let result = false; if (membershipId) { const membersCol = this.getDb().collection(groupMembersColl); const actionResult = await membersCol.deleteOne(groupQueries.findById(membershipId)); result = actionResult?.result?.n > 0; } return [null, { result }]; } async getGroupMembers(reqData) { const { groupId, ownerType, memberType, groupType, name, ownerId } = reqData; if (!groupId && !(ownerType && memberType && groupType && name && ownerId)) { const errorObj = this.errMgr.get(modErrs.getGroup.missingData); return [errorObj, null]; } const groupCol = this.getDb().collection(groupsColl); const groupDetail = await groupCol.findOne(groupQueries.findGroup(groupId, ownerType, memberType, groupType, name, ownerId)); if (!groupDetail) { const errorDetail = groupId ? `Grupo ${groupId} no fue encontrado` : `Grupo ${name} de tipo ${groupType} entre ${ownerType} y ${memberType} perteneciente a ${ownerId} no encontrato`; const errorObj = this.errMgr.get(modErrs.getGroup.notFound, errorDetail); return [errorObj, null]; } const foundGroupId = groupDetail?._id; const membersCol = this.getDb().collection(groupMembersColl); const memberships = await membersCol.find(groupQueries.findGroupMembers(foundGroupId)).toArray(); const members = memberships.map((membership) => membership.memberId); return [null, { group: groupDetail, members }]; } async getGroupsByMember(reqData) { const { memberId, memberType, ownerType, groupType } = reqData; if (!memberId || !memberType) { const errorObj = this.errMgr.get(modErrs.getMemberGroups.missingData); return [errorObj, null]; } const membersCol = this.getDb().collection(groupMembersColl); const memberships = await membersCol .find(groupQueries.findMemberGroups(memberId), { projection: { groupId: 1, _id: 0 } }) .toArray(); const groupIds = memberships?.map((membership) => membership.groupId) ?? []; if (!memberships || memberships.length < 1) { const errorDetail = `No se encontraron grupos con miembro ${memberId} de tipo ${memberType}`; const errorObj = this.errMgr.get(modErrs.findGroup.notFound, errorDetail); return [errorObj, null]; } const groupCol = this.getDb().collection(groupsColl); const groups = await groupCol.find(groupQueries.findGroupsByIdsAndData(groupIds, memberType, ownerType, groupType)).toArray(); return [null, { groups }]; } } module.exports = GroupManager;