From d428991539377c9407a5364f588a33eb3242f82f Mon Sep 17 00:00:00 2001 From: CookieDasora Date: Tue, 25 Jul 2023 18:25:43 -0300 Subject: [PATCH] Created new routes, changed file names, new tables --- .../migration.sql | 46 +++++++++++++ .../migration.sql | 20 ++++++ .../migration.sql | 2 + prisma/schema.prisma | 64 ++++++++++++++----- src/app.ts | 3 +- src/controllers/comments-router.ts | 22 +++++++ src/controllers/comments/create.ts | 26 ++++++++ src/controllers/comments/delete.ts | 22 +++++++ src/controllers/comments/fetch.ts | 21 ++++++ src/controllers/comments/update.ts | 26 ++++++++ src/controllers/posts-router.ts | 6 +- src/controllers/posts/create.ts | 4 ++ .../posts/{get-info.ts => fetch-info.ts} | 4 +- src/controllers/posts/fetch-likes.ts | 21 ++++++ src/controllers/users-router.ts | 8 ++- .../users/{get-info.ts => fetch-info.ts} | 6 +- src/controllers/users/fetch-posts.ts | 17 +++++ src/controllers/users/search-user.ts | 17 +++++ src/routes.ts | 2 + src/services/comments/create.ts | 35 ++++++++++ src/services/comments/delete.ts | 35 ++++++++++ src/services/comments/fetch.ts | 31 +++++++++ src/services/comments/update.ts | 40 ++++++++++++ src/services/index.ts | 33 ++++++++-- .../posts/{get-info.ts => fetch-info.ts} | 8 +-- src/services/posts/fetch-likes.ts | 26 ++++++++ src/services/posts/get-likes.ts | 0 src/services/users/delete.ts | 6 -- .../users/{get-info.ts => fetch-info.ts} | 4 +- src/services/users/fetch-posts.ts | 21 ++++++ src/services/users/search-user.ts | 20 ++++++ 31 files changed, 550 insertions(+), 46 deletions(-) create mode 100644 prisma/migrations/20230725192001_created_comments_model/migration.sql create mode 100644 prisma/migrations/20230725193554_created_notifications_model/migration.sql create mode 100644 prisma/migrations/20230725204148_modified_comments_model/migration.sql create mode 100644 src/controllers/comments-router.ts create mode 100644 src/controllers/comments/create.ts create mode 100644 src/controllers/comments/delete.ts create mode 100644 src/controllers/comments/fetch.ts create mode 100644 src/controllers/comments/update.ts rename src/controllers/posts/{get-info.ts => fetch-info.ts} (76%) create mode 100644 src/controllers/posts/fetch-likes.ts rename src/controllers/users/{get-info.ts => fetch-info.ts} (66%) create mode 100644 src/controllers/users/fetch-posts.ts create mode 100644 src/controllers/users/search-user.ts create mode 100644 src/services/comments/create.ts create mode 100644 src/services/comments/delete.ts create mode 100644 src/services/comments/fetch.ts create mode 100644 src/services/comments/update.ts rename src/services/posts/{get-info.ts => fetch-info.ts} (74%) create mode 100644 src/services/posts/fetch-likes.ts delete mode 100644 src/services/posts/get-likes.ts rename src/services/users/{get-info.ts => fetch-info.ts} (82%) create mode 100644 src/services/users/fetch-posts.ts create mode 100644 src/services/users/search-user.ts diff --git a/prisma/migrations/20230725192001_created_comments_model/migration.sql b/prisma/migrations/20230725192001_created_comments_model/migration.sql new file mode 100644 index 0000000..107ad5f --- /dev/null +++ b/prisma/migrations/20230725192001_created_comments_model/migration.sql @@ -0,0 +1,46 @@ +-- DropForeignKey +ALTER TABLE "Follows" DROP CONSTRAINT "Follows_followerId_fkey"; + +-- DropForeignKey +ALTER TABLE "Follows" DROP CONSTRAINT "Follows_followingId_fkey"; + +-- DropForeignKey +ALTER TABLE "Like" DROP CONSTRAINT "Like_postId_fkey"; + +-- DropForeignKey +ALTER TABLE "Like" DROP CONSTRAINT "Like_userId_fkey"; + +-- DropForeignKey +ALTER TABLE "Post" DROP CONSTRAINT "Post_authorId_fkey"; + +-- CreateTable +CREATE TABLE "Comments" ( + "id" TEXT NOT NULL, + "content" TEXT NOT NULL, + "userId" TEXT NOT NULL, + "postId" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "Comments_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "Post" ADD CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Like" ADD CONSTRAINT "Like_postId_fkey" FOREIGN KEY ("postId") REFERENCES "Post"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Like" ADD CONSTRAINT "Like_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Follows" ADD CONSTRAINT "Follows_followerId_fkey" FOREIGN KEY ("followerId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Follows" ADD CONSTRAINT "Follows_followingId_fkey" FOREIGN KEY ("followingId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Comments" ADD CONSTRAINT "Comments_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Comments" ADD CONSTRAINT "Comments_postId_fkey" FOREIGN KEY ("postId") REFERENCES "Post"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/20230725193554_created_notifications_model/migration.sql b/prisma/migrations/20230725193554_created_notifications_model/migration.sql new file mode 100644 index 0000000..800bf6b --- /dev/null +++ b/prisma/migrations/20230725193554_created_notifications_model/migration.sql @@ -0,0 +1,20 @@ +-- CreateEnum +CREATE TYPE "NotificationType" AS ENUM ('WARNING', 'FRIEND'); + +-- CreateTable +CREATE TABLE "Notifications" ( + "id" TEXT NOT NULL, + "type" "NotificationType" NOT NULL, + "content" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "fromUserId" TEXT NOT NULL, + "toUserId" TEXT NOT NULL, + + CONSTRAINT "Notifications_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "Notifications" ADD CONSTRAINT "Notifications_fromUserId_fkey" FOREIGN KEY ("fromUserId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Notifications" ADD CONSTRAINT "Notifications_toUserId_fkey" FOREIGN KEY ("toUserId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/20230725204148_modified_comments_model/migration.sql b/prisma/migrations/20230725204148_modified_comments_model/migration.sql new file mode 100644 index 0000000..36a46c3 --- /dev/null +++ b/prisma/migrations/20230725204148_modified_comments_model/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Comments" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 390d2bb..8b173e2 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -8,25 +8,29 @@ datasource db { } model User { - id String @id @default(uuid()) - displayName String? - username String @unique - email String @unique - password String - posts Post[] - profileImage String? - likedPosts Like[] - followers Follows[] @relation("following") - following Follows[] @relation("follower") - createdAt DateTime @default(now()) + id String @id @default(uuid()) + displayName String? + username String @unique + email String @unique + password String + posts Post[] + profileImage String? + likedPosts Like[] + followers Follows[] @relation("following") + following Follows[] @relation("follower") + postComments Comments[] + fromNotifications Notifications[] @relation("fromNotifications") + toNotifications Notifications[] @relation("toNotifications") + createdAt DateTime @default(now()) } model Post { id String @id @default(uuid()) content String authorId String - author User @relation(fields: [authorId], references: [id]) + author User @relation(fields: [authorId], references: [id], onDelete: Cascade) likes Like[] + comments Comments[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } @@ -34,16 +38,44 @@ model Post { model Like { id String @id @default(uuid()) postId String - post Post @relation(fields: [postId], references: [id]) + post Post @relation(fields: [postId], references: [id], onDelete: Cascade) userId String - user User @relation(fields: [userId], references: [id]) + user User @relation(fields: [userId], references: [id], onDelete: Cascade) createdAt DateTime @default(now()) } + model Follows { - follower User @relation("follower", fields: [followerId], references: [id]) + follower User @relation("follower", fields: [followerId], references: [id], onDelete: Cascade) followerId String - following User @relation("following", fields: [followingId], references: [id]) + following User @relation("following", fields: [followingId], references: [id], onDelete: Cascade) followingId String @@id([followerId, followingId]) } + +model Comments { + id String @id @default(uuid()) + content String + userId String + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + postId String + post Post @relation(fields: [postId], references: [id], onDelete: Cascade) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt @default(now()) +} + +model Notifications { + id String @id @default(uuid()) + type NotificationType + content String + createdAt DateTime @default(now()) + fromUserId String + fromUser User? @relation(name: "fromNotifications", fields: [fromUserId], references: [id], onDelete: Cascade) + toUserId String + toUser User? @relation(name: "toNotifications", fields: [toUserId], references: [id], onDelete: Cascade) +} + +enum NotificationType { + WARNING + FRIEND +} \ No newline at end of file diff --git a/src/app.ts b/src/app.ts index 3c3a13e..6ceb351 100644 --- a/src/app.ts +++ b/src/app.ts @@ -7,8 +7,7 @@ import limiter from './middlewares/rate-limit' const app = express() -// TODO: find a way to declare global variables for better refactor on test -// TODO: must pass userMock as a global +// TODO: Create a documentation page or create the client because this is getting really big app.use(express.json()) app.use(express.urlencoded({ extended: true })) diff --git a/src/controllers/comments-router.ts b/src/controllers/comments-router.ts new file mode 100644 index 0000000..6f3395a --- /dev/null +++ b/src/controllers/comments-router.ts @@ -0,0 +1,22 @@ +/* eslint-disable @typescript-eslint/no-misused-promises */ + +import { Router } from 'express' + +// Controllers +import commentCreateController from './comments/create' +import commentDeleteController from './comments/delete' +import commentFetchController from './comments/fetch' +import commentUpdateController from './comments/update' + +// Middlewares +import ensureAuthenticated from '../middlewares/ensure-authenticated' + +const commentsRouter = Router() + +// Posts related +commentsRouter.post('/create', ensureAuthenticated, commentCreateController) +commentsRouter.post('/delete', ensureAuthenticated, commentDeleteController) +commentsRouter.get('/info', commentFetchController) +commentsRouter.put('/update', ensureAuthenticated, commentUpdateController) + +export default commentsRouter diff --git a/src/controllers/comments/create.ts b/src/controllers/comments/create.ts new file mode 100644 index 0000000..a212e31 --- /dev/null +++ b/src/controllers/comments/create.ts @@ -0,0 +1,26 @@ +import { comment } from '../../services' +import type { Request, Response } from 'express' +import { badRequest } from '../../lib/http-errors' + +async function commentCreateController (req: Request, res: Response): Promise { + const { content, postId } = req.body + const id = req.user?.id ?? '' + + if (postId === undefined) { + return badRequest(res, 'Expected post id') + } + + if (content === undefined) { + return badRequest(res, 'Expected comment content') + } + + const result = await comment.create(postId, content, id) + + if (result instanceof Error) { + return badRequest(res, result.message) + } + + res.json(result) +} + +export default commentCreateController diff --git a/src/controllers/comments/delete.ts b/src/controllers/comments/delete.ts new file mode 100644 index 0000000..76a35fb --- /dev/null +++ b/src/controllers/comments/delete.ts @@ -0,0 +1,22 @@ +import { comment } from '../../services' +import type { Request, Response } from 'express' +import { badRequest } from '../../lib/http-errors' + +async function commentDeleteController (req: Request, res: Response): Promise { + const { commentId } = req.body + const id = req.user?.id ?? '' + + if (commentId === undefined) { + return badRequest(res, 'Expected post id') + } + + const result = await comment.delete(commentId, id) + + if (result instanceof Error) { + return badRequest(res, result.message) + } + + res.json(result) +} + +export default commentDeleteController diff --git a/src/controllers/comments/fetch.ts b/src/controllers/comments/fetch.ts new file mode 100644 index 0000000..9882a07 --- /dev/null +++ b/src/controllers/comments/fetch.ts @@ -0,0 +1,21 @@ +import { comment } from '../../services' +import type { Request, Response } from 'express' +import { badRequest } from '../../lib/http-errors' + +async function commentFetchController (req: Request, res: Response): Promise { + const commentId = req.query.id as string + + if (commentId === undefined) { + return badRequest(res, 'Expected post id') + } + + const result = await comment.fetch(commentId) + + if (result instanceof Error) { + return badRequest(res, result.message) + } + + res.json(result) +} + +export default commentFetchController diff --git a/src/controllers/comments/update.ts b/src/controllers/comments/update.ts new file mode 100644 index 0000000..5914b17 --- /dev/null +++ b/src/controllers/comments/update.ts @@ -0,0 +1,26 @@ +import { comment } from '../../services' +import type { Request, Response } from 'express' +import { badRequest } from '../../lib/http-errors' + +async function commentUpdateController (req: Request, res: Response): Promise { + const { commentId, content } = req.body + const id = req.user?.id ?? '' + + if (commentId === undefined) { + return badRequest(res, 'Expected comment content') + } + + if (content === undefined) { + return badRequest(res, 'Expected content to update') + } + + const result = await comment.update(content, id, commentId) + + if (result instanceof Error) { + return badRequest(res, result.message) + } + + res.json(result) +} + +export default commentUpdateController diff --git a/src/controllers/posts-router.ts b/src/controllers/posts-router.ts index f19b878..7035f1b 100644 --- a/src/controllers/posts-router.ts +++ b/src/controllers/posts-router.ts @@ -5,18 +5,20 @@ import { Router } from 'express' // Controllers import postCreateController from './posts/create' import postDeleteController from './posts/delete' -import postInfoController from './posts/get-info' +import postFetchInfoController from './posts/fetch-info' import postUpdateController from './posts/update' // Middlewares import ensureAuthenticated from '../middlewares/ensure-authenticated' +import postFetchLikesController from './posts/fetch-likes' const postsRouter = Router() // Posts related postsRouter.post('/create', ensureAuthenticated, postCreateController) postsRouter.post('/delete', ensureAuthenticated, postDeleteController) -postsRouter.get('/info', postInfoController) +postsRouter.get('/info', postFetchInfoController) postsRouter.put('/update', ensureAuthenticated, postUpdateController) +postsRouter.get('/fetch-likes', postFetchLikesController) export default postsRouter diff --git a/src/controllers/posts/create.ts b/src/controllers/posts/create.ts index 7034f28..bcca1d1 100644 --- a/src/controllers/posts/create.ts +++ b/src/controllers/posts/create.ts @@ -6,6 +6,10 @@ async function postCreateController (req: Request, res: Response): Promise const { content } = req.body const id: string = req.user?.id ?? '' + if (content === undefined) { + return badRequest(res, 'Expected post content') + } + const result = await post.create(content, id) if (result instanceof Error) { diff --git a/src/controllers/posts/get-info.ts b/src/controllers/posts/fetch-info.ts similarity index 76% rename from src/controllers/posts/get-info.ts rename to src/controllers/posts/fetch-info.ts index 6947e4e..47b7e25 100644 --- a/src/controllers/posts/get-info.ts +++ b/src/controllers/posts/fetch-info.ts @@ -2,7 +2,7 @@ import { post } from '../../services/index' import type { Request, Response } from 'express' import { badRequest } from '../../lib/http-errors' -async function postInfoController (req: Request, res: Response): Promise { +async function postFetchInfoController (req: Request, res: Response): Promise { const id = req.query.id as string if (id === undefined) { @@ -18,4 +18,4 @@ async function postInfoController (req: Request, res: Response): Promise { res.json(result) } -export default postInfoController +export default postFetchInfoController diff --git a/src/controllers/posts/fetch-likes.ts b/src/controllers/posts/fetch-likes.ts new file mode 100644 index 0000000..08b1957 --- /dev/null +++ b/src/controllers/posts/fetch-likes.ts @@ -0,0 +1,21 @@ +import { post } from '../../services/index' +import type { Request, Response } from 'express' +import { badRequest } from '../../lib/http-errors' + +async function postFetchLikesController (req: Request, res: Response): Promise { + const id = req.query.id as string + + if (id === undefined) { + return badRequest(res, 'Missing post id') + } + + const result = await post.fetchLikes(id) + + if (result instanceof Error) { + return badRequest(res, result.message) + } + + res.json(result) +} + +export default postFetchLikesController diff --git a/src/controllers/users-router.ts b/src/controllers/users-router.ts index 94b0169..eecfacf 100644 --- a/src/controllers/users-router.ts +++ b/src/controllers/users-router.ts @@ -6,8 +6,10 @@ import { Router } from 'express' import userAuthController from './users/auth' import userDeleteController from './users/delete' import userFollowController from './users/follow-user' -import userInfoController from './users/get-info' +import userFetchInfoController from './users/fetch-info' +import userFetchPostsController from './users/fetch-posts' import userLikePostController from './users/like-post' +import userSearchController from './users/search-user' import userSignupController from './users/signup' import userUpdateController from './users/update' import userUploadPictureController from './users/upload-picture' @@ -21,11 +23,13 @@ const usersRouter = Router() // Users related usersRouter.post('/auth', userAuthController) usersRouter.post('/delete', ensureAuthenticated, userDeleteController) -usersRouter.get('/info', userInfoController) +usersRouter.get('/info', userFetchInfoController) usersRouter.post('/signup', userSignupController) usersRouter.put('/update', ensureAuthenticated, userUpdateController) usersRouter.put('/profile-picture/upload', ensureAuthenticated, uploadFile, userUploadPictureController) usersRouter.post('/like-post', ensureAuthenticated, userLikePostController) usersRouter.post('/follow-user', ensureAuthenticated, userFollowController) +usersRouter.get('/fetch-posts', userFetchPostsController) +usersRouter.get('/search', userSearchController) export default usersRouter diff --git a/src/controllers/users/get-info.ts b/src/controllers/users/fetch-info.ts similarity index 66% rename from src/controllers/users/get-info.ts rename to src/controllers/users/fetch-info.ts index 808c914..138f7b9 100644 --- a/src/controllers/users/get-info.ts +++ b/src/controllers/users/fetch-info.ts @@ -2,14 +2,14 @@ import { user } from '../../services' import type { Request, Response } from 'express' import { badRequest } from '../../lib/http-errors' -async function userInfoController (req: Request, res: Response): Promise { +async function userFetchInfoController (req: Request, res: Response): Promise { const username = req.query.u as string if (username === undefined) { return badRequest(res, 'Missing username') } - const result = await user.info(username.toLowerCase()) + const result = await user.fetchInfo(username.toLowerCase()) if (result instanceof Error) { return badRequest(res, result.message) @@ -18,4 +18,4 @@ async function userInfoController (req: Request, res: Response): Promise { res.json(result) } -export default userInfoController +export default userFetchInfoController diff --git a/src/controllers/users/fetch-posts.ts b/src/controllers/users/fetch-posts.ts new file mode 100644 index 0000000..b0c3f90 --- /dev/null +++ b/src/controllers/users/fetch-posts.ts @@ -0,0 +1,17 @@ +import { user } from '../../services' +import type { Request, Response } from 'express' +import { badRequest } from '../../lib/http-errors' + +async function userFetchPostsController (req: Request, res: Response): Promise { + const username = req.query.u as string + + if (username === undefined) { + return badRequest(res, 'Missing username') + } + + const result = await user.fetchPosts(username) + + res.json(result) +} + +export default userFetchPostsController diff --git a/src/controllers/users/search-user.ts b/src/controllers/users/search-user.ts new file mode 100644 index 0000000..6af6354 --- /dev/null +++ b/src/controllers/users/search-user.ts @@ -0,0 +1,17 @@ +import { user } from '../../services' +import { Request, Response } from 'express' +import { badRequest } from '../../lib/http-errors' + +async function userSearchController (req: Request, res: Response): Promise { + const username = req.query.u as string + + if (username === undefined) { + return badRequest(res, 'Missing username') + } + + const result = await user.searchUser(username) + + res.json(result) +} + +export default userSearchController diff --git a/src/routes.ts b/src/routes.ts index 1ea81e4..bd0a48f 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -3,10 +3,12 @@ import { Router } from 'express' // Routers import usersRouter from './controllers/users-router' import postsRouter from './controllers/posts-router' +import commentsRouter from './controllers/comments-router' const router = Router() router.use('/user', usersRouter) router.use('/post', postsRouter) +router.use('/comment', commentsRouter) export default router diff --git a/src/services/comments/create.ts b/src/services/comments/create.ts new file mode 100644 index 0000000..c77725a --- /dev/null +++ b/src/services/comments/create.ts @@ -0,0 +1,35 @@ +import prisma from '../../clients/prisma-client' + +async function commentCreateService (postId: string, content: string, authorId: string): Promise { + const post = await prisma.post.findFirst({ + where: { + id: postId + } + }) + + if (post === null) { + return new Error('Post not found') + } + + const user = await prisma.user.findFirst({ + where: { + id: authorId + } + }) + + if (user === null) { + return new Error('User not found') + } + + const comment = await prisma.comments.create({ + data: { + content, + postId, + userId: authorId + } + }) + + return comment +} + +export default commentCreateService diff --git a/src/services/comments/delete.ts b/src/services/comments/delete.ts new file mode 100644 index 0000000..6c53f26 --- /dev/null +++ b/src/services/comments/delete.ts @@ -0,0 +1,35 @@ +import prisma from '../../clients/prisma-client' + +async function commentDeleteService (commentId: string, authorId: string): Promise { + const user = await prisma.user.findFirst({ + where: { + id: authorId + } + }) + + if (user === null) { + return new Error('User not found') + } + + const comment = await prisma.comments.findFirst({ + where: { + id: commentId, + userId: user.id + } + }) + + if (comment === null) { + return new Error('Comment not found') + } + + await prisma.comments.deleteMany({ + where: { + id: comment.id, + userId: user.id + } + }) + + return {} +} + +export default commentDeleteService diff --git a/src/services/comments/fetch.ts b/src/services/comments/fetch.ts new file mode 100644 index 0000000..577825a --- /dev/null +++ b/src/services/comments/fetch.ts @@ -0,0 +1,31 @@ +import prisma from '../../clients/prisma-client' + +async function commentFetchService (commentId: string): Promise { + const comment = await prisma.comments.findFirst({ + where: { + id: commentId + }, + select: { + id: true, + content: true, + createdAt: true, + updatedAt: true, + user: { + select: { + id: true, + displayName: true, + username: true, + profileImage: true + } + } + } + }) + + if (comment === null) { + return new Error('Comment not found') + } + + return comment +} + +export default commentFetchService diff --git a/src/services/comments/update.ts b/src/services/comments/update.ts new file mode 100644 index 0000000..2df3a71 --- /dev/null +++ b/src/services/comments/update.ts @@ -0,0 +1,40 @@ +import prisma from '../../clients/prisma-client' + +async function commentUpdateService (content: string, authorId: string, commentId: string): Promise { + const comment = await prisma.comments.findFirst({ + where: { + id: commentId, + userId: authorId + } + }) + + if (comment === null) { + return new Error('Comment does not exists') + } + + const updatedComment = await prisma.comments.update({ + where: { + id: comment.id, + userId: authorId + }, + data: { + content + }, + select: { + id: true, + content: true, + createdAt: true, + updatedAt: true, + user: { + select: { + displayName: true, + username: true, + profileImage: true + } + } + } + }) + return updatedComment +} + +export default commentUpdateService diff --git a/src/services/index.ts b/src/services/index.ts index 6be1287..b1f152d 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -1,35 +1,54 @@ import userAuthService from './users/auth' import userDeleteService from './users/delete' import userFollowService from './users/follow-user' -import userInfoService from './users/get-info' +import userFetchPostsService from './users/fetch-posts' +import userFetchInfoService from './users/fetch-info' import userLikePostService from './users/like-post' +import userSearchService from './users/search-user' import userSignupService from './users/signup' import userUpdateService from './users/update' import userUploadPictureService from './users/upload-picture' import postCreateService from './posts/create' import postDeleteService from './posts/delete' -import postInfoService from './posts/get-info' +import postFetchInfoService from './posts/fetch-info' +import postFetchLikesService from './posts/fetch-likes' import postUpdateService from './posts/update' +import commentCreateService from './comments/create' +import commentDeleteService from './comments/delete' +import commentFetchService from './comments/fetch' +import commentUpdateService from './comments/update' + // User services const user = { auth: userAuthService, delete: userDeleteService, - info: userInfoService, + fetchInfo: userFetchInfoService, signup: userSignupService, update: userUpdateService, uploadPicture: userUploadPictureService, likePost: userLikePostService, - follow: userFollowService + follow: userFollowService, + fetchPosts: userFetchPostsService, + searchUser: userSearchService } // Post services const post = { create: postCreateService, delete: postDeleteService, - info: postInfoService, - update: postUpdateService + info: postFetchInfoService, + update: postUpdateService, + fetchLikes: postFetchLikesService } -export { user, post } +// Comment services +const comment = { + create: commentCreateService, + delete: commentDeleteService, + fetch: commentFetchService, + update: commentUpdateService +} + +export { user, post, comment } diff --git a/src/services/posts/get-info.ts b/src/services/posts/fetch-info.ts similarity index 74% rename from src/services/posts/get-info.ts rename to src/services/posts/fetch-info.ts index 8e26366..3caf73c 100644 --- a/src/services/posts/get-info.ts +++ b/src/services/posts/fetch-info.ts @@ -1,6 +1,6 @@ import prisma from '../../clients/prisma-client' -async function postInfoService (id: string): Promise { +async function postFetchInfoService (id: string): Promise { const post = await prisma.post.findFirst({ where: { id @@ -10,13 +10,13 @@ async function postInfoService (id: string): Promise { content: true, createdAt: true, updatedAt: true, + likes: true, author: { select: { displayName: true, username: true } - }, - likes: true + } } }) @@ -27,4 +27,4 @@ async function postInfoService (id: string): Promise { return post } -export default postInfoService +export default postFetchInfoService diff --git a/src/services/posts/fetch-likes.ts b/src/services/posts/fetch-likes.ts new file mode 100644 index 0000000..e08930d --- /dev/null +++ b/src/services/posts/fetch-likes.ts @@ -0,0 +1,26 @@ +import prisma from '../../clients/prisma-client' + +async function postFetchLikesService (id: string): Promise { + const post = await prisma.like.findMany({ + where: { + postId: id + }, + select: { + user: { + select: { + displayName: true, + username: true, + profileImage: true + } + } + } + }) + + if (post === null) { + return new Error('Post not found') + } + + return post +} + +export default postFetchLikesService diff --git a/src/services/posts/get-likes.ts b/src/services/posts/get-likes.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/services/users/delete.ts b/src/services/users/delete.ts index 40754a2..e22ac4a 100644 --- a/src/services/users/delete.ts +++ b/src/services/users/delete.ts @@ -11,12 +11,6 @@ async function userDeleteService (userId: string): Promise { return new Error('Forbidden') } - await prisma.post.deleteMany({ - where: { - authorId: user.id - } - }) - await prisma.user.deleteMany({ where: { id: userId diff --git a/src/services/users/get-info.ts b/src/services/users/fetch-info.ts similarity index 82% rename from src/services/users/get-info.ts rename to src/services/users/fetch-info.ts index eece93f..181724b 100644 --- a/src/services/users/get-info.ts +++ b/src/services/users/fetch-info.ts @@ -1,6 +1,6 @@ import prisma from '../../clients/prisma-client' -async function userInfoService (username: string): Promise { +async function userFetchInfoService (username: string): Promise { const user = await prisma.user.findFirst({ where: { username @@ -33,4 +33,4 @@ async function userInfoService (username: string): Promise { return user } -export default userInfoService +export default userFetchInfoService diff --git a/src/services/users/fetch-posts.ts b/src/services/users/fetch-posts.ts new file mode 100644 index 0000000..a792633 --- /dev/null +++ b/src/services/users/fetch-posts.ts @@ -0,0 +1,21 @@ +import prisma from '../../clients/prisma-client' + +async function userFetchPostsService (username: string): Promise { + const posts = await prisma.post.findMany({ + where: { + author: { + username + } + }, + select: { + _count: true, + id: true, + content: true, + createdAt: true, + updatedAt: true + } + }) + return posts +} + +export default userFetchPostsService diff --git a/src/services/users/search-user.ts b/src/services/users/search-user.ts new file mode 100644 index 0000000..b6a1338 --- /dev/null +++ b/src/services/users/search-user.ts @@ -0,0 +1,20 @@ +import prisma from '../../clients/prisma-client' + +async function userSearchService (username: string): Promise { + const users = await prisma.user.findMany({ + where: { + username: { + contains: username + } + }, + select: { + displayName: true, + username: true, + profileImage: true + }, + take: 10 + }) + return users +} + +export default userSearchService