Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ jobs:
ssh ec2 "echo '$ENV_FILE' > /opt/app/.env"
env:
ENV_FILE: ${{ secrets.ENV_FILE }}

- name: Restore Firebase service account key
run: |
ssh ec2 "mkdir -p /opt/app/config && echo $FIREBASE_SERVICE_ACCOUNT_BASE64 | base64 -d > /opt/app/config/service-account-key.json"
env:
FIREBASE_SERVICE_ACCOUNT_BASE64: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_BASE64 }}

- name: Install dependencies
run: ssh ec2 "cd /opt/app && npm install"
Expand Down
17 changes: 9 additions & 8 deletions src/chat/chat.routes.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
import express from "express";
import { createChatroom } from "./controller/chatroom.controller.js";
import { showChatroom } from "./controller/chatroom.controller.js";
import { getChatroom } from "./controller/chatroom.controller.js";
import { deleteChatrooms } from "./controller/chatroom.controller.js";
import { showMessages } from "./controller/chat.controller.js";
import { getMessages } from "./controller/chat.controller.js";
import { getMessageByKeyword } from "./controller/chat.controller.js";
import { authenticate } from "../middlewares/auth.middleware.js";

const router = express.Router();

// 채팅방 생성 API
router.post("", createChatroom);
router.post("", authenticate, createChatroom);

// 채팅방 삭제 API
router.delete("/delete", deleteChatrooms);
router.delete("/delete", authenticate, deleteChatrooms);

// 채팅 메시지 검색 API
router.get("/search/messages", getMessageByKeyword);
// 채팅 메시지 검색 API (다중)
router.get("/search/messages", authenticate, getMessageByKeyword);

// 채팅방 조회 API
router.get("/:consumerId", showChatroom);
router.get("/list", authenticate, getChatroom);

// 채팅 메시지 조회 API
router.get("/:chatroomId/messages", showMessages);
router.get("/:chatroomId/messages", authenticate, getMessages);

export default router;
18 changes: 13 additions & 5 deletions src/chat/controller/chat.controller.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { StatusCodes } from "http-status-codes";
import { parseWithBigInt, stringifyWithBigInt } from "../../bigintJson.js";
import { ShowMessagesDto } from "../dto/chat.dto.js";
import { GetMessagesDto } from "../dto/chat.dto.js";
import { ChatService } from "../service/chat.service.js";
import { FindChatroomByMessageDto } from "../dto/chat.dto.js";

export const showMessages = async (req, res, next) => {
export const getMessages = async (req, res, next) => {
try {
const dto = new ShowMessagesDto ({
const userId = BigInt(req.user.userId);

const dto = new GetMessagesDto ({
chatroomId: BigInt(req.params.chatroomId),
limit: req.query.limit,
cursor: req.query.cursor,
userId: userId,
});

const messages = await ChatService.getMessagesByChatroomId(dto);
Expand All @@ -23,9 +26,14 @@ export const showMessages = async (req, res, next) => {

export const getMessageByKeyword = async (req, res, next) => {
try {
const dto = new FindChatroomByMessageDto(req.query);
const userId = BigInt(req.user.userId);

const dto = new FindChatroomByMessageDto({
keyword: req.query.keyword,
userId: userId,
});

const messages = await ChatService.searchMessagesByKeyword(dto.keyword);
const messages = await ChatService.searchMessagesByKeyword(dto);
const responseData = parseWithBigInt(stringifyWithBigInt(messages));

res.status(StatusCodes.OK).success(responseData);
Expand Down
15 changes: 10 additions & 5 deletions src/chat/controller/chatroom.controller.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { StatusCodes } from "http-status-codes";
import { ChatroomService } from "../service/chatroom.service.js";
import { CreateChatroomDto } from "../dto/chatroom.dto.js";
import { ShowChatroomDto } from "../dto/chatroom.dto.js";
import { GetChatroomDto } from "../dto/chatroom.dto.js";
import { DeleteChatroomDto } from "../dto/chatroom.dto.js";
import { parseWithBigInt, stringifyWithBigInt } from "../../bigintJson.js";

export const createChatroom = async (req, res, next) => {
try {
const consumerId = BigInt(req.user.userId);

const dto = new CreateChatroomDto({
consumerId: BigInt(req.body.consumerId),
consumerId: consumerId,
artistId: BigInt(req.body.artistId),
requestId: BigInt(req.body.requestId),
});
Expand All @@ -22,10 +24,10 @@ export const createChatroom = async (req, res, next) => {
}
};

export const showChatroom = async (req, res, next) => {
export const getChatroom = async (req, res, next) => {
try {
const dto = new ShowChatroomDto({
consumerId: BigInt(req.params.consumerId)
const dto = new GetChatroomDto({
consumerId: BigInt(req.user.userId)
});

const chatrooms = await ChatroomService.getChatroomsByUserId(dto);
Expand All @@ -39,9 +41,12 @@ export const showChatroom = async (req, res, next) => {

export const deleteChatrooms = async (req, res, next) => {
try {
const userId = BigInt(req.user.userId);

const dto = new DeleteChatroomDto({
chatroomIds: req.body.chatroomIds,
userType: req.body.userType,
userId: userId,
});

const chatrooms = await ChatroomService.softDeleteChatroomsByUser(dto);
Expand Down
10 changes: 6 additions & 4 deletions src/chat/dto/chat.dto.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
export class ShowMessagesDto {
constructor({ chatroomId, limit, cursor }) {
export class GetMessagesDto {
constructor({ chatroomId, limit, cursor, userId }) {
this.chatroomId = chatroomId;
this.limit = limit ? Number(limit) : 20;
this.cursor = cursor ? BigInt(cursor) : null;
this.userId = BigInt(userId);
}
}

export class FindChatroomByMessageDto {
constructor(query) {
this.keyword = query.keyword;
constructor({ keyword, userId }) {
this.keyword = keyword;
this.userId = BigInt(userId);
}
}
13 changes: 7 additions & 6 deletions src/chat/dto/chatroom.dto.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ export class CreateChatroomDto {
}
}

export class ShowChatroomDto {
export class GetChatroomDto {
constructor({ consumerId }) {
this.consumerId = consumerId;
this.consumerId = BigInt(consumerId);
}
}

export class DeleteChatroomDto {
constructor({ chatroomIds, userType }) {
this.chatroomIds = chatroomIds.map(id => BigInt(id));
this.userType = userType;
}
constructor({ chatroomIds, userType, userId }) {
this.chatroomIds = chatroomIds.map(id => BigInt(id));
this.userType = userType;
this.userId = BigInt(userId);
}
}
9 changes: 6 additions & 3 deletions src/chat/repository/chatroom.repository.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,19 @@ export const ChatroomRepository = {
return await prisma.chatroom.findMany({
where: {
consumerId: consumerId,
},
hiddenConsumer: false,
}
});
},

async softDeleteChatrooms(chatroomIds, userType) {
async softDeleteChatrooms(chatroomIds, userType, userId) {
const hiddenField = userType === "consumer" ? "hiddenConsumer" : "hiddenArtist";
const userField = userType === "consumer" ? "consumerId" : "artistId";

await prisma.chatroom.updateMany({
where: {
id: { in: chatroomIds }
id: { in: chatroomIds },
[userField]: userId
},
data: {
[hiddenField]: true
Expand Down
12 changes: 10 additions & 2 deletions src/chat/service/chat.service.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
import { ChatroomRepository } from "../repository/chatroom.repository.js";
import { ChatRepository } from "../repository/chat.repository.js";
import { ChatroomNotFoundError } from "../../common/errors/chat.errors.js";
import { ForbiddenError } from "../../common/errors/chat.errors.js";

export const ChatService = {
async getMessagesByChatroomId(dto) {
const chatroom = await ChatroomRepository.findChatroomById(dto.chatroomId);
if (!chatroom) {
throw new ChatroomNotFoundError({ chatroomId: dto.chatroomId });
}

if (dto.userId !== chatroom.consumerId && dto.userId !== chatroom.artistId) {
throw new ForbiddenError({ consumerId: dto.userId });
}

const messages = await ChatRepository.findMessagesWithImages(dto);
return messages;
},

async searchMessagesByKeyword(keyword) {
const messages = await ChatRepository.searchByKeyword(keyword);
async searchMessagesByKeyword(dto) {
const userChatrooms = await ChatroomRepository.findChatroomsByUser(dto.userId);
const chatroomIds = userChatrooms.map(cr => cr.id);

const messages = await ChatRepository.searchByKeyword(dto.keyword, chatroomIds);
return messages;
},
};
2 changes: 1 addition & 1 deletion src/chat/service/chatroom.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const ChatroomService = {
throw new ChatroomNotFoundError({ chatroomIds: dto.chatroomIds });
}

await ChatroomRepository.softDeleteChatrooms(dto.chatroomIds, dto.userType);
await ChatroomRepository.softDeleteChatrooms(dto.chatroomIds, dto.userType, dto.userId);

const chatrooms = await ChatroomRepository.findChatroomsByIds(dto.chatroomIds);

Expand Down
11 changes: 11 additions & 0 deletions src/common/errors/chat.errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,15 @@ export class ChatroomNotFoundError extends BaseError {
data,
});
}
}

export class ForbiddenError extends BaseError {
constructor(data = null) {
super({
errorCode: "M002",
reason: "권한이 없습니다.",
statusCode: 403,
data,
});
}
}
Loading