Add new Surveys endpoint to list all surveys of an account (#500)

This commit is contained in:
Matti Nannt
2023-07-10 10:44:37 +02:00
committed by GitHub
parent f4237e3121
commit 31ccb9d43f
4 changed files with 118 additions and 42 deletions

View File

@@ -19,7 +19,7 @@ export async function GET() {
return responses.notAuthenticatedResponse();
}
// get webhooks from database
// get responses from database
try {
const environmentResponses = await getEnvironmentResponses(apiKeyData.environmentId);
return responses.successResponse(environmentResponses);

View File

@@ -0,0 +1,32 @@
import { responses } from "@/lib/api/response";
import { DatabaseError } from "@formbricks/errors";
import { getApiKeyFromKey } from "@formbricks/lib/services/apiKey";
import { getSurveys } from "@formbricks/lib/services/survey";
import { headers } from "next/headers";
export async function GET() {
const apiKey = headers().get("x-api-key");
if (!apiKey) {
return responses.notAuthenticatedResponse();
}
let apiKeyData;
try {
apiKeyData = await getApiKeyFromKey(apiKey);
if (!apiKeyData) {
return responses.notAuthenticatedResponse();
}
} catch (error) {
return responses.notAuthenticatedResponse();
}
// get surveys from database
try {
const surveys = await getSurveys(apiKeyData.environmentId);
return responses.successResponse(surveys);
} catch (error) {
if (error instanceof DatabaseError) {
return responses.badRequestResponse(error.message);
}
throw error;
}
}

View File

@@ -2,59 +2,61 @@ import { prisma } from "@formbricks/database";
import { z } from "zod";
import { ValidationError } from "@formbricks/errors";
import { DatabaseError, ResourceNotFoundError } from "@formbricks/errors";
import { TSurvey, ZSurvey } from "@formbricks/types/v1/surveys";
import { TSurvey, TSurveyWithAnalytics, ZSurvey, ZSurveyWithAnalytics } from "@formbricks/types/v1/surveys";
import { Prisma } from "@prisma/client";
import "server-only";
import { cache } from "react";
const selectSurvey = {
id: true,
createdAt: true,
updatedAt: true,
name: true,
type: true,
environmentId: true,
status: true,
questions: true,
thankYouCard: true,
displayOption: true,
recontactDays: true,
autoClose: true,
delay: true,
autoComplete: true,
triggers: {
select: {
eventClass: {
select: {
id: true,
name: true,
description: true,
type: true,
noCodeConfig: true,
},
},
},
},
attributeFilters: {
select: {
id: true,
attributeClassId: true,
condition: true,
value: true,
},
},
};
export const preloadSurvey = (surveyId: string) => {
void getSurvey(surveyId);
};
export const getSurvey = cache(async (surveyId: string): Promise<TSurvey | null> => {
export const getSurvey = cache(async (surveyId: string): Promise<TSurveyWithAnalytics | null> => {
let surveyPrisma;
try {
surveyPrisma = await prisma.survey.findUnique({
where: {
id: surveyId,
},
select: {
id: true,
createdAt: true,
updatedAt: true,
name: true,
type: true,
environmentId: true,
status: true,
questions: true,
thankYouCard: true,
displayOption: true,
recontactDays: true,
autoClose: true,
delay: true,
autoComplete: true,
triggers: {
select: {
eventClass: {
select: {
id: true,
name: true,
description: true,
type: true,
noCodeConfig: true,
},
},
},
},
attributeFilters: {
select: {
id: true,
attributeClassId: true,
condition: true,
value: true,
},
},
},
select: selectSurvey,
});
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
@@ -94,7 +96,7 @@ export const getSurvey = cache(async (surveyId: string): Promise<TSurvey | null>
};
try {
const survey = ZSurvey.parse(transformedSurvey);
const survey = ZSurveyWithAnalytics.parse(transformedSurvey);
return survey;
} catch (error) {
if (error instanceof z.ZodError) {
@@ -103,3 +105,40 @@ export const getSurvey = cache(async (surveyId: string): Promise<TSurvey | null>
throw new ValidationError("Data validation of survey failed");
}
});
export const getSurveys = cache(async (environmentId: string): Promise<TSurvey[]> => {
let surveysPrisma;
try {
surveysPrisma = await prisma.survey.findMany({
where: {
environmentId,
},
select: selectSurvey,
});
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
throw new DatabaseError("Database operation failed");
}
throw error;
}
const surveys: TSurvey[] = [];
for (const surveyPrisma of surveysPrisma) {
const transformedSurvey = {
...surveyPrisma,
triggers: surveyPrisma.triggers.map((trigger) => trigger.eventClass),
};
const survey = ZSurvey.parse(transformedSurvey);
surveys.push(survey);
}
try {
return surveys;
} catch (error) {
if (error instanceof z.ZodError) {
console.error(JSON.stringify(error.errors, null, 2)); // log the detailed error information
}
throw new ValidationError("Data validation of survey failed");
}
});

View File

@@ -205,10 +205,15 @@ export const ZSurvey = z.object({
thankYouCard: ZSurveyThankYouCard,
delay: z.number(),
autoComplete: z.union([z.number(), z.null()]),
});
export type TSurvey = z.infer<typeof ZSurvey>;
export const ZSurveyWithAnalytics = ZSurvey.extend({
analytics: z.object({
numDisplays: z.number(),
responseRate: z.number(),
}),
});
export type TSurvey = z.infer<typeof ZSurvey>;
export type TSurveyWithAnalytics = z.infer<typeof ZSurveyWithAnalytics>;