From 10b081dc95e47960ec8e46aaf55e9168ebe70680 Mon Sep 17 00:00:00 2001 From: hpkoh Date: Sun, 30 Oct 2022 15:01:01 +0800 Subject: [PATCH] [questions][feat] refactor vote mutations --- .../questions-answer-comment-user-router.ts | 244 +++++++++++------ .../questions/questions-answer-user-router.ts | 249 +++++++++++------ .../questions-question-comment-user-router.ts | 244 +++++++++++------ .../questions-question-user-router.ts | 250 ++++++++++++------ 4 files changed, 662 insertions(+), 325 deletions(-) diff --git a/apps/portal/src/server/router/questions/questions-answer-comment-user-router.ts b/apps/portal/src/server/router/questions/questions-answer-comment-user-router.ts index f41dc46b..c2bb0089 100644 --- a/apps/portal/src/server/router/questions/questions-answer-comment-user-router.ts +++ b/apps/portal/src/server/router/questions/questions-answer-comment-user-router.ts @@ -100,130 +100,212 @@ export const questionsAnswerCommentUserRouter = createProtectedRouter() }); }, }) - .mutation('createVote', { + .mutation('setUpVote', { input: z.object({ answerCommentId: z.string(), - vote: z.nativeEnum(Vote), }), async resolve({ ctx, input }) { const userId = ctx.session?.user?.id; + const { answerCommentId } = input; - const { answerCommentId, vote } = input; + return await ctx.prisma.$transaction(async (tx) => { + const vote = await tx.questionsAnswerCommentVote.findUnique({ + where: { + answerCommentId_userId: { answerCommentId, userId }, + }, + }) - const incrementValue = vote === Vote.UPVOTE ? 1 : -1; + if (vote === null) { + const createdVote = await tx.questionsAnswerCommentVote.create({ + data: { + answerCommentId, + userId, + vote: Vote.UPVOTE, + }, + }); - const [answerCommentVote] = await ctx.prisma.$transaction([ - ctx.prisma.questionsAnswerCommentVote.create({ - data: { - answerCommentId, - userId, - vote, - }, - }), - ctx.prisma.questionsAnswerComment.update({ - data: { - upvotes: { - increment: incrementValue, + await tx.questionsAnswerComment.update({ + data: { + upvotes: { + increment: 1, + }, }, - }, - where: { - id: answerCommentId, - }, - }), - ]); + where: { + id: answerCommentId, + }, + }); + + return createdVote + } + + if (vote!.userId !== userId) { + throw new TRPCError({ + code: 'UNAUTHORIZED', + message: 'User have no authorization to record.', + }); + } + + if (vote!.vote === Vote.UPVOTE) { + return vote; + } + + if (vote.vote === Vote.DOWNVOTE) { + tx.questionsAnswerCommentVote.delete({ + where: { + id: vote.id, + }, + }); - return answerCommentVote; + const createdVote = await tx.questionsAnswerCommentVote.create({ + data: { + answerCommentId, + userId, + vote: Vote.UPVOTE, + }, + }); + + await tx.questionsAnswerComment.update({ + data: { + upvotes: { + increment: 2, + }, + }, + where: { + id: answerCommentId, + }, + }); + + return createdVote + } + }); }, }) - .mutation('updateVote', { + .mutation('setDownVote', { input: z.object({ - id: z.string(), - vote: z.nativeEnum(Vote), + answerCommentId: z.string(), }), async resolve({ ctx, input }) { const userId = ctx.session?.user?.id; - const { id, vote } = input; + const { answerCommentId } = input; - const voteToUpdate = - await ctx.prisma.questionsAnswerCommentVote.findUnique({ + return await ctx.prisma.$transaction(async (tx) => { + const vote = await tx.questionsAnswerCommentVote.findUnique({ where: { - id: input.id, + answerCommentId_userId: { answerCommentId, userId }, }, - }); + }) - if (voteToUpdate?.userId !== userId) { - throw new TRPCError({ - code: 'UNAUTHORIZED', - message: 'User have no authorization to record.', - }); - } + if (vote === null) { + const createdVote = await tx.questionsAnswerCommentVote.create({ + data: { + answerCommentId, + userId, + vote: Vote.DOWNVOTE, + }, + }); - const incrementValue = vote === Vote.UPVOTE ? 2 : -2; + await tx.questionsAnswerComment.update({ + data: { + upvotes: { + increment: -1, + }, + }, + where: { + id: answerCommentId, + }, + }); - const [answerCommentVote] = await ctx.prisma.$transaction([ - ctx.prisma.questionsAnswerCommentVote.update({ - data: { - vote, - }, - where: { - id, - }, - }), - ctx.prisma.questionsAnswerComment.update({ - data: { - upvotes: { - increment: incrementValue, + return createdVote + } + + if (vote!.userId !== userId) { + throw new TRPCError({ + code: 'UNAUTHORIZED', + message: 'User have no authorization to record.', + }); + } + + if (vote!.vote === Vote.DOWNVOTE) { + return vote; + } + + if (vote.vote === Vote.UPVOTE) { + tx.questionsAnswerCommentVote.delete({ + where: { + id: vote.id, }, - }, - where: { - id: voteToUpdate.answerCommentId, - }, - }), - ]); + }); + + const createdVote = await tx.questionsAnswerCommentVote.create({ + data: { + answerCommentId, + userId, + vote: Vote.DOWNVOTE, + }, + }); - return answerCommentVote; + await tx.questionsAnswerComment.update({ + data: { + upvotes: { + increment: -2, + }, + }, + where: { + id: answerCommentId, + }, + }); + + return createdVote + } + }); }, }) - .mutation('deleteVote', { + .mutation('setNoVote', { input: z.object({ - id: z.string(), + answerCommentId: z.string(), }), async resolve({ ctx, input }) { const userId = ctx.session?.user?.id; + const { answerCommentId } = input; - const voteToDelete = - await ctx.prisma.questionsAnswerCommentVote.findUnique({ + return await ctx.prisma.$transaction(async (tx) => { + const voteToDelete = await tx.questionsAnswerCommentVote.findUnique({ where: { - id: input.id, + answerCommentId_userId: { answerCommentId, userId }, }, - }); + }) - if (voteToDelete?.userId !== userId) { - throw new TRPCError({ - code: 'UNAUTHORIZED', - message: 'User have no authorization to record.', - }); - } + if (voteToDelete === null) { + return null; + } + + if (voteToDelete!.userId !== userId) { + throw new TRPCError({ + code: 'UNAUTHORIZED', + message: 'User have no authorization to record.', + }); + } - const incrementValue = voteToDelete.vote === Vote.UPVOTE ? -1 : 1; + const incrementValue = voteToDelete!.vote === Vote.UPVOTE ? -1 : 1; - const [answerCommentVote] = await ctx.prisma.$transaction([ - ctx.prisma.questionsAnswerCommentVote.delete({ + tx.questionsAnswerCommentVote.delete({ where: { - id: input.id, + id: voteToDelete.id, }, - }), - ctx.prisma.questionsAnswerComment.update({ + }); + + await tx.questionsAnswerComment.update({ data: { upvotes: { increment: incrementValue, }, }, where: { - id: voteToDelete.answerCommentId, + id: answerCommentId, }, - }), - ]); - return answerCommentVote; + }); + + return voteToDelete; + }); }, - }); + }); \ No newline at end of file diff --git a/apps/portal/src/server/router/questions/questions-answer-user-router.ts b/apps/portal/src/server/router/questions/questions-answer-user-router.ts index a73f5a21..24597eaa 100644 --- a/apps/portal/src/server/router/questions/questions-answer-user-router.ts +++ b/apps/portal/src/server/router/questions/questions-answer-user-router.ts @@ -98,127 +98,212 @@ export const questionsAnswerUserRouter = createProtectedRouter() }); }, }) - .mutation('createVote', { + .mutation('setUpVote', { input: z.object({ answerId: z.string(), - vote: z.nativeEnum(Vote), }), async resolve({ ctx, input }) { const userId = ctx.session?.user?.id; + const { answerId } = input; - const { answerId, vote } = input; + return await ctx.prisma.$transaction(async (tx) => { + const vote = await tx.questionsAnswerVote.findUnique({ + where: { + answerId_userId: { answerId, userId }, + }, + }) - const incrementValue = vote === Vote.UPVOTE ? 1 : -1; + if (vote === null) { + const createdVote = await tx.questionsAnswerVote.create({ + data: { + answerId, + userId, + vote: Vote.UPVOTE, + }, + }); - const [answerVote] = await ctx.prisma.$transaction([ - ctx.prisma.questionsAnswerVote.create({ - data: { - answerId, - userId, - vote, - }, - }), - ctx.prisma.questionsAnswer.update({ - data: { - upvotes: { - increment: incrementValue, + await tx.questionsAnswer.update({ + data: { + upvotes: { + increment: 1, + }, }, - }, - where: { - id: answerId, - }, - }), - ]); - return answerVote; + where: { + id: answerId, + }, + }); + + return createdVote + } + + if (vote!.userId !== userId) { + throw new TRPCError({ + code: 'UNAUTHORIZED', + message: 'User have no authorization to record.', + }); + } + + if (vote!.vote === Vote.UPVOTE) { + return vote; + } + + if (vote.vote === Vote.DOWNVOTE) { + tx.questionsAnswerVote.delete({ + where: { + id: vote.id, + }, + }); + + const createdVote = await tx.questionsAnswerVote.create({ + data: { + answerId, + userId, + vote: Vote.UPVOTE, + }, + }); + + await tx.questionsAnswer.update({ + data: { + upvotes: { + increment: 2, + }, + }, + where: { + id: answerId, + }, + }); + + return createdVote + } + }); }, }) - .mutation('updateVote', { + .mutation('setDownVote', { input: z.object({ - id: z.string(), - vote: z.nativeEnum(Vote), + answerId: z.string(), }), async resolve({ ctx, input }) { const userId = ctx.session?.user?.id; - const { id, vote } = input; + const { answerId } = input; - const voteToUpdate = await ctx.prisma.questionsAnswerVote.findUnique({ - where: { - id: input.id, - }, - }); + return await ctx.prisma.$transaction(async (tx) => { + const vote = await tx.questionsAnswerVote.findUnique({ + where: { + answerId_userId: { answerId, userId }, + }, + }) - if (voteToUpdate?.userId !== userId) { - throw new TRPCError({ - code: 'UNAUTHORIZED', - message: 'User have no authorization to record.', - }); - } + if (vote === null) { + const createdVote = await tx.questionsAnswerVote.create({ + data: { + answerId, + userId, + vote: Vote.DOWNVOTE, + }, + }); - const incrementValue = vote === Vote.UPVOTE ? 2 : -2; + await tx.questionsAnswer.update({ + data: { + upvotes: { + increment: -1, + }, + }, + where: { + id: answerId, + }, + }); - const [questionsAnswerVote] = await ctx.prisma.$transaction([ - ctx.prisma.questionsAnswerVote.update({ - data: { - vote, - }, - where: { - id, - }, - }), - ctx.prisma.questionsAnswer.update({ - data: { - upvotes: { - increment: incrementValue, + return createdVote + } + + if (vote!.userId !== userId) { + throw new TRPCError({ + code: 'UNAUTHORIZED', + message: 'User have no authorization to record.', + }); + } + + if (vote!.vote === Vote.DOWNVOTE) { + return vote; + } + + if (vote.vote === Vote.UPVOTE) { + tx.questionsAnswerVote.delete({ + where: { + id: vote.id, }, - }, - where: { - id: voteToUpdate.answerId, - }, - }), - ]); + }); + + const createdVote = await tx.questionsAnswerVote.create({ + data: { + answerId, + userId, + vote: Vote.DOWNVOTE, + }, + }); - return questionsAnswerVote; + await tx.questionsAnswer.update({ + data: { + upvotes: { + increment: -2, + }, + }, + where: { + id: answerId, + }, + }); + + return createdVote + } + }); }, }) - .mutation('deleteVote', { + .mutation('setNoVote', { input: z.object({ - id: z.string(), + answerId: z.string(), }), async resolve({ ctx, input }) { const userId = ctx.session?.user?.id; + const { answerId } = input; - const voteToDelete = await ctx.prisma.questionsAnswerVote.findUnique({ - where: { - id: input.id, - }, - }); + return await ctx.prisma.$transaction(async (tx) => { + const voteToDelete = await tx.questionsAnswerVote.findUnique({ + where: { + answerId_userId: { answerId, userId }, + }, + }) - if (voteToDelete?.userId !== userId) { - throw new TRPCError({ - code: 'UNAUTHORIZED', - message: 'User have no authorization to record.', - }); - } + if (voteToDelete === null) { + return null; + } - const incrementValue = voteToDelete.vote === Vote.UPVOTE ? -1 : 1; + if (voteToDelete!.userId !== userId) { + throw new TRPCError({ + code: 'UNAUTHORIZED', + message: 'User have no authorization to record.', + }); + } - const [questionsAnswerVote] = await ctx.prisma.$transaction([ - ctx.prisma.questionsAnswerVote.delete({ + const incrementValue = voteToDelete!.vote === Vote.UPVOTE ? -1 : 1; + + tx.questionsAnswerVote.delete({ where: { - id: input.id, + id: voteToDelete.id, }, - }), - ctx.prisma.questionsAnswer.update({ + }); + + await tx.questionsAnswer.update({ data: { upvotes: { increment: incrementValue, }, }, where: { - id: voteToDelete.answerId, + id: answerId, }, - }), - ]); - return questionsAnswerVote; + }); + + return voteToDelete; + }); }, }); diff --git a/apps/portal/src/server/router/questions/questions-question-comment-user-router.ts b/apps/portal/src/server/router/questions/questions-question-comment-user-router.ts index 9f29ad0a..e2cc34c6 100644 --- a/apps/portal/src/server/router/questions/questions-question-comment-user-router.ts +++ b/apps/portal/src/server/router/questions/questions-question-comment-user-router.ts @@ -101,128 +101,212 @@ export const questionsQuestionCommentUserRouter = createProtectedRouter() }); }, }) - .mutation('createVote', { + .mutation('setUpVote', { input: z.object({ questionCommentId: z.string(), - vote: z.nativeEnum(Vote), }), async resolve({ ctx, input }) { const userId = ctx.session?.user?.id; - const { questionCommentId, vote } = input; - - const incrementValue: number = vote === Vote.UPVOTE ? 1 : -1; + const { questionCommentId } = input; - const [questionCommentVote] = await ctx.prisma.$transaction([ - ctx.prisma.questionsQuestionCommentVote.create({ - data: { - questionCommentId, - userId, - vote, - }, - }), - ctx.prisma.questionsQuestionComment.update({ - data: { - upvotes: { - increment: incrementValue, - }, - }, + return await ctx.prisma.$transaction(async (tx) => { + const vote = await tx.questionsQuestionCommentVote.findUnique({ where: { - id: questionCommentId, + questionCommentId_userId: { questionCommentId, userId }, }, - }), - ]); - return questionCommentVote; + }) + + if (vote === null) { + const createdVote = await tx.questionsQuestionCommentVote.create({ + data: { + questionCommentId, + userId, + vote: Vote.UPVOTE, + }, + }); + + await tx.questionsQuestionComment.update({ + data: { + upvotes: { + increment: 1, + }, + }, + where: { + id: questionCommentId, + }, + }); + + return createdVote + } + + if (vote!.userId !== userId) { + throw new TRPCError({ + code: 'UNAUTHORIZED', + message: 'User have no authorization to record.', + }); + } + + if (vote!.vote === Vote.UPVOTE) { + return vote; + } + + if (vote.vote === Vote.DOWNVOTE) { + tx.questionsQuestionCommentVote.delete({ + where: { + id: vote.id, + }, + }); + + const createdVote = await tx.questionsQuestionCommentVote.create({ + data: { + questionCommentId, + userId, + vote: Vote.UPVOTE, + }, + }); + + await tx.questionsQuestionComment.update({ + data: { + upvotes: { + increment: 2, + }, + }, + where: { + id: questionCommentId, + }, + }); + + return createdVote + } + }); }, }) - .mutation('updateVote', { + .mutation('setDownVote', { input: z.object({ - id: z.string(), - vote: z.nativeEnum(Vote), + questionCommentId: z.string(), }), async resolve({ ctx, input }) { const userId = ctx.session?.user?.id; - const { id, vote } = input; + const { questionCommentId } = input; - const voteToUpdate = - await ctx.prisma.questionsQuestionCommentVote.findUnique({ + return await ctx.prisma.$transaction(async (tx) => { + const vote = await tx.questionsQuestionCommentVote.findUnique({ where: { - id: input.id, + questionCommentId_userId: { questionCommentId, userId }, }, - }); + }) - if (voteToUpdate?.userId !== userId) { - throw new TRPCError({ - code: 'UNAUTHORIZED', - message: 'User have no authorization to record.', - }); - } + if (vote === null) { + const createdVote = await tx.questionsQuestionCommentVote.create({ + data: { + questionCommentId, + userId, + vote: Vote.DOWNVOTE, + }, + }); - const incrementValue = vote === Vote.UPVOTE ? 2 : -2; + await tx.questionsQuestionComment.update({ + data: { + upvotes: { + increment: -1, + }, + }, + where: { + id: questionCommentId, + }, + }); - const [questionCommentVote] = await ctx.prisma.$transaction([ - ctx.prisma.questionsQuestionCommentVote.update({ - data: { - vote, - }, - where: { - id, - }, - }), - ctx.prisma.questionsQuestionComment.update({ - data: { - upvotes: { - increment: incrementValue, + return createdVote + } + + if (vote!.userId !== userId) { + throw new TRPCError({ + code: 'UNAUTHORIZED', + message: 'User have no authorization to record.', + }); + } + + if (vote!.vote === Vote.DOWNVOTE) { + return vote; + } + + if (vote.vote === Vote.UPVOTE) { + tx.questionsQuestionCommentVote.delete({ + where: { + id: vote.id, }, - }, - where: { - id: voteToUpdate.questionCommentId, - }, - }), - ]); + }); + + const createdVote = await tx.questionsQuestionCommentVote.create({ + data: { + questionCommentId, + userId, + vote: Vote.DOWNVOTE, + }, + }); + + await tx.questionsQuestionComment.update({ + data: { + upvotes: { + increment: -2, + }, + }, + where: { + id: questionCommentId, + }, + }); - return questionCommentVote; + return createdVote + } + }); }, }) - .mutation('deleteVote', { + .mutation('setNoVote', { input: z.object({ - id: z.string(), + questionCommentId: z.string(), }), async resolve({ ctx, input }) { const userId = ctx.session?.user?.id; + const { questionCommentId } = input; - const voteToDelete = - await ctx.prisma.questionsQuestionCommentVote.findUnique({ + return await ctx.prisma.$transaction(async (tx) => { + const voteToDelete = await tx.questionsQuestionCommentVote.findUnique({ where: { - id: input.id, + questionCommentId_userId: { questionCommentId, userId }, }, - }); + }) - if (voteToDelete?.userId !== userId) { - throw new TRPCError({ - code: 'UNAUTHORIZED', - message: 'User have no authorization to record.', - }); - } + if (voteToDelete === null) { + return null; + } + + if (voteToDelete!.userId !== userId) { + throw new TRPCError({ + code: 'UNAUTHORIZED', + message: 'User have no authorization to record.', + }); + } - const incrementValue = voteToDelete.vote === Vote.UPVOTE ? -1 : 1; + const incrementValue = voteToDelete!.vote === Vote.UPVOTE ? -1 : 1; - const [questionCommentVote] = await ctx.prisma.$transaction([ - ctx.prisma.questionsQuestionCommentVote.delete({ + tx.questionsQuestionCommentVote.delete({ where: { - id: input.id, + id: voteToDelete.id, }, - }), - ctx.prisma.questionsQuestionComment.update({ + }); + + await tx.questionsQuestionComment.update({ data: { upvotes: { increment: incrementValue, }, }, where: { - id: voteToDelete.questionCommentId, + id: questionCommentId, }, - }), - ]); - return questionCommentVote; + }); + + return voteToDelete; + }); }, }); diff --git a/apps/portal/src/server/router/questions/questions-question-user-router.ts b/apps/portal/src/server/router/questions/questions-question-user-router.ts index 96334c8d..7f8050c7 100644 --- a/apps/portal/src/server/router/questions/questions-question-user-router.ts +++ b/apps/portal/src/server/router/questions/questions-question-user-router.ts @@ -123,126 +123,212 @@ export const questionsQuestionUserRouter = createProtectedRouter() }); }, }) - .mutation('createVote', { + .mutation('setUpVote', { input: z.object({ questionId: z.string(), - vote: z.nativeEnum(Vote), }), async resolve({ ctx, input }) { const userId = ctx.session?.user?.id; - const { questionId, vote } = input; - - const incrementValue = vote === Vote.UPVOTE ? 1 : -1; + const { questionId } = input; - const [questionVote] = await ctx.prisma.$transaction([ - ctx.prisma.questionsQuestionVote.create({ - data: { - questionId, - userId, - vote, - }, - }), - ctx.prisma.questionsQuestion.update({ - data: { - upvotes: { - increment: incrementValue, - }, - }, + return await ctx.prisma.$transaction(async (tx) => { + const vote = await tx.questionsQuestionVote.findUnique({ where: { - id: questionId, + questionId_userId: { questionId, userId }, }, - }), - ]); - return questionVote; + }) + + if (vote === null) { + const createdVote = await tx.questionsQuestionVote.create({ + data: { + questionId, + userId, + vote: Vote.UPVOTE, + }, + }); + + await tx.questionsQuestion.update({ + data: { + upvotes: { + increment: 1, + }, + }, + where: { + id: questionId, + }, + }); + + return createdVote + } + + if (vote!.userId !== userId) { + throw new TRPCError({ + code: 'UNAUTHORIZED', + message: 'User have no authorization to record.', + }); + } + + if (vote!.vote === Vote.UPVOTE) { + return vote; + } + + if (vote.vote === Vote.DOWNVOTE) { + tx.questionsQuestionVote.delete({ + where: { + id: vote.id, + }, + }); + + const createdVote = await tx.questionsQuestionVote.create({ + data: { + questionId, + userId, + vote: Vote.UPVOTE, + }, + }); + + await tx.questionsQuestion.update({ + data: { + upvotes: { + increment: 2, + }, + }, + where: { + id: questionId, + }, + }); + + return createdVote + } + }); }, }) - .mutation('updateVote', { + .mutation('setDownVote', { input: z.object({ - id: z.string(), - vote: z.nativeEnum(Vote), + questionId: z.string(), }), async resolve({ ctx, input }) { const userId = ctx.session?.user?.id; - const { id, vote } = input; + const { questionId } = input; - const voteToUpdate = await ctx.prisma.questionsQuestionVote.findUnique({ - where: { - id: input.id, - }, - }); + return await ctx.prisma.$transaction(async (tx) => { + const vote = await tx.questionsQuestionVote.findUnique({ + where: { + questionId_userId: { questionId, userId }, + }, + }) - if (voteToUpdate?.userId !== userId) { - throw new TRPCError({ - code: 'UNAUTHORIZED', - message: 'User have no authorization to record.', - }); - } + if (vote === null) { + const createdVote = await tx.questionsQuestionVote.create({ + data: { + questionId, + userId, + vote: Vote.DOWNVOTE, + }, + }); - const incrementValue = vote === Vote.UPVOTE ? 2 : -2; + await tx.questionsQuestion.update({ + data: { + upvotes: { + increment: -1, + }, + }, + where: { + id: questionId, + }, + }); - const [questionVote] = await ctx.prisma.$transaction([ - ctx.prisma.questionsQuestionVote.update({ - data: { - vote, - }, - where: { - id, - }, - }), - ctx.prisma.questionsQuestion.update({ - data: { - upvotes: { - increment: incrementValue, + return createdVote + } + + if (vote!.userId !== userId) { + throw new TRPCError({ + code: 'UNAUTHORIZED', + message: 'User have no authorization to record.', + }); + } + + if (vote!.vote === Vote.DOWNVOTE) { + return vote; + } + + if (vote.vote === Vote.UPVOTE) { + tx.questionsQuestionVote.delete({ + where: { + id: vote.id, }, - }, - where: { - id: voteToUpdate.questionId, - }, - }), - ]); + }); + + const createdVote = await tx.questionsQuestionVote.create({ + data: { + questionId, + userId, + vote: Vote.DOWNVOTE, + }, + }); + + await tx.questionsQuestion.update({ + data: { + upvotes: { + increment: -2, + }, + }, + where: { + id: questionId, + }, + }); - return questionVote; + return createdVote + } + }); }, }) - .mutation('deleteVote', { + .mutation('setNoVote', { input: z.object({ - id: z.string(), + questionId: z.string(), }), async resolve({ ctx, input }) { const userId = ctx.session?.user?.id; + const { questionId } = input; - const voteToDelete = await ctx.prisma.questionsQuestionVote.findUnique({ - where: { - id: input.id, - }, - }); + return await ctx.prisma.$transaction(async (tx) => { + const voteToDelete = await tx.questionsQuestionVote.findUnique({ + where: { + questionId_userId: { questionId, userId }, + }, + }) - if (voteToDelete?.userId !== userId) { - throw new TRPCError({ - code: 'UNAUTHORIZED', - message: 'User have no authorization to record.', - }); - } + if (voteToDelete === null) { + return null; + } + + if (voteToDelete!.userId !== userId) { + throw new TRPCError({ + code: 'UNAUTHORIZED', + message: 'User have no authorization to record.', + }); + } - const incrementValue = voteToDelete.vote === Vote.UPVOTE ? -1 : 1; + const incrementValue = voteToDelete!.vote === Vote.UPVOTE ? -1 : 1; - const [questionVote] = await ctx.prisma.$transaction([ - ctx.prisma.questionsQuestionVote.delete({ + tx.questionsQuestionVote.delete({ where: { - id: input.id, + id: voteToDelete.id, }, - }), - ctx.prisma.questionsQuestion.update({ + }); + + await tx.questionsQuestion.update({ data: { upvotes: { increment: incrementValue, }, }, where: { - id: voteToDelete.questionId, + id: questionId, }, - }), - ]); - return questionVote; + }); + + return voteToDelete; + }); }, });