Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
524c5b3
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Jan 16, 2025
ab0b658
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Jan 16, 2025
fd44479
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Jan 17, 2025
7906205
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Jan 17, 2025
73923a4
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Jan 19, 2025
f1e8ab1
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Jan 19, 2025
d3f8016
[Merge] branch 'develop' of https://github.com/NoGiveUpWeCarry/backen…
JaeHye0k Jan 20, 2025
0fb33c0
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Jan 22, 2025
8416aae
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Jan 22, 2025
9a2ab44
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Jan 22, 2025
26d6335
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Jan 22, 2025
1e422f2
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Jan 22, 2025
36ee61c
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Jan 22, 2025
ed76b15
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Jan 22, 2025
a832b10
[Merge] branch 'develop' of https://github.com/NoGiveUpWeCarry/backen…
JaeHye0k Jan 23, 2025
0f16b9f
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Jan 24, 2025
497bb19
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 1, 2025
6901e82
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 1, 2025
57b9b7d
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 1, 2025
d26d636
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 1, 2025
7bf98de
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 2, 2025
d2ad20c
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 2, 2025
0eaa54d
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 2, 2025
d31ed68
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 2, 2025
a91f4eb
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 2, 2025
7ea7f76
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 2, 2025
979518d
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 2, 2025
608269e
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 2, 2025
dfdd80f
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 2, 2025
869720e
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 2, 2025
e7cb9f1
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 2, 2025
4df8436
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 2, 2025
3caa891
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 2, 2025
5df71da
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 2, 2025
b030653
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 2, 2025
8df99fd
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 2, 2025
5277f7f
[Fix] 디버깅 문 제거
Ss0Mae Feb 4, 2025
a0c9b9c
[Fix] 디버깅 문 제거
Ss0Mae Feb 4, 2025
0377fde
[Fix] 디버깅문 추가
Ss0Mae Feb 4, 2025
1da0094
[Fix] 피드별 게시글 조회 라스트커서 오류 수정
peppertown Feb 4, 2025
e6ecbbc
[Fix] 디버깅문 제거
Ss0Mae Feb 4, 2025
37b5588
[Fix] 오류 수정
Ss0Mae Feb 5, 2025
6e62e6f
[Fix] DB 수정
Ss0Mae Feb 5, 2025
7faaa71
[Fix] DB 수정
Ss0Mae Feb 5, 2025
54434ca
[Refactor] 타입 명시 구체화
peppertown Feb 10, 2025
363e1cc
[Refactor] 서비스 로직 파라미터에 타입 명시
peppertown Feb 12, 2025
1899226
[Feat] 채팅방 알림 핸들러 구현
peppertown Feb 12, 2025
a13e993
[Refactor] 개인 채팅방 생성 알림 핸들러로 처리
peppertown Feb 12, 2025
4b420a6
[Refactor] 그룹 채팅방 생성 알림 핸들러로 처리
peppertown Feb 12, 2025
77d1ac5
[Refactor] 메세지 알림 핸들러로 처리
peppertown Feb 12, 2025
fec276c
[Fix] 메세지 검색 로직 수정;
peppertown Feb 13, 2025
b63610d
[Merge] branch 'develop' of https://github.com/NoGiveUpWeCarry/backen…
peppertown Feb 13, 2025
6c2404e
[Merge] branch 'develop' of https://github.com/NoGiveUpWeCarry/backen…
JaeHye0k Feb 18, 2025
7ed3305
[Feat] 채널 메세지 조회 시 direction 상관없이 prev, next 둘다 전달 및 prev / next 위치 교체
peppertown Feb 19, 2025
523f967
[Feat] GetMessageDto 수정;
peppertown Feb 19, 2025
34d48bc
[Feat] 메세지 조회/검색에 cursor 대신 파라미터로 prev, next 사용
peppertown Feb 19, 2025
f250993
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 20, 2025
1a29fa2
[Feat] SearchMessageDto 수정; cursor 사용
peppertown Feb 20, 2025
15aa94a
[Fix] 메세지 검색 시 커서 사용하는 로직으로 수정
peppertown Feb 20, 2025
d58bbd7
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 20, 2025
7a1a268
[Refactor] 메세지 검색값 없을 시 404 예외처리
peppertown Feb 28, 2025
223891c
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Feb 28, 2025
a682f44
[Refactor] broadcastChannelJoined 이벤트 수신 범위 수정
peppertown Mar 4, 2025
3a5f04c
[Refactor] 비동기 처리 위치 변경
peppertown Mar 4, 2025
abd93d1
[Feat] exitChannel 이벤트 발생 시 나간 유저의 last_message_id ~ 가장 최근 메세지 read_…
peppertown Mar 4, 2025
71bdf21
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Mar 5, 2025
c8b12a8
[Fix] 사용자가 채팅 나갈때 메세지 리드카운트 오류 수정
peppertown Mar 6, 2025
97dc6b9
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Mar 6, 2025
ea85400
[Fix] 증가 -> 감소로 수정
peppertown Mar 6, 2025
923635a
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Mar 6, 2025
bd036d4
[Fix] 리드 카운트 에러 수정
peppertown Mar 6, 2025
07e02ec
[Feat] DTO 수정
peppertown Mar 6, 2025
b289d1f
[Refactor] 채널 메세지 조회
peppertown Mar 6, 2025
67c21c3
[Refactor] 메세지 검색
peppertown Mar 6, 2025
befe24a
[Merge] branch 'feature/chat-service' of https://github.com/NoGiveUpW…
JaeHye0k Mar 11, 2025
4e154ce
[Refactor] cursors -> cursor 로 변경, cursors 삼항 연산자 조건에 따른 결과 순서 반대로 변경
JaeHye0k Mar 12, 2025
26d9d30
[Refactor] data.reverse 제거
JaeHye0k Mar 12, 2025
6473742
[Refactor] 주석 제거
JaeHye0k Mar 12, 2025
72ad6f0
[Refactor] 불필요한 소켓 이벤트 응답 데이터 제거
JaeHye0k Mar 13, 2025
03bf61f
[Fix] 버그 수정
JaeHye0k Mar 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ model ProjectPost {
id Int @id @default(autoincrement())
user_id Int
title String
content String @db.Text
content String @db.LongText
thumbnail_url String?
role String
start_date DateTime
Expand Down
81 changes: 16 additions & 65 deletions src/chat/chat.gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {

// 유저 소켓 접속
async handleConnection(client: Socket) {
const userId = +client.handshake.query.userId;
const userId = Number(client.handshake.query.userId);
client.data.userId = userId; // userId 넘버로 저장

// 유저 온라인 -> DB에 저장
Expand Down Expand Up @@ -90,33 +90,15 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
console.log(`User ${userId2} is not connected.`);
}

// 알람 기능
// 알림
const sender = await this.chatService.getSenderProfile(userId1);

const message = `${sender.nickname}님과의 개인 채팅방이 생성되었습니다.`;

// 알람 DB에 저장
const createdNotification =
await this.notificationService.createNotification(
userId2,
userId1,
'privateChat',
message
);

// 전송할 알림 데이터 객체
const notificationData = {
notificationId: createdNotification.notificationId, // 포함된 notificationId
type: 'privateChat',
message,
senderNickname: sender.nickname,
senderProfileUrl: sender.profileUrl,
};

// SSE를 통해 실시간 알림 전송
this.notificationService.sendRealTimeNotification(
await this.chatService.handleChatNotices(
sender,
userId2,
notificationData
'privateChat',
message
);

// 클라이언트에 채널id 전달
Expand Down Expand Up @@ -173,31 +155,16 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
console.log('모든 유저가 오프라인 상태입니다.');
}

// 알림
const sender = await this.chatService.getSenderProfile(userId);
const message = `${sender.nickname}님이 단체 채팅방을 생성했습니다.`;

groupMemberIds.forEach(async memberId => {
const createdNotification =
await this.notificationService.createNotification(
memberId,
userId,
'groupChat',
message
);

// 전송할 알림 데이터 객체
const notificationData = {
notificationId: createdNotification.notificationId, // 포함된 notificationId
type: 'groupChat',
message,
senderNickname: sender.nickname,
senderProfileUrl: sender.profileUrl,
};

// SSE를 통해 실시간 알림 전송
this.notificationService.sendRealTimeNotification(
await this.chatService.handleChatNotices(
sender,
memberId,
notificationData
'groupChat',
message
);
});

Expand Down Expand Up @@ -247,7 +214,8 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {

// 클라이언트에 채널 객체 전달
client.emit('channelJoined', channel);
this.server.to(channelId.toString()).emit('broadcastChannelJoined');
console.log(client.id);
client.broadcast.to(channelId.toString()).emit('broadcastChannelJoined');
}

// 메세지 송수신
Expand Down Expand Up @@ -303,7 +271,6 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
date,
readCount: messageData.read_count,
};
console.log(sendData);

// 오프라인 유저들에게 알람
const offlineUsers = await this.chatService.getChannelOfflineUsers(
Expand All @@ -314,23 +281,7 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
const message = '새로운 메세지가 있습니다.';

offlineUsers.forEach(async id => {
const createdNotification =
await this.notificationService.createNotification(
id,
userId,
'groupChat',
message
);

const notificationData = {
notificationId: createdNotification.notificationId, // 포함된 notificationId
type: 'groupChat',
message,
senderNickname: user.nickname,
senderProfileUrl: user.profileUrl,
};

this.notificationService.sendRealTimeNotification(id, notificationData);
await this.chatService.handleChatNotices(user, id, 'message', message);
});
}

Expand All @@ -353,7 +304,7 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
// DB에서 유저 삭제 + 채널 탈퇴 메세지 DB 저장 후 반환
const leaveMessage = await this.chatService.deleteUser(userId, channelId);

this.server.to(channelId.toString()).emit('message', leaveMessage);
client.broadcast.to(channelId.toString()).emit('message', leaveMessage);
}

// 메세지 실시간 읽음처리
Expand All @@ -369,6 +320,6 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
const { userId, channelId, messageId } = data;
await this.chatService.increaseReadCount(messageId);
await this.chatService.setLastMessageId(userId, channelId, messageId);
this.server.to(data.channelId.toString()).emit('readCounted', messageId);
this.server.to(data.channelId.toString()).emit('readCounted');
}
}
104 changes: 71 additions & 33 deletions src/chat/chat.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import { GetMessageDto } from './dto/getMessage.dto';
import { SearchMessageDto } from './dto/serchMessage.dto';
import { S3Service } from '@src/s3/s3.service';
import * as fileType from 'file-type';
import { NotificationsService } from '@src/modules/notification/notification.service';

@Injectable()
export class ChatService {
constructor(
private readonly prisma: PrismaService,
private readonly s3: S3Service
private readonly s3: S3Service,
private readonly notificationsService: NotificationsService
) {}

// 온라인 유저 DB에 저장
Expand Down Expand Up @@ -314,7 +316,7 @@ export class ChatService {
const result = await this.prisma.message.findMany({
orderBy: {
// 커서값이 없다면(초기요청) direction 상관없이 desc 정렬
id: cursor ? (direction == 'forward' ? 'asc' : 'desc') : 'desc',
id: cursor || direction === 'backward' ? 'desc' : 'asc',
},
where: cursor
? {
Expand Down Expand Up @@ -343,21 +345,16 @@ export class ChatService {
});

// 메세지 데이터 양식화
const data = await this.getMessageObj(result);
const messages = await this.getMessageObj(result);

// 메세지 데이터, 메세지 id순 오름차순 정렬
const messages =
!cursor || direction == 'backward' ? data.reverse() : data;

// 커서
const cursors =
direction == 'backward'
? { prev: data[0] ? data[0].messageId : null }
: {
next: data[data.length - 1]
? data[data.length - 1].messageId
: null,
};
? messages[messages.length - 1]
? messages[messages.length - 1].messageId
: null
: messages[0]
? messages[0].messageId
: null;

// 응답 메세지
const message = {
Expand All @@ -366,7 +363,7 @@ export class ChatService {
};

// 응답데이터 {메세지데이터, 커서, 응답메세지}
return { messages, cursors, message };
return { messages, cursor: cursors, message };
} catch (err) {
return err.message;
}
Expand All @@ -392,7 +389,7 @@ export class ChatService {
select: { id: true },
});
direction = 'backward';
cursor = res.id;
cursor = res.id + 1;
}

// 키워드에 해당하는 메세지id 검색
Expand All @@ -409,8 +406,10 @@ export class ChatService {
});

if (!keywordMessage) {
const message = { code: 404, text: '메세지를 찾을 수 없습니다' };
return { message };
throw new HttpException(
'메세지를 찾을 수 없습니다',
HttpStatus.NOT_FOUND
);
}

// 키워드 메세지 커서 설정
Expand Down Expand Up @@ -438,23 +437,16 @@ export class ChatService {

const messages = await this.getMessageById(ids);
// 무한 스크롤용 커서 데이터
const cursors = {
// backward 무한스크롤 요청 커서
prev: forwardIds.length ? forwardIds[0] : null,
// forward 무한스크롤 요청 커서
next: backwordIds.length ? backwordIds[backwordIds.length - 1] : null,
// 검색 메세지 아이디 커서
search,
};
const cursors = search;

const message = {
code: 200,
message: '데이터 패칭 성공',
};

return { messages, cursors, message };
return { messages, cursor: cursors, message };
} catch (err) {
return err;
throw err;
}
}

Expand Down Expand Up @@ -510,8 +502,8 @@ export class ChatService {
user_id: userId,
},
});
const userData = this.getSenderProfile(userId);
const nickname = (await userData).nickname;
const userData = await this.getSenderProfile(userId);
const nickname = userData.nickname;

const data = {
type: 'exit',
Expand All @@ -524,6 +516,16 @@ export class ChatService {
data,
});

const lastMessage = await this.getLastMessageId(userId, channelId);

await this.prisma.message.updateMany({
where: {
id: { lt: lastMessage?.last_message_id || 0 },
channel_id: channelId,
},
data: { read_count: { decrement: 1 } },
});

return {
userId,
type: msg.type,
Expand Down Expand Up @@ -566,14 +568,18 @@ export class ChatService {
};
}

async increaseReadCount(messageId) {
async increaseReadCount(messageId: number) {
await this.prisma.message.update({
where: { id: messageId },
data: { read_count: { increment: 1 } },
});
}

async setLastMessageId(userId, channelId, lastMessageId) {
async setLastMessageId(
userId: number,
channelId: number,
lastMessageId: number
) {
const exist = await this.prisma.last_message_status.findFirst({
where: { user_id: userId, channel_id: channelId },
});
Expand All @@ -595,7 +601,7 @@ export class ChatService {
}

// 라스트 메세지 id 조회
async getLastMessageId(userId, channelId) {
async getLastMessageId(userId: number, channelId: number) {
const lastMessageId = await this.prisma.last_message_status.findFirst({
where: {
user_id: userId,
Expand Down Expand Up @@ -647,4 +653,36 @@ export class ChatService {

return result;
}

// 알림 생성 및 전송
async handleChatNotices(
sender,
targetUserId: number,
type: string,
message: string
) {
// 알림 생성 및 DB에 저장
const createdNotification =
await this.notificationsService.createNotification(
targetUserId,
sender.userId,
type,
message
);

// 전송할 알림 데이터 객체
const notificationData = {
notificationId: createdNotification.notificationId, // 포함된 notificationId
type: 'privateChat',
message,
senderNickname: sender.nickname,
senderProfileUrl: sender.profileUrl,
};

// SSE를 통해 실시간 알림 전송
this.notificationsService.sendRealTimeNotification(
targetUserId,
notificationData
);
}
}
2 changes: 1 addition & 1 deletion src/feed/feed.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ export class FeedService {
const result = await this.prisma.feedPost.findMany({
orderBy: { id: 'desc' },
where: {
...(cursor ? { id: { lt: cursor } } : {}), // cursor 조건 추가 (옵셔널)
...(feedTagIds ? { id: { in: feedTagIds } } : {}), // 태그 조건 추가 (옵셔널)
...(cursor ? { id: { lt: cursor } } : {}), // cursor 조건 추가 (옵셔널)
},

take: limit,
Expand Down
1 change: 0 additions & 1 deletion src/modules/notification/notification.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ export class NotificationsController {
}

console.log(`✅ SSE 연결 성공 - 사용자 ${userId}`);

req.on('close', () => {
console.log(`❌ 사용자 ${userId}와의 SSE 연결 종료`);
});
Expand Down
Loading
Loading