Newer
Older
const { Meeting, MeetingParticipant, User, Schedule } = require('../models');
const MeetingResponseDTO = require('../dtos/MeetingResponseDTO');
const MeetingDetailResponseDTO = require('../dtos/MeetingDetailResponseDTO');
const CreateMeetingRequestDTO = require('../dtos/CreateMeetingRequestDTO');
const ScheduleService = require('./scheduleService'); // ScheduleService 임포트
/**
* 번개 모임 생성
* @returns 생성된 모임 ID와 채팅방 ID
*/
async createMeeting(meetingData) {
const createMeetingDTO = new CreateMeetingRequestDTO(meetingData);
createMeetingDTO.validate();
const { title, description, start_time, end_time, location, deadline, type, created_by } = meetingData;
// 사용자와 FCM 토큰 조회
const user = await this._findUserWithFcmTokens(created_by);
const userFcmTokens = user.fcmTokenList.map((fcmToken) => fcmToken.token);
// 스케줄 충돌 확인
const hasConflict = await ScheduleService.checkScheduleOverlap(
created_by,
new Date(start_time),
new Date(end_time)
);
if (hasConflict) {
throw new Error('스케줄이 겹칩니다. 다른 시간을 선택해주세요.');
}
// 트랜잭션을 사용하여 모임 생성과 스케줄 추가를 원자적으로 처리
return await Meeting.sequelize.transaction(async (transaction) => {
const chatRoomData = this._constructChatRoomData(title, user, userFcmTokens);
const chatRoomResponse = await chatService.createChatRoom(chatRoomData);
if (!chatRoomResponse.success) {
throw new Error('채팅방 생성 실패');
}
const chatRoomId = chatRoomResponse.chatRoomId;
const newMeeting = await Meeting.create({
title,
description,
start_time,
end_time,
location,
deadline,
type,
created_by,
chatRoomId,
}, { transaction });
await MeetingParticipant.create({
meeting_id: newMeeting.id,
user_id: created_by,
}, { transaction });
await ScheduleService.createSchedule({
userId: created_by,
title: `번개 모임: ${title}`,
start_time: new Date(start_time),
end_time: new Date(end_time),
is_fixed: true,
});
const chatRoom = await ChatRoom.findOne({ chatRoomId: chatRoomId });
if (chatRoom) {
console.log("채팅방 찾음");
this._addParticipantToChatRoom(chatRoom, user, userFcmTokens);
}
return { meeting_id: newMeeting.id, chatRoomId };
});
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
*/
async getMeetings(userId) {
const meetings = await Meeting.findAll({
attributes: ['id', 'title', 'description', 'start_time', 'end_time', 'location', 'deadline', 'type'],
include: [
{
model: User,
as: 'creator',
attributes: ['name'],
},
{
model: MeetingParticipant,
as: 'participants',
attributes: ['user_id'],
},
],
});
return meetings.map((meeting) => {
const creatorName = meeting.creator ? meeting.creator.name : 'Unknown';
const isParticipant = meeting.participants.some(participant => participant.user_id === parseInt(userId, 10));
return new MeetingResponseDTO(
meeting,
isParticipant,
false, // isScheduleConflict: 필요 시 추가 로직 구현
creatorName
);
});
*/
async joinMeeting(meetingId, userId) {
const meeting = await Meeting.findByPk(meetingId);
if (!meeting) {
throw new Error('모임을 찾을 수 없습니다.');
}
if (meeting.type === 'CLOSE') {
throw new Error('이미 마감된 모임입니다.');
}
if (new Date() > new Date(meeting.deadline)) {
throw new Error('참가 신청이 마감되었습니다.');
}
const existingParticipant = await MeetingParticipant.findOne({
where: { meeting_id: meetingId, user_id: userId }
if (existingParticipant) {
throw new Error('이미 참가한 사용자입니다.');
await Meeting.sequelize.transaction(async (transaction) => {
const hasConflict = await ScheduleService.checkScheduleOverlap(
userId,
new Date(meeting.start_time),
new Date(meeting.end_time)
);
if (hasConflict) {
throw new Error('스케줄이 겹칩니다. 다른 모임에 참가하세요.');
}
await MeetingParticipant.create({ meeting_id: meetingId, user_id: userId }, { transaction });
await ScheduleService.createSchedule({
title: `번개 모임: ${meeting.title}`,
start_time: new Date(meeting.start_time),
end_time: new Date(meeting.end_time),
is_fixed: true,
});
// 사용자와 FCM 토큰 조회
const user = await this._findUserWithFcmTokens(userId);
const userFcmTokens = user.fcmTokenList.map((fcmToken) => fcmToken.token);
const chatRoom = await ChatRoom.findOne({ chatRoomId: meeting.chatRoomId });
if (chatRoom) {
console.log("채팅방 찾음");
this._addParticipantToChatRoom(chatRoom, user, userFcmTokens);
/**
* 번개 모임 상세 조회
* @return 모임 상세 DTO
*/
async getMeetingDetail(meetingId) {
const meeting = await Meeting.findByPk(meetingId, {
include: [
{
model: User,
as: 'creator',
},
{
model: MeetingParticipant,
as: 'participants',
include: [
{
model: User,
as: 'participantUser',
});
if (!meeting) {
throw new Error('모임을 찾을 수 없습니다.');
}
return new MeetingDetailResponseDTO(meeting);
}
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
/**
* 번개 모임 마감
*/
async closeMeeting(meetingId) {
const meeting = await Meeting.findByPk(meetingId);
if (!meeting) {
throw new Error('모임을 찾을 수 없습니다.');
}
if (meeting.type === 'CLOSE') {
throw new Error('이미 마감된 모임입니다.');
}
meeting.type = 'CLOSE';
await meeting.save();
return meeting;
}
// Helper functions
async _findUserWithFcmTokens(userId) {
const user = await User.findOne({
where: { id: userId },
include: [
{
model: FcmToken,
as: 'fcmTokenList',
attributes: ['token'],
},
],
});
if (!user) {
throw new Error('사용자를 찾을 수 없습니다.');
}
return user;
}
_constructChatRoomData(title, user, userFcmTokens) {
return {
meeting_id: null,
participants: [
{
name: user.name,
fcmTokens: userFcmTokens || [],
isOnline: true,
lastReadAt: new Date(),
lastReadLogId: null,
},
],
chatRoomName: title,
};
}
_addParticipantToChatRoom(chatRoom, user, userFcmTokens) {
// Map 필드가 초기화되지 않은 경우 기본값 설정
if (!chatRoom.isOnline) chatRoom.isOnline = new Map();
if (!chatRoom.lastReadAt) chatRoom.lastReadAt = new Map();
if (!chatRoom.lastReadLogId) chatRoom.lastReadLogId = new Map();
// 참가자 추가 로직
if (!chatRoom.participants.some(participant => participant.name === user.name)) {
chatRoom.participants.push({ name: user.name, fcmTokens: userFcmTokens });
chatRoom.isOnline.set(user.name, true);
chatRoom.lastReadAt.set(user.name, new Date());
chatRoom.lastReadLogId.set(user.name, null);
}
// 저장
chatRoom.save();
}