profileStore.ts
Purpose
This module manages the user’s physiological profile, providing typed load and save operations backed by AsyncStorage. It is the single source of truth for profile data consumed by inference, the home screen, and the landing screen.
Its responsibilities include:
- Defining the canonical
UserProfiletype with all physiological and preference fields - Providing a
defaultProfileused for first-run and field fallback - Loading and merging persisted profile data with defaults to handle partial saves
- Saving a complete
UserProfileto AsyncStorage - Computing BMI from height and weight
Invariants
Default Merge on Load
loadProfile merges the persisted object with defaultProfile using spread:
{ ...defaultProfile, ...parsed }
This ensures any fields missing from an older persisted schema are filled with current defaults, providing forward compatibility.
Parse Failure Fallback
If the raw stored value cannot be parsed as JSON, loadProfile returns defaultProfile rather than throwing.
BMI Zero Guard
calcBMI returns 0 when heightCm is zero or falsy, preventing division by zero.
Constants
| Field | Default value | Description |
|---|---|---|
gender | "male" | Biological sex |
unitSystem | "metric" | Display unit preference |
age | 25 | Age in years |
heightCm | 175 | Height in centimeters |
weightKg | 75 | Weight in kilograms |
daysActive14 | 4 | Active days in past 14 |
Exports
UserProfile
type UserProfile = {
gender: Gender;
unitSystem: "metric" | "imperial";
age: number;
heightCm: number;
weightKg: number;
daysActive14: number;
};
calcBMI(...)
function calcBMI(heightCm: number, weightKg: number): number
Returns weightKg / (heightM²), or 0 if heightCm is zero.
loadProfile()
async function loadProfile(): Promise<UserProfile>
Loads and returns the persisted profile merged with defaultProfile. Never throws.
saveProfile(...)
async function saveProfile(next: UserProfile): Promise<void>
Serializes and writes the full profile to AsyncStorage.