# Product Requirements Document: Simple Loan Calculator

## 1. Overview

The Simple Loan Calculator is a single-page web application that enables users to calculate loan payment schedules, monthly payments, and total interest costs based on loan parameters. Users can input loan amount, interest rate, and loan term to instantly view detailed amortization information and payment breakdowns. This tool serves individuals, financial advisors, and lending professionals who need quick, accurate loan calculations without complex navigation or authentication requirements.

## 2. User Roles

### Anonymous User (Default)
- Access the loan calculator interface without authentication
- Input loan parameters (principal, interest rate, term)
- View calculated monthly payment amount
- View total interest paid over loan lifetime
- View total amount paid (principal + interest)
- View amortization schedule breakdown
- Adjust parameters and recalculate instantly
- Print or export calculation results (optional)

**Note:** This application does not require user authentication or role-based access control. All visitors have identical capabilities.

## 3. Core Entities

### Calculation
Represents a single loan calculation session with input parameters and computed results.

**Attributes:**
- `id` (UUID): Unique identifier for the calculation
- `principal` (Decimal): Loan amount borrowed
- `annual_interest_rate` (Decimal): Annual interest rate as percentage
- `loan_term_months` (Integer): Duration of loan in months
- `monthly_payment` (Decimal): Calculated monthly payment amount
- `total_interest` (Decimal): Total interest paid over loan lifetime
- `total_amount_paid` (Decimal): Principal + total interest
- `created_at` (Timestamp): When calculation was performed
- `calculation_method` (String): Fixed-rate amortization method identifier

### AmortizationScheduleEntry
Represents a single payment period in the loan's amortization schedule.

**Attributes:**
- `id` (UUID): Unique identifier
- `calculation_id` (UUID): Reference to parent calculation
- `payment_number` (Integer): Sequential payment number (1 to N)
- `payment_date` (Date): Scheduled payment date
- `beginning_balance` (Decimal): Principal balance at start of period
- `payment_amount` (Decimal): Total payment for this period
- `principal_payment` (Decimal): Portion applied to principal
- `interest_payment` (Decimal): Portion applied to interest
- `ending_balance` (Decimal): Principal balance after payment
- `cumulative_interest` (Decimal): Total interest paid to date

### CalculationInput
Represents the input parameters for validation and storage.

**Attributes:**
- `principal_amount` (Decimal): Loan amount (positive value)
- `interest_rate` (Decimal): Annual interest rate (0-100)
- `term_months` (Integer): Loan duration in months (1-360)
- `start_date` (Date): Optional first payment date

## 4. Entity Relationships

```
Calculation (1) ──────< (Many) AmortizationScheduleEntry
```

**Relationship Details:**

- **Calculation → AmortizationScheduleEntry**: One-to-Many
  - One Calculation contains multiple AmortizationScheduleEntry records
  - Number of entries equals `loan_term_months`
  - Cascade delete: If Calculation is deleted, all associated schedule entries are deleted
  - Ordered by `payment_number` ascending

- **CalculationInput → Calculation**: One-to-One
  - Input validates before creating Calculation
  - Input is transformed into Calculation entity with computed fields

## 5. Key Workflows

### Workflow 1: Perform Loan Calculation

**Actors:** Anonymous User

**Steps:**

1. User navigates to application homepage
2. System displays loan calculator form with empty/default fields:
   - Loan Amount field (default: empty or 0)
   - Annual Interest Rate field (default: empty or 0)
   - Loan Term field (default: empty or 0)
   - Term unit selector (months/years)
3. User enters loan amount (e.g., $250,000)
4. User enters annual interest rate (e.g., 4.5%)
5. User enters loan term (e.g., 30 years or 360 months)
6. System validates inputs in real-time:
   - Principal > 0
   - Interest rate >= 0 and <= 100
   - Term > 0 and <= 360 months
7. User clicks "Calculate" button (or calculation triggers automatically)
8. System performs calculations:
   - Converts annual rate to monthly rate
   - Calculates monthly payment using amortization formula
   - Generates complete amortization schedule
9. System displays results:
   - Monthly payment amount (prominent display)
   - Total interest paid
   - Total amount paid
   - Summary statistics
10. System displays amortization schedule table with all payment entries
11. User reviews results

**Alternative Flows:**
- **A1:** Invalid input detected → Display validation error inline, prevent calculation
- **A2:** User modifies input → Clear previous results, require recalculation
- **A3:** User clears form → Reset all fields to default state

### Workflow 2: View and Analyze Amortization Schedule

**Actors:** Anonymous User

**Precondition:** Loan calculation has been performed successfully

**Steps:**

1. User scrolls to amortization schedule section
2. System displays table with columns:
   - Payment # 
   - Payment Date
   - Beginning Balance
   - Payment Amount
   - Principal
   - Interest
   - Ending Balance
   - Cumulative Interest
3. User reviews payment-by-payment breakdown
4. User observes interest vs. principal distribution over time
5. User identifies specific payment milestones

**Alternative Flows:**
- **A1:** User clicks payment row → Highlight row, show detailed tooltip (optional enhancement)
- **A2:** Schedule exceeds screen height → Provide scrollable table with fixed headers

### Workflow 3: Adjust Parameters and Recalculate

**Actors:** Anonymous User

**Precondition:** Initial calculation displayed

**Steps:**

1. User modifies one or more input fields:
   - Changes loan amount, OR
   - Changes interest rate, OR
   - Changes loan term
2. System detects input change
3. System marks current results as stale (optional visual indicator)
4. User triggers recalculation (auto-calculate or button click)
5. System validates new inputs
6. System recalculates all values
7. System updates displayed results and schedule
8. User compares new results with mental note of previous values

**Alternative Flows:**
- **A1:** Auto-calculate enabled → System recalculates immediately on input change (with debouncing)
- **A2:** Invalid new input → Display error, retain previous valid calculation

## 6. Features & Requirements

### 6.1 Calculation Input Module

**FR-1.1:** Loan Amount Input
- Display labeled input field for principal amount
- Accept numeric input with decimal precision (2 decimal places)
- Support input range: $1 - $100,000,000
- Format display with currency symbol and thousand separators
- Validate minimum value (> 0)

**FR-1.2:** Interest Rate Input
- Display labeled input field for annual interest rate
- Accept numeric input with decimal precision (up to 3 decimal places)
- Support input range: 0% - 30%
- Display with percentage symbol
- Validate range (0 <= rate <= 30)

**FR-1.3:** Loan Term Input
- Display labeled input field for loan duration
- Accept integer input only
- Provide unit selector (months or years)
- If years selected, convert to months internally (years × 12)
- Support range: 1 month - 360 months (30 years)
- Validate minimum 1 month, maximum 360 months

**FR-1.4:** Input Validation
- Perform real-time validation on field blur
- Display inline error messages for invalid inputs
- Prevent calculation with invalid inputs
- Show field-level error styling (red border, error text)
- Clear errors when user corrects input

**FR-1.5:** Form Actions
- Provide "Calculate" button (primary action)
- Provide "Clear" or "Reset" button (secondary action)
- Disable Calculate button when inputs invalid
- Show loading indicator during calculation (if async)

### 6.2 Calculation Engine Module

**FR-2.1:** Monthly Payment Calculation
- Implement standard amortization formula:
  ```
  M = P × [r(1+r)^n] / [(1+r)^n - 1]
  Where:
  M = Monthly payment
  P = Principal
  r = Monthly interest rate (annual rate / 12 / 100)
  n = Number of payments (months)
  ```
- Handle edge case where interest rate = 0 (M = P / n)
- Round result to 2 decimal places

**FR-2.2:** Total Interest Calculation
- Calculate: (Monthly Payment × Number of Months) - Principal
- Round to 2 decimal places

**FR-2.3:** Total Amount Paid Calculation
- Calculate: Principal + Total Interest
- Round to 2 decimal places

**FR-2.4:** Amortization Schedule Generation
- Generate entry for each payment period (1 to N months)
- For each payment, calculate:
  - Interest payment = Beginning balance × monthly interest rate
  - Principal payment = Monthly payment - Interest payment
  - Ending balance = Beginning balance - Principal payment
  - Cumulative interest = Previous cumulative interest + Current interest payment
- Handle final payment adjustment (ensure ending balance = 0)
- Assign sequential payment numbers (1, 2, 3, ... N)

**FR-2.5:** Payment Date Calculation
- Default start date: First day of next month from current date
- Calculate subsequent payment dates by adding 1 month incrementally
- Handle month-end dates appropriately (e.g., Jan 31 → Feb 28/29)

### 6.3 Results Display Module

**FR-3.1:** Summary Results Card
- Display prominently above schedule:
  - **Monthly Payment:** Large, bold, currency formatted
  - **Total Interest Paid:** Currency formatted
  - **Total Amount Paid:** Currency formatted
  - **Loan Term:** Displayed in months and years
  - **Interest Rate:** Display as percentage

**FR-3.2:** Results Formatting
- Format all currency values: $X,XXX.XX
- Format percentages: X.XXX%
- Use consistent decimal precision (2 places for currency)
- Use visual hierarchy (size, weight, color) to emphasize key metrics

**FR-3.3:** Amortization Schedule Table
- Display data table with columns:
  1. Payment # (integer)
  2. Payment Date (MM/DD/YYYY)
  3. Beginning Balance (currency)
  4. Payment Amount (currency)
  5. Principal (currency)
  6. Interest (currency)
  7. Ending Balance (currency)
  8. Cumulative Interest (currency)
- Support scrolling for long schedules
- Fix table headers when scrolling
- Apply alternating row colors for readability
- Right-align numeric columns
- Left-align date columns

**FR-3.4:** Responsive Results Display
- Adapt table layout for mobile devices:
  - Consider card-based layout for small screens
  - Show essential columns only, expand for details
  - Maintain data readability at all viewport sizes

### 6.4 User Interface Module

**FR-4.1:** Single Page Layout
- Display all content on one page (no navigation required)
- Organize sections vertically:
  1. Header/Title
  2. Input Form
  3. Results Summary
  4. Amortization Schedule
- Use clear section dividers

**FR-4.2:** Responsive Design
- Support desktop (1920px+), tablet (768px-1024px), mobile (320px-767px)
- Use fluid layouts and breakpoints
- Ensure touch-friendly controls on mobile (min 44px tap targets)
- Optimize typography for readability across devices

**FR-4.3:** Visual Design
- Apply clean, professional visual design
- Use consistent color scheme (primary, secondary, neutral colors)
- Ensure adequate contrast for accessibility (WCAG AA minimum)
- Use clear typography hierarchy
- Apply appropriate spacing and padding

**FR-4.4:** User Feedback
- Show loading states during calculations
- Display success state when calculation completes
- Show error states with actionable messages
- Provide hover states for interactive elements
- Use smooth transitions for state changes

### 6.5 Data Persistence Module (Optional)

**FR-5.1:** Browser Storage
- Optionally save last calculation inputs to localStorage
- Restore inputs on page reload
- Clear storage on explicit user reset

**FR-5.2:** Export Functionality (Optional Enhancement)
- Provide "Export to CSV" button for schedule
- Generate CSV with all schedule columns
- Trigger browser download with filename: `loan_schedule_YYYYMMDD.csv`

**FR-5.3:** Print Functionality (Optional Enhancement)
- Provide "Print" button
- Apply print-specific CSS styling
- Include all results and schedule in print output
- Optimize page breaks for multi-page schedules

## 7. Business Rules

### BR-1: Input Constraints

**BR-1.1:** Principal Amount
- Minimum: $1.00
- Maximum: $100,000,000.00
- Must be positive number
- Required field

**BR-1.2:** Interest Rate
- Minimum: 0% (interest-free loan)
- Maximum: 30%
- Must be non-negative
- Support up to 3 decimal places (e.g., 4.875%)
- Required field

**BR-1.3:** Loan Term
- Minimum: 1 month
- Maximum: 360 months (30 years)
- Must be positive integer
- Required field

### BR-2: Calculation Rules

**BR-2.1:** Rounding Rules
- All currency values rounded to 2 decimal places
- Use standard rounding (round half up)
- Monthly payment always rounded to nearest cent

**BR-2.2:** Final Payment Adjustment
- Last payment adjusted to ensure ending balance = $0.00
- Difference between calculated and actual should be < $1.00
- Document final payment separately if different from regular payment

**BR-2.3:** Zero Interest Rate Handling
- When interest rate = 0%:
  - Monthly payment = Principal / Number of months
  - All payments go to principal
  - No interest calculated
  - Total interest = $0

**BR-2.4:** Interest Calculation Precision
- Calculate monthly interest rate as: (Annual Rate / 12 / 100)
- Use at least 6 decimal places in intermediate calculations
- Round only final display values

### BR-3: Display Rules

**BR-3.1:** Currency Formatting
- Always show dollar sign ($)
- Use comma as thousand separator
- Show exactly 2 decimal places
- Negative values shown as ($X,XXX.XX) or -$X,XXX.XX

**BR-3.2:** Date Formatting
- Default format: MM/DD/YYYY
- Start date: First day of next month from today
- Increment by exactly 1 month for each payment

**BR-3.3:** Schedule Length
- Always generate exactly N entries where N = loan term in months
- First payment number = 1
- Last payment number = N
- No gaps in sequence

### BR-4: Validation Rules

**BR-4.1:** Required Field Validation
- All three inputs must be provided
- Empty fields prevent calculation
- Show "Required" error message

**BR-4.2:** Range Validation
- Out-of-range values prevent calculation
- Show specific error: "Must be between X and Y"

**BR-4.3:** Type Validation
- Non-numeric input rejected
- Show error: "Must be a valid number"
- Loan term must be integer (no decimals)

### BR-5: Calculation Accuracy

**BR-5.1:** Standard Amortization Formula
- Use industry-standard amortization formula
- Results must match standard financial calculators
- Variance tolerance: ±$0.01 on monthly payment

**BR-5.2:** Schedule Balance Verification
- Sum of all principal payments must equal original principal (±$0.01)
- Final ending balance must equal $0.00 (±$0.01)
- Sum of all interest payments must equal total interest calculated (±$0.01)

## 8. Non-Functional Requirements

### 8.1 Performance

**NFR-1.1:** Calculation Speed
- Loan calculation must complete in < 100ms for any valid input
- Schedule generation must complete in < 500ms for 360-month term
- Page load time < 2 seconds on standard broadband connection

**NFR-1.2:** UI Responsiveness
- Input field updates must reflect within 16ms (60fps)
- Form validation feedback must appear within 100ms
- Auto-calculate debounce delay: 300-500ms after last input

**NFR-1.3:** Rendering Performance
- Large amortization tables (360 rows) must render without UI blocking
- Consider virtualization for tables > 100 rows
- Smooth scrolling maintained even with large datasets

### 8.2 Security

**NFR-2.1:** Data Privacy
- No personally identifiable information (PII) collected
- No authentication or user accounts required
- No calculation data transmitted to backend servers
- All calculations performed client-side in browser

**NFR-2.2:** Input Sanitization
- Sanitize all user inputs to prevent XSS attacks
- Validate data types before processing
- Escape special characters in any displayed user input

**NFR-2.3:** HTTPS
- Application must be served over HTTPS
- Enforce secure connection at domain level
- Include security headers (CSP, X-Frame-Options, etc.)

### 8.3 Scalability

**NFR-3.1:** Client-Side Processing
- All calculations performed in browser (no backend required)
- No server-side computation load
- Stateless architecture

**NFR-3.2:** Memory Management
- Calculation results not stored beyond session
- Clear previous calculations when new calculation performed
- No memory leaks from repeated calculations

**NFR-3.3:** Concurrent Users
- Application supports unlimited concurrent users
- Each user session completely independent
- No shared state between sessions

### 8.4 Availability

**NFR-4.1:** Uptime
- Target availability: 99.9% uptime
- Static hosting with CDN distribution
- No backend dependencies that could fail

**NFR-4.2:** Offline Capability (Optional)
- Consider Progressive Web App (PWA) implementation
- Allow calculations to work offline after initial load
- Cache static assets using service worker

### 8.5 Accessibility

**NFR-5.1:** WCAG Compliance
- Meet WCAG 2.1 Level AA standards minimum
- All interactive elements keyboard accessible
- Logical tab order through form fields
- Focus indicators visible on all focusable elements

**NFR-5.2:** Screen Reader Support
- All form inputs have associated labels
- Error messages announced to screen readers
- Results announced when calculation completes
- ARIA labels and landmarks used appropriately

**NFR-5.3:** Visual Accessibility
- Color contrast ratio ≥ 4.5:1 for normal text
- Color contrast ratio ≥ 3:1 for large text
- Information not conveyed by color alone
- Text resizable up to 200% without loss of functionality

### 8.6 Compatibility

**NFR-6.1:** Browser Support
- Chrome (last 2 versions)
- Firefox (last 2 versions)
- Safari (last 2 versions)
- Edge (last 2 versions)
- Mobile browsers: iOS Safari, Chrome Mobile

**NFR-6.2:** Device Support
- Desktop: Windows, macOS, Linux
- Mobile: iOS 13+, Android 8+
- Tablet: iPad, Android tablets

**NFR-6.3:** Screen Size Support
- Minimum supported width: 320px (iPhone SE)
- Maximum optimized width: 1920px
- Responsive breakpoints: 768px, 1024px, 1440px

### 8.7 Usability

**NFR-7.1:** Learning Curve
- First-time users should successfully calculate loan within 30 seconds
- No tutorial or documentation required for basic use
- Intuitive labels and placeholders guide user

**NFR-7.2:** Error Recovery
- Clear error messages explain what's wrong and how to fix
- Invalid inputs easily correctable without page reload
- Undo/clear functionality available

**NFR-7.3:** Efficiency
- Repeat calculations require only changing relevant fields
- Previous inputs retained until explicitly cleared
- Auto-calculate option reduces clicks required

### 8.8 Maintainability

**NFR-8.1:** Code Quality
- Clean, well-documented code
- Separation of concerns (UI, business logic, calculations)
- Reusable components and functions
- Unit tests for calculation engine (90%+ coverage)

**NFR-8.2:** Calculation Transparency
- Calculation formulas documented in code comments
- Intermediate values logged for debugging (dev mode)
- Easy to audit and verify accuracy

**NFR-8.3:** Extensibility
- Architecture allows adding new calculation types
- Support for future features (charts, comparisons, export)
- Modular design enables feature additions without refactoring

### 8.9 Internationalization (Future Consideration)

**NFR-9.1:** Localization Readiness
- Code structured to support multiple languages
- Number and currency formatting adaptable to locale
- Date formatting respects locale conventions

---

## Appendix A: Calculation Formula Reference

### Standard Amortization Formula

```
Monthly Payment = P × [r(1+r)^n] / [(1+r)^n - 1]

Where:
P = Principal (loan amount)
r = Monthly interest rate (annual rate / 12 / 100)
n = Number of monthly payments

Example:
P = $250,000
Annual Rate = 4.5%
n = 360 months (30 years)

r = 4.5 / 12 / 100 = 0.00375
Monthly Payment = 250,000 × [0.00375(1.00375)^360] / [(1.00375)^360 - 1]
Monthly Payment = $1,266.71
```

### Amortization Schedule Formula (Per Payment)

```
Interest Payment = Beginning Balance × Monthly Interest Rate
Principal Payment = Monthly Payment - Interest Payment
Ending Balance = Beginning Balance - Principal Payment
```

---

## Appendix B: Validation Error Messages

| Validation Rule | Error Message |
|----------------|---------------|
| Empty principal | "Loan amount is required" |
| Principal ≤ 0 | "Loan amount must be greater than $0" |
| Principal > $100M | "Loan amount cannot exceed $100,000,000" |
| Empty interest rate | "Interest rate is required" |
| Interest rate < 0 | "Interest rate cannot be negative" |
| Interest rate > 30 | "Interest rate cannot exceed 30%" |
| Empty loan term | "Loan term is required" |
| Loan term < 1 | "Loan term must be at least 1 month" |
| Loan term > 360 | "Loan term cannot exceed 360 months (30 years)" |
| Non-numeric input | "Please enter a valid number" |
| Invalid decimal | "Invalid number format" |

---

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