[questions][feat]: WIP: list crud

pull/393/head
hpkoh 3 years ago
parent 4fddf62021
commit 88d582a443

@ -60,6 +60,7 @@ model User {
questionsAnswerCommentVotes QuestionsAnswerCommentVote[]
OffersProfile OffersProfile[]
offersDiscussion OffersReply[]
QuestionsList QuestionsList[]
}
enum Vote {
@ -369,11 +370,12 @@ model QuestionsQuestion {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
encounters QuestionsQuestionEncounter[]
votes QuestionsQuestionVote[]
comments QuestionsQuestionComment[]
answers QuestionsAnswer[]
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
encounters QuestionsQuestionEncounter[]
votes QuestionsQuestionVote[]
comments QuestionsQuestionComment[]
answers QuestionsAnswer[]
QuestionsListQuestion QuestionsListQuestion[]
}
model QuestionsQuestionEncounter {
@ -488,4 +490,30 @@ model QuestionsAnswerCommentVote {
@@unique([answerCommentId, userId])
}
model QuestionsList {
id String @id @default(cuid())
userId String
name String @db.VarChar(256)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
QuestionsListQuestion QuestionsListQuestion[]
@@unique([userId, name])
}
model QuestionsListQuestionEntry {
id String @id @default(cuid())
listId String
questionId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
list QuestionsList @relation(fields: [listId], references: [id], onDelete: Cascade)
question QuestionsQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade)
@@unique([listId, questionId])
}
// End of Questions project models.

@ -0,0 +1,287 @@
import { z } from 'zod';
import { Vote } from '@prisma/client';
import { TRPCError } from '@trpc/server';
import { createProtectedRouter } from './context';
import type { Answer } from '~/types/questions';
export const questionListRouter = createProtectedRouter()
.query('getListsByUser', {
input: z.object({
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user?.id;
const listsData = await ctx.prisma.questionsList.findMany({
include: {
questions: true,
},
orderBy: {
createdAt: 'asc',
},
where: {
id: userId,
},
});
return listsData.map((data) => {
const votes: number = data.votes.reduce(
(previousValue: number, currentValue) => {
let result: number = previousValue;
switch (currentValue.vote) {
case Vote.UPVOTE:
result += 1;
break;
case Vote.DOWNVOTE:
result -= 1;
break;
}
return result;
},
0,
);
const answer: Answer = {
content: data.content,
createdAt: data.createdAt,
id: data.id,
numComments: data._count.comments,
numVotes: votes,
user: data.user?.name ?? '',
userImage: data.user?.image ?? '',
};
return answer;
});
},
})
.query('getAnswerById', {
input: z.object({
answerId: z.string(),
}),
async resolve({ ctx, input }) {
const answerData = await ctx.prisma.questionsAnswer.findUnique({
include: {
_count: {
select: {
comments: true,
},
},
user: {
select: {
image: true,
name: true,
},
},
votes: true,
},
where: {
id: input.answerId,
},
});
if (!answerData) {
throw new TRPCError({
code: 'NOT_FOUND',
message: 'Answer not found',
});
}
const votes: number = answerData.votes.reduce(
(previousValue: number, currentValue) => {
let result: number = previousValue;
switch (currentValue.vote) {
case Vote.UPVOTE:
result += 1;
break;
case Vote.DOWNVOTE:
result -= 1;
break;
}
return result;
},
0,
);
const answer: Answer = {
content: answerData.content,
createdAt: answerData.createdAt,
id: answerData.id,
numComments: answerData._count.comments,
numVotes: votes,
user: answerData.user?.name ?? '',
userImage: answerData.user?.image ?? '',
};
return answer;
},
})
.mutation('create', {
input: z.object({
content: z.string(),
questionId: z.string(),
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user?.id;
const { content, questionId } = input;
return await ctx.prisma.questionsAnswer.create({
data: {
content,
questionId,
userId,
},
});
},
})
.mutation('update', {
input: z.object({
content: z.string().optional(),
id: z.string(),
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user?.id;
const { content, id } = input;
const answerToUpdate = await ctx.prisma.questionsAnswer.findUnique({
where: {
id: input.id,
},
});
if (answerToUpdate?.id !== userId) {
throw new TRPCError({
code: 'UNAUTHORIZED',
message: 'User have no authorization to record.',
});
}
return await ctx.prisma.questionsAnswer.update({
data: {
content,
},
where: {
id,
},
});
},
})
.mutation('delete', {
input: z.object({
id: z.string(),
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user?.id;
const answerToDelete = await ctx.prisma.questionsAnswer.findUnique({
where: {
id: input.id,
},
});
if (answerToDelete?.id !== userId) {
throw new TRPCError({
code: 'UNAUTHORIZED',
message: 'User have no authorization to record.',
});
}
return await ctx.prisma.questionsAnswer.delete({
where: {
id: input.id,
},
});
},
})
.query('getVote', {
input: z.object({
answerId: z.string(),
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user?.id;
const { answerId } = input;
return await ctx.prisma.questionsAnswerVote.findUnique({
where: {
answerId_userId: { answerId, userId },
},
});
},
})
.mutation('createQuestionEntry', {
input: z.object({
answerId: z.string(),
vote: z.nativeEnum(Vote),
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user?.id;
const { answerId, vote } = input;
return await ctx.prisma.questionsAnswerVote.create({
data: {
answerId,
userId,
vote,
},
});
},
})
.mutation('updateQuestionEntry', {
input: z.object({
id: z.string(),
vote: z.nativeEnum(Vote),
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user?.id;
const { id, vote } = input;
const voteToUpdate = await ctx.prisma.questionsAnswerVote.findUnique({
where: {
id: input.id,
},
});
if (voteToUpdate?.userId !== userId) {
throw new TRPCError({
code: 'UNAUTHORIZED',
message: 'User have no authorization to record.',
});
}
return await ctx.prisma.questionsAnswerVote.update({
data: {
vote,
},
where: {
id,
},
});
},
})
.mutation('deleteQuestionEntry', {
input: z.object({
id: z.string(),
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user?.id;
const voteToDelete = await ctx.prisma.questionsAnswerVote.findUnique({
where: {
id: input.id,
},
});
if (voteToDelete?.userId !== userId) {
throw new TRPCError({
code: 'UNAUTHORIZED',
message: 'User have no authorization to record.',
});
}
return await ctx.prisma.questionsAnswerVote.delete({
where: {
id: input.id,
},
});
},
});
Loading…
Cancel
Save