mirror of
https://github.com/formbricks/formbricks.git
synced 2026-01-24 03:09:52 -06:00
Add new Surveys endpoint to list all surveys of an account (#500)
This commit is contained in:
@@ -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);
|
||||
|
||||
32
apps/web/app/api/v1/surveys/route.ts
Normal file
32
apps/web/app/api/v1/surveys/route.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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>;
|
||||
|
||||
Reference in New Issue
Block a user