# Product Requirements Document: Simple Loan Calculator

## 1. Overview

The Simple Loan Calculator is a single-page web application that enables users to calculate loan payments and view amortization schedules. Users input loan parameters (principal amount, interest rate, loan term) and receive instant calculations showing monthly payments, total interest paid, and a detailed payment breakdown over the life of the loan. The application provides a clean, intuitive interface for quickly evaluating different loan scenarios without requiring user authentication or data persistence.

## 2. User Roles

### Anonymous User (Default)
- Access the loan calculator interface without registration or login
- Input loan parameters (principal, interest rate, term)
- View calculated monthly payment amount
- View total amount paid over loan lifetime
- View total interest paid
- View detailed amortization schedule
- Adjust calculation parameters and recalculate in real-time
- Print or export amortization schedule (optional)

## 3. Core Entities

### LoanCalculation
Represents a single loan calculation instance with all input parameters and computed results.

**Attributes:**
- `calculationId` (string, UUID): Unique identifier for the calculation session
- `principalAmount` (decimal): The initial loan amount borrowed
- `annualInterestRate` (decimal): The yearly interest rate as a percentage
- `loanTermMonths` (integer): The duration of the loan in months
- `loanTermYears` (integer): The duration of the loan in years (alternative input)
- `monthlyPayment` (decimal, calculated): The fixed monthly payment amount
- `totalAmountPaid` (decimal, calculated): Total amount paid over loan lifetime
- `totalInterestPaid` (decimal, calculated): Total interest paid over loan lifetime
- `createdAt` (timestamp): When the calculation was performed

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

**Attributes:**
- `entryId` (string, UUID): Unique identifier for the schedule entry
- `calculationId` (string, foreign key): Reference to parent calculation
- `paymentNumber` (integer): Sequential payment number (1 to N)
- `paymentDate` (date, calculated): Scheduled payment date
- `paymentAmount` (decimal): Total payment amount for this period
- `principalPortion` (decimal): Amount applied to principal
- `interestPortion` (decimal): Amount applied to interest
- `remainingBalance` (decimal): Outstanding principal after this payment
- `cumulativeInterest` (decimal): Total interest paid up to this point
- `cumulativePrincipal` (decimal): Total principal paid up to this point

## 4. Entity Relationships

### LoanCalculation ← AmortizationScheduleEntry (One-to-Many)
- One `LoanCalculation` has many `AmortizationScheduleEntry` records (equal to `loanTermMonths`)
- Each `AmortizationScheduleEntry` belongs to exactly one `LoanCalculation`
- Relationship: `LoanCalculation.calculationId` → `AmortizationScheduleEntry.calculationId`
- Cascade behavior: When a calculation is cleared/reset, all associated schedule entries are removed

## 5. Key Workflows

### Workflow 1: Perform Loan Calculation

**Actors:** Anonymous User

**Steps:**
1. User navigates to the application homepage
2. System displays loan calculator form with empty/default input fields
3. User enters principal amount (e.g., $250,000)
4. User enters annual interest rate (e.g., 6.5%)
5. User enters loan term (either months or years)
6. User clicks "Calculate" button or system auto-calculates on input change
7. System validates all inputs (see Business Rules)
8. System calculates monthly payment using amortization formula: `M = P[r(1+r)^n]/[(1+r)^n-1]` where:
   - M = Monthly payment
   - P = Principal amount
   - r = Monthly interest rate (annual rate / 12 / 100)
   - n = Number of payments
9. System calculates total amount paid (`monthlyPayment × loanTermMonths`)
10. System calculates total interest paid (`totalAmountPaid - principalAmount`)
11. System generates amortization schedule for each payment period
12. System displays results summary (monthly payment, total paid, total interest)
13. System displays full amortization schedule table
14. User can modify inputs and recalculate (return to step 3)

### Workflow 2: View Amortization Schedule Details

**Actors:** Anonymous User

**Prerequisites:** Loan calculation has been performed

**Steps:**
1. User views the results summary section
2. System displays amortization schedule table with columns:
   - Payment Number
   - Payment Date (optional, calculated from start date)
   - Payment Amount
   - Principal Paid
   - Interest Paid
   - Remaining Balance
3. User scrolls through the schedule to view all payment periods
4. User can sort or filter schedule entries (optional enhancement)
5. User can optionally download/print the schedule

### Workflow 3: Reset Calculator

**Actors:** Anonymous User

**Steps:**
1. User clicks "Reset" or "Clear" button
2. System clears all input fields to default values
3. System clears all calculated results
4. System clears amortization schedule display
5. User can begin a new calculation

## 6. Features & Requirements

### Module: Loan Input Form

**FR-1.1: Principal Amount Input**
- Provide numeric input field for loan principal amount
- Support decimal values
- Display currency symbol ($) or allow currency selection
- Accept values from $1 to $100,000,000
- Format display with thousand separators (e.g., 250,000.00)

**FR-1.2: Interest Rate Input**
- Provide numeric input field for annual interest rate
- Support decimal values (e.g., 6.75)
- Display percentage symbol (%)
- Accept values from 0.01% to 99.99%
- Format to 2-4 decimal places

**FR-1.3: Loan Term Input**
- Provide numeric input field for loan term
- Support input in EITHER years OR months
- Provide toggle/dropdown to switch between years and months
- Accept values from 1 month to 50 years (600 months)
- Auto-convert between years and months when unit is changed

**FR-1.4: Calculate Button**
- Provide prominent "Calculate" button
- Enable button only when all required fields are valid
- Trigger calculation on button click
- Optional: Support real-time calculation on input change
- Show loading indicator during calculation (if needed)

**FR-1.5: Reset/Clear Button**
- Provide "Reset" or "Clear" button
- Clear all input fields to default/empty state
- Clear all calculation results
- Clear amortization schedule

**FR-1.6: Input Validation & Error Display**
- Validate all inputs in real-time
- Display field-level error messages for invalid inputs
- Highlight invalid fields with visual indicators
- Prevent calculation until all fields are valid

### Module: Calculation Results Display

**FR-2.1: Monthly Payment Display**
- Display calculated monthly payment amount prominently
- Format as currency with 2 decimal places
- Label clearly as "Monthly Payment"
- Update immediately after calculation

**FR-2.2: Total Amount Paid Display**
- Display total amount to be paid over loan lifetime
- Format as currency with 2 decimal places
- Label as "Total Amount Paid" or "Total Cost"
- Show calculation: (Monthly Payment × Number of Payments)

**FR-2.3: Total Interest Paid Display**
- Display total interest to be paid over loan lifetime
- Format as currency with 2 decimal places
- Label as "Total Interest Paid"
- Show calculation: (Total Amount Paid - Principal)
- Optionally show percentage of principal (e.g., "42% of loan amount")

**FR-2.4: Summary Card/Section**
- Group all key results in a visually distinct summary section
- Use clear typography hierarchy
- Highlight monthly payment as primary metric
- Show loan parameters used for calculation

### Module: Amortization Schedule Display

**FR-3.1: Schedule Table Generation**
- Generate complete amortization schedule with one row per payment period
- Number of rows equals loan term in months
- Calculate each row based on loan amortization formula
- Ensure final payment results in $0.00 remaining balance

**FR-3.2: Schedule Table Columns**
- **Payment #**: Sequential number (1, 2, 3, ... N)
- **Payment Amount**: Fixed monthly payment (same for all periods except possibly last)
- **Principal**: Portion of payment applied to principal
- **Interest**: Portion of payment applied to interest
- **Remaining Balance**: Outstanding principal after payment
- Optional: **Payment Date** (if start date provided)
- Optional: **Cumulative Interest** (total interest paid to date)

**FR-3.3: Schedule Table Formatting**
- Format all currency values with $ symbol and 2 decimal places
- Use alternating row colors for readability
- Make table responsive for mobile devices
- Support horizontal scrolling on small screens if needed
- Show column headers with clear labels

**FR-3.4: Schedule Table Navigation**
- Display full schedule (all payments visible with scroll)
- OR implement pagination (e.g., 12 payments per page)
- Option to "Expand All" or "Collapse" schedule
- Optionally group by year with subtotals

**FR-3.5: Schedule Export/Print**
- Provide "Export" button to download schedule as CSV or PDF
- Provide "Print" button to print-friendly view
- Include all loan parameters in exported document
- Include calculation summary in exported document

### Module: User Interface & Experience

**FR-4.1: Single Page Layout**
- Display all functionality on a single page (no navigation required)
- Organize content into logical sections: Input → Results → Schedule
- Use clear visual hierarchy and spacing
- Maintain focus on core calculator functionality

**FR-4.2: Responsive Design**
- Support desktop, tablet, and mobile viewports
- Adapt layout for screen sizes from 320px to 2560px width
- Stack sections vertically on mobile devices
- Ensure touch-friendly input controls on mobile

**FR-4.3: Visual Design**
- Implement clean, modern UI design
- Use consistent color scheme and typography
- Provide sufficient contrast for accessibility
- Use whitespace effectively to reduce cognitive load

**FR-4.4: Interactive Feedback**
- Provide visual feedback for button clicks and interactions
- Show hover states for interactive elements
- Display loading states for calculations (if applicable)
- Use smooth transitions for content updates

**FR-4.5: Help & Guidance**
- Provide brief instructions or help text for inputs
- Include tooltips or info icons explaining terms (e.g., "What is APR?")
- Show example values or placeholders in input fields
- Optionally provide "Sample Calculation" preset button

## 7. Business Rules

### Input Validation Rules

**BR-1.1: Principal Amount Validation**
- MUST be a positive number greater than 0
- MUST be less than or equal to $100,000,000
- MUST accept decimal values (e.g., 250000.50)
- SHOULD default to empty or suggested value (e.g., $250,000)

**BR-1.2: Interest Rate Validation**
- MUST be a positive number greater than 0
- MUST be less than or equal to 99.99%
- MUST accept decimal values to at least 2 decimal places
- MAY accept up to 4 decimal places for precision (e.g., 6.7525%)
- SHOULD default to empty or market-average rate

**BR-1.3: Loan Term Validation**
- MUST be a positive integer greater than 0
- When in months: MUST be between 1 and 600 months
- When in years: MUST be between 1 and 50 years (converted to months)
- MUST convert accurately between months and years (years × 12 = months)

### Calculation Rules

**BR-2.1: Monthly Payment Calculation**
- MUST use standard amortization formula: `M = P[r(1+r)^n]/[(1+r)^n-1]`
- Monthly interest rate (r) = Annual Interest Rate / 12 / 100
- Number of payments (n) = Loan Term in Months
- MUST round result to 2 decimal places
- MUST handle edge case where interest rate = 0% (simple division: P / n)

**BR-2.2: Amortization Schedule Generation**
- MUST generate exactly N entries where N = loan term in months
- For each payment period:
  - Interest portion = Remaining Balance × Monthly Interest Rate
  - Principal portion = Monthly Payment - Interest Portion
  - New Balance = Previous Balance - Principal Portion
- Final payment MAY differ slightly to account for rounding and bring balance to exactly $0.00
- MUST ensure final remaining balance equals $0.00 (within $0.01 tolerance)

**BR-2.3: Rounding and Precision**
- ALL currency values MUST be rounded to 2 decimal places for display
- Internal calculations SHOULD use higher precision (e.g., 6 decimal places) to minimize compounding rounding errors
- Final balance MUST be adjusted in last payment if rounding causes minor discrepancy

### Display Rules

**BR-3.1: Result Visibility**
- Results section MUST NOT be visible until calculation is performed
- Amortization schedule MUST NOT be displayed until calculation is performed
- All results MUST update whenever inputs change and recalculation occurs

**BR-3.2: Currency Formatting**
- All currency values MUST display with $ symbol (or selected currency)
- All currency values MUST use thousand separators (e.g., $250,000.00)
- All currency values MUST show exactly 2 decimal places

**BR-3.3: Percentage Formatting**
- Interest rates MUST display with % symbol
- Percentage values MUST show 2-4 decimal places as appropriate

## 8. Non-Functional Requirements

### Performance

**NFR-1.1: Calculation Speed**
- Loan calculation MUST complete within 100ms for loans up to 50 years
- Amortization schedule generation MUST complete within 500ms for up to 600 payment periods
- Page load time MUST be under 2 seconds on standard broadband connection
- UI MUST remain responsive during calculations (no blocking)

**NFR-1.2: Client-Side Processing**
- ALL calculations MUST be performed client-side (JavaScript)
- NO backend API calls required for calculation logic
- Application MUST function without internet connection after initial load

### Security

**NFR-2.1: Data Privacy**
- NO user data is collected or stored on servers
- NO authentication or user accounts required
- All calculations performed locally in browser
- NO personally identifiable information (PII) collected

**NFR-2.2: Input Sanitization**
- ALL user inputs MUST be sanitized to prevent XSS attacks
- Validate input types (numeric only for amount/rate/term fields)
- Reject non-numeric characters except decimal point

### Scalability

**NFR-3.1: Browser Compatibility**
- MUST support latest versions of Chrome, Firefox, Safari, Edge
- MUST support browsers released within past 2 years
- SHOULD gracefully degrade on older browsers with warning message

**NFR-3.2: Concurrent Users**
- Application MUST support unlimited concurrent users (static hosting)
- No server-side session management required
- Each user operates independently in their own browser context

### Accessibility

**NFR-4.1: WCAG Compliance**
- MUST meet WCAG 2.1 Level AA standards
- All form inputs MUST have associated labels
- All interactive elements MUST be keyboard accessible
- Color contrast ratios MUST meet WCAG AA requirements (4.5:1 for normal text)

**NFR-4.2: Screen Reader Support**
- All content MUST be accessible via screen readers
- ARIA labels MUST be provided for dynamic content updates
- Error messages MUST be announced to screen readers
- Calculation results MUST be announced when updated

**NFR-4.3: Keyboard Navigation**
- All functionality MUST be accessible via keyboard only
- Tab order MUST follow logical flow
- Focus indicators MUST be visible
- Enter key MUST trigger calculation from any input field

### Usability

**NFR-5.1: User Experience**
- First-time users MUST be able to perform calculation within 30 seconds without instructions
- Form inputs MUST provide immediate validation feedback
- Error messages MUST be clear and actionable
- UI MUST be intuitive and self-explanatory

**NFR-5.2: Mobile Experience**
- Touch targets MUST be at least 44×44 pixels
- Form inputs MUST trigger appropriate mobile keyboards (numeric for number fields)
- Scrolling MUST be smooth and predictable
- Pinch-to-zoom MUST be enabled

### Maintainability

**NFR-6.1: Code Quality**
- Code MUST be modular and well-documented
- Calculation logic MUST be separate from UI logic
- MUST use modern JavaScript (ES6+)
- SHOULD use a modern framework (React, Vue, or Svelte)

**NFR-6.2: Testing**
- Unit tests MUST cover all calculation functions
- Test cases MUST validate edge cases (0% interest, 1 month term, max values)
- Tests MUST verify rounding accuracy
- Visual regression tests SHOULD be implemented

### Deployment

**NFR-7.1: Hosting**
- Application MUST be deployable as static files
- MUST be hostable on standard web servers or CDN
- No server-side runtime required
- MUST be accessible at https://freemeal.dev.dalfin.ai

**NFR-7.2: Browser Storage**
- MAY use localStorage to persist last calculation (optional enhancement)
- MUST function correctly if localStorage is disabled
- MUST NOT depend on cookies

---

## Appendix: Calculation Formulas

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

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

Special case: If r = 0, then M = P / n
```

### Amortization Schedule Formulas (per payment period)
```
Interest Payment = Remaining Balance × Monthly Interest Rate
Principal Payment = Monthly Payment - Interest Payment
New Remaining Balance = Previous Remaining Balance - Principal Payment
```

### Summary Calculations
```
Total Amount Paid = Monthly Payment × Number of Payments
Total Interest Paid = Total Amount Paid - Principal
```

---

**Document Version:** 1.0  
**Last Updated:** 2025-01-17  
**Document Owner:** Product Management  
**Status:** Ready for Development