# Backend Specification

## 1. System Summary

**System Name:** Loan Calculator

**Description:** A single-page web application that calculates loan payment details including monthly payment, total interest, and amortization schedules based on principal, interest rate, and term. The system provides loan calculation capabilities for anonymous users with configurable defaults and validation constraints. It supports storing calculation history, generating detailed amortization schedules, and retrieving past calculations by session.

**Key Capabilities:**
- Calculate monthly payments using standard amortization formulas
- Generate detailed amortization schedules showing principal and interest breakdown per payment
- Store calculation history for session tracking
- Configure system-wide defaults and validation constraints
- Support interest rates from 0% to 50% including zero-interest scenarios

## 2. Source Input Summary

This backend specification is generated from the following source materials:

- **DDL Schema:** `/home/ubuntu/dpg/pipeline/step-02-prd-generation/output/simple_loa_042319/schema.sql`
  - Contains three tables: `calculator_defaults`, `loan_calculations`, `amortization_schedule_entries`
  - Defines data types, constraints, and relationships
  
- **Product Requirements Document:** `/home/ubuntu/dpg/pipeline/step-02-prd-generation/output/simple_loa_042319/full_prd.md`
  - Comprehensive description of loan calculation workflows
  - Business rules and validation constraints
  - User interface and interaction patterns
  - Calculation formulas and algorithms

- **Prompt:** Provided configuration and generation instructions

- **Images:** Not provided

## 3. Generation Mode

**Mode:** `strict`

This specification is generated in strict mode, meaning the backend implementation must adhere precisely to the entities, fields, relationships, and business rules defined in the source materials. No additional entities, fields, or endpoints should be added beyond those explicitly specified or directly implied by the requirements.

## 4. Backend Scope

The backend system encompasses two primary modules:

### Module: calculator_config
- **Entities:** CalculatorDefaults
- **Purpose:** System-wide configuration and constraints for loan calculator inputs and defaults
- **Responsibilities:**
  - Store default values for principal, interest rate, and loan term
  - Define minimum and maximum validation constraints
  - Provide configuration retrieval API
  - Support administrative updates to defaults

### Module: loan_calculation
- **Entities:** LoanCalculation, AmortizationScheduleEntry
- **Purpose:** Loan calculation engine, results storage, and amortization schedule generation
- **Responsibilities:**
  - Calculate monthly payment using amortization formula
  - Compute total payment and total interest
  - Generate complete amortization schedules
  - Store calculation history by session
  - Provide retrieval APIs for calculations and schedules

## 5. Roles

The system supports a single role model:

| Role | Description | Permissions |
|------|-------------|-------------|
| AnonymousUser | Any unauthenticated visitor to the application | Can perform loan calculations, retrieve calculation results, generate amortization schedules, and view calculator defaults. Cannot modify system configuration. |

**Note:** While the API specification includes a PUT endpoint for updating calculator defaults marked as "admin only," no explicit admin role is defined in the current scope. This endpoint is reserved for future authentication and authorization implementation.

## 6. Entities and Fields

### Entity: CalculatorDefaults

**Table Name:** `calculator_defaults`

**Description:** Global configuration entity storing default values and validation constraints for the loan calculator. This is a singleton entity with only one active record.

| Field Name | Type | Required | Description |
|------------|------|----------|-------------|
| id | str | Yes | Unique identifier |
| default_principal | Decimal | Yes | Default loan principal amount |
| default_interest_rate | Decimal | Yes | Default annual interest rate percentage |
| default_term_months | int | Yes | Default loan term in months |
| min_principal | Decimal | Yes | Minimum allowed principal amount |
| max_principal | Decimal | Yes | Maximum allowed principal amount |
| min_interest_rate | Decimal | Yes | Minimum allowed annual interest rate |
| max_interest_rate | Decimal | Yes | Maximum allowed annual interest rate |
| min_term_months | int | Yes | Minimum allowed loan term in months |
| max_term_months | int | Yes | Maximum allowed loan term in months |
| created_at | datetime | Yes | Creation timestamp |
| updated_at | datetime | Yes | Last update timestamp |

**Status Management:** None (entity does not have status field)

**Default Values:**
- default_principal: $250,000
- default_interest_rate: 6.5%
- default_term_months: 360 months (30 years)
- min_principal: $1,000
- max_principal: $10,000,000
- min_interest_rate: 0%
- max_interest_rate: 50%
- min_term_months: 1 month
- max_term_months: 600 months (50 years)

### Entity: LoanCalculation

**Table Name:** `loan_calculations`

**Description:** Stored loan calculation result containing input parameters and computed monthly payment, total payment, and total interest.

| Field Name | Type | Required | Description |
|------------|------|----------|-------------|
| id | str | Yes | Unique identifier |
| principal | Decimal | Yes | Initial loan amount borrowed |
| annual_interest_rate | Decimal | Yes | Yearly interest rate as a percentage |
| loan_term_months | int | Yes | Duration of the loan in months |
| monthly_payment | Decimal | Yes | Calculated monthly payment amount |
| total_payment | Decimal | Yes | Calculated total amount paid over loan term |
| total_interest | Decimal | Yes | Calculated total interest paid over loan term |
| session_id | str | Yes | Browser session identifier for tracking user calculations |
| created_at | datetime | Yes | Timestamp when calculation was performed |
| updated_at | datetime | Yes | Last update timestamp |

**Status Management:** None (entity does not have status field)

### Entity: AmortizationScheduleEntry

**Table Name:** `amortization_schedule_entries`

**Description:** Individual payment breakdown for each period of the loan term showing principal and interest portions.

| Field Name | Type | Required | Description |
|------------|------|----------|-------------|
| id | str | Yes | Unique identifier |
| calculation_id | str | Yes | Reference to parent LoanCalculation |
| payment_number | int | Yes | Sequential payment number (1 to N) |
| payment_date | date | Yes | Scheduled payment date |
| beginning_balance | Decimal | Yes | Loan balance at start of period |
| payment_amount | Decimal | Yes | Total payment for this period |
| principal_portion | Decimal | Yes | Amount applied to principal |
| interest_portion | Decimal | Yes | Amount applied to interest |
| ending_balance | Decimal | Yes | Loan balance at end of period |
| created_at | datetime | Yes | Creation timestamp |
| updated_at | datetime | Yes | Last update timestamp |

**Status Management:** None (entity does not have status field)

## 7. Enumerations

No enumerations are defined for this system.

## 8. Relationships

### AmortizationScheduleEntry → LoanCalculation (Many-to-One)

- **Relationship Type:** Belongs To (required)
- **Foreign Key:** `calculation_id` in `amortization_schedule_entries` references `id` in `loan_calculations`
- **Navigation Required:** Yes
- **Description:** Each amortization schedule entry belongs to exactly one loan calculation. A loan calculation may have multiple schedule entries (one per payment period).
- **Cascade Behavior:** When a loan calculation is deleted, all associated amortization schedule entries should be deleted (cascade delete recommended).

### Relationship Summary Table

| From Entity | Relationship | To Entity | Foreign Key | Required | Navigation |
|-------------|--------------|-----------|-------------|----------|------------|
| AmortizationScheduleEntry | belongs to | LoanCalculation | calculation_id | Yes | Yes |
| LoanCalculation | has many | AmortizationScheduleEntry | - | No | Yes |

## 9. API Endpoints

### Calculator Defaults Endpoints

#### GET /calculator-defaults
- **Purpose:** Retrieve current calculator defaults and validation constraints
- **Method:** GET
- **Authentication:** None (public)
- **Request Parameters:** None
- **Response:** CalculatorDefaults object with all fields
- **Status Codes:** 
  - 200: Success
  - 404: No defaults configured

#### PUT /calculator-defaults/{id}
- **Purpose:** Update calculator defaults (admin only - reserved for future implementation)
- **Method:** PUT
- **Authentication:** Admin (not currently enforced)
- **Path Parameters:** 
  - `id` (string): CalculatorDefaults ID
- **Request Body:** Partial or complete CalculatorDefaults update payload
- **Response:** Updated CalculatorDefaults object
- **Status Codes:**
  - 200: Success
  - 400: Validation error
  - 404: CalculatorDefaults not found

### Loan Calculation Endpoints

#### POST /loan-calculations
- **Purpose:** Create new loan calculation with computed results
- **Method:** POST
- **Authentication:** None (public)
- **Request Body:**
  ```json
  {
    "principal": "250000.00",
    "annual_interest_rate": "6.5",
    "loan_term_months": 360,
    "session_id": "session-uuid"
  }
  ```
- **Response:** Complete LoanCalculation object with computed fields (monthly_payment, total_payment, total_interest)
- **Business Logic:**
  - Validate inputs against CalculatorDefaults constraints
  - Calculate monthly interest rate: (annual_interest_rate / 100) / 12
  - Calculate monthly payment using formula: M = P * [r(1+r)^n] / [(1+r)^n - 1]
  - Handle zero interest rate case: M = P / n
  - Round all currency values to 2 decimal places
  - Store calculation with timestamp
- **Status Codes:**
  - 201: Created
  - 400: Validation error
  - 422: Unprocessable entity

#### GET /loan-calculations/{id}
- **Purpose:** Retrieve stored loan calculation
- **Method:** GET
- **Authentication:** None (public)
- **Path Parameters:**
  - `id` (string): LoanCalculation ID
- **Response:** LoanCalculation object
- **Status Codes:**
  - 200: Success
  - 404: Not found

#### GET /loan-calculations
- **Purpose:** List loan calculations, optionally filtered by session_id
- **Method:** GET
- **Authentication:** None (public)
- **Query Parameters:**
  - `session_id` (optional, string): Filter by session ID
  - `limit` (optional, integer): Maximum results to return
  - `offset` (optional, integer): Pagination offset
- **Response:** Array of LoanCalculation objects
- **Status Codes:**
  - 200: Success

#### GET /loan-calculations/{id}/details
- **Purpose:** Retrieve loan calculation with full amortization schedule
- **Method:** GET
- **Authentication:** None (public)
- **Path Parameters:**
  - `id` (string): LoanCalculation ID
- **Response:** LoanCalculation object with embedded amortization_schedule_entries array
- **Eager Loading:** AmortizationScheduleEntry collection loaded in single query
- **Response Includes:**
  - All LoanCalculation fields
  - amortization_schedule_entries[] with all fields per entry
- **Status Codes:**
  - 200: Success
  - 404: LoanCalculation not found

#### POST /loan-calculations/{id}/generate-schedule
- **Purpose:** Generate amortization schedule for existing calculation
- **Method:** POST
- **Authentication:** None (public)
- **Path Parameters:**
  - `id` (string): LoanCalculation ID
- **Request Body:** Optional parameters
  ```json
  {
    "start_date": "2024-01-01"
  }
  ```
- **Response:** Array of AmortizationScheduleEntry objects
- **Business Logic:** See Batch Write Service: generate_amortization_schedule
- **Status Codes:**
  - 201: Schedule created
  - 400: Validation error
  - 404: LoanCalculation not found
  - 409: Schedule already exists (optional behavior)

### Amortization Schedule Endpoints

#### GET /amortization-schedule-entries
- **Purpose:** List schedule entries for a calculation_id
- **Method:** GET
- **Authentication:** None (public)
- **Query Parameters:**
  - `calculation_id` (required, string): Filter by LoanCalculation ID
  - `limit` (optional, integer): Maximum results
  - `offset` (optional, integer): Pagination offset
- **Response:** Array of AmortizationScheduleEntry objects ordered by payment_number
- **Status Codes:**
  - 200: Success
  - 400: Missing required calculation_id

## 10. Workflow Logic

### Workflow 1: Loan Calculation

**Trigger:** User submits principal, interest rate, and term via POST /loan-calculations

**Steps:**
1. **Input Reception:** Receive principal, annual_interest_rate, loan_term_months, and session_id
2. **Validation:** Validate inputs against CalculatorDefaults constraints
   - Check principal is between min_principal and max_principal
   - Check annual_interest_rate is between min_interest_rate and max_interest_rate
   - Check loan_term_months is between min_term_months and max_term_months
   - Verify all values are properly formatted (decimals to 2 places for currency, 4 for rate)
3. **Monthly Interest Rate Calculation:** monthly_rate = (annual_interest_rate / 100) / 12
4. **Monthly Payment Calculation:**
   - If monthly_rate > 0:
     - M = P * [r(1+r)^n] / [(1+r)^n - 1]
     - Where: P = principal, r = monthly_rate, n = loan_term_months
   - If monthly_rate == 0:
     - M = P / n
5. **Total Calculations:**
   - total_payment = monthly_payment * loan_term_months
   - total_interest = total_payment - principal
6. **Rounding:** Round all currency values to 2 decimal places
7. **Persistence:** Create and save LoanCalculation record with all input and computed fields
8. **Response:** Return complete LoanCalculation object

**Error Handling:**
- Return 400 with validation messages if constraints violated
- Return 422 if data types invalid

### Workflow 2: Amortization Schedule Generation

**Trigger:** User requests schedule via POST /loan-calculations/{id}/generate-schedule

**Steps:**
1. **Calculation Retrieval:** Load LoanCalculation by ID
2. **Initialization:**
   - Set starting balance = principal
   - Determine start_date (from request body or current date)
   - Calculate monthly_rate = (annual_interest_rate / 100) / 12
3. **Batch Deletion:** Remove any existing AmortizationScheduleEntry records for this calculation_id
4. **Iteration:** For each payment number from 1 to loan_term_months:
   - Calculate payment_date = start_date + (payment_number - 1) months
   - Set beginning_balance = previous ending_balance (or principal for first payment)
   - Calculate interest_portion = beginning_balance * monthly_rate
   - Calculate principal_portion = monthly_payment - interest_portion
   - Calculate ending_balance = beginning_balance - principal_portion
   - Handle final payment adjustment to zero out balance
   - Create AmortizationScheduleEntry with all computed fields
5. **Final Payment Adjustment:** Ensure last entry has ending_balance = 0 or negligible (< $0.01)
6. **Batch Insert:** Save all AmortizationScheduleEntry records
7. **Response:** Return array of all created schedule entries

**Batch Write Service Details:**
- **Service Name:** generate_amortization_schedule
- **Primary Entity:** LoanCalculation
- **Batch Loads:** AmortizationScheduleEntry filtered by calculation_id
- **Transaction:** All entries created within single database transaction

### Workflow 3: Reset Calculator

**Trigger:** User clicks reset button (frontend action)

**Steps:**
1. **Defaults Retrieval:** Frontend calls GET /calculator-defaults
2. **Response Processing:** Receive CalculatorDefaults object
3. **Form Reset:** Frontend resets input fields:
   - principal = default_principal
   - annual_interest_rate = default_interest_rate
   - loan_term_months = default_term_months
4. **Clear Results:** Frontend clears displayed calculation results
5. **UI Update:** Update UI to show default values

**Note:** This workflow is primarily frontend-driven with backend providing defaults via API.

## 11. Business Logic

### Calculation Formulas

#### Monthly Payment Calculation (Interest-Bearing Loan)

Formula: `M = P * [r(1+r)^n] / [(1+r)^n - 1]`

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

**Implementation Notes:**
- Calculate (1+r)^n using power function
- Handle division carefully to avoid division by zero
- Round final result to 2 decimal places

#### Monthly Payment Calculation (Zero Interest)

Formula: `M = P / n`

Where:
- M = Monthly payment
- P = Principal amount
- n = Number of payments

**Implementation Notes:**
- Apply when annual_interest_rate = 0
- Round final result to 2 decimal places

#### Total Payment

Formula: `Total Payment = Monthly Payment * Number of Payments`

**Implementation Notes:**
- Simple multiplication
- Round to 2 decimal places

#### Total Interest

Formula: `Total Interest = Total Payment - Principal`

**Implementation Notes:**
- Simple subtraction
- Round to 2 decimal places

### Amortization Schedule Calculations

#### Interest Portion (Per Payment)

Formula: `Interest = Beginning Balance * Monthly Interest Rate`

**Implementation Notes:**
- Calculated fresh each payment period
- Round to 2 decimal places

#### Principal Portion (Per Payment)

Formula: `Principal = Payment Amount - Interest Portion`

**Implementation Notes:**
- Difference between fixed payment and calculated interest
- Round to 2 decimal places

#### Ending Balance (Per Payment)

Formula: `Ending Balance = Beginning Balance - Principal Portion`

**Implementation Notes:**
- Next payment's beginning balance equals previous ending balance
- Final payment must result in ending_balance = $0.00

#### Final Payment Adjustment

**Logic:**
- Due to rounding, cumulative principal portions may not exactly equal original principal
- On final payment (payment_number = loan_term_months):
  - Calculate interest_portion normally
  - Set principal_portion = beginning_balance (to zero out loan)
  - Set payment_amount = interest_portion + principal_portion (may differ from regular monthly_payment)
  - Set ending_balance = 0.00

### Payment Date Calculation

**Logic:**
- Start from start_date (provided or current date)
- For each payment_number, add (payment_number - 1) months
- Use date arithmetic to handle month boundaries and leap years
- Payment dates are monthly intervals

### Constraint Enforcement

| Constraint | Min | Max | Decimal Precision |
|------------|-----|-----|-------------------|
| Principal | $1,000 | $10,000,000 | 2 places |
| Annual Interest Rate | 0% | 50% | 4 places |
| Loan Term (months) | 1 | 600 | Integer |

**Validation Logic:**
- Retrieve constraints from CalculatorDefaults entity
- Apply min/max checks before calculation
- Validate decimal precision
- Return detailed error messages indicating which constraint failed

### Session Management

**Logic:**
- session_id is a required field for all loan calculations
- Frontend generates or retrieves session_id from browser storage
- Backend stores session_id with each calculation for tracking
- Multiple calculations can share same session_id
- No session expiration logic in backend (optional future enhancement)

## 12. Validation Rules

### Input Validation Rules

| Field | Rule | Error Message |
|-------|------|---------------|
| principal | Required, not null | "Principal amount is required" |
| principal | Must be numeric (Decimal) | "Principal must be a valid number" |
| principal | Must be positive (> 0) | "Principal must be greater than zero" |
| principal | Must be >= min_principal | "Principal must be at least ${min_principal}" |
| principal | Must be <= max_principal | "Principal cannot exceed ${max_principal}" |
| principal | Max 2 decimal places | "Principal can have at most 2 decimal places" |
| annual_interest_rate | Required, not null | "Interest rate is required" |
| annual_interest_rate | Must be numeric (Decimal) | "Interest rate must be a valid number" |
| annual_interest_rate | Must be non-negative (>= 0) | "Interest rate cannot be negative" |
| annual_interest_rate | Must be >= min_interest_rate | "Interest rate must be at least {min_interest_rate}%" |
| annual_interest_rate | Must be <= max_interest_rate | "Interest rate cannot exceed {max_interest_rate}%" |
| annual_interest_rate | Max 4 decimal places | "Interest rate can have at most 4 decimal places" |
| loan_term_months | Required, not null | "Loan term is required" |
| loan_term_months | Must be integer | "Loan term must be a whole number of months" |
| loan_term_months | Must be positive (> 0) | "Loan term must be at least 1 month" |
| loan_term_months | Must be >= min_term_months | "Loan term must be at least {min_term_months} months" |
| loan_term_months | Must be <= max_term_months | "Loan term cannot exceed {max_term_months} months" |
| session_id | Required, not null | "Session ID is required" |
| session_id | Must be non-empty string | "Session ID cannot be empty" |

### Entity Validation Rules

#### CalculatorDefaults

| Rule | Description |
|------|-------------|
| Singleton | Only one active record should exist; enforce at application level |
| Min < Max | min_principal < max_principal, min_interest_rate < max_interest_rate, min_term_months < max_term_months |
| Positive Minimums | All min_ fields must be non-negative |
| Reasonable Defaults | Default values must fall within their respective min/max ranges |

#### AmortizationScheduleEntry

| Rule | Description |
|------|-------------|
| Sequential Payment Numbers | payment_number must be sequential starting from 1 for each calculation_id |
| First Payment Balance | beginning_balance for payment_number = 1 must equal parent LoanCalculation.principal |
| Balance Continuity | beginning_balance for payment N must equal ending_balance for payment N-1 |
| Final Payment Balance | ending_balance for final payment (payment_number = loan_term_months) must be 0.00 or < $0.01 |
| Payment Composition | payment_amount = principal_portion + interest_portion (with rounding tolerance) |
| Balance Reduction | ending_balance = beginning_balance - principal_portion |
| Non-negative Balances | beginning_balance and ending_balance must be >= 0 |
| Non-negative Portions | principal_portion and interest_portion must be >= 0 |

### Cross-Entity Validation

| Rule | Description |
|------|-------------|
| Calculation-Schedule Consistency | Sum of all principal_portion values for a calculation must equal the LoanCalculation.principal (within rounding tolerance of $0.01) |
| Schedule Completeness | Number of AmortizationScheduleEntry records for a calculation_id must equal LoanCalculation.loan_term_months |

## 13. Implementation Notes

### Technology Stack

- **Framework:** FastAPI (Python web framework)
- **ORM:** SQLAlchemy ORM with SQLite database backend
- **Validation:** Pydantic v2 for request/response models and validation
- **Dependency Injection:** FastAPI Depends(get_db) pattern for database session management
- **Package Management:** uv for dependency management
- **API Documentation:** Automatic OpenAPI (Swagger) docs at /docs and ReDoc at /redoc

### Architecture Patterns

#### Service Layer Pattern

Implement a service layer to separate business logic from API route handlers:

- **Service Classes:**
  - `CalculatorDefaultsService`: Manages calculator defaults retrieval and updates
  - `LoanCalculationService`: Handles loan calculation logic and CRUD operations
  - `AmortizationScheduleService`: Generates and manages amortization schedules

- **Benefits:**
  - Testable business logic independent of HTTP layer
  - Reusable logic across multiple endpoints
  - Clear separation of concerns

#### Repository Pattern (Optional)

Consider implementing repository classes for data access abstraction:

- `CalculatorDefaultsRepository`
- `LoanCalculationRepository`
- `AmortizationScheduleEntryRepository`

### Database Session Management

Use FastAPI dependency injection for database sessions:

```python
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()
```

All route handlers should receive database session via `db: Session = Depends(get_db)`

### Decimal Precision

- Use Python `Decimal` type for all currency and percentage fields
- Configure SQLAlchemy models with appropriate precision: `Numeric(precision=12, scale=2)` for currency
- Perform all calculations using Decimal arithmetic to avoid floating-point errors
- Round explicitly using `quantize()` method with ROUND_HALF_UP rounding mode

### Error Handling

- Return structured error responses with detail messages
- Use FastAPI HTTPException for error responses
- Validate inputs in Pydantic models before reaching service layer
- Handle database exceptions gracefully (unique constraints, foreign key violations)
- Log errors for debugging while returning user-friendly messages

### Batch Operations

For amortization schedule generation:
- Use bulk insert operations for performance
- Wrap schedule generation in database transaction
- Delete existing schedule entries before regenerating to ensure consistency
- Consider pagination if retrieving large schedules (600-month terms = 600 entries)

### Date Handling

- Use Python `date` type for payment_date field
- Use `datetime` with timezone awareness for created_at and updated_at timestamps
- Implement date arithmetic using `relativedelta` from `dateutil` library for accurate month addition

### API Versioning

Current implementation does not include API versioning. Consider adding /v1/ prefix to all routes for future compatibility.

## 14. Assumptions

1. **Loan Type:** Calculations are for standard amortizing loans with fixed interest rate and equal monthly payments. Balloon payments, adjustable rates, and interest-only periods are not supported.

2. **Authentication:** No authentication required; all users are anonymous visitors. The system does not distinguish between users beyond session tracking.

3. **Session Tracking:** Session tracking uses browser session storage or cookies to generate and maintain session_id. Backend does not manage session lifecycle or expiration.

4. **Payment Date Calculation:** Payment dates calculated as monthly intervals from start date (current date or user-specified). Assumes payment on same day of each month; does not adjust for business days or holidays.

5. **Disclaimer:** Calculator is informational only with appropriate disclaimers on frontend. Results are not financial advice and actual loan terms may vary.

6. **CalculatorDefaults Singleton:** CalculatorDefaults entity contains only one active record representing system-wide configuration. No multi-tenancy or per-user defaults.

7. **Calculation Persistence:** Loan calculations may be persisted for history tracking and amortization schedule association, but persistence is not required for core functionality (stateless calculation endpoint possible).

8. **Schedule Generation:** Amortization schedules generated on-demand rather than automatically created with each loan calculation. Provides flexibility for users who only need summary results.

9. **Currency:** All currency values assumed to be in USD. No multi-currency support.

10. **Rounding Methodology:** All currency rounding uses standard round-half-up (banker's rounding) to 2 decimal places. Final payment adjusted to zero out balance regardless of cumulative rounding errors.

11. **Database Choice:** SQLite used for development and demonstration. Production deployment should migrate to PostgreSQL or similar RDBMS.

12. **Concurrency:** No explicit concurrency control (optimistic/pessimistic locking) implemented. Assumes low contention on CalculatorDefaults updates.

13. **Data Retention:** No automatic data retention or archival policy. Calculations and schedules persist indefinitely unless manually deleted.

14. **Performance:** Expected usage patterns support synchronous request processing. No queue-based or asynchronous calculation processing required.

15. **Validation Constraints:** Min/max constraints in CalculatorDefaults are for user input validation only. System does not enforce these constraints on historical data or administrative updates.

## 15. Future Improvements

### Near-Term Enhancements

1. **Database Migration:** Implement Alembic migrations for schema versioning and database change management. Establish migration workflow for development, staging, and production environments.

2. **PostgreSQL Migration:** Replace SQLite with PostgreSQL for production deployment. Configure connection pooling, optimize indexes, and implement full-text search if needed.

3. **Authentication & Authorization:** Implement JWT-based authentication system. Add user registration, login, and session management. Enforce admin role for calculator defaults updates using RBAC (Role-Based Access Control).

4. **Comprehensive Testing:** Develop unit tests for service layer, integration tests for API endpoints, and end-to-end tests for workflows. Achieve >80% code coverage. Use pytest framework with fixtures for database mocking.

5. **Containerization:** Create Dockerfile for application containerization. Implement docker-compose configuration for local development with PostgreSQL. Prepare for Kubernetes deployment.

6. **API Rate Limiting:** Implement rate limiting to prevent abuse of calculation endpoints. Use Redis for distributed rate limiting state.

7. **Logging & Monitoring:** Enhance structured logging with correlation IDs. Integrate application performance monitoring (APM) tools. Set up alerts for error rates and performance degradation.

8. **Input Sanitization:** Add comprehensive input sanitization beyond Pydantic validation to prevent injection attacks and malformed data.

### Mid-Term Enhancements

9. **Payment Frequency Options:** Support bi-weekly (26 payments/year) and weekly (52 payments/year) payment schedules. Adjust calculation formulas and amortization logic accordingly.

10. **Extra Payment Scenarios:** Allow users to model extra principal payments (one-time or recurring). Calculate impact on loan term and total interest savings. Show payoff acceleration.

11. **Loan Comparison:** Enable side-by-side comparison of multiple loan scenarios with different terms, rates, or payment strategies. Provide comparison summary and recommendations.

12. **Export Functionality:** Generate PDF and CSV exports of amortization schedules. Include calculation summary, loan details, and payment breakdown. Support email delivery.

13. **Visualization APIs:** Provide data endpoints optimized for charting libraries. Support principal vs interest breakdown over time, balance reduction charts, and payment distribution pie charts.

14. **User Accounts:** Implement user account system to save and manage multiple calculation scenarios. Support scenario naming, tagging, and organization. Sync across devices.

15. **Caching Strategy:** Implement Redis caching for CalculatorDefaults and frequently accessed calculations. Set appropriate TTL values and cache invalidation logic.

### Long-Term Enhancements

16. **Advanced Loan Types:** Support balloon payment loans, interest-only periods, and graduated payment mortgages. Add adjustable-rate mortgage (ARM) calculations with rate adjustment schedules.

17. **Tax and Insurance Integration:** Expand to PITI (Principal, Interest, Taxes, Insurance) calculations. Allow users to input property tax rates and insurance estimates for complete monthly payment calculation.

18. **Refinancing Calculator:** Build refinancing analysis tool showing break-even point for refinancing costs. Compare current loan with refinancing scenarios considering closing costs and rate differences.

19. **Multi-Language Support:** Internationalize API responses and error messages. Support Spanish, French, and other languages. Implement locale-specific date and currency formatting.

20. **Webhook Notifications:** Implement webhook system for calculation completion notifications. Support integration with third-party systems for calculation result delivery.

21. **GraphQL API:** Provide GraphQL endpoint alongside REST API for more flexible data querying. Allow clients to request exactly the fields needed for their use case.

22. **Audit Logging:** Implement comprehensive audit trail for all calculation and configuration changes. Track who, what, when for compliance and debugging purposes.

23. **Machine Learning Insights:** Analyze historical calculation patterns to provide insights and recommendations. Predict common loan scenarios and offer pre-configured options.

24. **Microservices Architecture:** Decompose monolithic application into microservices (calculation engine, configuration service, reporting service) for independent scaling and deployment.
