Skip to content
Snippets Groups Projects
friendService.js 4.76 KiB
Newer Older
  • Learn to ignore specific revisions
  • const { Op } = require('sequelize');
    const Friend = require('../models/Friend');
    
    조대희's avatar
    조대희 committed
    const User = require('../models/User');
    
    
    class friendService {
    
    
        /**
         * User 존재 여부 유효성 검사
         */
        async validUser(userId) {
            const user = await User.findByPk(userId);
            if (!user) {
                throw new Error('User not found');
            }
            return user;
        }
    
        /**
         * 친구 요청 보내기
         * 나 자신에게 보내기 or 이미 존재하는 친구 -> X
         * 이후, PENDING 상태로 변환 -> 수락/거절에 따라 변화
         */
        async sendFriendRequest(userId, friendId) {
    
            await this.validUser(userId);
            await this.validUser(friendId);
    
    
            if (userId === friendId) {
                throw new Error('Cannot send friend request to yourself');
            }
    
            const existingFriend = await Friend.findOne({
                where: {
                    [Op.or]: [
                        { user_id: userId, friend_id: friendId },
                        { user_id: friendId, friend_id: userId }
                    ]
                }
            });
    
            if (existingFriend) {
                throw new Error('Friend request already exists');
            }
    
            return Friend.create({
                user_id: userId,
                friend_id: friendId,
                status: 'PENDING'
            });
        }
    
    
        /**
         * 받은 친구 요청 목록 조회
         */
    
    조대희's avatar
    조대희 committed
        async getReceivedRequests(userId) {
    
            return Friend.findAll({
                where: {
                    friend_id: userId,
                    status: 'PENDING'
                },
                include: [{
                    model: User,
                    as: 'user',
                    attributes: ['id', 'name', 'email']
                }]
            });
        }
    
        /**
         * 보낸 친구 요청 목록 조회
         */
        async getSentRequests(userId) {
            return Friend.findAll({
                where: {
    
    조대희's avatar
    조대희 committed
                    user_id: userId,
    
                    status: 'PENDING'
                },
                include: [{
                    model: User,
    
                    attributes: ['id', 'name', 'email']
                }]
            });
        }
    
    
        /**
         * 친구 요청 수락
         */
    
        async acceptFriendRequest(userId, friendId) {
    
            const request = await Friend.findOne({
                where: {
    
                    friend_id: userId,
                    status: 'PENDING'
                }
            });
    
            if (!request) {
    
    조대희's avatar
    조대희 committed
                throw new Error('Friend request not found');
    
        
            return request.update({ status: 'ACCEPTED' });
    
    
        /**
         * 친구 요청 거절
         */
    
        async rejectFriendRequest(userId, friendId) { 
    
            const result = await Friend.destroy({
                where: {
    
                    user_id: friendId,  
                    friend_id: userId,  
    
                    status: 'PENDING'
                }
            });
    
            if (!result) {
    
                throw new Error('Friend request not found');
    
            return result;
        }
    
        /**
         * 친구 목록 조회
         */
        async getFriendList(userId) {
    
            const friends = await Friend.findAll({
    
                where: {
                    [Op.or]: [
    
                        { user_id: userId },
                        { friend_id: userId }
    
                    ],
                    status: 'ACCEPTED'
    
                }
            });
        
            const friendIds = friends.map(friend => 
                friend.user_id === userId ? friend.friend_id : friend.user_id
            );
        
            const friendUsers = await User.findAll({
                where: {
                    id: friendIds
    
                attributes: ['id', 'name', 'email']
            });
        
            const friendsMap = friendUsers.reduce((map, user) => {
                map[user.id] = user;
                return map;
            }, {});
        
            return friends.map(friend => {
                const isSender = friend.user_id === userId;
                const friendId = isSender ? friend.friend_id : friend.user_id;
                
                return {
                    id: friend.id,
                    status: friend.status,
                    createdAt: friend.createdAt,
                    updatedAt: friend.updatedAt,
                    friendInfo: friendsMap[friendId],
                    relationshipType: isSender ? 'sent' : 'received'
                };
    
    조대희's avatar
    조대희 committed
        /**
         * 친구 삭제
         */
    
    조대희's avatar
    조대희 committed
        async deleteFriend(userId, friendId) {
    
    조대희's avatar
    조대희 committed
            const result = await Friend.destroy({
                where: {
                    [Op.or]: [
                        {user_id: userId, friend_id: friendId},
                        {user_id: friendId, friend_id: userId}
                    ],
                    status: 'ACCEPTED'
                }
            });
    
            if (!result) {
                throw new Error('Friend relationship not found');
            }
            return result;
        }
    
    
    조대희's avatar
    조대희 committed
    module.exports = new friendService();