diff --git a/models/Friend.js b/models/Friend.js index d9c41e2be2ea225a11caebc7cd5fed37f1391f56..d3d71311660d8478bd78c4d8f6357ba93257df27 100644 --- a/models/Friend.js +++ b/models/Friend.js @@ -5,19 +5,20 @@ const sequelize = require('../config/sequelize'); const User = require('./User'); const Friend = sequelize.define('Friend', { - type: { - type: DataTypes.ENUM('NORMAL', 'SPECIAL'), - allowNull: false, - }, + status: { + type: DataTypes.ENUM('PENDING', 'ACCEPTED'), + allowNull: false, + defaultValue: 'PENDING' + } }, { - tableName: 'Friends', - timestamps: true, + tableName: 'Friends', + timestamps: true, }); Friend.belongsTo(User, { foreignKey: 'user_id', as: 'user' }); Friend.belongsTo(User, { foreignKey: 'friend_id', as: 'friend' }); User.hasMany(Friend, { foreignKey: 'user_id', as: 'friends' }); -User.hasMany(Friend, { foreignKey: 'friend_id', as: 'friendOf' }); +User.hasMany(Friend, { foreignKey: 'friend_id', as: 'friendRequests' }); -module.exports = Friend; +module.exports = Friend; \ No newline at end of file diff --git a/services/friendService.js b/services/friendService.js new file mode 100644 index 0000000000000000000000000000000000000000..c39d05f9ea59e79eddb849bc490c8e6477a70303 --- /dev/null +++ b/services/friendService.js @@ -0,0 +1,168 @@ +const { Op } = require('sequelize'); +const Friend = require('../models/Friend'); +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' + }); + } + + /** + * 받은 친구 요청 목록 조회 + */ + 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: { + user_id: userId, + status: 'PENDING' + }, + include: [{ + model: User, + as: 'friend', + attributes: ['id', 'name', 'email'] + }] + }); + } + + /** + * 친구 요청 수락 + */ + async acceptFriendRequest(requestId, userId) { + const request = await Friend.findOne({ + where: { + id: requestId, + friend_id: userId, + status: 'PENDING' + } + }); + + if (!request) { + throw new Error('Friend request not found'); + } + + return request.update({ status: 'ACCEPTED'}); + } + + /** + * 친구 요청 거절 + */ + async rejectFriendRequest(requestId, userId) { + const result = await Friend.destroy({ + where: { + id: requestId, + friend_id: userId, + status: 'PENDING' + } + }); + + if (!result) { + throw new Error('Friend reqeust not found'); + } + + return result; + } + + /** + * 친구 목록 조회 + */ + async getFriendList(userId) { + return Friend.findAll({ + where: { + [Op.or]: [ + {user_id: userId}, + {friend_id: userId} + ], + status: 'ACCEPTED' + }, + include: [{ + model: User, + as: 'friend', + attributes: ['id', 'name', 'email'] + }, { + model: User, + as: 'user', + attributes: ['id', 'name', 'email'] + }] + }); + } + + /** + * 친구 삭제 + */ + async deleteFriend(userId, friendId) { + 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; + } + +} + +module.exports = new friendService(); \ No newline at end of file