diff --git a/controllers/TripController.js b/controllers/TripController.js index 006c151f75f8c638c91b47b476212520334b9de0..9d0493efd9e109edd96e101fda6c3d0262f26b1f 100644 --- a/controllers/TripController.js +++ b/controllers/TripController.js @@ -66,24 +66,38 @@ const addCollaborator = async (req, res) => { try { const { collaboratorEmail } = req.body; - // Verify if the collaboratorEmail corresponds to a valid user - const user = await User.findOne({ email: collaboratorEmail }); - if (!user) { - return res.status(404).json({ message: 'User not found' }); + const collaborator = await User.findOne({ email: collaboratorEmail }); + if (!collaborator) { + return res.status(404).json({ message: '해당 이메일의 사용자를 찾을 수 없습니다.' }); } - const trip = await Trip.findById(req.params.id); - if (!trip) return res.status(404).json({ message: 'Trip not found' }); + const trip = await Trip.findById(req.params.id).populate('create_by'); + if (!trip) { + return res.status(404).json({ message: '여행을 찾을 수 없습니다.' }); + } - // Check if the user is already a collaborator - if (trip.collaborators.includes(user._id)) { - return res.status(400).json({ message: 'User is already a collaborator' }); + const isAlreadyCollaborator = trip.collaborators.some( + collab => collab.toString() === collaborator._id.toString() + ); + + if (isAlreadyCollaborator) { + return res.status(400).json({ message: '이미 공동작업자로 등록된 사용자입니다.' }); } - trip.collaborators.push(user._id); + if (trip.create_by._id.toString() === collaborator._id.toString()) { + return res.status(400).json({ message: '생성자는 공동작업자로 추가할 수 없습니다.' }); + } + + trip.collaborators.push(collaborator._id); await trip.save(); - res.status(200).json(trip); + + const updatedTrip = await Trip.findById(trip._id) + .populate('create_by') + .populate('collaborators'); + + res.status(200).json(updatedTrip); } catch (err) { + console.error('공동작업자 추가 오류:', err); res.status(500).json({ error: err.message }); } }; diff --git a/models/trips.js b/models/trips.js index 63624581a6bc9d622a18fd51f4aa5b049f343075..0cc86fdd0d0a90a4c8fb0f3ecdab0e6d2faf0a25 100644 --- a/models/trips.js +++ b/models/trips.js @@ -26,7 +26,10 @@ const tripSchema = new mongoose.Schema({ end_date: { type: Date, required: true }, location: { type: String, required: true }, create_by: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }, - collaborators: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }], + collaborators: [{ + type: mongoose.Schema.Types.ObjectId, + ref: 'User' + }], plans: { type: Map, // Object 대신 Map 사용 of: { diff --git a/route/tripRoute.js b/route/tripRoute.js index ea0de05047642dce83b18d7bed424cc2493ee8b5..4ecb8f6ee43e63e63b281562d79559d3e237f10e 100644 --- a/route/tripRoute.js +++ b/route/tripRoute.js @@ -3,243 +3,28 @@ const router = express.Router(); const Trip = require('../models/trips'); // Trip 스키마 참조 const User = require('../models/user'); // User 스키마 참조 -/* -테스트 방법: -1. 전체 여행 목록 조회 테스트 (GET /api/trips/trips) -- GET http://localhost:3000/api/trips/trips 요청 -- 응답으로 전체 여행 목록이 반환되는지 확인 - -2. 특정 여행 조회 테스트 (GET /api/trips/trips/:id) -- GET http://localhost:3000/api/trips/trips/{여행ID} 요청 -- 해당 ID의 여행 정보가 반환되는지 확인 - -3. 새 여행 생성 테스트 (POST /api/trips/trips) -- POST http://localhost:3000/api/trips/trips -- Body: { - "name": "테스트 여행", - "start_date": "2023-12-01", - "end_date": "2023-12-03", - "create_by": "사용자ID", - "collaborators": ["협업자ID1", "협업자ID2"] - } - -4. 여행 수정 테스트 (PUT /api/trips/trips/:id) -- PUT http://localhost:3000/api/trips/trips/{여행ID} -- Body: { - "name": "수정된 여행명", - "start_date": "2023-12-02", - "end_date": "2023-12-04", - "collaborators": ["협업자ID1"] - } - -5. 여행 삭제 테스트 (DELETE /api/trips/trips/:id) -- DELETE http://localhost:3000/api/trips/trips/{여행ID} -- 삭제 성공 메시지 확인 - -6. 공동 작업자 추가 테스트 (POST /api/trips/trips/:id/collaborators) -- POST http://localhost:3000/api/trips/trips/{여행ID}/collaborators -- Body: { - "collaboratorId": "새로운협업자ID" - } - -7. 하루 계획 추가 테스트 (POST /api/trips/trips/:id/plans) -- POST http://localhost:3000/api/trips/trips/{여행ID}/plans -- Body: { - "dayKey": "day1", - "places": [ - { - "id": 1, - "name": "장소1", - "location": "위치1", - "coordinates": { - "lat": 37.5665, - "lng": 126.9780 - } - } - ], - "route": [1] - } - -테스트 도구: Postman 또는 curl 사용 권장 -*/ +const tripController = require('../controllers/TripController'); // **GET**: 전체 여행 목록 조회 -router.get('/trips', async (req, res) => { - try { - const trips = await Trip.find().populate('create_by collaborators'); - res.status(200).json(trips); - console.log('여행 목록 조회 내역', trips); - } catch (err) { - console.error('여행 계획 조회 실패', err); - res.status(500).json({ error: err.message }); - } -}); +router.get('/trips', tripController.getAllTrips); // **GET**: 특정 여행 계획 조회 -router.get('/trips/:id', async (req, res) => { - try { - const trip = await Trip.findById(req.params.id).populate('create_by collaborators'); - if (!trip) return res.status(404).json({ message: 'Trip not found' }); - res.status(200).json(trip); - } catch (err) { - console.error('여행 계획 조회 실패', err); - res.status(500).json({ error: err.message }); - } -}); +router.get('/trips/:id', tripController.getTripById); // **POST**: 새로운 여행 계획 생성 -router.post('/trips', async (req, res) => { - try { - const { name, start_date, end_date, create_by, location, collaborators } = req.body; - const trip = new Trip({ - name, - start_date, - end_date, - create_by, - location, - collaborators - }); - const savedTrip = await trip.save(); - res.status(201).json(savedTrip); - } catch (err) { - console.error('여행 계획 작성 실패', err); - res.status(500).json({ error: err.message }); - } -}); - -// // **PUT**: 특정 여행 계획 수정 -// router.put('/trips/:id', async (req, res) => { -// try { -// const { name, start_date, end_date, location, collaborators } = req.body; -// const updatedTrip = await Trip.findByIdAndUpdate( -// req.params.id, -// { name, start_date, end_date, location, collaborators }, -// { new: true } -// ); -// if (!updatedTrip) return res.status(404).json({ message: 'Trip not found' }); -// res.status(200).json(updatedTrip); -// } catch (err) { -// console.err('여행계획 수정 실패', err); -// res.status(500).json({ error: err.message }); -// } -// }); +router.post('/trips', tripController.createTrip); // **PUT**: 특정 여행 계획 수정(협업자도 수정할 수 있게) -router.put('/trips/:id', async (req, res) => { - try { - const { name, start_date, end_date, location, collaborators } = req.body; - - // 여행 계획 조회 - const trip = await Trip.findById(req.params.id); - if (!trip) { - return res.status(404).json({ message: 'Trip not found' }); - } - - // 권한 확인: 생성자나 협업자인 경우에만 수정 허용 - const userId = req.user._id; // Passport 세션을 통해 인증된 사용자 ID - const isAuthorized = - trip.create_by.toString() === userId.toString() || - trip.collaborators.includes(userId.toString()); - - if (!isAuthorized) { - return res.status(403).json({ message: '수정 권한이 없습니다.' }); - } - - // MongoDB의 `findByIdAndUpdate` 함수로 업데이트 - const updatedTrip = await Trip.findByIdAndUpdate( - req.params.id, - { name, start_date, end_date, location, collaborators }, - { new: true } // 업데이트 후 새로운 문서를 반환 - ); - - res.status(200).json(updatedTrip); - } catch (err) { - console.error('여행 계획 수정 실패:', err); - res.status(500).json({ error: err.message }); - } -}); - - +router.put('/trips/:id', tripController.updateTrip); // **DELETE**: 특정 여행 계획 삭제 -router.delete('/trips/:id', async (req, res) => { - try { - const deletedTrip = await Trip.findById(req.params.id); - if (!deletedTrip) return res.status(404).json({ message: 'Trip not found' }); - - // 요청한 사용자가 여행의 생성자인지 확인 - const userId = req.user._id; // Passport 세션을 통해 인증된 사용자 ID - if (trip.create_by.toString() !== userId.toString()) { - console.log('삭제 권한이 없습니다'); - return res.status(403).json({ message: '삭제 권한이 없습니다.' }); - } - - await Trip.findByIdAndDelete(req.params.id); - res.status(200).json({ message: 'Trip deleted successfully' }); - } catch (err) { - console.error('여행 계획 삭제 실패: ', err); - res.status(500).json({ error: err.message }); - } -}); +router.delete('/trips/:id', tripController.deleteTrip); // **POST**: 공동 작업자 추가 -router.post('/trips/:id/collaborators', async (req, res) => { - try { - const { collaboratorId } = req.body; - const trip = await Trip.findById(req.params.id); - if (!trip) return res.status(404).json({ message: 'Trip not found' }); - trip.collaborators.push(collaboratorId); - await trip.save(); - res.status(200).json(trip); - } catch (err) { - console.error('공동 작업자 추가 실패: ',err); - res.status(500).json({ error: err.message }); - } -}); - -router.put('/trips/:id/plans/day', async (req, res) => { - try { - const { dayKey, places, route } = req.body; // 요청 데이터 - const trip = await Trip.findById(req.params.id); // Trip 찾기 - - if (!trip) { - return res.status(404).json({ message: 'Trip not found' }); - } - - // `plans` 디버깅 - console.log('Existing Plans:', JSON.stringify(trip.plans, null, 2)); - - // `Map`을 사용하여 dayKey 접근 - const currentDay = trip.plans.get(dayKey); - if (!currentDay) { - return res.status(404).json({ message: `Day ${dayKey} not found in trip plans` }); - } - - // 데이터 업데이트 - if (places) currentDay.places = places; - if (route) currentDay.route = route; - - // `Map`에 업데이트된 day 데이터 설정 - trip.plans.set(dayKey, currentDay); - - // Mongoose에 변경 사항 알림 - trip.markModified('plans'); - - console.log('Before Save:', JSON.stringify(trip.plans.get(dayKey), null, 2)); - - // 변경 사항 저장 - const updatedTrip = await trip.save(); - - console.log('After Save:', JSON.stringify(updatedTrip.plans.get(dayKey), null, 2)); - - res.status(200).json(updatedTrip.plans.get(dayKey)); // 수정된 day 데이터 반환 - } catch (err) { - console.error('Error updating day:', err); - res.status(500).json({ error: err.message }); - } -}); - +router.post('/trips/:id/collaborators', tripController.addCollaborator); +// **PUT**: 하루 계획 추가 +router.put('/trips/:id/plans/day', tripController.addDayPlan); -module.exports = router; +module.exports = router; \ No newline at end of file