Files
formbricks/apps/web/modules/survey/lib/utils.ts
Piyush Gupta ef78c68ac1 chore: refactor survey module (#4696)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
2025-02-17 10:56:09 +00:00

121 lines
3.5 KiB
TypeScript

import "server-only";
import { Prisma } from "@prisma/client";
import { generateObject } from "ai";
import { z } from "zod";
import { llmModel } from "@formbricks/lib/aiModels";
import { TJsEnvironmentStateSurvey } from "@formbricks/types/js";
import { TSegment } from "@formbricks/types/segment";
import {
TSurvey,
TSurveyFilterCriteria,
TSurveyQuestion,
TSurveyQuestions,
} from "@formbricks/types/surveys/types";
export const getInsightsEnabled = async (question: TSurveyQuestion): Promise<boolean> => {
try {
const { object } = await generateObject({
model: llmModel,
schema: z.object({
insightsEnabled: z.boolean(),
}),
prompt: `We extract insights (e.g. feature requests, complaints, other) from survey questions. Can we find them in this question?: ${question.headline.default}`,
experimental_telemetry: { isEnabled: true },
});
return object.insightsEnabled;
} catch (error) {
throw error;
}
};
export const transformPrismaSurvey = <T extends TSurvey | TJsEnvironmentStateSurvey>(
surveyPrisma: any
): T => {
let segment: TSegment | null = null;
if (surveyPrisma.segment) {
segment = {
...surveyPrisma.segment,
surveys: surveyPrisma.segment.surveys.map((survey) => survey.id),
};
}
const transformedSurvey = {
...surveyPrisma,
displayPercentage: Number(surveyPrisma.displayPercentage) || null,
segment,
} as T;
return transformedSurvey;
};
export const buildWhereClause = (filterCriteria?: TSurveyFilterCriteria) => {
const whereClause: Prisma.SurveyWhereInput["AND"] = [];
// for name
if (filterCriteria?.name) {
whereClause.push({ name: { contains: filterCriteria.name, mode: "insensitive" } });
}
// for status
if (filterCriteria?.status && filterCriteria?.status?.length) {
whereClause.push({ status: { in: filterCriteria.status } });
}
// for type
if (filterCriteria?.type && filterCriteria?.type?.length) {
whereClause.push({ type: { in: filterCriteria.type } });
}
// for createdBy
if (filterCriteria?.createdBy?.value && filterCriteria?.createdBy?.value?.length) {
if (filterCriteria.createdBy.value.length === 1) {
if (filterCriteria.createdBy.value[0] === "you") {
whereClause.push({ createdBy: filterCriteria.createdBy.userId });
}
if (filterCriteria.createdBy.value[0] === "others") {
whereClause.push({
OR: [
{
createdBy: {
not: filterCriteria.createdBy.userId,
},
},
{
createdBy: null,
},
],
});
}
}
}
return { AND: whereClause };
};
export const buildOrderByClause = (
sortBy?: TSurveyFilterCriteria["sortBy"]
): Prisma.SurveyOrderByWithRelationInput[] | undefined => {
const orderMapping: { [key: string]: Prisma.SurveyOrderByWithRelationInput } = {
name: { name: "asc" },
createdAt: { createdAt: "desc" },
updatedAt: { updatedAt: "desc" },
};
return sortBy ? [orderMapping[sortBy] || { updatedAt: "desc" }] : undefined;
};
export const anySurveyHasFilters = (surveys: TSurvey[]): boolean => {
return surveys.some((survey) => {
if ("segment" in survey && survey.segment) {
return survey.segment.filters && survey.segment.filters.length > 0;
}
return false;
});
};
export const doesSurveyHasOpenTextQuestion = (questions: TSurveyQuestions): boolean => {
return questions.some((question) => question.type === "openText");
};