# Product Requirements Document: Loan Calculator

**Version:** 1.0  
**Domain:** https://anil.dev.dalfin.ai  
**Date:** 2025  

---

## 1. Overview

The Loan Calculator is a single-page web application that enables users to quickly calculate loan payment details based on principal amount, interest rate, and loan term. Users can input loan parameters and instantly view monthly payment amounts, total interest paid, and total payment over the life of the loan. The application provides a simple, intuitive interface for personal loan planning and financial decision-making.

---

## 2. User Roles

### 2.1 Anonymous User (Visitor)
- Can access the loan calculator interface without authentication
- Can input loan parameters (principal, interest rate, term)
- Can view calculated results (monthly payment, total interest, total payment)
- Can adjust inputs and recalculate in real-time
- Can reset the calculator to default values

---

## 3. Core Entities

### 3.1 LoanCalculation
A calculation session containing input parameters and computed results for a loan scenario.

**Attributes:**
- `id` (UUID): Unique identifier for the calculation
- `principal` (Decimal): The initial loan amount borrowed
- `annualInterestRate` (Decimal): The yearly interest rate as a percentage
- `loanTermMonths` (Integer): The duration of the loan in months
- `monthlyPayment` (Decimal): Calculated monthly payment amount
- `totalPayment` (Decimal): Calculated total amount paid over loan term
- `totalInterest` (Decimal): Calculated total interest paid over loan term
- `createdAt` (DateTime): Timestamp when calculation was performed
- `sessionId` (String): Browser session identifier for tracking user calculations

### 3.2 AmortizationScheduleEntry
Individual payment breakdown for each period of the loan term.

**Attributes:**
- `id` (UUID): Unique identifier for the entry
- `calculationId` (UUID): Reference to parent LoanCalculation
- `paymentNumber` (Integer): Sequential payment number (1 to N)
- `paymentDate` (Date): Scheduled payment date
- `beginningBalance` (Decimal): Loan balance at start of period
- `paymentAmount` (Decimal): Total payment for this period
- `principalPortion` (Decimal): Amount applied to principal
- `interestPortion` (Decimal): Amount applied to interest
- `endingBalance` (Decimal): Loan balance at end of period

### 3.3 CalculatorDefaults
System-wide default values and constraints for the calculator.

**Attributes:**
- `id` (UUID): Unique identifier
- `defaultPrincipal` (Decimal): Default loan amount
- `defaultInterestRate` (Decimal): Default annual interest rate
- `defaultTermMonths` (Integer): Default loan term
- `minPrincipal` (Decimal): Minimum allowed principal amount
- `maxPrincipal` (Decimal): Maximum allowed principal amount
- `minInterestRate` (Decimal): Minimum allowed interest rate
- `maxInterestRate` (Decimal): Maximum allowed interest rate
- `minTermMonths` (Integer): Minimum allowed term length
- `maxTermMonths` (Integer): Maximum allowed term length
- `updatedAt` (DateTime): Last update timestamp

---

## 4. Entity Relationships

### 4.1 LoanCalculation → AmortizationScheduleEntry
- **Relationship Type:** One-to-Many
- **Description:** One LoanCalculation can have multiple AmortizationScheduleEntry records (one per payment period)
- **Cardinality:** 1 LoanCalculation : N AmortizationScheduleEntry (where N = loanTermMonths)
- **Cascade Behavior:** Deleting a LoanCalculation deletes all associated AmortizationScheduleEntry records

### 4.2 CalculatorDefaults (Singleton)
- **Relationship Type:** Standalone
- **Description:** Single configuration entity that applies globally across all calculations
- **Cardinality:** 1 record only

---

## 5. Key Workflows

### 5.1 Loan Calculation Workflow

**Actor:** Anonymous User

**Steps:**
1. User lands on the loan calculator page
2. System loads CalculatorDefaults and populates form with default values
3. User enters/modifies loan parameters:
   - Principal amount
   - Annual interest rate (%)
   - Loan term (months or years with conversion)
4. System validates inputs against min/max constraints
5. User triggers calculation (auto-calculate on input change OR explicit "Calculate" button)
6. System performs calculation:
   - Calculate monthly interest rate: `monthlyRate = annualRate / 12 / 100`
   - Calculate monthly payment using formula: `M = P * [r(1+r)^n] / [(1+r)^n - 1]`
     - Where: M = monthly payment, P = principal, r = monthly interest rate, n = number of payments
   - Calculate total payment: `totalPayment = monthlyPayment * loanTermMonths`
   - Calculate total interest: `totalInterest = totalPayment - principal`
7. System creates LoanCalculation record in database (optional persistence)
8. System displays results to user:
   - Monthly payment amount
   - Total interest paid
   - Total amount paid
9. System generates AmortizationScheduleEntry records (if user requests detailed schedule)
10. User can adjust inputs and repeat calculation

### 5.2 Amortization Schedule Generation Workflow

**Actor:** Anonymous User

**Precondition:** Valid LoanCalculation exists

**Steps:**
1. User clicks "Show Amortization Schedule" or similar trigger
2. System retrieves LoanCalculation parameters
3. System iterates through each payment period (1 to N months):
   - For each period i:
     - Calculate interest for period: `interestPortion = beginningBalance * monthlyInterestRate`
     - Calculate principal for period: `principalPortion = monthlyPayment - interestPortion`
     - Calculate ending balance: `endingBalance = beginningBalance - principalPortion`
     - Create AmortizationScheduleEntry record
     - Set next period's beginningBalance = current endingBalance
4. System displays amortization schedule table with all entries
5. User can view payment breakdown by period
6. User can download/print schedule (optional)

### 5.3 Reset Calculator Workflow

**Actor:** Anonymous User

**Steps:**
1. User clicks "Reset" or "Clear" button
2. System retrieves CalculatorDefaults
3. System resets all input fields to default values
4. System clears displayed results
5. Calculator returns to initial state

---

## 6. Features & Requirements

### 6.1 Loan Input Module

**FR-1.1:** Display input form with the following fields:
- Principal Amount (currency input)
- Annual Interest Rate (percentage input)
- Loan Term with unit selector (months/years)

**FR-1.2:** Support multiple term input formats:
- Months (direct input)
- Years (auto-convert to months: years * 12)

**FR-1.3:** Provide inline input validation with error messages:
- Principal: numeric, within min/max range
- Interest rate: numeric, within min/max range, supports 2 decimal places
- Term: positive integer, within min/max range

**FR-1.4:** Display currency formatting for principal input (e.g., $10,000.00)

**FR-1.5:** Support keyboard navigation and form submission via Enter key

**FR-1.6:** Provide "Reset" button to restore default values

### 6.2 Calculation Engine Module

**FR-2.1:** Implement standard amortizing loan payment formula:
```
M = P * [r(1+r)^n] / [(1+r)^n - 1]
```

**FR-2.2:** Handle edge case where interest rate = 0:
```
M = P / n
```

**FR-2.3:** Calculate derived values:
- Total Payment = Monthly Payment × Number of Months
- Total Interest = Total Payment - Principal

**FR-2.4:** Perform calculations with precision to 2 decimal places for currency

**FR-2.5:** Support real-time calculation (on input change) OR manual calculation trigger

**FR-2.6:** Store calculation history in session (optional persistence)

### 6.3 Results Display Module

**FR-3.1:** Display primary results prominently:
- Monthly Payment Amount (emphasized, large font)
- Total Interest Paid
- Total Amount Paid

**FR-3.2:** Format all currency values consistently (e.g., $1,234.56)

**FR-3.3:** Display percentage values consistently (e.g., 5.75%)

**FR-3.4:** Show calculation summary with input parameters for reference

**FR-3.5:** Provide visual breakdown of principal vs. interest (optional chart/graph)

### 6.4 Amortization Schedule Module

**FR-4.1:** Provide "Show Details" or "Amortization Schedule" toggle/button

**FR-4.2:** Display amortization schedule table with columns:
- Payment Number (#)
- Payment Date
- Payment Amount
- Principal Portion
- Interest Portion
- Remaining Balance

**FR-4.3:** Calculate payment dates based on:
- Start date (current date OR user-specified)
- Monthly intervals

**FR-4.4:** Support collapsible/expandable schedule view to save space

**FR-4.5:** Provide export functionality:
- Download as CSV
- Print view (optional)

**FR-4.6:** Highlight key milestones (e.g., when principal > interest)

### 6.5 User Interface Module

**FR-5.1:** Implement responsive single-page design:
- Mobile-friendly (320px minimum width)
- Tablet optimized
- Desktop optimized

**FR-5.2:** Use clear, readable typography and sufficient contrast

**FR-5.3:** Provide loading indicators during calculation (if async)

**FR-5.4:** Display helpful tooltips/info icons for technical terms

**FR-5.5:** Implement accessible form labels and ARIA attributes

**FR-5.6:** Support light/dark mode (optional)

### 6.6 Configuration Module (Admin)

**FR-6.1:** Provide administrative interface to update CalculatorDefaults (optional):
- Default values for inputs
- Min/max constraints
- Display formatting preferences

**FR-6.2:** Store configuration in database or configuration file

**FR-6.3:** Apply configuration changes without application restart

---

## 7. Business Rules

### 7.1 Input Validation Rules

**BR-1.1:** Principal amount must be:
- Minimum: $1,000
- Maximum: $10,000,000
- Positive numeric value
- Up to 2 decimal places

**BR-1.2:** Annual interest rate must be:
- Minimum: 0%
- Maximum: 50%
- Non-negative numeric value
- Up to 4 decimal places (e.g., 5.7500%)

**BR-1.3:** Loan term must be:
- Minimum: 1 month
- Maximum: 600 months (50 years)
- Positive integer value

**BR-1.4:** All required fields must be populated before calculation

### 7.2 Calculation Rules

**BR-2.1:** Monthly interest rate calculation:
```
monthlyRate = (annualRate / 100) / 12
```

**BR-2.2:** Number of payments equals loan term in months

**BR-2.3:** All currency calculations rounded to 2 decimal places

**BR-2.4:** Final payment may differ slightly to account for rounding (adjust final payment to zero out balance)

**BR-2.5:** Amortization schedule must completely amortize loan (ending balance = $0)

### 7.3 Display Rules

**BR-3.1:** Currency values displayed with currency symbol and 2 decimal places

**BR-3.2:** Percentage values displayed with % symbol and 2 decimal places

**BR-3.3:** Large numbers formatted with thousands separators (e.g., 1,000,000)

**BR-3.4:** Negative values not allowed in any calculation result

### 7.4 Data Persistence Rules

**BR-4.1:** Calculation history stored per session (session storage)

**BR-4.2:** No personal data collected without user consent

**BR-4.3:** Optional: Store anonymous calculation statistics for analytics

**BR-4.4:** Amortization schedules generated on-demand (not pre-stored)

---

## 8. Non-Functional Requirements

### 8.1 Performance

**NFR-1.1:** Calculation completion time < 100ms for standard loans (< 360 months)

**NFR-1.2:** Calculation completion time < 500ms for extended loans (up to 600 months)

**NFR-1.3:** Page load time < 2 seconds on 3G connection

**NFR-1.4:** Amortization schedule generation < 1 second for any valid loan term

**NFR-1.5:** Support at least 100 concurrent users without performance degradation

### 8.2 Security

**NFR-2.1:** Implement HTTPS for all communications (SSL/TLS)

**NFR-2.2:** Sanitize all user inputs to prevent XSS attacks

**NFR-2.3:** Implement rate limiting to prevent abuse (e.g., 100 calculations per IP per hour)

**NFR-2.4:** No storage of sensitive financial information

**NFR-2.5:** Implement Content Security Policy (CSP) headers

**NFR-2.6:** Regular security dependency updates

### 8.3 Scalability

**NFR-3.1:** Stateless calculation engine to support horizontal scaling

**NFR-3.2:** Database design supports indexing for query optimization (if persistence enabled)

**NFR-3.3:** Caching strategy for CalculatorDefaults to reduce database load

**NFR-3.4:** CDN integration for static assets

### 8.4 Availability

**NFR-4.1:** Target uptime: 99.5% monthly

**NFR-4.2:** Graceful error handling with user-friendly messages

**NFR-4.3:** Fallback mechanism if calculation service unavailable (client-side calculation)

### 8.5 Usability

**NFR-5.1:** Intuitive interface requiring no training or documentation

**NFR-5.2:** Form validation feedback within 200ms of user input

**NFR-5.3:** WCAG 2.1 Level AA accessibility compliance

**NFR-5.4:** Support for screen readers and keyboard-only navigation

**NFR-5.5:** Multi-language support (optional: English, Spanish, French)

### 8.6 Compatibility

**NFR-6.1:** Browser support:
- Chrome (last 2 versions)
- Firefox (last 2 versions)
- Safari (last 2 versions)
- Edge (last 2 versions)

**NFR-6.2:** Mobile browser support:
- iOS Safari (last 2 versions)
- Chrome Mobile (last 2 versions)

**NFR-6.3:** Responsive design breakpoints:
- Mobile: 320px - 767px
- Tablet: 768px - 1023px
- Desktop: 1024px+

### 8.7 Maintainability

**NFR-7.1:** Modular code architecture for easy updates

**NFR-7.2:** Comprehensive unit test coverage (>80%)

**NFR-7.3:** API documentation for calculation endpoints

**NFR-7.4:** Logging of errors and system events

**NFR-7.5:** Configuration-driven defaults (no hard-coded values)

### 8.8 Compliance

**NFR-8.1:** GDPR compliance for data handling (if applicable)

**NFR-8.2:** Cookie consent implementation (if tracking enabled)

**NFR-8.3:** Privacy policy and terms of service links

**NFR-8.4:** Disclaimer that calculations are estimates for informational purposes

---

## Appendix A: Calculation Formula Reference

### Monthly Payment Formula (Amortizing Loan)
```
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 = Total number of payments (months)
```

### Special Case: Zero Interest Rate
```
M = P / n
```

### Amortization Schedule Formulas
```
For each payment period i:
Interest Portion = Beginning Balance × Monthly Interest Rate
Principal Portion = Monthly Payment - Interest Portion
Ending Balance = Beginning Balance - Principal Portion
```

---

## Appendix B: Default Configuration Values

| Parameter | Default Value |
|-----------|---------------|
| Default Principal | $250,000 |
| Default Interest Rate | 6.5% |
| Default Term | 360 months (30 years) |
| Min Principal | $1,000 |
| Max Principal | $10,000,000 |
| Min Interest Rate | 0% |
| Max Interest Rate | 50% |
| Min Term | 1 month |
| Max Term | 600 months |

---

**Document End**