mirror of
https://github.com/hknsh/project-knedita.git
synced 2024-11-28 17:41:15 +00:00
Created new routes, changed file names, new tables
This commit is contained in:
parent
11d74d846b
commit
d428991539
31 changed files with 550 additions and 46 deletions
|
@ -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;
|
|
@ -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;
|
|
@ -0,0 +1,2 @@
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Comments" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
|
@ -8,25 +8,29 @@ datasource db {
|
||||||
}
|
}
|
||||||
|
|
||||||
model User {
|
model User {
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
displayName String?
|
displayName String?
|
||||||
username String @unique
|
username String @unique
|
||||||
email String @unique
|
email String @unique
|
||||||
password String
|
password String
|
||||||
posts Post[]
|
posts Post[]
|
||||||
profileImage String?
|
profileImage String?
|
||||||
likedPosts Like[]
|
likedPosts Like[]
|
||||||
followers Follows[] @relation("following")
|
followers Follows[] @relation("following")
|
||||||
following Follows[] @relation("follower")
|
following Follows[] @relation("follower")
|
||||||
createdAt DateTime @default(now())
|
postComments Comments[]
|
||||||
|
fromNotifications Notifications[] @relation("fromNotifications")
|
||||||
|
toNotifications Notifications[] @relation("toNotifications")
|
||||||
|
createdAt DateTime @default(now())
|
||||||
}
|
}
|
||||||
|
|
||||||
model Post {
|
model Post {
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
content String
|
content String
|
||||||
authorId String
|
authorId String
|
||||||
author User @relation(fields: [authorId], references: [id])
|
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
|
||||||
likes Like[]
|
likes Like[]
|
||||||
|
comments Comments[]
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
}
|
}
|
||||||
|
@ -34,16 +38,44 @@ model Post {
|
||||||
model Like {
|
model Like {
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
postId String
|
postId String
|
||||||
post Post @relation(fields: [postId], references: [id])
|
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
|
||||||
userId String
|
userId String
|
||||||
user User @relation(fields: [userId], references: [id])
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
}
|
}
|
||||||
|
|
||||||
model Follows {
|
model Follows {
|
||||||
follower User @relation("follower", fields: [followerId], references: [id])
|
follower User @relation("follower", fields: [followerId], references: [id], onDelete: Cascade)
|
||||||
followerId String
|
followerId String
|
||||||
following User @relation("following", fields: [followingId], references: [id])
|
following User @relation("following", fields: [followingId], references: [id], onDelete: Cascade)
|
||||||
followingId String
|
followingId String
|
||||||
|
|
||||||
@@id([followerId, followingId])
|
@@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
|
||||||
|
}
|
|
@ -7,8 +7,7 @@ import limiter from './middlewares/rate-limit'
|
||||||
|
|
||||||
const app = express()
|
const app = express()
|
||||||
|
|
||||||
// TODO: find a way to declare global variables for better refactor on test
|
// TODO: Create a documentation page or create the client because this is getting really big
|
||||||
// TODO: must pass userMock as a global
|
|
||||||
|
|
||||||
app.use(express.json())
|
app.use(express.json())
|
||||||
app.use(express.urlencoded({ extended: true }))
|
app.use(express.urlencoded({ extended: true }))
|
||||||
|
|
22
src/controllers/comments-router.ts
Normal file
22
src/controllers/comments-router.ts
Normal file
|
@ -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
|
26
src/controllers/comments/create.ts
Normal file
26
src/controllers/comments/create.ts
Normal file
|
@ -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<void> {
|
||||||
|
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
|
22
src/controllers/comments/delete.ts
Normal file
22
src/controllers/comments/delete.ts
Normal file
|
@ -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<void> {
|
||||||
|
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
|
21
src/controllers/comments/fetch.ts
Normal file
21
src/controllers/comments/fetch.ts
Normal file
|
@ -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<void> {
|
||||||
|
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
|
26
src/controllers/comments/update.ts
Normal file
26
src/controllers/comments/update.ts
Normal file
|
@ -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<void> {
|
||||||
|
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
|
|
@ -5,18 +5,20 @@ import { Router } from 'express'
|
||||||
// Controllers
|
// Controllers
|
||||||
import postCreateController from './posts/create'
|
import postCreateController from './posts/create'
|
||||||
import postDeleteController from './posts/delete'
|
import postDeleteController from './posts/delete'
|
||||||
import postInfoController from './posts/get-info'
|
import postFetchInfoController from './posts/fetch-info'
|
||||||
import postUpdateController from './posts/update'
|
import postUpdateController from './posts/update'
|
||||||
|
|
||||||
// Middlewares
|
// Middlewares
|
||||||
import ensureAuthenticated from '../middlewares/ensure-authenticated'
|
import ensureAuthenticated from '../middlewares/ensure-authenticated'
|
||||||
|
import postFetchLikesController from './posts/fetch-likes'
|
||||||
|
|
||||||
const postsRouter = Router()
|
const postsRouter = Router()
|
||||||
|
|
||||||
// Posts related
|
// Posts related
|
||||||
postsRouter.post('/create', ensureAuthenticated, postCreateController)
|
postsRouter.post('/create', ensureAuthenticated, postCreateController)
|
||||||
postsRouter.post('/delete', ensureAuthenticated, postDeleteController)
|
postsRouter.post('/delete', ensureAuthenticated, postDeleteController)
|
||||||
postsRouter.get('/info', postInfoController)
|
postsRouter.get('/info', postFetchInfoController)
|
||||||
postsRouter.put('/update', ensureAuthenticated, postUpdateController)
|
postsRouter.put('/update', ensureAuthenticated, postUpdateController)
|
||||||
|
postsRouter.get('/fetch-likes', postFetchLikesController)
|
||||||
|
|
||||||
export default postsRouter
|
export default postsRouter
|
||||||
|
|
|
@ -6,6 +6,10 @@ async function postCreateController (req: Request, res: Response): Promise<void>
|
||||||
const { content } = req.body
|
const { content } = req.body
|
||||||
const id: string = req.user?.id ?? ''
|
const id: string = req.user?.id ?? ''
|
||||||
|
|
||||||
|
if (content === undefined) {
|
||||||
|
return badRequest(res, 'Expected post content')
|
||||||
|
}
|
||||||
|
|
||||||
const result = await post.create(content, id)
|
const result = await post.create(content, id)
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { post } from '../../services/index'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from '../../lib/http-errors'
|
||||||
|
|
||||||
async function postInfoController (req: Request, res: Response): Promise<void> {
|
async function postFetchInfoController (req: Request, res: Response): Promise<void> {
|
||||||
const id = req.query.id as string
|
const id = req.query.id as string
|
||||||
|
|
||||||
if (id === undefined) {
|
if (id === undefined) {
|
||||||
|
@ -18,4 +18,4 @@ async function postInfoController (req: Request, res: Response): Promise<void> {
|
||||||
res.json(result)
|
res.json(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default postInfoController
|
export default postFetchInfoController
|
21
src/controllers/posts/fetch-likes.ts
Normal file
21
src/controllers/posts/fetch-likes.ts
Normal file
|
@ -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<void> {
|
||||||
|
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
|
|
@ -6,8 +6,10 @@ import { Router } from 'express'
|
||||||
import userAuthController from './users/auth'
|
import userAuthController from './users/auth'
|
||||||
import userDeleteController from './users/delete'
|
import userDeleteController from './users/delete'
|
||||||
import userFollowController from './users/follow-user'
|
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 userLikePostController from './users/like-post'
|
||||||
|
import userSearchController from './users/search-user'
|
||||||
import userSignupController from './users/signup'
|
import userSignupController from './users/signup'
|
||||||
import userUpdateController from './users/update'
|
import userUpdateController from './users/update'
|
||||||
import userUploadPictureController from './users/upload-picture'
|
import userUploadPictureController from './users/upload-picture'
|
||||||
|
@ -21,11 +23,13 @@ const usersRouter = Router()
|
||||||
// Users related
|
// Users related
|
||||||
usersRouter.post('/auth', userAuthController)
|
usersRouter.post('/auth', userAuthController)
|
||||||
usersRouter.post('/delete', ensureAuthenticated, userDeleteController)
|
usersRouter.post('/delete', ensureAuthenticated, userDeleteController)
|
||||||
usersRouter.get('/info', userInfoController)
|
usersRouter.get('/info', userFetchInfoController)
|
||||||
usersRouter.post('/signup', userSignupController)
|
usersRouter.post('/signup', userSignupController)
|
||||||
usersRouter.put('/update', ensureAuthenticated, userUpdateController)
|
usersRouter.put('/update', ensureAuthenticated, userUpdateController)
|
||||||
usersRouter.put('/profile-picture/upload', ensureAuthenticated, uploadFile, userUploadPictureController)
|
usersRouter.put('/profile-picture/upload', ensureAuthenticated, uploadFile, userUploadPictureController)
|
||||||
usersRouter.post('/like-post', ensureAuthenticated, userLikePostController)
|
usersRouter.post('/like-post', ensureAuthenticated, userLikePostController)
|
||||||
usersRouter.post('/follow-user', ensureAuthenticated, userFollowController)
|
usersRouter.post('/follow-user', ensureAuthenticated, userFollowController)
|
||||||
|
usersRouter.get('/fetch-posts', userFetchPostsController)
|
||||||
|
usersRouter.get('/search', userSearchController)
|
||||||
|
|
||||||
export default usersRouter
|
export default usersRouter
|
||||||
|
|
|
@ -2,14 +2,14 @@ import { user } from '../../services'
|
||||||
import type { Request, Response } from 'express'
|
import type { Request, Response } from 'express'
|
||||||
import { badRequest } from '../../lib/http-errors'
|
import { badRequest } from '../../lib/http-errors'
|
||||||
|
|
||||||
async function userInfoController (req: Request, res: Response): Promise<void> {
|
async function userFetchInfoController (req: Request, res: Response): Promise<void> {
|
||||||
const username = req.query.u as string
|
const username = req.query.u as string
|
||||||
|
|
||||||
if (username === undefined) {
|
if (username === undefined) {
|
||||||
return badRequest(res, 'Missing username')
|
return badRequest(res, 'Missing username')
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await user.info(username.toLowerCase())
|
const result = await user.fetchInfo(username.toLowerCase())
|
||||||
|
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
return badRequest(res, result.message)
|
return badRequest(res, result.message)
|
||||||
|
@ -18,4 +18,4 @@ async function userInfoController (req: Request, res: Response): Promise<void> {
|
||||||
res.json(result)
|
res.json(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default userInfoController
|
export default userFetchInfoController
|
17
src/controllers/users/fetch-posts.ts
Normal file
17
src/controllers/users/fetch-posts.ts
Normal file
|
@ -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<void> {
|
||||||
|
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
|
17
src/controllers/users/search-user.ts
Normal file
17
src/controllers/users/search-user.ts
Normal file
|
@ -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<void> {
|
||||||
|
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
|
|
@ -3,10 +3,12 @@ import { Router } from 'express'
|
||||||
// Routers
|
// Routers
|
||||||
import usersRouter from './controllers/users-router'
|
import usersRouter from './controllers/users-router'
|
||||||
import postsRouter from './controllers/posts-router'
|
import postsRouter from './controllers/posts-router'
|
||||||
|
import commentsRouter from './controllers/comments-router'
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
router.use('/user', usersRouter)
|
router.use('/user', usersRouter)
|
||||||
router.use('/post', postsRouter)
|
router.use('/post', postsRouter)
|
||||||
|
router.use('/comment', commentsRouter)
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
|
35
src/services/comments/create.ts
Normal file
35
src/services/comments/create.ts
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import prisma from '../../clients/prisma-client'
|
||||||
|
|
||||||
|
async function commentCreateService (postId: string, content: string, authorId: string): Promise<Object | Error> {
|
||||||
|
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
|
35
src/services/comments/delete.ts
Normal file
35
src/services/comments/delete.ts
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import prisma from '../../clients/prisma-client'
|
||||||
|
|
||||||
|
async function commentDeleteService (commentId: string, authorId: string): Promise<Object | Error> {
|
||||||
|
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
|
31
src/services/comments/fetch.ts
Normal file
31
src/services/comments/fetch.ts
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import prisma from '../../clients/prisma-client'
|
||||||
|
|
||||||
|
async function commentFetchService (commentId: string): Promise<Object | Error> {
|
||||||
|
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
|
40
src/services/comments/update.ts
Normal file
40
src/services/comments/update.ts
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
import prisma from '../../clients/prisma-client'
|
||||||
|
|
||||||
|
async function commentUpdateService (content: string, authorId: string, commentId: string): Promise<Object | Error> {
|
||||||
|
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
|
|
@ -1,35 +1,54 @@
|
||||||
import userAuthService from './users/auth'
|
import userAuthService from './users/auth'
|
||||||
import userDeleteService from './users/delete'
|
import userDeleteService from './users/delete'
|
||||||
import userFollowService from './users/follow-user'
|
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 userLikePostService from './users/like-post'
|
||||||
|
import userSearchService from './users/search-user'
|
||||||
import userSignupService from './users/signup'
|
import userSignupService from './users/signup'
|
||||||
import userUpdateService from './users/update'
|
import userUpdateService from './users/update'
|
||||||
import userUploadPictureService from './users/upload-picture'
|
import userUploadPictureService from './users/upload-picture'
|
||||||
|
|
||||||
import postCreateService from './posts/create'
|
import postCreateService from './posts/create'
|
||||||
import postDeleteService from './posts/delete'
|
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 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
|
// User services
|
||||||
const user = {
|
const user = {
|
||||||
auth: userAuthService,
|
auth: userAuthService,
|
||||||
delete: userDeleteService,
|
delete: userDeleteService,
|
||||||
info: userInfoService,
|
fetchInfo: userFetchInfoService,
|
||||||
signup: userSignupService,
|
signup: userSignupService,
|
||||||
update: userUpdateService,
|
update: userUpdateService,
|
||||||
uploadPicture: userUploadPictureService,
|
uploadPicture: userUploadPictureService,
|
||||||
likePost: userLikePostService,
|
likePost: userLikePostService,
|
||||||
follow: userFollowService
|
follow: userFollowService,
|
||||||
|
fetchPosts: userFetchPostsService,
|
||||||
|
searchUser: userSearchService
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post services
|
// Post services
|
||||||
const post = {
|
const post = {
|
||||||
create: postCreateService,
|
create: postCreateService,
|
||||||
delete: postDeleteService,
|
delete: postDeleteService,
|
||||||
info: postInfoService,
|
info: postFetchInfoService,
|
||||||
update: postUpdateService
|
update: postUpdateService,
|
||||||
|
fetchLikes: postFetchLikesService
|
||||||
}
|
}
|
||||||
|
|
||||||
export { user, post }
|
// Comment services
|
||||||
|
const comment = {
|
||||||
|
create: commentCreateService,
|
||||||
|
delete: commentDeleteService,
|
||||||
|
fetch: commentFetchService,
|
||||||
|
update: commentUpdateService
|
||||||
|
}
|
||||||
|
|
||||||
|
export { user, post, comment }
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from '../../clients/prisma-client'
|
||||||
|
|
||||||
async function postInfoService (id: string): Promise<Object | Error> {
|
async function postFetchInfoService (id: string): Promise<Object | Error> {
|
||||||
const post = await prisma.post.findFirst({
|
const post = await prisma.post.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id
|
id
|
||||||
|
@ -10,13 +10,13 @@ async function postInfoService (id: string): Promise<Object | Error> {
|
||||||
content: true,
|
content: true,
|
||||||
createdAt: true,
|
createdAt: true,
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
|
likes: true,
|
||||||
author: {
|
author: {
|
||||||
select: {
|
select: {
|
||||||
displayName: true,
|
displayName: true,
|
||||||
username: true
|
username: true
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
likes: true
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -27,4 +27,4 @@ async function postInfoService (id: string): Promise<Object | Error> {
|
||||||
return post
|
return post
|
||||||
}
|
}
|
||||||
|
|
||||||
export default postInfoService
|
export default postFetchInfoService
|
26
src/services/posts/fetch-likes.ts
Normal file
26
src/services/posts/fetch-likes.ts
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import prisma from '../../clients/prisma-client'
|
||||||
|
|
||||||
|
async function postFetchLikesService (id: string): Promise<Object | Error> {
|
||||||
|
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
|
|
@ -11,12 +11,6 @@ async function userDeleteService (userId: string): Promise<Object | Error> {
|
||||||
return new Error('Forbidden')
|
return new Error('Forbidden')
|
||||||
}
|
}
|
||||||
|
|
||||||
await prisma.post.deleteMany({
|
|
||||||
where: {
|
|
||||||
authorId: user.id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
await prisma.user.deleteMany({
|
await prisma.user.deleteMany({
|
||||||
where: {
|
where: {
|
||||||
id: userId
|
id: userId
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import prisma from '../../clients/prisma-client'
|
import prisma from '../../clients/prisma-client'
|
||||||
|
|
||||||
async function userInfoService (username: string): Promise<Object> {
|
async function userFetchInfoService (username: string): Promise<Object | Error> {
|
||||||
const user = await prisma.user.findFirst({
|
const user = await prisma.user.findFirst({
|
||||||
where: {
|
where: {
|
||||||
username
|
username
|
||||||
|
@ -33,4 +33,4 @@ async function userInfoService (username: string): Promise<Object> {
|
||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
export default userInfoService
|
export default userFetchInfoService
|
21
src/services/users/fetch-posts.ts
Normal file
21
src/services/users/fetch-posts.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import prisma from '../../clients/prisma-client'
|
||||||
|
|
||||||
|
async function userFetchPostsService (username: string): Promise<Object | Error> {
|
||||||
|
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
|
20
src/services/users/search-user.ts
Normal file
20
src/services/users/search-user.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import prisma from '../../clients/prisma-client'
|
||||||
|
|
||||||
|
async function userSearchService (username: string): Promise<Object | Error> {
|
||||||
|
const users = await prisma.user.findMany({
|
||||||
|
where: {
|
||||||
|
username: {
|
||||||
|
contains: username
|
||||||
|
}
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
displayName: true,
|
||||||
|
username: true,
|
||||||
|
profileImage: true
|
||||||
|
},
|
||||||
|
take: 10
|
||||||
|
})
|
||||||
|
return users
|
||||||
|
}
|
||||||
|
|
||||||
|
export default userSearchService
|
Loading…
Reference in a new issue