import type { ContactPoint, Patient } from 'fhir/r4'; export interface SignupDetails { /** E.164, as the signup form validated it. */ phone?: string; /** YYYY-MM-DD. */ birthDate?: string; } // The phone and date of birth typed at signup, for the one address they were typed for. Held in memory like the // sign-in handoff, so they never reach the URL or storage and are gone after this visit. let held: { email: string; details: SignupDetails } | undefined; const sameAddress = (a: string, b: string) => a.trim().toLowerCase() === b.trim().toLowerCase(); /** An existing account's signup resumed: what was typed is kept for that address only. */ export const rememberSignupDetails = (email: string, details: SignupDetails) => { held = { email: email.trim(), details }; }; /** The details for this signed-in address, once; anything held for another address is dropped, never handed over. */ export const takeSignupDetailsFor = (signedInEmail: string): SignupDetails | undefined => { const taken = held; held = undefined; return taken && signedInEmail && sameAddress(taken.email, signedInEmail) ? taken.details : undefined; }; /** The date of birth typed at signup, for this signed-in address only, read without handing the details over. */ export const signupBirthDateFor = (signedInEmail: string): string | undefined => held && signedInEmail && sameAddress(held.email, signedInEmail) ? held.details.birthDate : undefined; /** * The home record with only what it lacks filled in from signup: a phone when it has none, a date of birth when it * has none. Undefined when there is nothing to add. The phone is added as a plain number: an email verified at * signup says nothing about the phone, so it is neither marked verified nor opted into texts. */ export const missingDetailsPatch = (patient: Patient, details: SignupDetails): Patient | undefined => { const telecom: ContactPoint[] = patient.telecom ?? []; const addPhone = Boolean(details.phone) && !telecom.some((point) => point.system === 'phone' && point.value); const addBirthDate = Boolean(details.birthDate) && !patient.birthDate; if (!addPhone && !addBirthDate) return undefined; return { ...patient, ...(addPhone ? { telecom: [...telecom, { system: 'phone', value: details.phone as string }] } : {}), ...(addBirthDate ? { birthDate: details.birthDate } : {}), }; };