import BaseService from './BaseService.js'; import { Op, col } from 'sequelize'; import User from '../models/community/user.js'; import UserParam from '../models/community/user_param.js'; import UserParamType from '../models/type/user_param.js'; import UserParamValue from '../models/type/user_param_value.js'; import UserParamVisibility from '../models/community/user_param_visibility.js'; import UserParamVisibilityType from '../models/type/user_param_visibility.js'; class SocialNetworkService extends BaseService { async searchUsers({ username, ageFrom, ageTo, genders }) { try { const whereClause = { active: true, searchable: true }; if (username) { whereClause.username = { [Op.iLike]: `%${username}%` }; } const users = await User.findAll({ where: whereClause, include: [ { model: UserParam, as: 'user_params', include: [ { model: UserParamType, as: 'paramType', where: { description: { [Op.in]: ['gender', 'birthdate'] } }, required: true } ], required: true } ] }); const results = []; for (const user of users) { const id = user.hashedId; const birthdateParam = user.user_params.find(param => param.paramType.description === 'birthdate'); const genderParam = user.user_params.find(param => param.paramType.description === 'gender'); const age = birthdateParam ? this.calculateAge(birthdateParam.value) : null; const decryptedGenderValue = genderParam ? genderParam.value : null; let gender = null; if (decryptedGenderValue) { const genderValue = await UserParamValue.findOne({ where: { id: decryptedGenderValue } }); gender = genderValue ? genderValue.value : null; } const isWithinAgeRange = (!ageFrom || age >= ageFrom) && (!ageTo || age <= ageTo); if (isWithinAgeRange && (!genders || !genders.length || (gender && genders.includes(gender))) && age >= 14) { results.push({ id: id, username: user.username, email: user.email, gender: gender, age: age }); } } return results; } catch (error) { console.error('Error in searchUsers:', error); throw new Error('Error searching users'); } } async getProfile(hashedUserId, requestingUserId) { try { const requestingUser = await this.getUserByHashedId(requestingUserId); const requestingUserParams = await this.getUserParams(requestingUser.id, ['birthdate']); let requestingUserAge = 0; for (const param of requestingUserParams) { if (param.paramType.description === 'birthdate') { requestingUserAge = this.calculateAge(param.value); break; } } const user = await User.findOne({ where: { hashedId: hashedUserId, active: true, searchable: true, }, include: [ { model: UserParam, as: 'user_params', include: [ { model: UserParamType, as: 'paramType', }, { model: UserParamVisibility, as: 'param_visibilities', include: [ { model: UserParamVisibilityType, as: 'visibility_type' } ] } ], order: [[ 'order_id', 'asc']] } ] }); if (user) { const userParams = {}; await Promise.all(user.user_params.map(async (param) => { const visibilityData = param.param_visibilities?.[0]?.visibility_type; const visibility = visibilityData ? visibilityData.description : 'Invisible'; let paramValue = param.value; let paramValueChanged = false; try { const parsedValue = JSON.parse(paramValue); if (Array.isArray(parsedValue)) { paramValue = await Promise.all(parsedValue.map(async (value) => { if (/^\d+$/.test(value)) { const userParamValue = await UserParamValue.findOne({ where: { id: parseInt(value, 10), userParamTypeId: param.paramTypeId } }); paramValueChanged = true; return userParamValue ? userParamValue.value : value; } return value; })); } } catch (e) { } if (!paramValueChanged) { if (/^\d+$/.test(paramValue)) { const userParamValue = await UserParamValue.findOne({ where: { id: parseInt(paramValue, 10), userParamTypeId: param.paramTypeId } }); if (userParamValue) { paramValue = userParamValue.value; } } } const paramTypeDescription = param.paramType.description; if (visibility === 'Invisible') { return; } if (visibility === 'All' || (visibility === 'FriendsAndAdults' && requestingUserAge >= 18) || (visibility === 'AdultsOnly' && requestingUserAge >= 18)) { userParams[paramTypeDescription] = { type: param.paramType.datatype, value: paramValue }; if (paramTypeDescription === 'birthdate') { userParams['age'] = { value: this.calculateAge(Date.parse(paramValue)), type: "int"}; } } })); const userProfile = { username: user.username, registrationDate: user.registrationDate, params: userParams }; return userProfile; } return null; } catch (error) { console.error('Error in getProfile:', error); throw new Error('Error getting profile'); } } } export default SocialNetworkService;