92 lines
3.0 KiB
JavaScript
92 lines
3.0 KiB
JavaScript
const { Op } = require('sequelize');
|
|
const { ValidationError, ConflictError } = require('../shared/errors');
|
|
|
|
class FriendsService {
|
|
constructor({ friendshipsRepository, friendRequestsRepository, usersRepository, sequelize }) {
|
|
this.friendshipsRepository = friendshipsRepository;
|
|
this.friendRequestsRepository = friendRequestsRepository;
|
|
this.usersRepository = usersRepository;
|
|
this.sequelize = sequelize;
|
|
}
|
|
|
|
async getFriendsByUserId(userId) {
|
|
return await this.friendshipsRepository.findByUserId(userId);
|
|
}
|
|
|
|
async getPendingRequests(userId) {
|
|
return await this.friendRequestsRepository.findPendingByUserId(userId);
|
|
}
|
|
|
|
async sendFriendRequest(fromUserId, identifier) {
|
|
let toUser;
|
|
|
|
if (typeof identifier === 'number' || !isNaN(identifier)) {
|
|
toUser = await this.usersRepository.findById(parseInt(identifier, 10));
|
|
} else {
|
|
toUser = await this.usersRepository.findOne({
|
|
[Op.or]: [{ name: identifier }, { email: identifier }],
|
|
});
|
|
|
|
if (!toUser) {
|
|
throw new ValidationError('User not found with provided name or email');
|
|
}
|
|
}
|
|
|
|
if (toUser.id === fromUserId) {
|
|
throw new ValidationError('Cannot send friend request to yourself');
|
|
}
|
|
|
|
const friendshipExists = await this.friendshipsRepository.exists(fromUserId, toUser.id);
|
|
if (friendshipExists) {
|
|
throw new ConflictError('You are already friends with this user');
|
|
}
|
|
|
|
const existingRequest = await this.friendRequestsRepository.findExisting(fromUserId, toUser.id);
|
|
if (existingRequest) {
|
|
throw new ConflictError('Friend request already exists');
|
|
}
|
|
|
|
return await this.friendRequestsRepository.create(fromUserId, toUser.id);
|
|
}
|
|
|
|
async acceptFriendRequest(requestId, userId) {
|
|
const request = await this.friendRequestsRepository.findById(requestId);
|
|
|
|
if (request.toUserId !== userId) {
|
|
throw new ValidationError('You can only accept requests sent to you');
|
|
}
|
|
|
|
if (request.status !== 'PENDING') {
|
|
throw new ValidationError('This request has already been processed');
|
|
}
|
|
|
|
const newFriend = request.fromUser;
|
|
|
|
const t = await this.sequelize.transaction();
|
|
try {
|
|
await this.friendRequestsRepository.updateStatus(requestId, 'ACCEPTED');
|
|
await this.friendshipsRepository.create(request.fromUserId, request.toUserId);
|
|
await this.friendRequestsRepository.delete(requestId);
|
|
await t.commit();
|
|
|
|
return { message: 'Friend request accepted successfully', newFriend };
|
|
} catch (error) {
|
|
await t.rollback();
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async rejectFriendRequest(requestId, userId) {
|
|
const request = await this.friendRequestsRepository.findById(requestId);
|
|
|
|
if (request.toUserId !== userId && request.fromUserId !== userId) {
|
|
throw new ValidationError('You can only manage your own requests');
|
|
}
|
|
|
|
await this.friendRequestsRepository.delete(requestId);
|
|
return { message: 'Friend request rejected successfully' };
|
|
}
|
|
}
|
|
|
|
module.exports = FriendsService;
|