mirror of
https://github.com/yangshun/tech-interview-handbook.git
synced 2025-07-28 04:33:42 +08:00
[questions][feat] add encounters transaction for crud (#409)
* [questions][chore] refactor question queries * [questions][chore] destructure values from input * [questions][feat] add sorting * [question][fix] fix frontend * [questions][feat] add sorting * [questions][feat] add sorting index * [questions][chore] push migration file * [questions][fix] fix ci issues * [questions][fix] fix import errors * [questions][feat] add encounters transaction for crud * [questions][chore] fix import * [questions][chore] update error handling * [questions][feat] parallelize queries * [questions][fix] update to use corrcet client * Update questions-question-encounter-router.ts * Update questions-question-encounter-router.ts Co-authored-by: Jeff Sieu <jeffsy00@gmail.com>
This commit is contained in:
@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "QuestionsQuestion" ALTER COLUMN "lastSeenAt" DROP NOT NULL;
|
@ -0,0 +1,8 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "QuestionsQuestion" ADD COLUMN "contentSearch" TSVECTOR
|
||||
GENERATED ALWAYS AS
|
||||
(to_tsvector('english', coalesce(content, '')))
|
||||
STORED;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "QuestionsQuestion_contentSearch_idx" ON "QuestionsQuestion" USING GIN("contentSearch");
|
@ -0,0 +1,8 @@
|
||||
-- DropIndex
|
||||
DROP INDEX "QuestionsQuestion_contentSearch_idx";
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "QuestionsQuestion" ALTER COLUMN "contentSearch" DROP DEFAULT;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "QuestionsQuestion_contentSearch_idx" ON "QuestionsQuestion"("contentSearch");
|
@ -1,7 +1,8 @@
|
||||
// Refer to the Prisma schema docs: https://pris.ly/d/prisma-schema
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
provider = "prisma-client-js"
|
||||
previewFeatures = ["interactiveTransactions"]
|
||||
}
|
||||
|
||||
datasource db {
|
||||
@ -402,7 +403,7 @@ model QuestionsQuestion {
|
||||
userId String?
|
||||
content String @db.Text
|
||||
questionType QuestionsQuestionType
|
||||
lastSeenAt DateTime
|
||||
lastSeenAt DateTime?
|
||||
upvotes Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
@ -4,6 +4,8 @@ import { TRPCError } from '@trpc/server';
|
||||
import { createProtectedRouter } from './context';
|
||||
|
||||
import type { AggregatedQuestionEncounter } from '~/types/questions';
|
||||
import { SortOrder } from '~/types/questions.d';
|
||||
|
||||
|
||||
export const questionsQuestionEncounterRouter = createProtectedRouter()
|
||||
.query('getAggregatedEncounters', {
|
||||
@ -68,11 +70,40 @@ export const questionsQuestionEncounterRouter = createProtectedRouter()
|
||||
async resolve({ ctx, input }) {
|
||||
const userId = ctx.session?.user?.id;
|
||||
|
||||
return await ctx.prisma.questionsQuestionEncounter.create({
|
||||
data: {
|
||||
...input,
|
||||
userId,
|
||||
},
|
||||
return await ctx.prisma.$transaction(async (tx) => {
|
||||
const [questionToUpdate, questionEncounterCreated] = await Promise.all([
|
||||
tx.questionsQuestion.findUnique({
|
||||
where: {
|
||||
id: input.questionId,
|
||||
},
|
||||
}),
|
||||
tx.questionsQuestionEncounter.create({
|
||||
data: {
|
||||
...input,
|
||||
userId,
|
||||
},
|
||||
})
|
||||
]);
|
||||
|
||||
|
||||
if (questionToUpdate === null) {
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message: 'Question does not exist',
|
||||
});
|
||||
}
|
||||
|
||||
if (!questionToUpdate.lastSeenAt || questionToUpdate.lastSeenAt < input.seenAt) {
|
||||
await tx.questionsQuestion.update({
|
||||
data: {
|
||||
lastSeenAt : input.seenAt,
|
||||
},
|
||||
where: {
|
||||
id: input.questionId,
|
||||
},
|
||||
});
|
||||
}
|
||||
return questionEncounterCreated;
|
||||
});
|
||||
},
|
||||
})
|
||||
@ -101,14 +132,48 @@ export const questionsQuestionEncounterRouter = createProtectedRouter()
|
||||
});
|
||||
}
|
||||
|
||||
return await ctx.prisma.questionsQuestionEncounter.update({
|
||||
data: {
|
||||
...input,
|
||||
},
|
||||
where: {
|
||||
id: input.id,
|
||||
},
|
||||
return await ctx.prisma.$transaction(async (tx) => {
|
||||
const [questionToUpdate, questionEncounterUpdated] = await Promise.all([
|
||||
tx.questionsQuestion.findUnique({
|
||||
where: {
|
||||
id: questionEncounterToUpdate.questionId,
|
||||
},
|
||||
}),
|
||||
tx.questionsQuestionEncounter.update({
|
||||
data: {
|
||||
...input,
|
||||
},
|
||||
where: {
|
||||
id: input.id,
|
||||
},
|
||||
})
|
||||
]);
|
||||
|
||||
|
||||
if (questionToUpdate!.lastSeenAt === questionEncounterToUpdate.seenAt) {
|
||||
const latestEncounter = await ctx.prisma.questionsQuestionEncounter.findFirst({
|
||||
orderBy: {
|
||||
seenAt: SortOrder.DESC,
|
||||
},
|
||||
where: {
|
||||
questionId: questionToUpdate!.id,
|
||||
},
|
||||
});
|
||||
|
||||
await tx.questionsQuestion.update({
|
||||
data: {
|
||||
lastSeenAt : latestEncounter!.seenAt,
|
||||
},
|
||||
where: {
|
||||
id: questionToUpdate!.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return questionEncounterUpdated;
|
||||
});
|
||||
|
||||
},
|
||||
})
|
||||
.mutation('delete', {
|
||||
@ -132,10 +197,43 @@ export const questionsQuestionEncounterRouter = createProtectedRouter()
|
||||
});
|
||||
}
|
||||
|
||||
return await ctx.prisma.questionsQuestionEncounter.delete({
|
||||
where: {
|
||||
id: input.id,
|
||||
},
|
||||
return await ctx.prisma.$transaction(async (tx) => {
|
||||
const [questionToUpdate, questionEncounterDeleted] = await Promise.all([
|
||||
tx.questionsQuestion.findUnique({
|
||||
where: {
|
||||
id: questionEncounterToDelete.questionId,
|
||||
},
|
||||
}),
|
||||
tx.questionsQuestionEncounter.delete({
|
||||
where: {
|
||||
id: input.id,
|
||||
},
|
||||
})
|
||||
]);
|
||||
|
||||
if (questionToUpdate!.lastSeenAt === questionEncounterToDelete.seenAt) {
|
||||
const latestEncounter = await ctx.prisma.questionsQuestionEncounter.findFirst({
|
||||
orderBy: {
|
||||
seenAt: SortOrder.DESC,
|
||||
},
|
||||
where: {
|
||||
questionId: questionToUpdate!.id,
|
||||
},
|
||||
});
|
||||
|
||||
const lastSeenVal = latestEncounter ? latestEncounter!.seenAt : null;
|
||||
|
||||
await tx.questionsQuestion.update({
|
||||
data: {
|
||||
lastSeenAt : lastSeenVal,
|
||||
},
|
||||
where: {
|
||||
id: questionToUpdate!.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return questionEncounterDeleted;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
Reference in New Issue
Block a user