From 5c71265ba9b8a4d5f1e5f109f44fdc9a2745f8be Mon Sep 17 00:00:00 2001 From: faker Date: Sun, 18 Jan 2026 23:12:57 +0900 Subject: [PATCH] =?UTF-8?q?feat=20:=20=ED=8F=B4=EB=8D=94=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=88=98=EC=A0=95=20=EC=82=AD=EC=A0=9C=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/folder.controller.js | 48 ++++++++++++++++++++++++++ src/dtos/folder.dto.js | 18 ++++++++++ src/repositories/folder.repository.js | 49 +++++++++++++++++++++++++++ src/routes/folder.route.js | 11 ++++++ src/routes/index.js | 2 ++ src/services/folder.service.js | 22 ++++++++++++ 6 files changed, 150 insertions(+) create mode 100644 src/controllers/folder.controller.js create mode 100644 src/dtos/folder.dto.js create mode 100644 src/repositories/folder.repository.js create mode 100644 src/routes/folder.route.js create mode 100644 src/services/folder.service.js diff --git a/src/controllers/folder.controller.js b/src/controllers/folder.controller.js new file mode 100644 index 0000000..3660203 --- /dev/null +++ b/src/controllers/folder.controller.js @@ -0,0 +1,48 @@ +import * as folderService from "../services/folder.service.js"; + +// 1. 폴더 생성 +export const createFolder = async (req, res, next) => { + try { + const userId = req.user.id; // 토큰에서 추출한 내 ID + const result = await folderService.createFolder(userId, req.body); + + res.status(201).json({ + resultType: "SUCCESS", + message: "폴더 생성 성공", + data: result }); + } catch (err) { + next(err); + } +}; + +// 2. 폴더 수정 +export const updateFolder = async (req, res, next) => { + try { + const userId = req.user.id; + const { folderId } = req.params; + const result = await folderService.updateFolder(userId, folderId, req.body); + + res.status(200).json({ + resultType: "SUCCESS", + message: "폴더 수정 성공", + data: result }); + } catch (err) { + next(err); + } +}; + +// 3. 폴더 삭제 +export const deleteFolder = async (req, res, next) => { + try { + const userId = req.user.id; + const { folderId } = req.params; + + await folderService.deleteFolder(userId, folderId); + + res.status(200).json({ + resultType: "SUCCESS", + message: "폴더 삭제 성공" }); + } catch (err) { + next(err); + } +}; \ No newline at end of file diff --git a/src/dtos/folder.dto.js b/src/dtos/folder.dto.js new file mode 100644 index 0000000..ac9c364 --- /dev/null +++ b/src/dtos/folder.dto.js @@ -0,0 +1,18 @@ +export const bodyToFolderDto = (body) => { + if (!body.folderTitle) { + throw new Error("폴더 이름(folderTitle)은 필수입니다."); + } + + return { + folderTitle: body.folderTitle, + color: body.color || "#000000", // 색상 없으면 기본 검정 + }; +}; + +export const responseFromFolder = (folder) => { + return { + folderId: folder.id, + folderTitle: folder.folderTitle, + color: folder.color + }; +}; \ No newline at end of file diff --git a/src/repositories/folder.repository.js b/src/repositories/folder.repository.js new file mode 100644 index 0000000..c8990d9 --- /dev/null +++ b/src/repositories/folder.repository.js @@ -0,0 +1,49 @@ +import { prisma } from "../db.config.js"; + +// 1. 폴더 생성 +export const addFolder = async (userId, data) => { + const newFolder = await prisma.folder.create({ + data: { + userId: userId, + folderTitle: data.folderTitle, + color: data.color, + }, + select: { + id: true, + folderTitle: true, + color: true, + } + }); + return newFolder; +}; + +// 2. 폴더 수정 +export const updateFolder = async (userId, folderId, data) => { + const updatedFolder = await prisma.folder.update({ + where: { + id: parseInt(folderId), + userId: userId, // 내 폴더인지 확인 + }, + data: { + folderTitle: data.folderTitle, + color: data.color, + }, + select: { + id: true, + folderTitle: true, + color: true, + } + }); + return updatedFolder; +}; + +// 3. 폴더 삭제 +export const removeFolder = async (userId, folderId) => { + const deletedFolder = await prisma.folder.delete({ + where: { + id: parseInt(folderId), + userId: userId, + }, + }); + return deletedFolder; +}; \ No newline at end of file diff --git a/src/routes/folder.route.js b/src/routes/folder.route.js new file mode 100644 index 0000000..efe59ed --- /dev/null +++ b/src/routes/folder.route.js @@ -0,0 +1,11 @@ +import express from "express"; +import * as folderController from "../controllers/folder.controller.js"; +import authenticate from "../middlewares/authenticate.middleware.js"; + +const router = express.Router(); + +router.post("/", authenticate, folderController.createFolder); +router.patch("/:folderId", authenticate, folderController.updateFolder); +router.delete("/:folderId", authenticate, folderController.deleteFolder); + +export default router; \ No newline at end of file diff --git a/src/routes/index.js b/src/routes/index.js index f7ccbae..6f53d37 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -2,10 +2,12 @@ import express from "express"; import userRouter from "./user.route.js"; import alarmRouter from "./alarm.route.js"; import modalRouter from "./modal.route.js"; +import folderRouter from "./folder.route.js"; const router = express.Router(); // 각 도메인별 라우터 등록 +router.use("/user/folder", folderRouter); router.use("/user", userRouter); router.use("/alarm", alarmRouter); router.use("/reference", modalRouter); diff --git a/src/services/folder.service.js b/src/services/folder.service.js new file mode 100644 index 0000000..34bfc42 --- /dev/null +++ b/src/services/folder.service.js @@ -0,0 +1,22 @@ +import * as folderRepository from "../repositories/folder.repository.js"; +import * as folderDto from "../dtos/folder.dto.js"; + +// 1. 폴더 생성 +export const createFolder = async (userId, body) => { + const folderData = folderDto.bodyToFolderDto(body); + const newFolder = await folderRepository.addFolder(userId, folderData); + return folderDto.responseFromFolder(newFolder); +}; + +// 2. 폴더 수정 +export const updateFolder = async (userId, folderId, body) => { + const folderData = folderDto.bodyToFolderDto(body); + const updatedFolder = await folderRepository.updateFolder(userId, folderId, folderData); + return folderDto.responseFromFolder(updatedFolder); +}; + +// 3. 폴더 삭제 +export const deleteFolder = async (userId, folderId) => { + await folderRepository.removeFolder(userId, folderId); + return; +}; \ No newline at end of file