Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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;
7 changes: 7 additions & 0 deletions apps/web/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down
84 changes: 83 additions & 1 deletion apps/web/utils/actions/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
});
},
);
Expand Down