import type { UserFactCategory } from "@rakazo/contracts"; import { isLanguageTag, isTimeZone } from "@rakazo/contracts"; export interface OnboardingAnswers { name: string; timezone: string; hobbies: string[]; workStyle: string; communication: string; } // Stored as data for the user's bots, so these stay plain English statements. const HOBBY_FACTS: Record = { coding: "Interested in coding", design: "Interested in design", writing: "Interested in writing", music: "Interested in music", gaming: "Interested in gaming", reading: "Interested in reading", sports: "Interested in sports", cooking: "Interested in cooking", tech: "Interested in tech and gadgets", }; const WORK_STYLE_FACTS: Record = { structured: "Works in a structured, planned way", flexible: "Works flexibly and spontaneously", "deep-dive": "Prefers focused deep dives", quick: "Works quickly and pragmatically", }; const COMMUNICATION_STYLES: Record = { direct: "Direct and concise", detailed: "Detailed and explanatory", balanced: "Balanced", casual: "Casual and friendly", }; /** Turns onboarding answers into one profile update; empty or unknown answers are left out. */ export function onboardingProfileUpdate(input: { answers: OnboardingAnswers; /** The account name, which only changes when the user typed a different one. */ accountName?: string; /** Used when the typed time zone is empty or unknown. */ browserTimeZone: string; /** Browser locale, e.g. "de-AT". */ locale?: string; /** Language the user picked for their Oos, when they picked one. */ language?: string | null; }) { const { answers } = input; const name = answers.name.trim(); const typedZone = answers.timezone.trim(); const workStyle = WORK_STYLE_FACTS[answers.workStyle]; const facts: Array<{ category: UserFactCategory; value: string }> = [ ...answers.hobbies.flatMap((hobby) => { const value = HOBBY_FACTS[hobby]; return value ? [{ category: "preferences" as const, value }] : []; }), ...(workStyle ? [{ category: "habits" as const, value: workStyle }] : []), ]; const communicationStyle = COMMUNICATION_STYLES[answers.communication]; return { ...(name && name !== input.accountName?.trim() ? { name } : {}), timeZone: typedZone && isTimeZone(typedZone) ? typedZone : input.browserTimeZone, ...(input.locale && isLanguageTag(input.locale) ? { locale: input.locale } : {}), ...(input.language && isLanguageTag(input.language) ? { language: input.language } : {}), ...(communicationStyle ? { communicationStyle } : {}), ...(facts.length > 0 ? { addFacts: facts.map((fact) => ({ ...fact, source: "onboarding" as const })) } : {}), }; }