From 9f4ab6ef5898a64ab42718302b8475df631b9a2d Mon Sep 17 00:00:00 2001 From: hpkoh Date: Sun, 30 Oct 2022 01:44:36 +0800 Subject: [PATCH] [questions][feat] sorting of Answers and comment --- apps/portal/prisma/schema.prisma | 9 ++++ .../questions-answer-comment-router.ts | 52 +++++++++++++++++-- .../questions/questions-answer-router.ts | 52 +++++++++++++++++-- .../questions-question-comment-router.ts | 51 ++++++++++++++++-- .../questions/questions-question-router.ts | 25 ++------- 5 files changed, 152 insertions(+), 37 deletions(-) diff --git a/apps/portal/prisma/schema.prisma b/apps/portal/prisma/schema.prisma index ec549a84..ddf12f41 100644 --- a/apps/portal/prisma/schema.prisma +++ b/apps/portal/prisma/schema.prisma @@ -463,6 +463,9 @@ model QuestionsQuestionComment { user User? @relation(fields: [userId], references: [id], onDelete: SetNull) question QuestionsQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade) votes QuestionsQuestionCommentVote[] + + @@index([updatedAt, id]) + @@index([upvotes, id]) } model QuestionsQuestionCommentVote { @@ -492,6 +495,9 @@ model QuestionsAnswer { question QuestionsQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade) votes QuestionsAnswerVote[] comments QuestionsAnswerComment[] + + @@index([updatedAt, id]) + @@index([upvotes, id]) } model QuestionsAnswerVote { @@ -520,6 +526,9 @@ model QuestionsAnswerComment { user User? @relation(fields: [userId], references: [id], onDelete: SetNull) answer QuestionsAnswer @relation(fields: [answerId], references: [id], onDelete: Cascade) votes QuestionsAnswerCommentVote[] + + @@index([updatedAt, id]) + @@index([upvotes, id]) } model QuestionsAnswerCommentVote { diff --git a/apps/portal/src/server/router/questions/questions-answer-comment-router.ts b/apps/portal/src/server/router/questions/questions-answer-comment-router.ts index 2ecd51b7..40eb6595 100644 --- a/apps/portal/src/server/router/questions/questions-answer-comment-router.ts +++ b/apps/portal/src/server/router/questions/questions-answer-comment-router.ts @@ -4,16 +4,43 @@ import { Vote } from '@prisma/client'; import { createRouter } from '../context'; import type { AnswerComment } from '~/types/questions'; +import { SortOrder, SortType } from '~/types/questions.d'; export const questionsAnswerCommentRouter = createRouter().query( 'getAnswerComments', { input: z.object({ answerId: z.string(), + cursor: z.string().nullish(), + limit: z.number().min(1).default(50), + sortOrder: z.nativeEnum(SortOrder), + sortType: z.nativeEnum(SortType), }), async resolve({ ctx, input }) { + const { answerId, cursor } = input; + + const sortCondition = + input.sortType === SortType.TOP + ? [ + { + upvotes: input.sortOrder, + }, + { + id: input.sortOrder, + }, + ] + : [ + { + updatedAt: input.sortOrder, + }, + { + id: input.sortOrder, + }, + ]; + const questionAnswerCommentsData = await ctx.prisma.questionsAnswerComment.findMany({ + cursor: cursor ? { id: cursor } : undefined, include: { user: { select: { @@ -23,14 +50,13 @@ export const questionsAnswerCommentRouter = createRouter().query( }, votes: true, }, - orderBy: { - createdAt: 'desc', - }, + orderBy: sortCondition, + take: input.limit + 1, where: { - answerId: input.answerId, + answerId, }, }); - return questionAnswerCommentsData.map((data) => { + const processedQuestionAnswerCommentsData = questionAnswerCommentsData.map((data) => { const votes: number = data.votes.reduce( (previousValue: number, currentValue) => { let result: number = previousValue; @@ -59,6 +85,22 @@ export const questionsAnswerCommentRouter = createRouter().query( }; return answerComment; }); + + let nextCursor: typeof cursor | undefined = undefined; + + if (questionAnswerCommentsData.length > input.limit) { + const nextItem = questionAnswerCommentsData.pop()!; + processedQuestionAnswerCommentsData.pop(); + + const nextIdCursor: string | undefined = nextItem.id; + + nextCursor = nextIdCursor; + } + + return { + nextCursor, + processedQuestionAnswerCommentsData, + } }, }, ); diff --git a/apps/portal/src/server/router/questions/questions-answer-router.ts b/apps/portal/src/server/router/questions/questions-answer-router.ts index bdc5ca31..e2e11715 100644 --- a/apps/portal/src/server/router/questions/questions-answer-router.ts +++ b/apps/portal/src/server/router/questions/questions-answer-router.ts @@ -5,16 +5,42 @@ import { TRPCError } from '@trpc/server'; import { createRouter } from '../context'; import type { Answer } from '~/types/questions'; +import { SortOrder, SortType } from '~/types/questions.d'; export const questionsAnswerRouter = createRouter() .query('getAnswers', { input: z.object({ + cursor: z.string().nullish(), + limit: z.number().min(1).default(50), questionId: z.string(), + sortOrder: z.nativeEnum(SortOrder), + sortType: z.nativeEnum(SortType), }), async resolve({ ctx, input }) { - const { questionId } = input; + const { questionId, cursor } = input; + + const sortCondition = + input.sortType === SortType.TOP + ? [ + { + upvotes: input.sortOrder, + }, + { + id: input.sortOrder, + }, + ] + : [ + { + updatedAt: input.sortOrder, + }, + { + id: input.sortOrder, + }, + ]; + const answersData = await ctx.prisma.questionsAnswer.findMany({ + cursor: cursor ? { id: cursor } : undefined, include: { _count: { select: { @@ -29,14 +55,14 @@ export const questionsAnswerRouter = createRouter() }, votes: true, }, - orderBy: { - createdAt: 'desc', - }, + orderBy: sortCondition, + take: input.limit + 1, where: { questionId, }, }); - return answersData.map((data) => { + + const processedAnswersData = answersData.map((data) => { const votes: number = data.votes.reduce( (previousValue: number, currentValue) => { let result: number = previousValue; @@ -65,6 +91,22 @@ export const questionsAnswerRouter = createRouter() }; return answer; }); + + let nextCursor: typeof cursor | undefined = undefined; + + if (answersData.length > input.limit) { + const nextItem = answersData.pop()!; + processedAnswersData.pop(); + + const nextIdCursor: string | undefined = nextItem.id; + + nextCursor = nextIdCursor; + } + + return { + nextCursor, + processedAnswersData, + } }, }) .query('getAnswerById', { diff --git a/apps/portal/src/server/router/questions/questions-question-comment-router.ts b/apps/portal/src/server/router/questions/questions-question-comment-router.ts index 1bf63789..9f42b88e 100644 --- a/apps/portal/src/server/router/questions/questions-question-comment-router.ts +++ b/apps/portal/src/server/router/questions/questions-question-comment-router.ts @@ -4,17 +4,43 @@ import { Vote } from '@prisma/client'; import { createRouter } from '../context'; import type { QuestionComment } from '~/types/questions'; +import { SortOrder, SortType } from '~/types/questions.d'; export const questionsQuestionCommentRouter = createRouter().query( 'getQuestionComments', { input: z.object({ + cursor: z.string().nullish(), + limit: z.number().min(1).default(50), questionId: z.string(), + sortOrder: z.nativeEnum(SortOrder), + sortType: z.nativeEnum(SortType), }), async resolve({ ctx, input }) { - const { questionId } = input; + const { questionId, cursor } = input; + + const sortCondition = + input.sortType === SortType.TOP + ? [ + { + upvotes: input.sortOrder, + }, + { + id: input.sortOrder, + }, + ] + : [ + { + updatedAt: input.sortOrder, + }, + { + id: input.sortOrder, + }, + ]; + const questionCommentsData = await ctx.prisma.questionsQuestionComment.findMany({ + cursor: cursor ? { id: cursor } : undefined, include: { user: { select: { @@ -24,14 +50,13 @@ export const questionsQuestionCommentRouter = createRouter().query( }, votes: true, }, - orderBy: { - createdAt: 'desc', - }, + orderBy: sortCondition, + take: input.limit + 1, where: { questionId, }, }); - return questionCommentsData.map((data) => { + const processedQuestionCommentsData = questionCommentsData.map((data) => { const votes: number = data.votes.reduce( (previousValue: number, currentValue) => { let result: number = previousValue; @@ -59,6 +84,22 @@ export const questionsQuestionCommentRouter = createRouter().query( }; return questionComment; }); + + let nextCursor: typeof cursor | undefined = undefined; + + if (questionCommentsData.length > input.limit) { + const nextItem = questionCommentsData.pop()!; + processedQuestionCommentsData.pop(); + + const nextIdCursor: string | undefined = nextItem.id; + + nextCursor = nextIdCursor; + } + + return { + nextCursor, + processedQuestionCommentsData, + } }, }, ); diff --git a/apps/portal/src/server/router/questions/questions-question-router.ts b/apps/portal/src/server/router/questions/questions-question-router.ts index f3b48b9b..cbac65b5 100644 --- a/apps/portal/src/server/router/questions/questions-question-router.ts +++ b/apps/portal/src/server/router/questions/questions-question-router.ts @@ -12,13 +12,7 @@ export const questionsQuestionRouter = createRouter() .query('getQuestionsByFilter', { input: z.object({ companyNames: z.string().array(), - cursor: z - .object({ - idCursor: z.string().optional(), - lastSeenCursor: z.date().nullish().optional(), - upvoteCursor: z.number().optional(), - }) - .nullish(), + cursor: z.string().nullish(), endDate: z.date().default(new Date()), limit: z.number().min(1).default(50), locations: z.string().array(), @@ -51,12 +45,7 @@ export const questionsQuestionRouter = createRouter() ]; const questionsData = await ctx.prisma.questionsQuestion.findMany({ - cursor: - cursor !== undefined - ? { - id: cursor ? cursor!.idCursor : undefined, - } - : undefined, + cursor: cursor ? { id: cursor } : undefined, include: { _count: { select: { @@ -134,16 +123,8 @@ export const questionsQuestionRouter = createRouter() processedQuestionsData.pop(); const nextIdCursor: string | undefined = nextItem.id; - const nextLastSeenCursor = - input.sortType === SortType.NEW ? nextItem.lastSeenAt : undefined; - const nextUpvoteCursor = - input.sortType === SortType.TOP ? nextItem.upvotes : undefined; - nextCursor = { - idCursor: nextIdCursor, - lastSeenCursor: nextLastSeenCursor, - upvoteCursor: nextUpvoteCursor, - }; + nextCursor = nextIdCursor; } return {