From ecac6da9174227c314de028115df1f1771a1a973 Mon Sep 17 00:00:00 2001 From: hpkoh Date: Sun, 9 Oct 2022 20:57:16 +0800 Subject: [PATCH] [questions][feat] add question encounter crud --- .../questions-question-encounter-router.ts | 131 ++++++++++++++++++ apps/portal/src/types/questions.d.ts | 8 +- 2 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 apps/portal/src/server/router/questions-question-encounter-router.ts diff --git a/apps/portal/src/server/router/questions-question-encounter-router.ts b/apps/portal/src/server/router/questions-question-encounter-router.ts new file mode 100644 index 00000000..eb598483 --- /dev/null +++ b/apps/portal/src/server/router/questions-question-encounter-router.ts @@ -0,0 +1,131 @@ +import { z } from 'zod'; +import { TRPCError } from '@trpc/server'; + +import { createProtectedRouter } from './context'; + +import type { AggregatedQuestionEncounter } from '~/types/questions'; + +export const questionsQuestionEncounterRouter = createProtectedRouter() + .query('getAggregatedEncounters', { + input: z.object({ + questionId: z.string(), + }), + async resolve({ ctx, input }) { + const questionEncountersData = await ctx.prisma.questionsQuestionEncounter.findMany({ + where: { + ...input, + }, + }); + + const companyCounts: Record = {}; + const locationCounts: Record = {}; + const roleCount:Record = {}; + + for (let i = 0; i < questionEncountersData.length; i++) { + const encounter = questionEncountersData[i]; + + if (!(encounter.company in companyCounts)) { + companyCounts[encounter.company] = 1; + } + companyCounts[encounter.company] += 1; + + if (!(encounter.location in locationCounts)) { + locationCounts[encounter.location] = 1; + } + locationCounts[encounter.location] += 1; + + if (!(encounter.role in roleCount)) { + roleCount[encounter.role] = 1; + } + roleCount[encounter.role] += 1; + + } + + const questionEncounter:AggregatedQuestionEncounter = { + companyCount: companyCounts, + locationCount: locationCounts, + roleCount, + } + return questionEncounter; + } + }) + .mutation('create', { + input: z.object({ + company: z.string(), + location: z.string(), + questionId: z.string(), + role: z.string(), + seenAt: z.date() + }), + async resolve({ ctx, input }) { + const userId = ctx.session?.user?.id; + + return await ctx.prisma.questionsQuestionEncounter.create({ + data: { + ...input, + userId, + }, + }); + }, + }) + .mutation('update', { + input: z.object({ + company: z.string().optional(), + id: z.string(), + location: z.string().optional(), + role: z.string().optional(), + seenAt: z.date().optional(), + }), + async resolve({ ctx, input }) { + const userId = ctx.session?.user?.id; + + const questionEncounterToUpdate = await ctx.prisma.questionsQuestionEncounter.findUnique({ + where: { + id: input.id, + }, + }); + + if (questionEncounterToUpdate?.id !== userId) { + throw new TRPCError({ + code: 'UNAUTHORIZED', + message: 'User have no authorization to record.', + }); + } + + return await ctx.prisma.questionsQuestionEncounter.update({ + data: { + ...input, + }, + where: { + id: input.id, + }, + }); + }, + }) + .mutation('delete', { + input: z.object({ + id: z.string(), + }), + async resolve({ ctx, input }) { + const userId = ctx.session?.user?.id; + + const questionEncounterToDelete = await ctx.prisma.questionsQuestionEncounter.findUnique({ + where: { + id: input.id, + }, + }); + + if (questionEncounterToDelete?.id !== userId) { + throw new TRPCError({ + code: 'UNAUTHORIZED', + message: 'User have no authorization to record.', + }); + } + + return await ctx.prisma.questionsQuestionEncounter.delete({ + where: { + id: input.id, + }, + }); + }, + }); \ No newline at end of file diff --git a/apps/portal/src/types/questions.d.ts b/apps/portal/src/types/questions.d.ts index fa72f638..2bcdfee7 100644 --- a/apps/portal/src/types/questions.d.ts +++ b/apps/portal/src/types/questions.d.ts @@ -10,4 +10,10 @@ export type Question = { role: string; updatedAt: Date; user: string; -}; \ No newline at end of file +}; + +export type AggregatedQuestionEncounter = { + companyCount: Record; + locationCount: Record; + roleCount:Record; +} \ No newline at end of file