diff --git a/apps/web/prisma/migrations/20250606102158_onboarding_answers/migration.sql b/apps/web/prisma/migrations/20250606102158_onboarding_answers/migration.sql new file mode 100644 index 0000000000..3d3af3a872 --- /dev/null +++ b/apps/web/prisma/migrations/20250606102158_onboarding_answers/migration.sql @@ -0,0 +1,6 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "surveyFeatures" TEXT[], +ADD COLUMN "surveyGoal" TEXT, +ADD COLUMN "surveyImprovements" TEXT, +ADD COLUMN "surveyRole" TEXT, +ADD COLUMN "surveySource" TEXT; diff --git a/apps/web/prisma/schema.prisma b/apps/web/prisma/schema.prisma index dc9c4264d0..ba6a705983 100644 --- a/apps/web/prisma/schema.prisma +++ b/apps/web/prisma/schema.prisma @@ -59,6 +59,13 @@ model User { utms Json? errorMessages Json? // eg. user set incorrect AI API key + // survey answers (extracted from onboardingAnswers for easier querying) + surveyFeatures String[] // multiple choice: features user is interested in + surveyRole String? // single choice: user's role + surveyGoal String? // single choice: what user wants to achieve + surveySource String? // single choice: how user heard about Inbox Zero + surveyImprovements String? // open text: what user wants to improve + // settings aiProvider String? aiModel String? diff --git a/apps/web/utils/actions/user.ts b/apps/web/utils/actions/user.ts index 061de9f6f5..a7712e4571 100644 --- a/apps/web/utils/actions/user.ts +++ b/apps/web/utils/actions/user.ts @@ -117,9 +117,91 @@ export const saveOnboardingAnswersAction = actionClientUser parsedInput: { surveyId, questions, answers }, ctx: { userId }, }) => { + // Helper function to extract survey answers from the response format + function extractSurveyAnswers(questions: any[], answers: any) { + const result: { + surveyFeatures?: string[]; + surveyRole?: string; + surveyGoal?: string; + surveySource?: string; + surveyImprovements?: string; + } = {}; + + if (!questions || !answers) return result; + + // Helper to get answer by question key + const getAnswerByKey = (key: string) => { + const questionIndex = questions.findIndex((q) => q.key === key); + if (questionIndex === -1) return null; + + const answerKey = + questionIndex === 0 + ? "$survey_response" + : `$survey_response_${questionIndex}`; + const answer = answers[answerKey]; + + return answer && answer !== "" ? answer : null; + }; + + // Extract features (multiple choice) + const featuresAnswer = getAnswerByKey("features"); + if (featuresAnswer) { + if (typeof featuresAnswer === "string") { + const features = featuresAnswer + .split(",") + .map((s) => s.trim()) + .filter(Boolean) + .filter((s) => s !== "undefined"); + if (features.length > 0) { + result.surveyFeatures = features; + } + } else if (Array.isArray(featuresAnswer)) { + const features = featuresAnswer.filter( + (f) => f && f !== "undefined", + ); + if (features.length > 0) { + result.surveyFeatures = features; + } + } + } + + // Extract other single choice/text answers - only set if not undefined/null/empty + const roleAnswer = getAnswerByKey("role"); + if (roleAnswer && roleAnswer !== "undefined") { + result.surveyRole = roleAnswer; + } + + const goalAnswer = getAnswerByKey("goal"); + if (goalAnswer && goalAnswer !== "undefined") { + result.surveyGoal = goalAnswer; + } + + const sourceAnswer = getAnswerByKey("source"); + if (sourceAnswer && sourceAnswer !== "undefined") { + result.surveySource = sourceAnswer; + } + + const improvementsAnswer = getAnswerByKey("improvements"); + if (improvementsAnswer && improvementsAnswer !== "undefined") { + result.surveyImprovements = improvementsAnswer; + } + + return result; + } + + // Extract individual survey answers for easier querying + const extractedAnswers = extractSurveyAnswers(questions, answers); + await prisma.user.update({ where: { id: userId }, - data: { onboardingAnswers: { surveyId, questions, answers } }, + data: { + onboardingAnswers: { surveyId, questions, answers }, + surveyFeatures: extractedAnswers.surveyFeatures, + surveyRole: extractedAnswers.surveyRole, + surveyGoal: extractedAnswers.surveyGoal, + surveySource: extractedAnswers.surveySource, + surveyImprovements: extractedAnswers.surveyImprovements, + }, }); }, );