diff --git a/src/pages/api/beer-comments/[id].ts b/src/pages/api/beer-comments/[id].ts index 30ece2b..9c87b6d 100644 --- a/src/pages/api/beer-comments/[id].ts +++ b/src/pages/api/beer-comments/[id].ts @@ -28,13 +28,13 @@ const checkIfCommentOwner = async ( ) => { const { id } = req.query; const user = req.user!; - const comment = await findBeerCommentById(id); + const comment = await findBeerCommentById({ beerCommentId: id }); if (!comment) { throw new ServerError('Comment not found', 404); } - if (comment.postedById !== user.id) { + if (comment.postedBy.id !== user.id) { throw new ServerError('You are not authorized to modify this comment', 403); } diff --git a/src/pages/api/beers/[id]/comments/index.ts b/src/pages/api/beers/[id]/comments/index.ts index 33afa40..e3741d7 100644 --- a/src/pages/api/beers/[id]/comments/index.ts +++ b/src/pages/api/beers/[id]/comments/index.ts @@ -53,10 +53,11 @@ const getAll = async ( // eslint-disable-next-line @typescript-eslint/naming-convention const { page_size, page_num } = req.query; - const comments = await getAllBeerComments( - { id: beerPostId }, - { pageSize: parseInt(page_size, 10), pageNum: parseInt(page_num, 10) }, - ); + const comments = await getAllBeerComments({ + beerPostId, + pageNum: parseInt(page_num, 10), + pageSize: parseInt(page_size, 10), + }); const pageCount = await DBClient.instance.beerComment.count({ where: { beerPostId } }); diff --git a/src/pages/api/beers/[id]/like/index.ts b/src/pages/api/beers/[id]/like/index.ts index ed58b52..b85dc25 100644 --- a/src/pages/api/beers/[id]/like/index.ts +++ b/src/pages/api/beers/[id]/like/index.ts @@ -37,7 +37,7 @@ const sendLikeRequest = async ( }; if (alreadyLiked) { - await removeBeerPostLikeById(alreadyLiked.id); + await removeBeerPostLikeById({ beerLikeId: alreadyLiked.id }); jsonResponse.message = 'Successfully unliked beer post'; } else { await createBeerPostLike({ id, user }); @@ -53,7 +53,7 @@ const getLikeCount = async ( ) => { const id = req.query.id as string; - const likeCount = await getBeerPostLikeCount(id); + const likeCount = await getBeerPostLikeCount({ beerPostId: id }); res.status(200).json({ success: true, diff --git a/src/pages/api/beers/index.ts b/src/pages/api/beers/index.ts index 48c1995..e0f65cb 100644 --- a/src/pages/api/beers/index.ts +++ b/src/pages/api/beers/index.ts @@ -1,6 +1,7 @@ import validateRequest from '@/config/nextConnect/middleware/validateRequest'; import DBClient from '@/prisma/DBClient'; import getAllBeerPosts from '@/services/BeerPost/getAllBeerPosts'; +import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; import { NextApiRequest, NextApiResponse } from 'next'; @@ -8,10 +9,7 @@ import { createRouter } from 'next-connect'; import { z } from 'zod'; interface GetBeerPostsRequest extends NextApiRequest { - query: { - page_num: string; - page_size: string; - }; + query: z.infer; } const getBeerPosts = async ( @@ -41,10 +39,7 @@ const router = createRouter< router.get( validateRequest({ - querySchema: z.object({ - page_num: z.string().regex(/^\d+$/), - page_size: z.string().regex(/^\d+$/), - }), + querySchema: PaginatedQueryResponseSchema, }), getBeerPosts, ); diff --git a/src/pages/api/beers/styles/index.ts b/src/pages/api/beers/styles/index.ts index b179e9a..20901bb 100644 --- a/src/pages/api/beers/styles/index.ts +++ b/src/pages/api/beers/styles/index.ts @@ -1,6 +1,7 @@ import validateRequest from '@/config/nextConnect/middleware/validateRequest'; import DBClient from '@/prisma/DBClient'; import getAllBeerStyles from '@/services/BeerStyles/getAllBeerStyles'; +import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; import { NextApiRequest, NextApiResponse } from 'next'; @@ -8,7 +9,7 @@ import { createRouter } from 'next-connect'; import { z } from 'zod'; interface GetBeerStylesRequest extends NextApiRequest { - query: { page_num: string; page_size: string }; + query: z.infer; } const getBeerStyles = async ( @@ -18,7 +19,7 @@ const getBeerStyles = async ( const pageNum = parseInt(req.query.page_num, 10); const pageSize = parseInt(req.query.page_size, 10); - const beerStyles = await getAllBeerStyles(pageNum, pageSize); + const beerStyles = await getAllBeerStyles({ pageNum, pageSize }); const beerStyleCount = await DBClient.instance.beerStyle.count(); res.setHeader('X-Total-Count', beerStyleCount); @@ -38,10 +39,7 @@ const router = createRouter< router.get( validateRequest({ - querySchema: z.object({ - page_num: z.string().regex(/^\d+$/), - page_size: z.string().regex(/^\d+$/), - }), + querySchema: PaginatedQueryResponseSchema, }), getBeerStyles, ); diff --git a/src/pages/api/breweries/index.ts b/src/pages/api/breweries/index.ts index 5f2f2aa..5320d25 100644 --- a/src/pages/api/breweries/index.ts +++ b/src/pages/api/breweries/index.ts @@ -1,6 +1,7 @@ import validateRequest from '@/config/nextConnect/middleware/validateRequest'; import DBClient from '@/prisma/DBClient'; import getAllBreweryPosts from '@/services/BreweryPost/getAllBreweryPosts'; +import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; import { NextApiRequest, NextApiResponse } from 'next'; @@ -8,10 +9,7 @@ import { createRouter } from 'next-connect'; import { z } from 'zod'; interface GetBreweryPostsRequest extends NextApiRequest { - query: { - page_num: string; - page_size: string; - }; + query: z.infer; } const getBreweryPosts = async ( @@ -25,7 +23,6 @@ const getBreweryPosts = async ( const breweryPostCount = await DBClient.instance.breweryPost.count(); res.setHeader('X-Total-Count', breweryPostCount); - res.status(200).json({ message: 'Brewery posts retrieved successfully', statusCode: 200, @@ -40,12 +37,7 @@ const router = createRouter< >(); router.get( - validateRequest({ - querySchema: z.object({ - page_num: z.string().regex(/^\d+$/), - page_size: z.string().regex(/^\d+$/), - }), - }), + validateRequest({ querySchema: PaginatedQueryResponseSchema }), getBreweryPosts, ); diff --git a/src/pages/api/breweries/map/index.ts b/src/pages/api/breweries/map/index.ts index 1016221..1696faf 100644 --- a/src/pages/api/breweries/map/index.ts +++ b/src/pages/api/breweries/map/index.ts @@ -1,6 +1,7 @@ import validateRequest from '@/config/nextConnect/middleware/validateRequest'; import DBClient from '@/prisma/DBClient'; import BreweryPostMapQueryResult from '@/services/BreweryPost/schema/BreweryPostMapQueryResult'; +import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema'; import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; import { NextApiRequest, NextApiResponse } from 'next'; @@ -8,10 +9,7 @@ import { createRouter } from 'next-connect'; import { z } from 'zod'; interface GetBreweryPostsRequest extends NextApiRequest { - query: { - page_num: string; - page_size: string; - }; + query: z.infer; } const getBreweryPosts = async ( @@ -28,12 +26,7 @@ const getBreweryPosts = async ( await DBClient.instance.breweryPost.findMany({ select: { location: { - select: { - coordinates: true, - city: true, - country: true, - stateOrProvince: true, - }, + select: { coordinates: true, city: true, country: true, stateOrProvince: true }, }, id: true, name: true, @@ -59,12 +52,7 @@ const router = createRouter< >(); router.get( - validateRequest({ - querySchema: z.object({ - page_num: z.string().regex(/^\d+$/), - page_size: z.string().regex(/^\d+$/), - }), - }), + validateRequest({ querySchema: PaginatedQueryResponseSchema }), getBreweryPosts, ); diff --git a/src/services/BeerComment/createNewBeerComment.ts b/src/services/BeerComment/createNewBeerComment.ts index 50fb141..66956d7 100644 --- a/src/services/BeerComment/createNewBeerComment.ts +++ b/src/services/BeerComment/createNewBeerComment.ts @@ -1,18 +1,21 @@ import DBClient from '@/prisma/DBClient'; import { z } from 'zod'; import CreateCommentValidationSchema from '../schema/CommentSchema/CreateCommentValidationSchema'; +import BeerCommentQueryResult from './schema/BeerCommentQueryResult'; const CreateNewBeerCommentServiceSchema = CreateCommentValidationSchema.extend({ userId: z.string().cuid(), beerPostId: z.string().cuid(), }); +type CreateNewBeerCommentArgs = z.infer; + const createNewBeerComment = async ({ content, rating, beerPostId, userId, -}: z.infer) => { +}: CreateNewBeerCommentArgs): Promise> => { return DBClient.instance.beerComment.create({ data: { content, @@ -26,6 +29,7 @@ const createNewBeerComment = async ({ rating: true, postedBy: { select: { id: true, username: true } }, createdAt: true, + updatedAt: true, }, }); }; diff --git a/src/services/BeerComment/editBeerCommentById.ts b/src/services/BeerComment/editBeerCommentById.ts index 61e4570..b6ec04e 100644 --- a/src/services/BeerComment/editBeerCommentById.ts +++ b/src/services/BeerComment/editBeerCommentById.ts @@ -1,4 +1,6 @@ import DBClient from '@/prisma/DBClient'; +import { z } from 'zod'; +import BeerCommentQueryResult from './schema/BeerCommentQueryResult'; interface EditBeerCommentByIdArgs { id: string; @@ -6,17 +8,23 @@ interface EditBeerCommentByIdArgs { rating: number; } -const editBeerCommentById = async ({ id, content, rating }: EditBeerCommentByIdArgs) => { - const updated = await DBClient.instance.beerComment.update({ +const editBeerCommentById = async ({ + id, + content, + rating, +}: EditBeerCommentByIdArgs): Promise> => { + return DBClient.instance.beerComment.update({ where: { id }, - data: { - content, - rating, - updatedAt: new Date(), + data: { content, rating, updatedAt: new Date() }, + select: { + id: true, + content: true, + rating: true, + createdAt: true, + updatedAt: true, + postedBy: { select: { id: true, username: true, createdAt: true } }, }, }); - - return updated; }; export default editBeerCommentById; diff --git a/src/services/BeerComment/findBeerCommentById.ts b/src/services/BeerComment/findBeerCommentById.ts index 1cc1f0a..3338536 100644 --- a/src/services/BeerComment/findBeerCommentById.ts +++ b/src/services/BeerComment/findBeerCommentById.ts @@ -1,11 +1,25 @@ import DBClient from '@/prisma/DBClient'; +import { z } from 'zod'; +import BeerCommentQueryResult from './schema/BeerCommentQueryResult'; -const findBeerCommentById = async (id: string) => { - const comment = await DBClient.instance.beerComment.findUnique({ - where: { id }, +interface FindBeerCommentArgs { + beerCommentId: string; +} + +const findBeerCommentById = async ({ + beerCommentId, +}: FindBeerCommentArgs): Promise | null> => { + return DBClient.instance.beerComment.findUnique({ + where: { id: beerCommentId }, + select: { + id: true, + content: true, + rating: true, + createdAt: true, + updatedAt: true, + postedBy: { select: { id: true, username: true, createdAt: true } }, + }, }); - - return comment; }; export default findBeerCommentById; diff --git a/src/services/BeerComment/getAllBeerComments.ts b/src/services/BeerComment/getAllBeerComments.ts index c414ed1..7976d66 100644 --- a/src/services/BeerComment/getAllBeerComments.ts +++ b/src/services/BeerComment/getAllBeerComments.ts @@ -1,28 +1,31 @@ import DBClient from '@/prisma/DBClient'; -import BeerPostQueryResult from '@/services/BeerPost/schema/BeerPostQueryResult'; import { z } from 'zod'; import CommentQueryResult from '../schema/CommentSchema/CommentQueryResult'; -const getAllBeerComments = async ( - { id }: Pick, 'id'>, - { pageSize, pageNum = 0 }: { pageSize: number; pageNum?: number }, -) => { - const skip = (pageNum - 1) * pageSize; - const beerComments: z.infer[] = - await DBClient.instance.beerComment.findMany({ - skip, - take: pageSize, - where: { beerPostId: id }, - select: { - id: true, - content: true, - rating: true, - createdAt: true, - postedBy: { select: { id: true, username: true, createdAt: true } }, - }, - orderBy: { createdAt: 'desc' }, - }); - return beerComments; +interface GetAllBeerCommentsArgs { + beerPostId: string; + pageNum: number; + pageSize: number; +} + +const getAllBeerComments = async ({ + beerPostId, + pageNum, + pageSize, +}: GetAllBeerCommentsArgs): Promise[]> => { + return DBClient.instance.beerComment.findMany({ + skip: (pageNum - 1) * pageSize, + take: pageSize, + where: { beerPostId }, + orderBy: { createdAt: 'desc' }, + select: { + id: true, + content: true, + rating: true, + createdAt: true, + postedBy: { select: { id: true, username: true, createdAt: true } }, + }, + }); }; export default getAllBeerComments; diff --git a/src/services/BeerComment/getBeerCommentCount.ts b/src/services/BeerComment/getBeerCommentCount.ts index c1d5e62..989e7cd 100644 --- a/src/services/BeerComment/getBeerCommentCount.ts +++ b/src/services/BeerComment/getBeerCommentCount.ts @@ -1,11 +1,13 @@ import DBClient from '@/prisma/DBClient'; -const getBeerCommentCount = async (beerPostId: string) => { - const count = await DBClient.instance.beerComment.count({ - where: { beerPostId }, - }); +interface GetBeerCommentCountArgs { + beerPostId: string; +} - return count; +const getBeerCommentCount = async ({ + beerPostId, +}: GetBeerCommentCountArgs): Promise => { + return DBClient.instance.beerComment.count({ where: { beerPostId } }); }; export default getBeerCommentCount; diff --git a/src/services/BeerComment/schema/BeerCommentQueryResult.ts b/src/services/BeerComment/schema/BeerCommentQueryResult.ts new file mode 100644 index 0000000..01d79da --- /dev/null +++ b/src/services/BeerComment/schema/BeerCommentQueryResult.ts @@ -0,0 +1,15 @@ +import { z } from 'zod'; + +const BeerCommentQueryResult = z.object({ + id: z.string().cuid(), + content: z.string(), + rating: z.number(), + postedBy: z.object({ + id: z.string().cuid(), + username: z.string(), + }), + createdAt: z.coerce.date(), + updatedAt: z.coerce.date().nullable(), +}); + +export default BeerCommentQueryResult; diff --git a/src/services/BeerComment/schema/CreateNewBeerCommentSchema.ts b/src/services/BeerComment/schema/CreateNewBeerCommentSchema.ts new file mode 100644 index 0000000..e9b9c27 --- /dev/null +++ b/src/services/BeerComment/schema/CreateNewBeerCommentSchema.ts @@ -0,0 +1,8 @@ +import { z } from 'zod'; + +const CreateCommentValidationSchema = z.object({ + userId: z.string().uuid(), + beerPostId: z.string().uuid(), +}); + +export default CreateCommentValidationSchema; diff --git a/src/services/BeerImage/addBeerImageToDB.ts b/src/services/BeerImage/addBeerImageToDB.ts index f99fc83..0ca896b 100644 --- a/src/services/BeerImage/addBeerImageToDB.ts +++ b/src/services/BeerImage/addBeerImageToDB.ts @@ -19,6 +19,7 @@ const addBeerImageToDB = ({ userId, }: ProcessImageDataArgs) => { const beerImagePromises: Promise[] = []; + files.forEach((file) => { beerImagePromises.push( DBClient.instance.beerImage.create({ diff --git a/src/services/BeerPost/editBeerPostById.ts b/src/services/BeerPost/editBeerPostById.ts index 58971d9..213e6b1 100644 --- a/src/services/BeerPost/editBeerPostById.ts +++ b/src/services/BeerPost/editBeerPostById.ts @@ -5,10 +5,6 @@ import EditBeerPostValidationSchema from './schema/EditBeerPostValidationSchema' const schema = EditBeerPostValidationSchema.omit({ id: true }); export default async function editBeerPostById(id: string, data: z.infer) { - const beerPost = await DBClient.instance.beerPost.update({ - where: { id }, - data, - }); - + const beerPost = await DBClient.instance.beerPost.update({ where: { id }, data }); return beerPost; } diff --git a/src/services/BeerPost/getBeerRecommendations.ts b/src/services/BeerPost/getBeerRecommendations.ts index 34beee7..4f5f45b 100644 --- a/src/services/BeerPost/getBeerRecommendations.ts +++ b/src/services/BeerPost/getBeerRecommendations.ts @@ -16,6 +16,7 @@ const getBeerRecommendations = async ({ }: GetBeerRecommendationsArgs) => { const skip = (pageNum - 1) * pageSize; const take = pageSize; + const beerRecommendations: z.infer[] = await DBClient.instance.beerPost.findMany({ where: { diff --git a/src/services/BeerPost/schema/BeerPostQueryResult.ts b/src/services/BeerPost/schema/BeerPostQueryResult.ts index 16934d1..d523f0e 100644 --- a/src/services/BeerPost/schema/BeerPostQueryResult.ts +++ b/src/services/BeerPost/schema/BeerPostQueryResult.ts @@ -13,6 +13,7 @@ const BeerPostQueryResult = z.object({ style: z.object({ id: z.string(), name: z.string(), description: z.string() }), postedBy: z.object({ id: z.string(), username: z.string() }), createdAt: z.coerce.date(), + updatedAt: z.coerce.date().optional(), }); export default BeerPostQueryResult; diff --git a/src/services/BeerPostLike/createBeerPostLike.ts b/src/services/BeerPostLike/createBeerPostLike.ts index f9ba2b8..f086321 100644 --- a/src/services/BeerPostLike/createBeerPostLike.ts +++ b/src/services/BeerPostLike/createBeerPostLike.ts @@ -2,19 +2,14 @@ import DBClient from '@/prisma/DBClient'; import { z } from 'zod'; import GetUserSchema from '../User/schema/GetUserSchema'; -const createBeerPostLike = async ({ - id, - user, -}: { +interface CreateBeerPostLikeArgs { id: string; user: z.infer; -}) => { - return DBClient.instance.beerPostLike.create({ - data: { - beerPost: { connect: { id } }, - likedBy: { connect: { id: user.id } }, - }, +} + +const createBeerPostLike = async ({ id, user }: CreateBeerPostLikeArgs) => + DBClient.instance.beerPostLike.create({ + data: { beerPost: { connect: { id } }, likedBy: { connect: { id: user.id } } }, }); -}; export default createBeerPostLike; diff --git a/src/services/BeerPostLike/getBeerPostLikeCount.ts b/src/services/BeerPostLike/getBeerPostLikeCount.ts index 0e44da2..14389b9 100644 --- a/src/services/BeerPostLike/getBeerPostLikeCount.ts +++ b/src/services/BeerPostLike/getBeerPostLikeCount.ts @@ -1,11 +1,6 @@ import DBClient from '@/prisma/DBClient'; -const getBeerPostLikeCount = async (beerPostId: string) => { - const count = await DBClient.instance.beerPostLike.count({ - where: { beerPostId }, - }); - - return count; -}; +const getBeerPostLikeCount = async ({ beerPostId }: { beerPostId: string }) => + DBClient.instance.beerPostLike.count({ where: { beerPostId } }); export default getBeerPostLikeCount; diff --git a/src/services/BeerPostLike/removeBeerPostLikeById.ts b/src/services/BeerPostLike/removeBeerPostLikeById.ts index 5e711d7..2a6e3e7 100644 --- a/src/services/BeerPostLike/removeBeerPostLikeById.ts +++ b/src/services/BeerPostLike/removeBeerPostLikeById.ts @@ -1,11 +1,10 @@ import DBClient from '@/prisma/DBClient'; -const removeBeerPostLikeById = async (id: string) => { - return DBClient.instance.beerPostLike.delete({ - where: { - id, - }, - }); -}; +interface RemoveBeerPostLikeArgs { + beerLikeId: string; +} + +const removeBeerPostLikeById = async ({ beerLikeId }: RemoveBeerPostLikeArgs) => + DBClient.instance.beerPostLike.delete({ where: { id: beerLikeId } }); export default removeBeerPostLikeById; diff --git a/src/services/BeerStyles/getAllBeerStyles.ts b/src/services/BeerStyles/getAllBeerStyles.ts index 20d04f5..a6e0f20 100644 --- a/src/services/BeerStyles/getAllBeerStyles.ts +++ b/src/services/BeerStyles/getAllBeerStyles.ts @@ -2,11 +2,14 @@ import DBClient from '@/prisma/DBClient'; import { z } from 'zod'; import BeerStyleQueryResult from './schema/BeerStyleQueryResult'; -const getAllBeerStyles = async ( - pageNum: number, - pageSize: number, -): Promise[]> => { - const styles = (await DBClient.instance.beerStyle.findMany({ +const getAllBeerStyles = async ({ + pageNum, + pageSize, +}: { + pageNum: number; + pageSize: number; +}): Promise[]> => + DBClient.instance.beerStyle.findMany({ take: pageSize, skip: (pageNum - 1) * pageSize, select: { @@ -20,9 +23,6 @@ const getAllBeerStyles = async ( description: true, glassware: { select: { id: true, name: true } }, }, - })) as z.infer[]; - - return styles; -}; + }) as ReturnType; export default getAllBeerStyles; diff --git a/src/services/schema/PaginatedQueryResponseSchema.ts b/src/services/schema/PaginatedQueryResponseSchema.ts new file mode 100644 index 0000000..22acabc --- /dev/null +++ b/src/services/schema/PaginatedQueryResponseSchema.ts @@ -0,0 +1,8 @@ +import { z } from 'zod'; + +const PaginatedQueryResponseSchema = z.object({ + page_num: z.string(), + page_size: z.string(), +}); + +export default PaginatedQueryResponseSchema;