From 39d70587ac8d683c5857a399abc6a64dfad8c80c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8F=84=ED=98=84?= Date: Fri, 9 Dec 2022 22:12:46 +0900 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20=EC=B1=85=EC=9D=B4=EB=82=98=20?= =?UTF-8?q?=EA=B8=80=EC=9D=98=20=EC=A0=9C=EB=AA=A9=EC=9D=84=20=EB=B9=84?= =?UTF-8?q?=EC=9B=8C=EB=86=93=EC=9D=84=20=EC=88=98=20=EC=9E=88=EB=8A=94=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20-=20#274?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/apis/articles/articles.controller.ts | 5 +++++ backend/src/apis/books/books.controller.ts | 5 +++++ backend/src/errors/message.ts | 8 +++++--- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/backend/src/apis/articles/articles.controller.ts b/backend/src/apis/articles/articles.controller.ts index b38b5ca6..c213bd21 100644 --- a/backend/src/apis/articles/articles.controller.ts +++ b/backend/src/apis/articles/articles.controller.ts @@ -4,6 +4,7 @@ import { SearchArticles } from '@apis/articles/articles.interface'; import articlesService from '@apis/articles/articles.service'; import { IScrap } from '@apis/scraps/scraps.interface'; import scrapsService from '@apis/scraps/scraps.service'; +import { Forbidden, Message } from '@errors'; const searchArticles = async (req: Request, res: Response) => { const { query, page, take, userId } = req.query as unknown as SearchArticles; @@ -23,6 +24,8 @@ const getArticle = async (req: Request, res: Response) => { const createArticle = async (req: Request, res: Response) => { const { article, scraps } = req.body; + if (!article.title.length) throw new Forbidden(Message.ARTICLE_INVALID_TITLE); + const createdArticle = await articlesService.createArticle({ title: article.title, content: article.content, @@ -49,6 +52,8 @@ const createArticle = async (req: Request, res: Response) => { const updateArticle = async (req: Request, res: Response) => { const { article, scraps } = req.body; + if (!article.title.length) throw new Forbidden(Message.ARTICLE_INVALID_TITLE); + const articleId = Number(req.params.articleId); const modifiedArticle = await articlesService.updateArticle(articleId, { diff --git a/backend/src/apis/books/books.controller.ts b/backend/src/apis/books/books.controller.ts index a7ddd4d8..dc94588a 100644 --- a/backend/src/apis/books/books.controller.ts +++ b/backend/src/apis/books/books.controller.ts @@ -4,6 +4,7 @@ import { FindBooks, SearchBooks } from '@apis/books/books.interface'; import booksService from '@apis/books/books.service'; import { IScrap } from '@apis/scraps/scraps.interface'; import scrapsService from '@apis/scraps/scraps.service'; +import { Forbidden, Message } from '@errors'; const getBook = async (req: Request, res: Response) => { const { bookId } = req.params; @@ -40,6 +41,8 @@ const searchBooks = async (req: Request, res: Response) => { const createBook = async (req: Request, res: Response) => { const { title } = req.body; + if (!title.length) throw new Forbidden(Message.BOOK_INVALID_TITLE); + const userId = res.locals.user.id; const book = await booksService.createBook({ title, userId }); @@ -52,6 +55,8 @@ const createBook = async (req: Request, res: Response) => { const updateBook = async (req: Request, res: Response) => { const { id, title, thumbnail_image, scraps } = req.body; + if (!title.length) throw new Forbidden(Message.BOOK_INVALID_TITLE); + const userId = res.locals.user.id; const book = await booksService.updateBook({ id, title, thumbnail_image }); diff --git a/backend/src/errors/message.ts b/backend/src/errors/message.ts index 3e0006e2..7c3f94f6 100644 --- a/backend/src/errors/message.ts +++ b/backend/src/errors/message.ts @@ -2,11 +2,13 @@ export default { AUTH_WRONG: '아이디 또는 비밀번호가 일치하지 않습니다.', AUTH_USERNAME_OVERLAP: '중복되는 아이디가 존재합니다.', AUTH_NICKNAME_OVERLAP: '중복되는 닉네임이 존재합니다.', - SCRAP_OVERLAP: '이미 스크랩되어 있는 글입니다.', - ARTICLE_NOTFOUND: '일치하는 글이 없습니다.', - BOOK_NOTFOUND: '일치하는 책이 없습니다.', USER_NOTFOUND: '일치하는 유저가 없습니다.', TOKEN_EXPIRED: '로그인이 필요합니다.', TOKEN_MALFORMED: '로그인이 필요합니다.', + BOOK_NOTFOUND: '일치하는 책이 없습니다.', + BOOK_INVALID_TITLE: '책 제목이 비어있습니다.', BOOKMARK_NOTFOUND: '북마크된 책이 아닙니다.', + ARTICLE_NOTFOUND: '일치하는 글이 없습니다.', + ARTICLE_INVALID_TITLE: '글 제목이 비어있습니다.', + SCRAP_OVERLAP: '이미 스크랩되어 있는 글입니다.', }; From 4fa49f9998aa8cdbfda7e09b7133251aa0cadace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8F=84=ED=98=84?= Date: Fri, 9 Dec 2022 22:58:35 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20Article=20=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=20title=20=EC=BB=AC=EB=9F=BC=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=ED=83=80=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/prisma/schema.prisma | 99 +++++++++++++++++------------------- 1 file changed, 48 insertions(+), 51 deletions(-) diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index 70d9fdf0..326bf0cc 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -1,8 +1,5 @@ -// This is your Prisma schema file, -// learn more about it in the docs: https://pris.ly/d/prisma-schema - generator client { - provider = "prisma-client-js" + provider = "prisma-client-js" previewFeatures = ["fullTextSearch", "fullTextIndex"] } @@ -12,77 +9,77 @@ datasource db { } model User { - id Int @id @default(autoincrement()) - username String @db.VarChar(20) - password String @db.VarChar(100) - nickname String @db.VarChar(20) @unique - description String @db.VarChar(100) - profile_image String @db.VarChar(255) @default("https://kr.object.ncloudstorage.com/j027/522da4f3-c9d7-403d-a98f-2b09cabefc47.png") - provider String @db.VarChar(20) - created_at DateTime @default(now()) - deleted_at DateTime? - books Book[] - bookmarks Bookmark[] + id Int @id @default(autoincrement()) + username String @db.VarChar(20) + password String @db.VarChar(100) + nickname String @unique @db.VarChar(20) + description String @db.VarChar(100) + profile_image String @default("https://kr.object.ncloudstorage.com/j027/522da4f3-c9d7-403d-a98f-2b09cabefc47.png") @db.VarChar(255) + provider String @db.VarChar(20) + created_at DateTime @default(now()) + deleted_at DateTime? + books Book[] + bookmarks Bookmark[] temporary_article TemporaryArticle? - token Token? + token Token? } model Book { - id Int @id @default(autoincrement()) - thumbnail_image String @db.VarChar(255) @default("https://kr.object.ncloudstorage.com/j027/3947d647-f26e-43cc-9834-82d59703cd9c.png") - title String @db.VarChar(50) - created_at DateTime @default(now()) - deleted_at DateTime? - user User @relation(fields: [user_id], references: [id]) - user_id Int - articles Article[] - scraps Scrap[] - bookmarks Bookmark[] + id Int @id @default(autoincrement()) + thumbnail_image String @default("https://kr.object.ncloudstorage.com/j027/3947d647-f26e-43cc-9834-82d59703cd9c.png") @db.VarChar(255) + title String @db.VarChar(50) + created_at DateTime @default(now()) + deleted_at DateTime? + user User @relation(fields: [user_id], references: [id]) + user_id Int + articles Article[] + scraps Scrap[] + bookmarks Bookmark[] - @@fulltext([title]) + @@fulltext([title], map: "title") } model Article { - id Int @id @default(autoincrement()) - title String @db.VarChar(50) - content String @db.Text - created_at DateTime @default(now()) + id Int @id @default(autoincrement()) + title String @db.VarChar(100) + content String @db.Text + created_at DateTime @default(now()) deleted_at DateTime? - book Book @relation(fields: [book_id], references: [id]) - book_id Int - scraps Scrap[] + book Book @relation(fields: [book_id], references: [id]) + book_id Int + scraps Scrap[] - @@fulltext([content, title]) + @@fulltext([title, content], map: "title_content") } model Scrap { - id Int @id @default(autoincrement()) - order Int + id Int @id @default(autoincrement()) + order Int is_original Boolean - article Article @relation(fields: [article_id], references: [id]) - article_id Int - book Book @relation(fields: [book_id], references: [id]) - book_id Int + article Article @relation(fields: [article_id], references: [id]) + article_id Int + book Book @relation(fields: [book_id], references: [id]) + book_id Int } model Bookmark { - id Int @id @default(autoincrement()) - user User @relation(fields: [user_id], references: [id]) + id Int @id @default(autoincrement()) + user User @relation(fields: [user_id], references: [id]) user_id Int - book Book @relation(fields: [book_id], references: [id]) + book Book @relation(fields: [book_id], references: [id]) book_id Int } model TemporaryArticle { - id Int @id @default(autoincrement()) - title String @db.VarChar(50) + id Int @id @default(autoincrement()) + title String @db.VarChar(50) content String @db.Text - user User @relation(fields: [user_id], references: [id]) - user_id Int @unique + user User @relation(fields: [user_id], references: [id]) + user_id Int @unique } model Token { refresh_token String @db.VarChar(200) - user User @relation(fields: [user_id], references: [id]) - user_id Int @unique -} \ No newline at end of file + user User @relation(fields: [user_id], references: [id]) + user_id Int @unique +} From 6ecede1a3f9eeb9ca6074b074ae41e4b6e49036e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8F=84=ED=98=84?= Date: Fri, 9 Dec 2022 22:59:30 +0900 Subject: [PATCH 3/3] =?UTF-8?q?chore:=20Prisma=20=EB=B2=84=EC=A0=84=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/package-lock.json | 60 +++++++++++++++++++-------------------- backend/package.json | 4 +-- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index e8b44764..fd694500 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -5,7 +5,7 @@ "packages": { "": { "dependencies": { - "@prisma/client": "^4.7.0", + "@prisma/client": "^4.7.1", "aws-sdk": "^2.1259.0", "axios": "^1.1.3", "bcrypt": "^5.1.0", @@ -37,7 +37,7 @@ "eslint-plugin-import": "^2.26.0", "eslint-plugin-prettier": "^4.2.1", "prettier": "^2.7.1", - "prisma": "^4.7.0", + "prisma": "^4.7.1", "ts-node": "^10.9.1", "tsc-watch": "^5.0.3", "tsconfig-paths": "^4.1.0", @@ -264,12 +264,12 @@ "dev": true }, "node_modules/@prisma/client": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.7.0.tgz", - "integrity": "sha512-keXMa0oJWJGOzMEFKp+CEgzJPwnOtGSrnTWw6qMYxnypYrRFdNxqyA06EzELZexBhgM4oLooZ1jDJ3iy46wExA==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.7.1.tgz", + "integrity": "sha512-/GbnOwIPtjiveZNUzGXOdp7RxTEkHL4DZP3vBaFNadfr6Sf0RshU5EULFzVaSi9i9PIK9PYd+1Rn7z2B2npb9w==", "hasInstallScript": true, "dependencies": { - "@prisma/engines-version": "4.7.0-74.39190b250ebc338586e25e6da45e5e783bc8a635" + "@prisma/engines-version": "4.7.1-1.272861e07ab64f234d3ffc4094e32bd61775599c" }, "engines": { "node": ">=14.17" @@ -284,16 +284,16 @@ } }, "node_modules/@prisma/engines": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.7.0.tgz", - "integrity": "sha512-afKrVFktaZ1pOK12/uFl2hRsBWIJZuC5FdDtacuKk5x/mR+rC5AbA+PlN3ZCZbmYTaeiBMHjcU5wbT5z2N3nSQ==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.7.1.tgz", + "integrity": "sha512-zWabHosTdLpXXlMefHmnouhXMoTB1+SCbUU3t4FCmdrtIOZcarPKU3Alto7gm/pZ9vHlGOXHCfVZ1G7OIrSbog==", "devOptional": true, "hasInstallScript": true }, "node_modules/@prisma/engines-version": { - "version": "4.7.0-74.39190b250ebc338586e25e6da45e5e783bc8a635", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.7.0-74.39190b250ebc338586e25e6da45e5e783bc8a635.tgz", - "integrity": "sha512-ImczGEQ8NS1OUApEeyAGxC4uLTtQp0wI1+2wM4MeQLVwIQbyMHk1vOhWWE8Pwbi3rnzLcPvsIrd9sm6oNXhERw==" + "version": "4.7.1-1.272861e07ab64f234d3ffc4094e32bd61775599c", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.7.1-1.272861e07ab64f234d3ffc4094e32bd61775599c.tgz", + "integrity": "sha512-Bd4LZ+WAnUHOq31e9X/ihi5zPlr4SzTRwUZZYxvWOxlerIZ7HJlVa9zXpuKTKLpI9O1l8Ec4OYCKsivWCs5a3Q==" }, "node_modules/@tsconfig/node10": { "version": "1.0.9", @@ -3795,13 +3795,13 @@ } }, "node_modules/prisma": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.7.0.tgz", - "integrity": "sha512-VsecNo0Ca3+bDTzSpJqIpdupKVhhQ8aOYeWc09JlUM89knqvhSrlMrg0U8BiOD4tFrY1OPaCcraK8leDBxKMBg==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.7.1.tgz", + "integrity": "sha512-CCQP+m+1qZOGIZlvnL6T3ZwaU0LAleIHYFPN9tFSzjs/KL6vH9rlYbGOkTuG9Q1s6Ki5D0LJlYlW18Z9EBUpGg==", "devOptional": true, "hasInstallScript": true, "dependencies": { - "@prisma/engines": "4.7.0" + "@prisma/engines": "4.7.1" }, "bin": { "prisma": "build/index.js", @@ -5017,23 +5017,23 @@ } }, "@prisma/client": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.7.0.tgz", - "integrity": "sha512-keXMa0oJWJGOzMEFKp+CEgzJPwnOtGSrnTWw6qMYxnypYrRFdNxqyA06EzELZexBhgM4oLooZ1jDJ3iy46wExA==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.7.1.tgz", + "integrity": "sha512-/GbnOwIPtjiveZNUzGXOdp7RxTEkHL4DZP3vBaFNadfr6Sf0RshU5EULFzVaSi9i9PIK9PYd+1Rn7z2B2npb9w==", "requires": { - "@prisma/engines-version": "4.7.0-74.39190b250ebc338586e25e6da45e5e783bc8a635" + "@prisma/engines-version": "4.7.1-1.272861e07ab64f234d3ffc4094e32bd61775599c" } }, "@prisma/engines": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.7.0.tgz", - "integrity": "sha512-afKrVFktaZ1pOK12/uFl2hRsBWIJZuC5FdDtacuKk5x/mR+rC5AbA+PlN3ZCZbmYTaeiBMHjcU5wbT5z2N3nSQ==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.7.1.tgz", + "integrity": "sha512-zWabHosTdLpXXlMefHmnouhXMoTB1+SCbUU3t4FCmdrtIOZcarPKU3Alto7gm/pZ9vHlGOXHCfVZ1G7OIrSbog==", "devOptional": true }, "@prisma/engines-version": { - "version": "4.7.0-74.39190b250ebc338586e25e6da45e5e783bc8a635", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.7.0-74.39190b250ebc338586e25e6da45e5e783bc8a635.tgz", - "integrity": "sha512-ImczGEQ8NS1OUApEeyAGxC4uLTtQp0wI1+2wM4MeQLVwIQbyMHk1vOhWWE8Pwbi3rnzLcPvsIrd9sm6oNXhERw==" + "version": "4.7.1-1.272861e07ab64f234d3ffc4094e32bd61775599c", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.7.1-1.272861e07ab64f234d3ffc4094e32bd61775599c.tgz", + "integrity": "sha512-Bd4LZ+WAnUHOq31e9X/ihi5zPlr4SzTRwUZZYxvWOxlerIZ7HJlVa9zXpuKTKLpI9O1l8Ec4OYCKsivWCs5a3Q==" }, "@tsconfig/node10": { "version": "1.0.9", @@ -7640,12 +7640,12 @@ } }, "prisma": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.7.0.tgz", - "integrity": "sha512-VsecNo0Ca3+bDTzSpJqIpdupKVhhQ8aOYeWc09JlUM89knqvhSrlMrg0U8BiOD4tFrY1OPaCcraK8leDBxKMBg==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.7.1.tgz", + "integrity": "sha512-CCQP+m+1qZOGIZlvnL6T3ZwaU0LAleIHYFPN9tFSzjs/KL6vH9rlYbGOkTuG9Q1s6Ki5D0LJlYlW18Z9EBUpGg==", "devOptional": true, "requires": { - "@prisma/engines": "4.7.0" + "@prisma/engines": "4.7.1" } }, "process-nextick-args": { diff --git a/backend/package.json b/backend/package.json index daac1602..10e0fcc5 100644 --- a/backend/package.json +++ b/backend/package.json @@ -6,7 +6,7 @@ "lint": "eslint ." }, "dependencies": { - "@prisma/client": "^4.7.0", + "@prisma/client": "^4.7.1", "aws-sdk": "^2.1259.0", "axios": "^1.1.3", "bcrypt": "^5.1.0", @@ -38,7 +38,7 @@ "eslint-plugin-import": "^2.26.0", "eslint-plugin-prettier": "^4.2.1", "prettier": "^2.7.1", - "prisma": "^4.7.0", + "prisma": "^4.7.1", "ts-node": "^10.9.1", "tsc-watch": "^5.0.3", "tsconfig-paths": "^4.1.0",