diff --git a/src/controllers/accountBookController.js b/src/controllers/accountBookController.js index 5b7938704eb9915881347489cd2521c2beba0887..2063f2b5e6897b26f4fb84dbcb9f47b8ba464d39 100644 --- a/src/controllers/accountBookController.js +++ b/src/controllers/accountBookController.js @@ -3,17 +3,17 @@ const accountBookService = require('../services/accountBookService'); const createAccountBook = async (req, res) => { try { - const { type, name, members } = req.body; - const userId = req.user._id; + const { type, name, memberEmailsInput } = req.body; + const userId = req.user._id; // MongoDB의 _id 사용 const accountBook = await accountBookService.createAccountBook( type, name, - members, + memberEmailsInput, userId ); - res.status(201).json({ accountBook }); + res.status(201).json({ message: '가계부 생성 성공', accountBook }); } catch (error) { - res.status(400).json({ message: error.message || '생성 실패' }); + res.status(500).json({ message: error.message || '생성 실패' }); } }; diff --git a/src/services/accountBookService.js b/src/services/accountBookService.js index 73dce7c984b0a0d0a8e758cd91a7401de33cb6c3..79f4a07f4aae1b3439beb91605b4793907a512cb 100644 --- a/src/services/accountBookService.js +++ b/src/services/accountBookService.js @@ -8,81 +8,35 @@ const User = require('../models/User'); const mongoose = require('mongoose'); class AccountBookService { - async createAccountBook(type, name, members, userId) { + async createAccountBook(type, name, memberEmailsInput, userId) { //memberEmailsInput은 입력받는 이메일 값 - const memberList = [{ memberId: userId, role: 'owner' }]; + //멤버 관리 + const members = [{ memberId: userId, role: 'owner' }]; // 기본적으로 생성자를 owner로 배열에 추가 - if (type === 'group' && members?.length > 0) { - const foundUsers = []; - const notFoundMembers = []; - - for (const member of members) { - let user; - - if (typeof member === 'object' && member !== null) { - if (member.email) { - user = await User.findOne({ email: member.email }); - if (!user) { - notFoundMembers.push(`이메일: ${member.email}`); - } - } else if (member.userId) { - if (!mongoose.Types.ObjectId.isValid(member.userId)) { - notFoundMembers.push(`잘못된 userId 형식: ${member.userId}`); - continue; - } - user = await User.findById(member.userId); - if (!user) { - notFoundMembers.push(`userId: ${member.userId}`); - } - } else { - notFoundMembers.push('잘못된 멤버 형식'); - continue; - } - } else { - notFoundMembers.push('잘못된 멤버 형식'); - continue; - } - - if (user) { - foundUsers.push(user); - } - } - - - if (notFoundMembers.length > 0) { - throw new Error(`다음 멤버를 찾을 수 없습니다: ${notFoundMembers.join(', ')}`); - } - - const duplicateUsers = foundUsers - .filter(user => user._id.toString() === userId.toString()) - .map(user => user.email); - - if (duplicateUsers.length > 0) { - throw new Error(`본인은 멤버로 추가할 수 없습니다: ${duplicateUsers.join(', ')}`); + if (type === 'group' && memberEmailsInput?.length > 0) { // 그룹 가계부일 경우 멤버 추가 + const foundedUsers = await User.find({ email: { $in: memberEmailsInput } });//User모델들에서 memberEmailsInput이랑 일치하는 이메일을 가진 유저를 모아 foundedUsers에 넣기 + if (foundedUsers.length !== memberEmailsInput.length) {//찾은 사용자들 수 != memberEmailsInput 길이일 때 + throw new Error('회원가입되지 않은 이메일의 사용자가 존재합니다.'); } - - const additionalMembers = foundUsers.map(user => ({ - memberId: user._id, - role: 'editor' - })); - - memberList.push(...additionalMembers); - - } else if (type === 'personal') { - if (members && members.length > 0) { + const additionalMembers = foundedUsers.map(user => ({ memberId: user._id, role: 'editor' })); + members.push(...additionalMembers); + } else if (type === 'personal') { // 개인 가계부일 경우 memberEmailsInput 무시 + if (memberEmailsInput && memberEmailsInput.length > 0) { throw new Error('개인 가계부에서는 멤버 추가가 불가능합니다.'); } } + //가계부 생성 const accountBook = new AccountBook({ name, type, - members: memberList + members }); return await accountBook.save(); } + async updateAccountBook(accountBookId, name, members, userId) { const accountBook = await AccountBook.findById(accountBookId); const userMember = this._getMember(accountBook, userId); //Member 검증 함수 사용 @@ -100,27 +54,42 @@ class AccountBookService { throw new Error('Owner만 가계부를 수정할 수 있습니다.'); } - if (members) { - members.forEach(update => { - const { action, memberId, role } = update; + if (Array.isArray(members) && members.length > 0) { + for (const update of members) { + const { action, memberId, memberEmail, role } = update;//구조분해할당 - if (action === 'update') { + if (action === 'update') {//멤버 권한 변경 (memberId 통해) const member = accountBook.members.find(m => m.memberId.toString() === memberId); if (member) { member.role = role; } else { throw new Error(`멤버 ${memberId}를 찾을 수 없습니다.`); } - } else if (action === 'delete') { + } else if (action === 'delete') {//멤버 삭제 (memberId 통해) accountBook.members = accountBook.members.filter(m => m.memberId.toString() !== memberId); } else if (action === 'add') { - if (!accountBook.members.some(m => m.memberId.toString() === memberId)) { - accountBook.members.push({ memberId, role }); + if (memberEmail) {//프론트에서 memberEmail을 제공해준 경우(배열 아니라 단수임) + const user = await User.findOne({ email: memberEmail }); //입력받은 이메일을 통해 유저 검색 + if (!user) { + throw new Error(`이메일 ${memberEmail}과 일치하는 사용자를 찾을 수 없습니다.`); + } + + if (!accountBook.members.some(m => m.memberId.equals(user._id))) { + accountBook.members.push({ memberId: user._id, role }); + } else { + throw new Error(`이미 존재하는 멤버입니다: 이메일(${memberEmail})`); + } + } else if (memberId) {//프론트엔드에서 memberId를 제공해준 경우 + if (!accountBook.members.some(m => m.memberId.equals(memberId))) { + accountBook.members.push({ memberId, role }); + } else { + throw new Error(`이미 존재하는 멤버입니다: ID(${memberId})`); + } } else { - throw new Error(`멤버 ${memberId}가 이미 존재합니다.`); + throw new Error('추가하려면 이메일 또는 멤버 ID를 제공해야 합니다.'); } } - }); + } } } else if (accountBook.type === 'personal' && members) { // Personal 가계부는 멤버 수정 불가