# Backend Specification

## 1. System Summary

**System Name:** SIP Calculator

**Description:** A single-page financial planning tool that calculates and visualizes potential returns from systematic investment plans in mutual funds. The system provides real-time calculation of investment growth using compound interest formulas, generates year-by-year projection data for visualization, and returns results to anonymous users without requiring authentication.

**Key Capabilities:**
- Real-time SIP calculation based on monthly investment, expected return rate, and time period
- Computation of total investment, estimated returns, and maturity value using standard SIP formulas
- Generation of year-by-year chart data points for investment growth visualization
- Validation of input parameters against defined business rules
- Stateless operation with ephemeral calculation storage for analytics

## 2. Source Input Summary

This specification is generated from the following source inputs:

| Input Type | Location | Description |
|------------|----------|-------------|
| DDL Schema | `/home/ubuntu/dpg/pipeline/step-02-prd-generation/output/jay_mata_di/schema.sql` | Database schema defining calculation_inputs, calculation_results, and chart_data_points tables with relationships |
| PRD | `/home/ubuntu/dpg/pipeline/step-02-prd-generation/output/jay_mata_di/full_prd.md` | Product requirements describing a stateless SIP calculator with real-time calculation, visualization, and no authentication |

The source materials define a simple three-table structure supporting SIP calculations with input parameters, computed results, and granular chart data for frontend visualization.

## 3. Generation Mode

**Mode:** `strict`

The backend implementation strictly adheres to the provided DDL schema, PRD specifications, and analysis document. All entities, fields, relationships, validation rules, and business logic are implemented exactly as specified without deviation or interpretation.

## 4. Backend Scope

**Module:** `sip_calculation`

**Entities in Scope:**
- `Calculationinput` - User-provided SIP parameters
- `Calculationresult` - Computed financial projections
- `Chartdatapoint` - Year-by-year visualization data

**Primary Responsibilities:**
- Accept and validate SIP calculation input parameters
- Apply SIP compound interest formula: M = P × ({[1 + i]^n – 1} / i) × (1 + i)
- Compute total investment, estimated returns, and maturity value
- Generate yearly chart data points showing cumulative investment and projected value
- Store calculation history with timestamps for analytics
- Provide RESTful API endpoints for calculation operations

**Out of Scope:**
- User authentication and authorization
- Multi-currency support (only Indian Rupee ₹)
- Step-up SIP calculations
- Tax calculations
- PDF report generation
- Historical mutual fund data integration

## 5. Roles

| Role | Description | Access Level |
|------|-------------|--------------|
| **AnonymousUser** | Any user accessing the SIP calculator without authentication | Full access to all calculation endpoints; can create, retrieve, list, and delete calculations |

**Note:** The system operates in a completely open mode without authentication. All API endpoints are publicly accessible.

## 6. Entities and Fields

### 6.1 Calculationinput

**Table:** `calculation_inputs`

**Description:** User-provided parameters for SIP calculation including monthly investment, expected return rate, and time period.

| Field Name | Type | Required | Constraints | Description |
|------------|------|----------|-------------|-------------|
| `id` | str (UUID) | Yes | Primary Key | Unique identifier |
| `monthly_investment` | Decimal(12,2) | Yes | 500 ≤ value ≤ 100000 | Amount invested every month (₹500 - ₹100,000) |
| `expected_return_rate` | Decimal(5,2) | Yes | 1 ≤ value ≤ 30 | Annual expected rate of return as percentage (1% - 30%) |
| `time_period` | int | Yes | 1 ≤ value ≤ 40 | Investment duration in years (1 - 40) |
| `timestamp` | datetime | Yes | Auto-generated | When the calculation was performed |
| `created_at` | datetime | Yes | Auto-generated | Creation timestamp |
| `updated_at` | datetime | Yes | Auto-updated | Last update timestamp |

**Status Field:** None (entity does not track status)

### 6.2 Calculationresult

**Table:** `calculation_results`

**Description:** Computed output from SIP calculation including total investment, estimated returns, and maturity value.

| Field Name | Type | Required | Constraints | Description |
|------------|------|----------|-------------|-------------|
| `id` | str (UUID) | Yes | Primary Key | Unique identifier |
| `calculation_input_id` | str (UUID) | Yes | Foreign Key, Unique | Reference to the calculation input used |
| `total_investment` | Decimal(15,2) | Yes | value ≥ 0 | Total amount invested over the period (monthly_investment × months) |
| `estimated_returns` | Decimal(15,2) | Yes | value ≥ 0 | Wealth gained (maturity_value - total_investment) |
| `maturity_value` | Decimal(15,2) | Yes | value ≥ 0 | Total corpus at the end of investment period |
| `created_at` | datetime | Yes | Auto-generated | Creation timestamp |
| `updated_at` | datetime | Yes | Auto-updated | Last update timestamp |

**Status Field:** None

**Unique Constraint:** `calculation_input_id` (enforces one-to-one relationship)

### 6.3 Chartdatapoint

**Table:** `chart_data_points`

**Description:** Data points for visualization of investment growth over time, one point per year.

| Field Name | Type | Required | Constraints | Description |
|------------|------|----------|-------------|-------------|
| `id` | str (UUID) | Yes | Primary Key | Unique identifier |
| `calculation_input_id` | str (UUID) | Yes | Foreign Key | Reference to parent calculation |
| `year` | int | Yes | 1 ≤ value ≤ time_period | Year number in the investment timeline (1 to time_period) |
| `invested_amount` | Decimal(15,2) | Yes | value ≥ 0 | Cumulative amount invested up to this year |
| `projected_value` | Decimal(15,2) | Yes | value ≥ 0 | Projected portfolio value at this year with compound interest |
| `created_at` | datetime | Yes | Auto-generated | Creation timestamp |
| `updated_at` | datetime | Yes | Auto-updated | Last update timestamp |

**Status Field:** None

## 7. Enumerations

No enumerations are defined for this system. All fields use primitive types (str, Decimal, int, datetime).

## 8. Relationships

### 8.1 Relationship Diagram

```
Calculationinput (1) ──────< (1) Calculationresult
       │
       │
       └──────< (*) Chartdatapoint
```

### 8.2 Relationship Definitions

| Relationship | Type | Navigation Required | Description |
|--------------|------|---------------------|-------------|
| `Calculationinput` → `Calculationresult` | One-to-One | Yes | Each calculation input has exactly one result; cascade delete |
| `Calculationinput` → `Chartdatapoint` | One-to-Many | Yes | Each calculation input has multiple chart data points (one per year); cascade delete |

**Foreign Key Constraints:**
- `calculation_results.calculation_input_id` → `calculation_inputs.id` (ON DELETE CASCADE)
- `chart_data_points.calculation_input_id` → `calculation_inputs.id` (ON DELETE CASCADE)

**Navigation Patterns:**
- From `Calculationinput`, navigate to `calculation_result` (singular)
- From `Calculationinput`, navigate to `chart_data_points` (collection)
- Both relationships support eager loading for detail endpoints

## 9. API Endpoints

### 9.1 Calculation Management Endpoints

#### POST /calculations

**Description:** Create new SIP calculation with input parameters, compute results using SIP formula, generate chart data points, and return complete calculation details.

**Request Body:**
```json
{
  "monthly_investment": 10000.00,
  "expected_return_rate": 12.00,
  "time_period": 10
}
```

**Response:** `201 Created`
```json
{
  "id": "uuid",
  "monthly_investment": 10000.00,
  "expected_return_rate": 12.00,
  "time_period": 10,
  "timestamp": "2024-01-15T10:30:00Z",
  "created_at": "2024-01-15T10:30:00Z",
  "updated_at": "2024-01-15T10:30:00Z",
  "calculation_result": {
    "id": "uuid",
    "calculation_input_id": "uuid",
    "total_investment": 1200000.00,
    "estimated_returns": 320000.00,
    "maturity_value": 1520000.00,
    "created_at": "2024-01-15T10:30:00Z",
    "updated_at": "2024-01-15T10:30:00Z"
  },
  "chart_data_points": [
    {
      "id": "uuid",
      "calculation_input_id": "uuid",
      "year": 1,
      "invested_amount": 120000.00,
      "projected_value": 127680.00,
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    }
  ]
}
```

**Validation Errors:** `400 Bad Request`

**Service:** `create_calculation_with_chart_data`

---

#### GET /calculations/{id}

**Description:** Retrieve calculation input by ID (without related result and chart data).

**Path Parameters:**
- `id` (str, required): Calculation input ID

**Response:** `200 OK`
```json
{
  "id": "uuid",
  "monthly_investment": 10000.00,
  "expected_return_rate": 12.00,
  "time_period": 10,
  "timestamp": "2024-01-15T10:30:00Z",
  "created_at": "2024-01-15T10:30:00Z",
  "updated_at": "2024-01-15T10:30:00Z"
}
```

**Error Response:** `404 Not Found` if calculation does not exist

---

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

**Description:** Retrieve calculation input with eagerly loaded calculation result and chart data points for complete visualization.

**Path Parameters:**
- `id` (str, required): Calculation input ID

**Eager Load Paths:**
- `CalculationInput.calculation_result`
- `CalculationInput.chart_data_points`

**Response:** `200 OK` (same structure as POST /calculations response)

**Error Response:** `404 Not Found` if calculation does not exist

---

#### GET /calculations

**Description:** List all calculations with optional timestamp filtering for analytics.

**Query Parameters:**
- `from_timestamp` (datetime, optional): Filter calculations from this timestamp
- `to_timestamp` (datetime, optional): Filter calculations up to this timestamp
- `limit` (int, optional, default: 100): Maximum number of results
- `offset` (int, optional, default: 0): Pagination offset

**Response:** `200 OK`
```json
{
  "items": [
    {
      "id": "uuid",
      "monthly_investment": 10000.00,
      "expected_return_rate": 12.00,
      "time_period": 10,
      "timestamp": "2024-01-15T10:30:00Z",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    }
  ],
  "total": 150,
  "limit": 100,
  "offset": 0
}
```

---

#### DELETE /calculations/{id}

**Description:** Delete a calculation (cascades to result and chart data points).

**Path Parameters:**
- `id` (str, required): Calculation input ID

**Response:** `204 No Content`

**Error Response:** `404 Not Found` if calculation does not exist

**Cascade Behavior:**
- Deletes associated `calculation_results` record
- Deletes all associated `chart_data_points` records

---

### 9.2 Endpoint Summary Table

| Method | Route | Purpose | Auth Required |
|--------|-------|---------|---------------|
| POST | `/calculations` | Create SIP calculation with results and chart data | No |
| GET | `/calculations/{id}` | Retrieve calculation input only | No |
| GET | `/calculations/{id}/details` | Retrieve calculation with result and chart data | No |
| GET | `/calculations` | List calculations with filtering | No |
| DELETE | `/calculations/{id}` | Delete calculation and related data | No |

## 10. Workflow Logic

### 10.1 Calculate SIP Returns

**Trigger:** User submits calculation request via POST /calculations

**Flow:**

1. **Input Reception & Validation**
   - Receive `monthly_investment`, `expected_return_rate`, `time_period` from request body
   - Validate monthly_investment: 500 ≤ value ≤ 100,000, max 2 decimal places
   - Validate expected_return_rate: 1 ≤ value ≤ 30, max 2 decimal places
   - Validate time_period: 1 ≤ value ≤ 40, integer only
   - If validation fails, return 400 with error details

2. **Create Calculation Input Record**
   - Generate UUID for `id`
   - Set `timestamp` to current UTC time
   - Save `Calculationinput` entity to database

3. **Apply SIP Formula**
   - Calculate monthly interest rate: `i = expected_return_rate / 12 / 100`
   - Calculate total months: `n = time_period × 12`
   - Apply SIP maturity formula: `M = P × ({[1 + i]^n – 1} / i) × (1 + i)`
     - Where P = monthly_investment
   - Round maturity_value to 2 decimal places

4. **Compute Result Metrics**
   - Calculate `total_investment = monthly_investment × n`
   - Calculate `estimated_returns = maturity_value - total_investment`
   - Create `Calculationresult` entity with calculation_input_id reference
   - Save to database

5. **Generate Chart Data Points**
   - For year = 1 to time_period:
     - Calculate months_elapsed = year × 12
     - Calculate `invested_amount = monthly_investment × months_elapsed`
     - Apply SIP formula for n = months_elapsed to get `projected_value`
     - Create `Chartdatapoint` entity with year, invested_amount, projected_value
     - Save to database
   - Batch insert all chart data points

6. **Return Response**
   - Eager load calculation_result and chart_data_points
   - Serialize complete calculation with nested data
   - Return 201 Created with full payload

**Error Handling:**
- Validation errors: 400 Bad Request with field-specific messages
- Database errors: 500 Internal Server Error with generic message

---

### 10.2 Adjust Investment Parameters

**Trigger:** User modifies any input parameter (frontend interaction)

**Flow:**

1. **Frontend Debounce**
   - User modifies monthly_investment, expected_return_rate, or time_period
   - Frontend applies 300ms debounce before making API call

2. **Submit New Calculation**
   - Frontend calls POST /calculations with updated parameters
   - Backend validates against business rules (same as 10.1 step 1)

3. **Validation Result**
   - **If Valid:**
     - Execute full calculation workflow (10.1 steps 2-6)
     - Return new calculation with fresh ID
     - Frontend replaces displayed results
   - **If Invalid:**
     - Return 400 Bad Request with validation errors
     - Frontend displays inline error messages
     - User corrects input

**Note:** Each parameter adjustment creates a new calculation record; no update operation exists. This supports stateless operation and calculation history tracking.

---

### 10.3 Display Investment Growth Chart

**Trigger:** Frontend receives calculation response with chart_data_points

**Backend Responsibility:**

1. **Chart Data Generation (during calculation)**
   - For time_period ≤ 10 years: Generate data point for every year
   - For time_period > 10 years: Generate data points every 2-3 years (implementation discretion)
   - Each data point includes:
     - `year`: Timeline position
     - `invested_amount`: Cumulative principal invested
     - `projected_value`: Portfolio value with compound interest

2. **Data Point Calculation**
   - For each year Y in 1..time_period:
     - `months = Y × 12`
     - `invested_amount = monthly_investment × months`
     - `projected_value = SIP_formula(monthly_investment, monthly_rate, months)`
   - Round all values to 2 decimal places

3. **Response Structure**
   - Return chart_data_points array ordered by year ascending
   - Include all calculated fields for frontend rendering

**Frontend Responsibility (out of backend scope):**
- Render interactive chart (e.g., line chart or area chart)
- Display invested_amount and projected_value on separate series
- Show hover tooltips with formatted currency values
- Highlight growth differential between investment and returns

## 11. Business Logic

### 11.1 SIP Calculation Formula

**Standard SIP Maturity Formula:**

```
M = P × ({[1 + i]^n – 1} / i) × (1 + i)

Where:
  M = Maturity value (total corpus)
  P = Monthly investment amount
  i = Monthly interest rate (annual_rate / 12 / 100)
  n = Total number of months (time_period × 12)
```

**Implementation Details:**
- Interest is compounded monthly
- Investments are made at the beginning of each month (SIP convention)
- Formula accounts for first payment earning interest for full month

**Calculation Sequence:**
1. Convert annual return rate to monthly: `monthly_rate = expected_return_rate / 12 / 100`
2. Calculate total months: `total_months = time_period × 12`
3. Calculate growth factor: `(1 + monthly_rate)^total_months`
4. Apply full formula: `M = monthly_investment × ((growth_factor - 1) / monthly_rate) × (1 + monthly_rate)`
5. Round to 2 decimal places

---

### 11.2 Investment Metrics

#### Total Investment
```
total_investment = monthly_investment × time_period × 12
```
Represents the principal amount contributed without any returns.

#### Estimated Returns
```
estimated_returns = maturity_value - total_investment
```
Represents the wealth gained through compound interest over the investment period.

#### Maturity Value
Calculated using SIP formula (11.1). Represents the final portfolio value.

---

### 11.3 Input Constraints

| Parameter | Minimum | Maximum | Decimal Places | Data Type |
|-----------|---------|---------|----------------|-----------|
| Monthly Investment | ₹500 | ₹100,000 | 2 | Decimal |
| Expected Return Rate | 1% | 30% | 2 | Decimal |
| Time Period | 1 year | 40 years | 0 (integer) | Integer |

**Default Values:**
- Monthly Investment: ₹10,000
- Expected Return Rate: 12%
- Time Period: 10 years

---

### 11.4 Chart Data Generation Rules

1. **Granularity:**
   - Time period ≤ 10 years: Generate one data point per year
   - Time period > 10 years: Generate data points every 2-3 years to optimize chart readability

2. **Data Point Calculation:**
   - For each selected year Y:
     - `invested_amount = monthly_investment × (Y × 12)`
     - `projected_value = SIP_formula(monthly_investment, monthly_rate, Y × 12)`

3. **Ordering:**
   - Chart data points ordered by year ascending (1, 2, 3, ...)

4. **Precision:**
   - All currency amounts rounded to 2 decimal places using standard rounding (half-up)

---

### 11.5 Currency Handling

- **Currency:** Indian Rupee (₹) only
- **Precision:** All decimal fields limited to 2 decimal places
- **Rounding:** Standard rounding (half-up) applied to all calculations
- **Storage:** Decimal type with appropriate precision (e.g., Decimal(15,2) for large amounts)

---

### 11.6 Timestamp Management

- **Creation:** All entities receive `created_at` timestamp on insertion
- **Updates:** All entities receive `updated_at` timestamp on modification
- **Calculation Timestamp:** `Calculationinput.timestamp` records when calculation was performed (for analytics)
- **Timezone:** All timestamps stored in UTC

## 12. Validation Rules

### 12.1 Field-Level Validations

#### Calculationinput

| Field | Validation Rule | Error Message |
|-------|----------------|---------------|
| `monthly_investment` | >= 500 AND <= 100000 | "Monthly investment must be between ₹500 and ₹100,000" |
| `monthly_investment` | Max 2 decimal places | "Monthly investment must have at most 2 decimal places" |
| `monthly_investment` | > 0 | "Monthly investment must be a positive non-zero value" |
| `expected_return_rate` | >= 1 AND <= 30 | "Expected return rate must be between 1% and 30%" |
| `expected_return_rate` | Max 2 decimal places | "Expected return rate must have at most 2 decimal places" |
| `expected_return_rate` | > 0 | "Expected return rate must be a positive non-zero value" |
| `time_period` | >= 1 AND <= 40 | "Time period must be between 1 and 40 years" |
| `time_period` | Integer only | "Time period must be a whole number (no decimals)" |
| `time_period` | > 0 | "Time period must be a positive non-zero value" |

#### Calculationresult

| Field | Validation Rule | Error Message |
|-------|----------------|---------------|
| `calculation_input_id` | Must reference existing calculation_inputs.id | "Invalid calculation input reference" |
| `total_investment` | >= 0 | "Total investment must be non-negative" |
| `estimated_returns` | >= 0 | "Estimated returns must be non-negative" |
| `maturity_value` | >= 0 | "Maturity value must be non-negative" |

#### Chartdatapoint

| Field | Validation Rule | Error Message |
|-------|----------------|---------------|
| `calculation_input_id` | Must reference existing calculation_inputs.id | "Invalid calculation input reference" |
| `year` | >= 1 AND <= time_period | "Year must be between 1 and the calculation time period" |
| `invested_amount` | >= 0 | "Invested amount must be non-negative" |
| `projected_value` | >= 0 | "Projected value must be non-negative" |

---

### 12.2 Cross-Field Validations

1. **Calculationresult Consistency:**
   ```
   estimated_returns = maturity_value - total_investment
   ```
   This must hold true within rounding tolerance (±0.01).

2. **Chartdatapoint Year Range:**
   ```
   chart_data_point.year <= calculation_input.time_period
   ```
   No data point can have a year beyond the investment time period.

3. **Total Investment Accuracy:**
   ```
   total_investment = monthly_investment × time_period × 12
   ```
   Calculated value must match stored value within rounding tolerance.

---

### 12.3 Referential Integrity

| Constraint | Rule | Action on Delete |
|------------|------|------------------|
| `calculation_results.calculation_input_id` | Must reference valid `calculation_inputs.id` | CASCADE DELETE |
| `chart_data_points.calculation_input_id` | Must reference valid `calculation_inputs.id` | CASCADE DELETE |

**Unique Constraints:**
- `calculation_results.calculation_input_id` must be unique (one-to-one relationship)

---

### 12.4 Validation Execution Points

1. **Request Body Validation (Pydantic):**
   - Type checking (Decimal, int, str)
   - Required field presence
   - Format validation (decimal places, UUID format)

2. **Business Rule Validation (Service Layer):**
   - Range constraints (min/max values)
   - Cross-field consistency
   - Referential integrity

3. **Database Constraints (SQLAlchemy/SQLite):**
   - Foreign key constraints
   - Unique constraints
   - NOT NULL constraints

**Error Response Format:**
```json
{
  "detail": [
    {
      "loc": ["body", "monthly_investment"],
      "msg": "Monthly investment must be between ₹500 and ₹100,000",
      "type": "value_error"
    }
  ]
}
```

## 13. Implementation Notes

### 13.1 Technology Stack

| Component | Technology | Version |
|-----------|------------|---------|
| **Framework** | FastAPI | Latest stable |
| **ORM** | SQLAlchemy | 2.x with async support |
| **Database** | SQLite | 3.x (development/production) |
| **Validation** | Pydantic | v2.x |
| **Package Manager** | uv | Latest |
| **Python** | Python | 3.11+ |

---

### 13.2 Architecture Pattern

**Service Layer Pattern:**
```
API Layer (FastAPI routes)
    ↓
Service Layer (business logic)
    ↓
Repository Layer (SQLAlchemy ORM)
    ↓
Database (SQLite)
```

**Key Principles:**
- Separation of concerns: Routes handle HTTP, services handle business logic, repositories handle data access
- Dependency injection: Use `Depends(get_db)` for database session management
- Transaction management: Services control transaction boundaries
- Single responsibility: Each service method performs one business operation

---

### 13.3 Database Session Management

**Dependency Injection:**
```python
from fastapi import Depends
from sqlalchemy.orm import Session

def get_db() -> Session:
    # Yield database session
    # Auto-close after request completes
```

**Usage in Routes:**
```python
@app.post("/calculations")
def create_calculation(
    data: CalculationInputCreate,
    db: Session = Depends(get_db)
):
    return calculation_service.create_with_chart_data(db, data)
```

---

### 13.4 Entity Models (SQLAlchemy)

**Base Configuration:**
- Use declarative base with mapped classes
- Define `__tablename__` for each model
- Include `created_at` and `updated_at` with auto-management
- Use UUID strings for primary keys
- Define relationships with `back_populates` for bidirectional navigation

**Relationship Definitions:**
```python
class Calculationinput(Base):
    calculation_result = relationship("Calculationresult", back_populates="calculation_input", uselist=False, cascade="all, delete-orphan")
    chart_data_points = relationship("Chartdatapoint", back_populates="calculation_input", cascade="all, delete-orphan")
```

---

### 13.5 Pydantic Schemas

**Schema Types:**
- **Create Schemas:** Accept user input (exclude id, timestamps)
- **Update Schemas:** Accept partial updates (all fields optional)
- **Response Schemas:** Include all fields + relationships
- **Detail Schemas:** Include nested related entities

**Validation:**
- Use Pydantic v2 field validators for business rules
- Use `@field_validator` for custom validation logic
- Define `model_config` for ORM mode: `ConfigDict(from_attributes=True)`

---

### 13.6 Service Layer Implementation

**Calculation Service Responsibilities:**
1. Input validation beyond Pydantic (business rules)
2. SIP formula computation
3. Coordinate multi-entity creation (input + result + chart data points)
4. Transaction management
5. Error handling and logging

**Batch Write Service:**
```python
def create_calculation_with_chart_data(db: Session, input_data: CalculationInputCreate):
    # 1. Create calculation input
    # 2. Compute SIP result
    # 3. Generate chart data points (batch)
    # 4. Commit transaction
    # 5. Return with eager-loaded relationships
```

---

### 13.7 API Documentation

**Automatic OpenAPI Documentation:**
- FastAPI generates interactive docs at `/docs` (Swagger UI)
- Alternative docs at `/redoc` (ReDoc)
- OpenAPI schema available at `/openapi.json`

**Documentation Enhancements:**
- Add `summary` and `description` to route decorators
- Use Pydantic schema `description` fields
- Provide example values in schemas
- Document response codes (200, 201, 400, 404, 500)

---

### 13.8 Error Handling

**Standard Error Responses:**
- `400 Bad Request`: Validation errors, business rule violations
- `404 Not Found`: Resource not found by ID
- `500 Internal Server Error`: Unexpected server errors

**Error Response Format (FastAPI default):**
```json
{
  "detail": "Error message or validation details"
}
```

**Logging:**
- Log all errors with stack traces
- Log calculation inputs for debugging (without PII concerns)
- Log API request/response times for performance monitoring

---

### 13.9 Database Setup

**SQLite Configuration:**
- Database file location: `./data/sip_calculator.db`
- Enable foreign key constraints: `PRAGMA foreign_keys = ON`
- Use WAL mode for better concurrency: `PRAGMA journal_mode = WAL`

**Initialization:**
- Use `Base.metadata.create_all(engine)` for table creation
- Populate with default/seed data if needed

---

### 13.10 Package Management with uv

**Project Setup:**
```bash
uv init
uv add fastapi sqlalchemy pydantic sqlite
uv add --dev pytest httpx
```

**Run Application:**
```bash
uv run uvicorn main:app --reload
```

---

### 13.11 Project Structure

```
/app
  /api
    /routes
      calculations.py
  /services
    calculation_service.py
  /repositories
    calculation_repository.py
  /models
    calculation.py
  /schemas
    calculation.py
  /core
    database.py
    config.py
  main.py
/tests
  /test_api
  /test_services
pyproject.toml
```

## 14. Assumptions

1. **Stateless Operation:**
   - Application is client-side focused with minimal backend persistence
   - Calculations happen on server but results are ephemeral from user perspective
   - Each calculation creates new records rather than updating existing ones

2. **No Authentication:**
   - All endpoints are publicly accessible without authentication
   - No user sessions or authorization checks required
   - AnonymousUser role has full access to all operations

3. **Chart Data Generation:**
   - Chart data points are generated programmatically for each calculation
   - Points are not stored incrementally; full set created on calculation
   - Granularity decision (yearly vs. every 2-3 years) made at generation time

4. **Data Persistence:**
   - Calculation results stored for analytics purposes (timestamp tracking)
   - Storage not required for user sessions or history viewing
   - Users cannot retrieve their "previous calculations" (no user identity)

5. **Currency:**
   - Indian Rupee (₹) is the primary and only currency
   - No multi-currency support needed initially
   - All amounts formatted and validated as INR

6. **SIP Formula Convention:**
   - Standard compound interest with monthly compounding
   - Investments made at beginning of each month (typical SIP convention)
   - Formula: M = P × ({[1 + i]^n – 1} / i) × (1 + i)

7. **Frontend Responsibilities:**
   - Frontend handles debouncing (300ms) for input changes
   - Frontend manages real-time UI updates
   - Backend provides calculation API without session state

8. **Cascade Deletion:**
   - Deleting a calculation input cascades to result and chart data points
   - No orphaned records remain after deletion
   - Enforced via database foreign key constraints

9. **Data Volume:**
   - Expected moderate calculation volume (not high-frequency trading)
   - SQLite sufficient for production workload
   - No sharding or distributed database required

10. **Calculation Accuracy:**
    - Standard rounding (half-up) acceptable for financial calculations
    - 2 decimal place precision sufficient for displayed amounts
    - No regulatory compliance for exact financial reporting

## 15. Future Improvements

### 15.1 Database & Deployment

1. **Alembic Migrations:**
   - Implement Alembic for database schema versioning
   - Support rollback and forward migrations
   - Track schema changes in version control

2. **PostgreSQL Migration:**
   - Move from SQLite to PostgreSQL for production
   - Support higher concurrency and data volume
   - Enable advanced features (full-text search, JSON columns)

3. **Docker Containerization:**
   - Create Dockerfile for consistent deployment
   - Docker Compose for local development (app + database)
   - Multi-stage builds for optimized image size

---

### 15.2 Authentication & Authorization

4. **JWT Authentication:**
   - Implement JWT-based authentication
   - Secure endpoints requiring user identity
   - Support login, logout, token refresh

5. **Role-Based Access Control (RBAC):**
   - Define roles: User, Admin, Analyst
   - Implement permission checks at endpoint level
   - Support role-based feature access

6. **User Management:**
   - User registration and profile management
   - Save multiple calculation scenarios per user
   - Compare and track historical calculations

---

### 15.3 Testing & Quality

7. **Comprehensive Test Suite:**
   - Unit tests for service layer (calculation logic)
   - Integration tests for API endpoints (using TestClient)
   - Fixtures for test data generation
   - Coverage target: 90%+

8. **Performance Testing:**
   - Load testing for concurrent calculation requests
   - Optimize database queries with indexing
   - Profile slow calculations for optimization

9. **Input Validation Testing:**
   - Boundary value testing for all input constraints
   - Negative testing for invalid inputs
   - Fuzzing for unexpected input patterns

---

### 15.4 Feature Enhancements

10. **Step-Up SIP:**
    - Support annually increasing SIP amounts
    - Add `step_up_percentage` parameter
    - Adjust calculations for growing contributions

11. **Tax Calculation:**
    - Calculate LTCG (Long-Term Capital Gains) and STCG (Short-Term Capital Gains)
    - Apply tax rates based on holding period
    - Display post-tax maturity value

12. **Multi-Currency Support:**
    - Support USD, EUR, GBP in addition to INR
    - Configurable currency symbols and formatting
    - Conversion rate integration (optional)

13. **Monthly Chart Granularity:**
    - Provide option for monthly data points (short-term investments)
    - Dynamic granularity based on time period
    - Optimize for chart rendering performance

14. **PDF Report Generation:**
    - Generate downloadable PDF with calculation summary
    - Include chart visualization in PDF
    - Branding and customization options

15. **Historical Data Integration:**
    - Integrate real mutual fund historical performance
    - Provide realistic return rate suggestions
    - Display past performance trends

16. **Scenario Comparison:**
    - Save multiple calculation scenarios
    - Side-by-side comparison UI
    - Highlight differences and optimal choices

---

### 15.5 Observability & Operations

17. **Logging & Monitoring:**
    - Structured logging (JSON format)
    - Integration with logging platforms (e.g., ELK, Splunk)
    - Performance metrics (response times, error rates)

18. **Health Checks:**
    - `/health` endpoint for container orchestration
    - Database connectivity check
    - Readiness and liveness probes

19. **API Versioning:**
    - Implement versioning strategy (e.g., `/v1/calculations`)
    - Support multiple API versions concurrently
    - Deprecation notices for old versions

20. **Rate Limiting:**
    - Implement rate limiting to prevent abuse
    - Per-IP or per-user limits
    - Graceful throttling responses

---

This backend specification provides a complete foundation for implementing the SIP Calculator system with FastAPI, SQLAlchemy, and SQLite, ready for development with clear implementation guidelines and future scalability paths.
