# Backend Specification

## 1. System Summary

**System Name:** Simple Loan Calculator

**Description:** A single-page web application that calculates loan payment schedules, monthly payments, and total interest costs based on loan parameters. The backend provides RESTful APIs for creating loan calculations, generating complete amortization schedules, and retrieving calculation results. All calculations are performed server-side using standard fixed-rate amortization formulas with precise financial computations.

**Domain:** https://freemeal.dev.dalfin.ai

## 2. Source Input Summary

The backend specification is derived from the following source materials:

- **DDL Schema:** `/home/ubuntu/dpg/pipeline/step-02-prd-generation/output/20260514_042319/schema.sql` - Contains table definitions for `calculations` and `amortization_schedule_entries` with complete field specifications and constraints
- **Product Requirements Document:** `/home/ubuntu/dpg/pipeline/step-02-prd-generation/output/20260514_042319/full_prd.md` - Provides detailed workflows, business rules, calculation formulas, validation requirements, and user interaction patterns
- **Prompt:** Provided specification requirements for backend generation
- **Images:** Not provided

## 3. Generation Mode

**Mode:** `strict`

All backend components, APIs, validation rules, and business logic must be implemented exactly as specified in the source materials. No creative interpretation or addition of features beyond the documented requirements is permitted. The implementation must strictly adhere to the calculation formulas, validation rules, and data constraints defined in the PRD and DDL schema.

## 4. Backend Scope

The backend encompasses a single functional module:

### Module: loan_calculation

**Entities:** Calculation, Amortizationscheduleentry

**Description:** Handles loan calculations, amortization schedule generation, and payment breakdowns. This module is responsible for:

- Accepting and validating loan input parameters (principal, annual interest rate, loan term)
- Computing monthly payment amounts using standard amortization formulas
- Generating complete amortization schedules with payment-by-payment breakdowns
- Storing calculation results and schedule entries for retrieval
- Providing APIs for creating, retrieving, listing, and deleting calculations
- Ensuring financial accuracy with proper rounding and precision handling
- Managing cascade deletion of schedule entries when calculations are removed

## 5. Roles

The system supports a single role:

| Role | Description | Authentication Required |
|------|-------------|------------------------|
| AnonymousUser | Any user accessing the loan calculator without authentication. Can create calculations, view results, and delete their calculations. | No |

**Note:** No user authentication or authorization is required. All users have identical access rights to create and manage calculations.

## 6. Entities and Fields

### Entity: Calculation

**Table Name:** `calculations`

**Description:** Represents a single loan calculation session with input parameters and computed results. Each calculation stores the user's loan inputs and the calculated financial outcomes (monthly payment, total interest, total amount paid).

| Field Name | Type | Required | Description | Constraints |
|------------|------|----------|-------------|-------------|
| id | str | Yes | Unique identifier for the calculation | Primary key, UUID format |
| principal | float | Yes | Loan amount borrowed (positive value) | > 0, ≤ 100,000,000 |
| annual_interest_rate | float | Yes | Annual interest rate as percentage (0-100) | ≥ 0, ≤ 30, up to 3 decimal places |
| loan_term_months | int | Yes | Duration of loan in months (1-360) | ≥ 1, ≤ 360 |
| monthly_payment | float | Yes | Calculated monthly payment amount | Non-negative, 2 decimal places |
| total_interest | float | Yes | Total interest paid over loan lifetime | Non-negative, 2 decimal places |
| total_amount_paid | float | Yes | Principal plus total interest | Non-negative, 2 decimal places |
| calculation_method | str | Yes | Fixed-rate amortization method identifier | Always 'standard_amortization' |
| start_date | Optional[date] | No | Optional first payment date | Defaults to first day of next month |
| created_at | datetime | Yes | When calculation was performed | Auto-generated on creation |
| updated_at | datetime | Yes | Last update timestamp | Auto-updated on modification |

**Status Management:** This entity does not use status fields.

### Entity: Amortizationscheduleentry

**Table Name:** `amortization_schedule_entries`

**Description:** Represents a single payment period in the loan's amortization schedule. Each entry shows the breakdown of a scheduled payment into principal and interest components, along with running balances and cumulative totals.

| Field Name | Type | Required | Description | Constraints |
|------------|------|----------|-------------|-------------|
| id | str | Yes | Unique identifier | Primary key, UUID format |
| calculation_id | str | Yes | Reference to parent calculation | Foreign key to calculations.id |
| payment_number | int | Yes | Sequential payment number (1 to N, positive) | ≥ 1, ≤ loan_term_months |
| payment_date | date | Yes | Scheduled payment date | Must be valid date |
| beginning_balance | float | Yes | Principal balance at start of period (non-negative) | ≥ 0, 2 decimal places |
| payment_amount | float | Yes | Total payment for this period (non-negative) | ≥ 0, 2 decimal places |
| principal_payment | float | Yes | Portion applied to principal (non-negative) | ≥ 0, 2 decimal places |
| interest_payment | float | Yes | Portion applied to interest (non-negative) | ≥ 0, 2 decimal places |
| ending_balance | float | Yes | Principal balance after payment (non-negative) | ≥ 0, 2 decimal places |
| cumulative_interest | float | Yes | Total interest paid to date (non-negative) | ≥ 0, 2 decimal places |
| created_at | datetime | Yes | Creation timestamp | Auto-generated on creation |
| updated_at | datetime | Yes | Last update timestamp | Auto-updated on modification |

**Status Management:** This entity does not use status fields.

## 7. Enumerations

No enumerations are defined for this system. The `calculation_method` field in the Calculation entity uses a fixed string value ('standard_amortization') rather than an enumeration type.

## 8. Relationships

### AmortizationScheduleEntry → Calculation

- **Type:** Many-to-One (AmortizationScheduleEntry belongs to one Calculation)
- **Foreign Key:** `amortization_schedule_entries.calculation_id` → `calculations.id`
- **Navigation Required:** Yes - The detail endpoint requires eager loading of all schedule entries for a calculation
- **Cascade Behavior:** DELETE CASCADE - When a Calculation is deleted, all associated AmortizationScheduleEntry records are automatically deleted
- **Cardinality:** Each Calculation has exactly N AmortizationScheduleEntry records, where N = loan_term_months

## 9. API Endpoints

### POST /calculations

**Description:** Create new loan calculation with input parameters and generate complete amortization schedule

**Request Body:**
```json
{
  "principal": float,
  "annual_interest_rate": float,
  "loan_term_months": int,
  "start_date": "YYYY-MM-DD" (optional)
}
```

**Response:** Returns created Calculation with computed fields (monthly_payment, total_interest, total_amount_paid) and all generated AmortizationScheduleEntry records

**Business Logic:**
- Validates all input parameters against defined constraints
- Calculates monthly payment using standard amortization formula: M = P × [r(1+r)^n] / [(1+r)^n - 1]
- For 0% interest rate: monthly payment = Principal / Number of months
- Generates N amortization schedule entries (where N = loan_term_months)
- Creates Calculation and all AmortizationScheduleEntry records in a single transaction
- Adjusts final payment to ensure ending balance equals exactly $0.00

**Service:** `create_calculation_with_schedule` (batch write service)

### GET /calculations/{id}

**Description:** Retrieve calculation summary without schedule entries

**Path Parameters:**
- `id` (string, required): Calculation identifier

**Response:** Returns single Calculation entity with computed results but excludes amortization_schedule_entries relationship

**Business Logic:**
- Returns 404 if calculation not found
- Does not eager-load schedule entries for performance

### GET /calculations/{id}/details

**Description:** Retrieve calculation with full amortization schedule

**Path Parameters:**
- `id` (string, required): Calculation identifier

**Response:** Returns Calculation entity with embedded array of AmortizationScheduleEntry records, ordered by payment_number ascending

**Eager Loading:**
- `Calculation.amortization_schedule_entries` - Loads all schedule entries in a single query

**Response Includes:**
- All Calculation fields
- Array of amortization_schedule_entries with fields:
  - payment_number
  - payment_date
  - beginning_balance
  - payment_amount
  - principal_payment
  - interest_payment
  - ending_balance
  - cumulative_interest

**Business Logic:**
- Returns 404 if calculation not found
- Optimized with eager loading to avoid N+1 query problems
- Schedule entries sorted by payment_number

**Service:** `get_calculation_details` (detail endpoint)

### GET /calculations

**Description:** List all calculations with pagination

**Query Parameters:**
- `page` (int, optional, default=1): Page number
- `page_size` (int, optional, default=20): Number of records per page

**Response:** Returns paginated list of Calculation entities with metadata (total count, page info)

**Business Logic:**
- Does not include schedule entries in list view
- Orders by created_at descending (most recent first)
- Returns empty array if no calculations exist

### DELETE /calculations/{id}

**Description:** Delete calculation and cascade delete all schedule entries

**Path Parameters:**
- `id` (string, required): Calculation identifier

**Response:** 204 No Content on successful deletion

**Business Logic:**
- Returns 404 if calculation not found
- Automatically deletes all associated AmortizationScheduleEntry records via CASCADE
- Operation is transactional (all-or-nothing)

## 10. Workflow Logic

### Workflow 1: Create New Loan Calculation

**Trigger:** User submits loan parameters via POST /calculations

**Steps:**

1. **Input Validation**
   - Validate principal: required, numeric, > 0, ≤ $100,000,000
   - Validate annual_interest_rate: required, numeric, ≥ 0, ≤ 30, up to 3 decimal places
   - Validate loan_term_months: required, integer, ≥ 1, ≤ 360
   - Validate start_date (if provided): valid date format
   - Return 400 Bad Request with field-level errors if validation fails

2. **Set Default Start Date**
   - If start_date not provided, set to first day of next month from current date

3. **Calculate Monthly Payment**
   - If annual_interest_rate > 0:
     - Calculate monthly rate: r = annual_interest_rate / 12 / 100 (maintain 6+ decimal precision)
     - Apply formula: M = P × [r(1+r)^n] / [(1+r)^n - 1]
     - Round to 2 decimal places using standard rounding (round half up)
   - If annual_interest_rate = 0:
     - Calculate: M = principal / loan_term_months
     - Round to 2 decimal places

4. **Create Calculation Record**
   - Generate UUID for id
   - Store principal, annual_interest_rate, loan_term_months, start_date
   - Store calculated monthly_payment
   - Set calculation_method = 'standard_amortization'
   - Set created_at and updated_at to current timestamp

5. **Generate Amortization Schedule**
   - Initialize: beginning_balance = principal, cumulative_interest = 0
   - For each payment number from 1 to loan_term_months:
     - Calculate payment_date: increment start_date by (payment_number - 1) months
     - Calculate interest_payment = beginning_balance × monthly_rate
     - Calculate principal_payment = monthly_payment - interest_payment
     - Calculate ending_balance = beginning_balance - principal_payment
     - Increment cumulative_interest += interest_payment
     - Create AmortizationScheduleEntry with all computed values
     - Set beginning_balance for next iteration = ending_balance

6. **Adjust Final Payment**
   - For last entry (payment_number = loan_term_months):
     - Adjust principal_payment to ensure ending_balance = 0.00
     - Recalculate payment_amount = principal_payment + interest_payment

7. **Calculate Total Interest and Total Amount**
   - total_interest = sum of all interest_payment values
   - total_amount_paid = principal + total_interest
   - Update Calculation record with these totals

8. **Commit Transaction**
   - Save Calculation and all AmortizationScheduleEntry records atomically
   - Rollback entire transaction if any error occurs

9. **Return Response**
   - Return 201 Created with Calculation and embedded schedule entries

**Exception Handling:**
- Validation errors → 400 Bad Request
- Database errors → 500 Internal Server Error with rollback

### Workflow 2: Retrieve Calculation with Schedule

**Trigger:** User requests GET /calculations/{id}/details

**Steps:**

1. **Query Database**
   - Fetch Calculation by id with eager loading of amortization_schedule_entries
   - Use single query with JOIN to avoid N+1 problem

2. **Validate Existence**
   - If calculation not found, return 404 Not Found

3. **Order Schedule Entries**
   - Sort amortization_schedule_entries by payment_number ascending

4. **Return Response**
   - Return 200 OK with Calculation entity and nested schedule array
   - Include all fields specified in detail endpoint definition

### Workflow 3: Delete Calculation

**Trigger:** User requests DELETE /calculations/{id}

**Steps:**

1. **Fetch Calculation**
   - Query Calculation by id

2. **Validate Existence**
   - If calculation not found, return 404 Not Found

3. **Delete Records**
   - Delete Calculation record
   - Database CASCADE automatically deletes all AmortizationScheduleEntry records

4. **Commit Transaction**
   - Commit deletion atomically

5. **Return Response**
   - Return 204 No Content on success

## 11. Business Logic

### Calculation Formulas

#### Monthly Payment Calculation (Interest Rate > 0%)

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

Where:
- M = Monthly payment amount
- P = Principal (loan amount)
- r = Monthly interest rate (annual_interest_rate / 12 / 100)
- n = Number of months (loan_term_months)

**Precision Requirements:**
- Maintain at least 6 decimal places for monthly rate in intermediate calculations
- Round final monthly payment to 2 decimal places using standard rounding (round half up)

#### Monthly Payment Calculation (Interest Rate = 0%)

Formula: `M = P / n`

Where:
- M = Monthly payment amount
- P = Principal (loan amount)
- n = Number of months (loan_term_months)

**Note:** When interest rate is 0%, all payments go toward principal, and total interest = $0.00

#### Amortization Schedule Entry Calculations

For each payment period:

1. **Interest Payment:** `Interest = Beginning Balance × Monthly Rate`
2. **Principal Payment:** `Principal = Payment Amount - Interest Payment`
3. **Ending Balance:** `Ending Balance = Beginning Balance - Principal Payment`
4. **Cumulative Interest:** `Cumulative Interest = Previous Cumulative Interest + Interest Payment`

**Rounding Rules:**
- All currency values rounded to 2 decimal places
- Standard rounding method (round half up) applied consistently

#### Final Payment Adjustment

The last payment must be adjusted to ensure the ending balance equals exactly $0.00:

1. Calculate final principal_payment: `Final Principal = Beginning Balance of Last Period`
2. Calculate final interest_payment normally
3. Set final payment_amount: `Final Payment = Final Principal + Final Interest`
4. Set final ending_balance = 0.00

### Financial Integrity Rules

1. **Principal Sum Validation**
   - Sum of all principal_payment values across all entries must equal original principal
   - Tolerance: ±$0.01 acceptable due to rounding

2. **Interest Sum Validation**
   - Sum of all interest_payment values must equal total_interest in Calculation
   - Tolerance: ±$0.01 acceptable due to rounding

3. **Final Balance Validation**
   - Ending balance of last payment must equal $0.00
   - Tolerance: ±$0.01 acceptable due to rounding

4. **Payment Count Validation**
   - Number of AmortizationScheduleEntry records must exactly equal loan_term_months

### Date Calculation Rules

1. **Default Start Date**
   - If start_date not provided, default to first day of month following calculation date
   - Example: Calculation created on 2024-06-15 → start_date = 2024-07-01

2. **Payment Date Increment**
   - Each subsequent payment_date increments by exactly 1 month
   - Month-end handling: If start_date is month-end (e.g., Jan 31), subsequent dates adjust to month-end of each month (Feb 28/29, Mar 31, etc.)

### Constraint Enforcement

1. **Principal Constraints**
   - Minimum: $1.00 (> 0)
   - Maximum: $100,000,000.00
   - Must be numeric and positive

2. **Interest Rate Constraints**
   - Minimum: 0% (zero interest allowed)
   - Maximum: 30%
   - Precision: Up to 3 decimal places (e.g., 5.875% valid)

3. **Loan Term Constraints**
   - Minimum: 1 month
   - Maximum: 360 months (30 years)
   - Must be positive integer

4. **Calculation Method**
   - Always set to 'standard_amortization'
   - No other methods supported in this version

## 12. Validation Rules

### Input Validation (POST /calculations)

| Field | Validation Rules | Error Message |
|-------|------------------|---------------|
| principal | Required | "Principal is required" |
| principal | Must be numeric | "Principal must be a valid number" |
| principal | Must be > 0 | "Principal must be greater than $0.00" |
| principal | Must be ≤ 100,000,000 | "Principal cannot exceed $100,000,000.00" |
| annual_interest_rate | Required | "Annual interest rate is required" |
| annual_interest_rate | Must be numeric | "Annual interest rate must be a valid number" |
| annual_interest_rate | Must be ≥ 0 | "Annual interest rate cannot be negative" |
| annual_interest_rate | Must be ≤ 30 | "Annual interest rate cannot exceed 30%" |
| annual_interest_rate | Up to 3 decimal places | "Annual interest rate can have at most 3 decimal places" |
| loan_term_months | Required | "Loan term is required" |
| loan_term_months | Must be integer | "Loan term must be a whole number" |
| loan_term_months | Must be ≥ 1 | "Loan term must be at least 1 month" |
| loan_term_months | Must be ≤ 360 | "Loan term cannot exceed 360 months" |
| start_date | Must be valid date | "Start date must be a valid date in YYYY-MM-DD format" |

### Field-Level Validation Behavior

1. **Real-Time Validation**
   - Validation executed on field blur (when user leaves input field)
   - Inline error messages displayed immediately below invalid fields

2. **Error Display**
   - Invalid fields highlighted with red border
   - Error text displayed in red below field
   - Error icon shown next to field label

3. **Error Clearing**
   - Errors cleared automatically when user corrects input
   - Revalidation occurs on next blur event

4. **Submission Prevention**
   - Calculate button disabled when any field has validation errors
   - Tooltip on disabled button indicates fields requiring correction

### API Response Validation

**400 Bad Request Response Format:**
```json
{
  "detail": [
    {
      "field": "principal",
      "message": "Principal must be greater than $0.00"
    },
    {
      "field": "loan_term_months",
      "message": "Loan term cannot exceed 360 months"
    }
  ]
}
```

### Internal Data Validation

1. **Payment Number Sequence**
   - Each AmortizationScheduleEntry must have unique payment_number within a Calculation
   - payment_number must form continuous sequence from 1 to N

2. **Non-Negative Constraints**
   - All balance, payment, and cumulative fields must be ≥ 0
   - Enforced at database level with CHECK constraints

3. **Reference Integrity**
   - calculation_id in AmortizationScheduleEntry must reference existing Calculation
   - Enforced with foreign key constraint

## 13. Implementation Notes

### Technology Stack

- **Framework:** FastAPI (Python 3.10+)
- **ORM:** SQLAlchemy 2.x with declarative models
- **Database:** SQLite (development and production)
- **Validation:** Pydantic v2 for request/response models
- **Package Management:** uv for dependency management
- **API Documentation:** Automatic OpenAPI (Swagger) documentation via FastAPI

### Architecture Pattern

**Service Layer Pattern:**
- **Controllers (Routers):** Handle HTTP request/response, parameter extraction, status codes
- **Services:** Contain business logic, calculations, transaction management
- **Models (SQLAlchemy):** Define database schema and ORM mappings
- **Schemas (Pydantic):** Define API request/response validation and serialization
- **Database:** Session management via FastAPI Depends(get_db) dependency injection

### Key Implementation Details

1. **Database Session Management**
   - Use FastAPI's Depends(get_db) for automatic session injection
   - Context manager pattern for transaction handling
   - Automatic session cleanup on request completion

2. **UUID Generation**
   - Use Python's `uuid.uuid4()` for generating unique identifiers
   - Store as strings in SQLite for compatibility

3. **Decimal Precision**
   - Use Python's `decimal.Decimal` for monetary calculations to avoid floating-point errors
   - Convert to float only for final storage/response
   - Maintain at least 6 decimal places in intermediate calculations

4. **Rounding**
   - Use Python's `round()` function with banker's rounding (round half to even)
   - Apply consistently to all monetary values before storage

5. **Eager Loading**
   - Use SQLAlchemy's `selectinload()` for loading amortization schedule entries
   - Prevents N+1 query problems in detail endpoint

6. **Cascade Deletion**
   - Configure SQLAlchemy relationship with `cascade="all, delete-orphan"`
   - Database-level CASCADE constraint as backup

7. **OpenAPI Documentation**
   - FastAPI automatically generates interactive API documentation at /docs (Swagger UI)
   - Alternative documentation at /redoc (ReDoc)
   - Pydantic models automatically generate request/response schemas

8. **Error Handling**
   - Use FastAPI's HTTPException for consistent error responses
   - Custom exception handlers for validation errors
   - Structured error responses with field-level details

### Module Organization

```
backend/
├── app/
│   ├── main.py                 # FastAPI application entry point
│   ├── database.py             # Database connection and session management
│   ├── models/
│   │   ├── calculation.py      # SQLAlchemy Calculation model
│   │   └── amortization.py     # SQLAlchemy AmortizationScheduleEntry model
│   ├── schemas/
│   │   ├── calculation.py      # Pydantic request/response schemas
│   │   └── amortization.py     # Pydantic amortization schemas
│   ├── services/
│   │   └── loan_calculator.py  # Business logic and calculation services
│   └── routers/
│       └── calculations.py     # API endpoints
└── pyproject.toml              # uv dependencies
```

## 14. Assumptions

1. **Calculation Storage**
   - All calculations are performed server-side and stored in database for retrieval
   - No client-side calculation or caching
   - Calculations persist indefinitely unless explicitly deleted

2. **User Model**
   - No user authentication or authorization required
   - All calculations are anonymous and accessible to anyone with the ID
   - No concept of "ownership" or access control on calculations

3. **Concurrency**
   - Application supports concurrent calculations from multiple anonymous users
   - Database handles concurrent writes with appropriate locking
   - No application-level locking or queuing required

4. **Calculation Precision**
   - Monthly interest rate calculated as: annual_interest_rate / 12 / 100
   - Maintain at least 6 decimal places precision in intermediate calculations
   - Final values rounded to 2 decimal places for currency

5. **Date Handling**
   - Payment dates increment by exactly 1 month
   - Month-end dates handled appropriately (e.g., Jan 31 → Feb 28/29)
   - No business day adjustment or holiday calendar considerations
   - All dates stored and processed in UTC

6. **Calculation Method**
   - Only 'standard_amortization' method supported (fixed-rate, fully amortizing)
   - No support for adjustable rates, balloon payments, or interest-only periods
   - Standard amortization formula always applied

7. **Data Retention**
   - Calculations stored indefinitely with no automatic cleanup
   - No archival or data lifecycle management
   - Deleted calculations cannot be recovered

8. **Performance**
   - Maximum loan term of 360 months means maximum 360 schedule entries per calculation
   - Single transaction for creating calculation with all entries
   - Acceptable to load all entries in memory for detail endpoint

9. **Currency**
   - All monetary values in USD (no currency field or conversion)
   - No internationalization of currency formatting in backend
   - Frontend responsible for currency display formatting

10. **Error Recovery**
    - Failed transactions automatically rolled back
    - No partial calculation states (all-or-nothing creation)
    - No retry logic required for calculation operations

## 15. Future Improvements

### Database and Infrastructure

1. **Alembic Migrations**
   - Implement Alembic for database schema versioning and migrations
   - Enable smooth schema evolution without data loss
   - Support rollback of schema changes

2. **PostgreSQL Support**
   - Migrate from SQLite to PostgreSQL for production
   - Improve concurrent access performance
   - Enable advanced indexing and query optimization

3. **Docker Containerization**
   - Create Dockerfile for consistent deployment
   - Docker Compose for local development environment
   - Support for container orchestration (Kubernetes)

### Authentication and Authorization

4. **JWT Authentication**
   - Implement JWT-based authentication for user sessions
   - Support user registration and login
   - Associate calculations with authenticated users

5. **Role-Based Access Control (RBAC)**
   - Define roles: Anonymous, RegisteredUser, Admin
   - Implement permissions for viewing/deleting calculations
   - Admin dashboard for system monitoring

### Testing and Quality

6. **Automated Testing**
   - Unit tests for calculation formulas and business logic
   - Integration tests for API endpoints
   - Test coverage reporting with pytest-cov
   - Property-based testing for financial calculations

7. **Load Testing**
   - Performance testing with concurrent users
   - Identify bottlenecks in calculation generation
   - Optimize database queries and transactions

### Feature Enhancements

8. **Additional Calculation Methods**
   - Support for bi-weekly and weekly payment schedules
   - Extra payment scenarios and payoff acceleration
   - Adjustable-rate mortgage (ARM) calculations
   - Interest-only periods and balloon payments

9. **Export and Reporting**
   - CSV export endpoint for amortization schedules
   - PDF generation for printable amortization tables
   - Email delivery of calculation results

10. **Calculation History**
    - Store calculation history per user
    - Enable comparison of multiple loan scenarios
    - Save and retrieve named calculations

11. **Analytics and Visualization**
    - Aggregate statistics on calculations performed
    - API endpoints for chart data (principal vs interest over time)
    - Total interest saved with different scenarios

### Operational Improvements

12. **Logging and Monitoring**
    - Structured logging with correlation IDs
    - Application performance monitoring (APM)
    - Error tracking and alerting

13. **API Versioning**
    - Implement versioned API endpoints (/v1/calculations)
    - Support backward compatibility for breaking changes
    - Deprecation warnings for old endpoints

14. **Rate Limiting**
    - Implement rate limiting per IP or user
    - Prevent abuse of calculation endpoints
    - Configurable limits for different user tiers

15. **Caching**
    - Redis-based caching for frequently accessed calculations
    - Cache calculation results for identical input parameters
    - Configurable TTL for cached data
