# 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 individual or all history entries
- 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, inches)
- `weightUnit` (string): Unit of weight measurement (kg, lbs)
- `bmiValue` (number): Calculated BMI result (rounded to 1 decimal place)
- `category` (string): Health category classification
- `timestamp` (datetime): When the calculation was performed
- `sessionId` (string): Browser session identifier for grouping calculations

### BMICategory
Represents the classification ranges for BMI values.

**Attributes:**
- `id` (string): Unique identifier for the category
- `name` (string): Category name (Underweight, Normal weight, Overweight, Obese)
- `minValue` (number): Minimum BMI value for this category
- `maxValue` (number): Maximum BMI value for this category (null for open-ended)
- `description` (string): Health information about this category
- `colorCode` (string): UI color representation for the category

### Session
Represents a user's browser session for tracking calculation history.

**Attributes:**
- `sessionId` (string, UUID): Unique session identifier
- `createdAt` (datetime): When the session was created
- `lastActivityAt` (datetime): Last calculation timestamp
- `calculationCount` (number): Total calculations in this session

## 4. Entity Relationships

### Calculation ↔ Session
- **Relationship Type:** Many-to-One
- **Description:** Multiple calculations belong to one session
- A Session can have zero or many Calculations
- A Calculation belongs to exactly one Session
- When a session expires/is cleared, associated calculations are removed

### Calculation ↔ BMICategory
- **Relationship Type:** Many-to-One (Logical)
- **Description:** Each calculation is classified into one BMI category based on the calculated BMI value
- A BMICategory can classify many Calculations
- A Calculation maps to exactly one BMICategory based on its bmiValue
- This is a computed relationship, not stored directly

## 5. Key Workflows

### Workflow 1: Calculate BMI

**Actors:** Anonymous User

**Steps:**
1. User lands on the BMI Calculator page
2. System generates or retrieves session ID from browser storage
3. User selects measurement unit system (Metric/Imperial)
4. User enters height value in the input field
5. User enters weight value in the input field
6. System validates inputs in real-time (numeric, positive values)
7. User clicks "Calculate BMI" button
8. System validates all inputs are complete and valid
9. System converts measurements to metric if imperial was selected
10. System calculates BMI using formula: weight(kg) / (height(m))²
11. System determines BMI category based on calculated value
12. System creates new Calculation entity with all data
13. System stores Calculation in session history
14. System displays BMI result with:
    - Numeric BMI value
    - Category name and description
    - Visual indicator (color-coded)
15. System updates calculation history list
16. User can view the result and perform another calculation

### Workflow 2: View Calculation History

**Actors:** Anonymous User

**Steps:**
1. User has performed one or more BMI calculations
2. System displays history section below the calculator
3. History shows list of calculations in reverse chronological order (newest first)
4. Each history entry displays:
   - Timestamp of calculation
   - Height and weight values with units
   - BMI result and category
5. User can scroll through history if multiple entries exist
6. User can reference previous calculations without re-entering data

### Workflow 3: Clear History

**Actors:** Anonymous User

**Steps:**
1. User views calculation history with one or more entries
2. **Option A - Clear Single Entry:**
   - User clicks delete icon on specific history entry
   - System prompts for confirmation (optional)
   - System removes that Calculation from history
   - System updates the display
3. **Option B - Clear All History:**
   - User clicks "Clear All History" button
   - System prompts for confirmation
   - User confirms action
   - System removes all Calculations for current session
   - System clears history display
   - System shows empty state message

### Workflow 4: Change Unit System

**Actors:** Anonymous User

**Steps:**
1. User has entered height and/or weight values
2. User toggles unit system (Metric ↔ Imperial)
3. System converts existing input values to new unit system:
   - Height: cm ↔ inches (1 inch = 2.54 cm)
   - Weight: kg ↔ lbs (1 lb = 0.453592 kg)
4. System updates input field labels and placeholders
5. System preserves converted values in input fields
6. User can continue with calculation or adjust values

## 6. Features & Requirements

### Module: BMI Calculator Form

**FR-1.1: Unit System Selection**
- Provide toggle/radio buttons for Metric and Imperial units
- Default to Metric system on initial load
- Persist unit preference in browser session
- Display appropriate labels based on selection:
  - Metric: Height (cm), Weight (kg)
  - Imperial: Height (inches), Weight (lbs)

**FR-1.2: Height Input**
- Provide numeric input field for height
- Accept decimal values (e.g., 175.5)
- Show unit label dynamically based on unit system
- Display placeholder text with example value
- Validate input in real-time
- Show error message for invalid inputs

**FR-1.3: Weight Input**
- Provide numeric input field for weight
- Accept decimal values (e.g., 70.5)
- Show unit label dynamically based on unit system
- Display placeholder text with example value
- Validate input in real-time
- Show error message for invalid inputs

**FR-1.4: Calculate Button**
- Display prominent "Calculate BMI" button
- Enable button only when all inputs are valid
- Disable button and show loading state during calculation
- Trigger calculation on click
- Support keyboard accessibility (Enter key)

**FR-1.5: Form Reset**
- Provide "Clear" or "Reset" button
- Clear all input fields when clicked
- Reset to default unit system (optional)
- Do not clear calculation history
- Return focus to first input field

### Module: BMI Result Display

**FR-2.1: BMI Value Display**
- Show calculated BMI value prominently
- Display value rounded to 1 decimal place
- Use large, readable font size
- Include "BMI" label

**FR-2.2: Category Display**
- Show BMI category name (Underweight, Normal weight, Overweight, Obese)
- Display category description/health information
- Use color coding for visual distinction:
  - Underweight: Blue (#3B82F6)
  - Normal weight: Green (#10B981)
  - Overweight: Orange (#F59E0B)
  - Obese: Red (#EF4444)
- Apply color to background, border, or text for emphasis

**FR-2.3: Result Animation**
- Animate result appearance after calculation
- Use fade-in or slide-in effect
- Ensure animation is smooth and not distracting
- Duration: 300-500ms

**FR-2.4: BMI Scale Visualization**
- Display visual BMI scale/gauge showing ranges
- Highlight current BMI position on scale
- Show category boundaries clearly
- Make visualization responsive to screen size

### Module: Calculation History

**FR-3.1: History List Display**
- Show all calculations from current session
- Display in reverse chronological order (newest first)
- Limit visible entries with scroll if needed (suggest max 10 visible)
- Show empty state when no history exists

**FR-3.2: History Entry Details**
- Display timestamp (relative time: "2 minutes ago" or absolute)
- Show height value with unit
- Show weight value with unit
- Display BMI result
- Show category name with color indicator
- Use compact, scannable layout

**FR-3.3: Delete Single Entry**
- Provide delete/remove icon for each entry
- Show confirmation dialog (optional, based on UX preference)
- Remove entry from history on confirmation
- Animate removal (fade out)

**FR-3.4: Clear All History**
- Provide "Clear All" button above or below history list
- Show confirmation dialog before clearing
- Remove all entries on confirmation
- Show empty state after clearing
- Provide feedback message (e.g., "History cleared")

**FR-3.5: History Persistence**
- Store history in browser localStorage
- Associate history with session ID
- Load history on page load/refresh
- Maintain history across page refreshes within same session
- Auto-expire history after 24 hours (optional)

### Module: Information & Help

**FR-4.1: BMI Information Panel**
- Provide expandable/collapsible section with BMI information
- Explain what BMI is and how it's calculated
- Display BMI category ranges and descriptions
- Include disclaimer about BMI limitations
- Provide link to additional health resources (optional)

**FR-4.2: Formula Display**
- Show BMI calculation formula
- Display both metric and imperial formulas
- Use clear mathematical notation

**FR-4.3: Health Disclaimer**
- Display disclaimer that BMI is a screening tool, not diagnostic
- Advise users to consult healthcare professionals
- Note limitations (doesn't account for muscle mass, age, etc.)

### Module: User Interface

**FR-5.1: Responsive Design**
- Support mobile devices (320px minimum width)
- Support tablets (768px and up)
- Support desktop (1024px and up)
- Adapt layout for different screen sizes
- Ensure touch-friendly controls on mobile (min 44x44px tap targets)

**FR-5.2: Accessibility**
- Support keyboard navigation
- Provide ARIA labels for screen readers
- Ensure sufficient color contrast (WCAG AA minimum)
- Support focus indicators
- Provide text alternatives for visual elements

**FR-5.3: Loading States**
- Show loading indicator during calculation (if async)
- Disable inputs during processing
- Provide visual feedback for all actions

**FR-5.4: Error Handling**
- Display clear error messages for invalid inputs
- Show inline validation errors
- Provide guidance on how to fix errors
- Use non-intrusive error styling

## 7. Business Rules

### BR-1: BMI Calculation Rules

**BR-1.1: BMI Formula**
- BMI = weight (kg) / (height (m))²
- Always convert to metric for calculation
- Round result to 1 decimal place

**BR-1.2: Unit Conversions**
- 1 inch = 2.54 cm
- 1 lb = 0.453592 kg
- 1 meter = 100 cm
- Maintain precision during conversion (minimum 2 decimal places)

**BR-1.3: BMI Category Ranges**
- Underweight: BMI < 18.5
- Normal weight: 18.5 ≤ BMI < 25.0
- Overweight: 25.0 ≤ BMI < 30.0
- Obese: BMI ≥ 30.0

### BR-2: Input Validation Rules

**BR-2.1: Height Validation**
- Must be a positive number
- Metric: Minimum 50 cm, Maximum 300 cm
- Imperial: Minimum 20 inches, Maximum 120 inches
- Allow decimal values (up to 2 decimal places)
- Required field

**BR-2.2: Weight Validation**
- Must be a positive number
- Metric: Minimum 10 kg, Maximum 500 kg
- Imperial: Minimum 20 lbs, Maximum 1100 lbs
- Allow decimal values (up to 2 decimal places)
- Required field

**BR-2.3: Unit System Validation**
- Must be either "metric" or "imperial"
- Default to "metric" if not specified
- Cannot be null or empty

### BR-3: History Management Rules

**BR-3.1: History Storage**
- Maximum 100 calculations per session
- If limit exceeded, remove oldest calculation automatically
- Each calculation must have unique ID
- Timestamp must be in ISO 8601 format

**BR-3.2: Session Management**
- Session ID generated on first visit
- Session persists across page refreshes
- Session expires after 24 hours of inactivity
- New session created after expiration

**BR-3.3: History Deletion**
- User can delete individual entries at any time
- User can clear all history at any time
- Deletion is immediate and cannot be undone
- Deleted entries are permanently removed from storage

### BR-4: Data Integrity Rules

**BR-4.1: Calculation Immutability**
- Once created, calculation records cannot be modified
- All fields must be populated at creation time
- Timestamp is set automatically and cannot be changed

**BR-4.2: Category Assignment**
- Category is determined automatically based on BMI value
- Category cannot be manually overridden
- Category must always match BMI value according to defined ranges

## 8. Non-Functional Requirements

### NFR-1: Performance

**NFR-1.1: Response Time**
- BMI calculation must complete within 100ms
- Page initial load must complete within 2 seconds
- History retrieval from localStorage must complete within 50ms
- UI interactions must respond within 100ms

**NFR-1.2: Resource Usage**
- Application bundle size must not exceed 500KB (uncompressed)
- localStorage usage must not exceed 5MB
- Memory footprint must remain under 50MB during normal operation

**NFR-1.3: Rendering Performance**
- Maintain 60 FPS during animations
- First Contentful Paint (FCP) under 1.5 seconds
- Time to Interactive (TTI) under 3 seconds

### NFR-2: Security

**NFR-2.1: Data Privacy**
- No personal health data transmitted to servers
- All calculations performed client-side
- No user tracking or analytics without consent
- No cookies except for essential session management

**NFR-2.2: Input Security**
- Sanitize all user inputs to prevent XSS
- Validate data types on client-side
- Implement input length limits
- Prevent script injection in all input fields

**NFR-2.3: Storage Security**
- Use browser localStorage only (no server storage)
- Do not store sensitive personal information
- Clear storage on user request
- Implement storage quota management

### NFR-3: Scalability

**NFR-3.1: Client-Side Scalability**
- Support up to 100 calculations in history without performance degradation
- Handle rapid successive calculations (stress testing)
- Gracefully handle localStorage quota exceeded scenarios

**NFR-3.2: Browser Compatibility**
- Support last 2 versions of Chrome, Firefox, Safari, Edge
- Graceful degradation for older browsers
- Polyfills for missing features where necessary

### NFR-4: Usability

**NFR-4.1: User Experience**
- Interface must be intuitive without instructions
- All actions must provide immediate feedback
- Error messages must be clear and actionable
- Support both mouse and keyboard interactions

**NFR-4.2: Accessibility (WCAG 2.1 Level AA)**
- Color contrast ratio minimum 4.5:1 for text
- All interactive elements keyboard accessible
- Screen reader compatible
- Support for browser zoom up to 200%
- Focus indicators visible and clear

**NFR-4.3: Internationalization (Future Consideration)**
- Use semantic HTML for easy translation
- Separate content from code
- Support for RTL languages (future)
- Number formatting based on locale (future)

### NFR-5: Reliability

**NFR-5.1: Error Handling**
- Graceful handling of localStorage failures
- Fallback to in-memory storage if localStorage unavailable
- Clear error messages for all failure scenarios
- No data loss during normal operations

**NFR-5.2: Browser Compatibility**
- Function correctly in all supported browsers
- Detect and handle missing browser features
- Provide fallback for unsupported features

**NFR-5.3: Data Persistence**
- History data must persist across page refreshes
- No data corruption in localStorage
- Automatic recovery from corrupted data (clear and restart)

### NFR-6: Maintainability

**NFR-6.1: Code Quality**
- Follow consistent coding standards
- Maintain minimum 80% code coverage with tests
- Use TypeScript for type safety (recommended)
- Document all business logic functions

**NFR-6.2: Architecture**
- Separate concerns (UI, business logic, data storage)
- Use modular component structure
- Implement clear interfaces between modules
- Follow SOLID principles where applicable

### NFR-7: Compatibility

**NFR-7.1: Device Support**
- iOS Safari 13+
- Android Chrome 80+
- Desktop browsers (Chrome, Firefox, Safari, Edge) - last 2 versions
- Minimum screen resolution: 320x568 (iPhone SE)

**NFR-7.2: Network Requirements**
- Application must work offline after initial load
- No external API dependencies
- All assets bundled with application
- Optional: Service Worker for offline support

---

## Appendix: BMI Reference Data

### BMI Categories (Seed Data)

| Category | Min BMI | Max BMI | Color Code | Description |
|----------|---------|---------|------------|-------------|
| Underweight | 0 | 18.4 | #3B82F6 | Below normal weight range. Consider consulting a healthcare provider. |
| Normal weight | 18.5 | 24.9 | #10B981 | Healthy weight range. Maintain through balanced diet and exercise. |
| Overweight | 25.0 | 29.9 | #F59E0B | Above normal weight range. Consider lifestyle modifications. |
| Obese | 30.0 | null | #EF4444 | Significantly above normal range. Consult healthcare provider for guidance. |

### Conversion Factors

- **Height:** 1 inch = 2.54 cm
- **Weight:** 1 pound = 0.453592 kg
- **Height for BMI:** 1 meter = 100 cm

---

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