# Product Requirements Document: BMI Calculator App

## 1. Overview

The BMI Calculator app is a single-page web application that allows users to calculate their Body Mass Index (BMI) by entering their height and weight. The application provides instant BMI calculation results along with health category classification (underweight, normal weight, overweight, obese) and stores calculation history for reference. This is a lightweight, user-friendly tool designed for quick health assessments without requiring user authentication.

## 2. User Roles

### Anonymous User (Default Role)
- Enter height and weight measurements
- Select measurement units (metric or imperial)
- Calculate BMI instantly
- View BMI result and health category
- View calculation history in current session
- Clear calculation history
- Access BMI information and health guidelines

## 3. Core Entities

### Calculation
Represents a single BMI calculation performed by a user.

**Attributes:**
- `id` (string/UUID): Unique identifier for the calculation
- `height` (number): Height value entered by user
- `weight` (number): Weight value entered by user
- `heightUnit` (string): Unit of height measurement (cm, m, ft, in)
- `weightUnit` (string): Unit of weight measurement (kg, lbs)
- `bmiValue` (number): Calculated BMI result
- `category` (string): Health category classification
- `timestamp` (datetime): When the calculation was performed

### MeasurementUnit
Defines available measurement systems and units.

**Attributes:**
- `id` (string): Unique identifier
- `system` (string): Measurement system (metric, imperial)
- `heightUnits` (array): Available height units for this system
- `weightUnits` (array): Available weight units for this system
- `defaultHeightUnit` (string): Default height unit
- `defaultWeightUnit` (string): Default weight unit

### BMICategory
Defines BMI ranges and their corresponding health categories.

**Attributes:**
- `id` (string): Unique identifier
- `name` (string): Category name (e.g., "Underweight", "Normal weight")
- `minBMI` (number): Minimum BMI value for this category
- `maxBMI` (number): Maximum BMI value for this category
- `description` (string): Health information about this category
- `colorCode` (string): UI color indicator for the category

## 4. Entity Relationships

### Calculation ↔ BMICategory
- **Relationship Type:** Many-to-One
- **Description:** Each Calculation is associated with one BMICategory based on the calculated BMI value. Multiple Calculations can belong to the same BMICategory.

### Calculation ↔ MeasurementUnit
- **Relationship Type:** Many-to-One (implicit)
- **Description:** Each Calculation references measurement units from the MeasurementUnit entity. The heightUnit and weightUnit fields in Calculation correspond to units defined in MeasurementUnit.

### Session ↔ Calculation
- **Relationship Type:** One-to-Many (session-based)
- **Description:** A single browser session can contain multiple Calculations. This is managed client-side through browser storage (localStorage/sessionStorage).

## 5. Key Workflows

### Workflow 1: Calculate BMI

**Actors:** Anonymous User

**Steps:**
1. User lands on the BMI Calculator page
2. System displays default measurement unit system (metric)
3. User selects preferred measurement system (metric or imperial)
4. System updates input fields with appropriate units
5. User enters height value
6. User enters weight value
7. System validates inputs (non-negative, numeric values)
8. User clicks "Calculate" button
9. System converts measurements to standard units if necessary
10. System calculates BMI using formula: BMI = weight(kg) / (height(m))²
11. System determines BMI category based on calculated value
12. System displays BMI result with category and color indicator
13. System adds calculation to history
14. System persists calculation to browser storage

**Success Criteria:**
- BMI is calculated accurately
- Correct category is displayed
- Calculation appears in history

**Error Scenarios:**
- Invalid input (non-numeric): Display error message
- Missing height or weight: Display validation message
- Negative values: Display error message

### Workflow 2: View Calculation History

**Actors:** Anonymous User

**Steps:**
1. User performs one or more BMI calculations
2. System displays history section below calculator
3. System shows list of previous calculations in reverse chronological order
4. Each history entry displays: timestamp, height, weight, BMI value, category
5. User can scroll through history if multiple entries exist

**Success Criteria:**
- All calculations from current session are visible
- Most recent calculation appears first
- Each entry shows complete information

### Workflow 3: Clear History

**Actors:** Anonymous User

**Steps:**
1. User views calculation history
2. User clicks "Clear History" button
3. System prompts for confirmation
4. User confirms action
5. System removes all calculations from browser storage
6. System clears history display
7. System shows empty state message

**Success Criteria:**
- All history is removed
- Storage is cleared
- Empty state is displayed

### Workflow 4: Switch Measurement Units

**Actors:** Anonymous User

**Steps:**
1. User is on BMI Calculator page
2. User clicks measurement unit toggle (Metric/Imperial)
3. System switches active measurement system
4. System updates height input label (cm/m ↔ ft/in)
5. System updates weight input label (kg ↔ lbs)
6. System clears previous input values
7. System resets any displayed results

**Success Criteria:**
- Units are switched correctly
- Labels are updated
- Previous inputs are cleared to avoid confusion

## 6. Features & Requirements

### Module: BMI Calculator Form

#### F1: Measurement Unit Selection
- **F1.1:** Display toggle/radio buttons for Metric and Imperial systems
- **F1.2:** Metric system uses: centimeters (cm) or meters (m) for height, kilograms (kg) for weight
- **F1.3:** Imperial system uses: feet (ft) and inches (in) for height, pounds (lbs) for weight
- **F1.4:** Default to Metric system on initial load
- **F1.5:** Persist selected unit preference in browser storage

#### F2: Height Input
- **F2.1:** Provide numeric input field for height
- **F2.2:** Display appropriate unit label based on selected system
- **F2.3:** For imperial system, provide separate inputs for feet and inches
- **F2.4:** Accept decimal values
- **F2.5:** Show placeholder text with example values
- **F2.6:** Validate input in real-time

#### F3: Weight Input
- **F3.1:** Provide numeric input field for weight
- **F3.2:** Display appropriate unit label based on selected system
- **F3.3:** Accept decimal values
- **F3.4:** Show placeholder text with example values
- **F3.5:** Validate input in real-time

#### F4: Calculate Button
- **F4.1:** Display prominent "Calculate BMI" button
- **F4.2:** Enable button only when valid height and weight are entered
- **F4.3:** Trigger BMI calculation on click
- **F4.4:** Show loading state during calculation (if applicable)
- **F4.5:** Support keyboard shortcut (Enter key) to trigger calculation

#### F5: BMI Result Display
- **F5.1:** Show calculated BMI value rounded to 1 decimal place
- **F5.2:** Display BMI category name prominently
- **F5.3:** Use color coding for categories (e.g., blue for underweight, green for normal, orange for overweight, red for obese)
- **F5.4:** Show visual indicator (gauge, chart, or colored bar)
- **F5.5:** Display category description and health information
- **F5.6:** Animate result appearance for better UX

### Module: Calculation History

#### F6: History List
- **F6.1:** Display list of all calculations from current session
- **F6.2:** Show calculations in reverse chronological order (newest first)
- **F6.3:** Display for each entry: date/time, height, weight, BMI, category
- **F6.4:** Use consistent formatting for all entries
- **F6.5:** Limit display to most recent 10 calculations
- **F6.6:** Show empty state message when no history exists

#### F7: History Management
- **F7.1:** Provide "Clear History" button
- **F7.2:** Show confirmation dialog before clearing
- **F7.3:** Allow individual entry deletion (optional enhancement)
- **F7.4:** Persist history in browser localStorage
- **F7.5:** Load history on page refresh

### Module: Information & Help

#### F8: BMI Information
- **F8.1:** Display BMI category ranges and descriptions
- **F8.2:** Show BMI formula explanation
- **F8.3:** Provide health guidelines and disclaimers
- **F8.4:** Include information about BMI limitations
- **F8.5:** Make information collapsible or accessible via info icon

#### F9: User Interface
- **F9.1:** Implement responsive design for mobile, tablet, and desktop
- **F9.2:** Use clear, readable typography
- **F9.3:** Ensure sufficient color contrast for accessibility
- **F9.4:** Provide clear visual hierarchy
- **F9.5:** Include appropriate spacing and padding
- **F9.6:** Support both light and dark mode (optional)

## 7. Business Rules

### BR1: BMI Calculation
- **BR1.1:** BMI formula: BMI = weight (kg) / [height (m)]²
- **BR1.2:** All measurements must be converted to metric (kg, m) before calculation
- **BR1.3:** BMI result must be rounded to 1 decimal place
- **BR1.4:** Minimum acceptable height: 50 cm (1.64 ft)
- **BR1.5:** Maximum acceptable height: 300 cm (9.84 ft)
- **BR1.6:** Minimum acceptable weight: 10 kg (22 lbs)
- **BR1.7:** Maximum acceptable weight: 500 kg (1102 lbs)

### BR2: BMI Categories (WHO Standard)
- **BR2.1:** Underweight: BMI < 18.5
- **BR2.2:** Normal weight: 18.5 ≤ BMI < 25
- **BR2.3:** Overweight: 25 ≤ BMI < 30
- **BR2.4:** Obese Class I: 30 ≤ BMI < 35
- **BR2.5:** Obese Class II: 35 ≤ BMI < 40
- **BR2.6:** Obese Class III: BMI ≥ 40

### BR3: Unit Conversions
- **BR3.1:** 1 inch = 2.54 cm
- **BR3.2:** 1 foot = 30.48 cm
- **BR3.3:** 1 pound = 0.453592 kg
- **BR3.4:** 1 meter = 100 cm
- **BR3.5:** Conversions must maintain precision to 2 decimal places

### BR4: Input Validation
- **BR4.1:** Height and weight must be positive numbers
- **BR4.2:** Height and weight cannot be zero
- **BR4.3:** Inputs must be numeric (decimals allowed)
- **BR4.4:** Empty inputs are not allowed for calculation
- **BR4.5:** Special characters are not permitted

### BR5: History Management
- **BR5.1:** History is session-based (no user accounts)
- **BR5.2:** Maximum 100 calculations stored per session
- **BR5.3:** History persists across page refreshes within same browser
- **BR5.4:** History is cleared when browser storage is cleared
- **BR5.5:** Oldest entries are automatically removed when limit is reached

### BR6: Data Privacy
- **BR6.1:** No personal data is collected or transmitted to servers
- **BR6.2:** All calculations are performed client-side
- **BR6.3:** History is stored only in user's browser
- **BR6.4:** No cookies are used for tracking
- **BR6.5:** No analytics data is collected without explicit consent

## 8. Non-Functional Requirements

### NFR1: Performance
- **NFR1.1:** BMI calculation must complete within 100ms
- **NFR1.2:** Page load time must be under 2 seconds on 3G connection
- **NFR1.3:** UI interactions must respond within 50ms
- **NFR1.4:** Application bundle size must be under 500KB
- **NFR1.5:** History retrieval from storage must complete within 200ms

### NFR2: Usability
- **NFR2.1:** Application must be usable without instructions
- **NFR2.2:** Error messages must be clear and actionable
- **NFR2.3:** Form inputs must have clear labels and placeholders
- **NFR2.4:** Visual feedback must be provided for all user actions
- **NFR2.5:** Application must be operable via keyboard only

### NFR3: Accessibility
- **NFR3.1:** Must comply with WCAG 2.1 Level AA standards
- **NFR3.2:** All interactive elements must be keyboard accessible
- **NFR3.3:** Must support screen readers (ARIA labels required)
- **NFR3.4:** Color contrast ratio must be at least 4.5:1 for text
- **NFR3.5:** Form inputs must have associated labels
- **NFR3.6:** Focus indicators must be clearly visible

### NFR4: Browser Compatibility
- **NFR4.1:** Must support Chrome (last 2 versions)
- **NFR4.2:** Must support Firefox (last 2 versions)
- **NFR4.3:** Must support Safari (last 2 versions)
- **NFR4.4:** Must support Edge (last 2 versions)
- **NFR4.5:** Must gracefully degrade on older browsers
- **NFR4.6:** Must support mobile browsers (iOS Safari, Chrome Mobile)

### NFR5: Responsive Design
- **NFR5.1:** Must be fully functional on mobile devices (320px width minimum)
- **NFR5.2:** Must adapt layout for tablet devices (768px - 1024px)
- **NFR5.3:** Must optimize layout for desktop (1024px and above)
- **NFR5.4:** Touch targets must be at least 44x44 pixels on mobile
- **NFR5.5:** Text must be readable without zooming on all devices

### NFR6: Security
- **NFR6.1:** All inputs must be sanitized to prevent XSS attacks
- **NFR6.2:** Application must use HTTPS in production
- **NFR6.3:** No sensitive data should be logged to console in production
- **NFR6.4:** Content Security Policy headers must be implemented
- **NFR6.5:** localStorage data must be validated before use

### NFR7: Reliability
- **NFR7.1:** Application must handle invalid inputs gracefully
- **NFR7.2:** Must function offline after initial load (PWA optional)
- **NFR7.3:** Must recover from localStorage errors
- **NFR7.4:** Must handle browser storage quota exceeded scenarios
- **NFR7.5:** Application must not crash on invalid data

### NFR8: Maintainability
- **NFR8.1:** Code must follow consistent style guidelines
- **NFR8.2:** Functions must be modular and reusable
- **NFR8.3:** Code must include inline comments for complex logic
- **NFR8.4:** BMI categories must be configurable without code changes
- **NFR8.5:** Unit conversion factors must be defined as constants

### NFR9: Scalability
- **NFR9.1:** Architecture must support adding new measurement units
- **NFR9.2:** Must support adding new BMI categories without refactoring
- **NFR9.3:** Must support internationalization (i18n) in future
- **NFR9.4:** Must support adding user accounts in future without major refactoring

### NFR10: Localization (Future Consideration)
- **NFR10.1:** UI text must be externalized for translation
- **NFR10.2:** Number formatting must respect locale settings
- **NFR10.3:** Date/time display must respect locale settings
- **NFR10.4:** Must support RTL languages in future

---

**Document Version:** 1.0  
**Last Updated:** 2025  
**Status:** Ready for Development