mirror of
https://github.com/formbricks/formbricks.git
synced 2026-02-22 18:18:45 -06:00
feat: adds a POST endpoint for response creation in management apis (#2652)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
import { authenticateRequest } from "@/app/api/v1/auth";
|
||||
import { responses } from "@/app/lib/api/response";
|
||||
import { transformErrorToDetails } from "@/app/lib/api/validator";
|
||||
import { NextRequest } from "next/server";
|
||||
|
||||
import { getResponses, getResponsesByEnvironmentId } from "@formbricks/lib/response/service";
|
||||
import { DatabaseError } from "@formbricks/types/errors";
|
||||
import { TResponse } from "@formbricks/types/responses";
|
||||
import { createResponse, getResponses, getResponsesByEnvironmentId } from "@formbricks/lib/response/service";
|
||||
import { getSurvey } from "@formbricks/lib/survey/service";
|
||||
import { DatabaseError, InvalidInputError } from "@formbricks/types/errors";
|
||||
import { TResponse, ZResponseInput } from "@formbricks/types/responses";
|
||||
|
||||
export const GET = async (request: NextRequest) => {
|
||||
const searchParams = request.nextUrl.searchParams;
|
||||
@@ -30,3 +32,76 @@ export const GET = async (request: NextRequest) => {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const POST = async (request: Request): Promise<Response> => {
|
||||
try {
|
||||
const authentication = await authenticateRequest(request);
|
||||
if (!authentication) return responses.notAuthenticatedResponse();
|
||||
|
||||
const environmentId = authentication.environmentId;
|
||||
|
||||
let jsonInput;
|
||||
|
||||
try {
|
||||
jsonInput = await request.json();
|
||||
} catch (err) {
|
||||
console.error(`Error parsing JSON input: ${err}`);
|
||||
return responses.badRequestResponse("Malformed JSON input, please check your request body");
|
||||
}
|
||||
|
||||
// add environmentId to response
|
||||
jsonInput.environmentId = environmentId;
|
||||
|
||||
const inputValidation = ZResponseInput.safeParse(jsonInput);
|
||||
|
||||
if (!inputValidation.success) {
|
||||
return responses.badRequestResponse(
|
||||
"Fields are missing or incorrectly formatted",
|
||||
transformErrorToDetails(inputValidation.error),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
const responseInput = inputValidation.data;
|
||||
|
||||
// get and check survey
|
||||
const survey = await getSurvey(responseInput.surveyId);
|
||||
if (!survey) {
|
||||
return responses.notFoundResponse("Survey", responseInput.surveyId, true);
|
||||
}
|
||||
if (survey.environmentId !== environmentId) {
|
||||
return responses.badRequestResponse(
|
||||
"Survey is part of another environment",
|
||||
{
|
||||
"survey.environmentId": survey.environmentId,
|
||||
environmentId,
|
||||
},
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// if there is a createdAt but no updatedAt, set updatedAt to createdAt
|
||||
if (responseInput.createdAt && !responseInput.updatedAt) {
|
||||
responseInput.updatedAt = responseInput.createdAt;
|
||||
}
|
||||
|
||||
let response: TResponse;
|
||||
try {
|
||||
response = await createResponse(inputValidation.data);
|
||||
} catch (error) {
|
||||
if (error instanceof InvalidInputError) {
|
||||
return responses.badRequestResponse(error.message);
|
||||
} else {
|
||||
console.error(error);
|
||||
return responses.internalServerErrorResponse(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
return responses.successResponse(response, true);
|
||||
} catch (error) {
|
||||
if (error instanceof DatabaseError) {
|
||||
return responses.badRequestResponse(error.message);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -203,6 +203,7 @@ export const createResponse = async (responseInput: TResponseInput): Promise<TRe
|
||||
singleUseId,
|
||||
ttc: initialTtc,
|
||||
} = responseInput;
|
||||
|
||||
try {
|
||||
let person: TPerson | null = null;
|
||||
let attributes: TAttributes | null = null;
|
||||
@@ -221,28 +222,30 @@ export const createResponse = async (responseInput: TResponseInput): Promise<TRe
|
||||
|
||||
const ttc = initialTtc ? (finished ? calculateTtcTotal(initialTtc) : initialTtc) : {};
|
||||
|
||||
const responsePrisma = await prisma.response.create({
|
||||
data: {
|
||||
survey: {
|
||||
const prismaData: Prisma.ResponseCreateInput = {
|
||||
survey: {
|
||||
connect: {
|
||||
id: surveyId,
|
||||
},
|
||||
},
|
||||
finished: finished,
|
||||
data: data,
|
||||
language: language,
|
||||
...(person?.id && {
|
||||
person: {
|
||||
connect: {
|
||||
id: surveyId,
|
||||
id: person.id,
|
||||
},
|
||||
},
|
||||
finished: finished,
|
||||
data: data,
|
||||
language: language,
|
||||
...(person?.id && {
|
||||
person: {
|
||||
connect: {
|
||||
id: person.id,
|
||||
},
|
||||
},
|
||||
personAttributes: attributes,
|
||||
}),
|
||||
...(meta && ({ meta } as Prisma.JsonObject)),
|
||||
singleUseId,
|
||||
ttc: ttc,
|
||||
},
|
||||
personAttributes: attributes,
|
||||
}),
|
||||
...(meta && ({ meta } as Prisma.JsonObject)),
|
||||
singleUseId,
|
||||
ttc: ttc,
|
||||
};
|
||||
|
||||
const responsePrisma = await prisma.response.create({
|
||||
data: prismaData,
|
||||
select: responseSelection,
|
||||
});
|
||||
|
||||
|
||||
@@ -238,6 +238,8 @@ export const ZResponse = z.object({
|
||||
export type TResponse = z.infer<typeof ZResponse>;
|
||||
|
||||
export const ZResponseInput = z.object({
|
||||
createdAt: z.coerce.date().optional(),
|
||||
updatedAt: z.coerce.date().optional(),
|
||||
environmentId: z.string().cuid2(),
|
||||
surveyId: z.string().cuid2(),
|
||||
userId: z.string().nullish(),
|
||||
|
||||
Reference in New Issue
Block a user