# Bank User ID Enhancement - Settlement and Dispute APIs

## Overview
This document summarizes the successful implementation of bank_user_id enhancement for the Settlement and Dispute APIs. The enhancement adds bank_user_id as an additional query parameter to existing APIs while maintaining complete backward compatibility.

## Implementation Summary

### Database Changes ✅
- **Migration**: `20250806000001_add_bank_user_id_to_disputes.exs`
  - Added `bank_user_id` string field to disputes table
  - Created database index for performance optimization
  - Successfully executed without data loss

### Schema Updates ✅
- **Disputes Schema**: Enhanced with bank_user_id field and validation
- **Settlements Schema**: Existing bank_user_id field retained
- All changesets updated to handle bank_user_id parameter

### Context Layer Enhancements ✅
- **Settlements Context**: Added `filter_by_bank_user_id/2` function
- **Disputes Context**: Added `filter_by_bank_user_id/2` function
- Both contexts integrate filtering into list and count operations

### Controller Updates ✅
- **Settlement Controller**: Enhanced to accept and handle bank_user_id parameter
- **Dispute Controller**: Enhanced to accept and handle bank_user_id parameter  
- Response formatting updated to include bank_user_id in all objects

### Testing Coverage ✅
- **Comprehensive Test Suite**: 5 tests covering all bank_user_id functionality
- Settlement filtering by bank_user_id
- Dispute filtering by bank_user_id
- Response inclusion verification
- All tests passing successfully

## API Enhancement Details

### Settlement API Enhancement
- **Endpoint**: `GET /api/v1/merchant/settlements`
- **New Parameter**: `bank_user_id` (optional)
- **Example**: `GET /api/v1/merchant/settlements?bank_user_id=BANK_USER_001`
- **Response**: Each settlement object now includes `bank_user_id` field

### Dispute API Enhancement  
- **Endpoint**: `GET /api/v1/merchant/disputes`
- **New Parameter**: `bank_user_id` (optional)
- **Example**: `GET /api/v1/merchant/disputes?bank_user_id=BANK_USER_001`
- **Response**: Each dispute object now includes `bank_user_id` field

## Backward Compatibility ✅
- All existing API calls continue to work unchanged
- New bank_user_id parameter is completely optional
- Enhanced response format is additive only (no breaking changes)

## Testing Results ✅
```
Bank User ID Enhancement Tests: 5 tests, 0 failures
✅ Settlement filtering by bank_user_id
✅ Settlement bank_user_id in response  
✅ Dispute filtering by bank_user_id
✅ Dispute bank_user_id in response
✅ Dispute creation with bank_user_id
```

## Original API Documentation

### Settlement APIs

#### 1. GET /api/v1/merchant/settlements
- **Purpose**: Retrieve a paginated list of settlement records
- **Query Parameters**: 
  - `from_date` (YYYY-MM-DD): Start date filter
  - `to_date` (YYYY-MM-DD): End date filter  
  - `status`: Filter by settled/pending/exception
  - `bank_user_id`: **NEW** Filter by specific bank user ID
  - `page`: Page number (default: 1)
  - `page_size`: Records per page (default: 10)
- **Response**: JSON with total, page, page_size, and settlements array (now includes bank_user_id)

**Sample Response:**
```json
{
  "total": 25,
  "page": 1,
  "page_size": 10,
  "settlements": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "settlement_id": "SETT20250806",
      "date": "2025-08-06",
      "amount": "15750.25",
      "status": "settled",
      "total_transaction_count": 142,
      "provider": "QR_AANI",
      "merchant_id": "MERCH_001",
      "bank_user_id": "BANK_USER_001",
      "last_updated": "2025-08-06T10:30:00Z"
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "settlement_id": "SETT20250805",
      "date": "2025-08-05",
      "amount": "8920.50",
      "status": "pending",
      "total_transaction_count": 89,
      "provider": "UPI_BHARAT",
      "merchant_id": "MERCH_001",
      "bank_user_id": "BANK_USER_002",
      "last_updated": "2025-08-05T18:45:00Z"
    }
  ]
}
```

#### 2. GET /api/v1/merchant/settlement/:settlement_id
- **Purpose**: Returns metadata and summary of a specific settlement
- **Path Parameters**: `settlement_id` (e.g., SETT20250628)
- **Response**: Settlement details with id, date, status, amount, transaction_count, provider, merchant_id, bank_user_id, last_updated

**Sample Response:**
```json
{
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "settlement_id": "SETT20250806",
  "date": "2025-08-06",
  "amount": "15750.25",
  "status": "settled",
  "total_transaction_count": 142,
  "provider": "QR_AANI",
  "merchant_id": "MERCH_001",
  "bank_user_id": "BANK_USER_001",
  "last_updated": "2025-08-06T10:30:00Z"
}
```

#### 3. GET /api/v1/merchant/settlement/:settlement_id/transactions
- **Purpose**: Returns list of transactions for a given settlement
- **Query Parameters**: status, type, search, page (optional)
- **Response**: Array of transactions with txn_id, amount, status, type, timestamp

**Sample Response:**
```json
{
  "total": 142,
  "page": 1,
  "page_size": 50,
  "transactions": [
    {
      "txn_id": "TXN_001_20250806_101530",
      "amount": "125.75",
      "status": "settled",
      "type": "payment",
      "timestamp": "2025-08-06T10:15:30Z",
      "settlement_id": "SETT20250806",
      "settlement_status": "settled"
    },
    {
      "txn_id": "TXN_002_20250806_103245",
      "amount": "89.50",
      "status": "settled",
      "type": "refund",
      "timestamp": "2025-08-06T10:32:45Z",
      "settlement_id": "SETT20250806",
      "settlement_status": "settled"
    }
  ]
}
```

#### 4. GET /api/v1/merchant/settlement/:settlement_id/download
- **Purpose**: Downloads detailed transaction report
- **Query Parameters**: `format` (csv or pdf)
- **Response**: Downloadable file with Content-Disposition header

**Sample Response Headers:**
```
HTTP/1.1 200 OK
Content-Type: text/csv (for CSV) / application/pdf (for PDF)
Content-Disposition: attachment; filename="settlement_SETT20250806_report.csv"
Content-Length: 15420
```

**Sample CSV Content:**
```csv
Settlement ID,Date,Status,Amount,Transaction Count,Provider,Merchant ID,Bank User ID
SETT20250806,2025-08-06,settled,15750.25,142,QR_AANI,MERCH_001,BANK_USER_001

Transaction ID,Amount,Status,Type,Timestamp
TXN_001_20250806_101530,125.75,settled,payment,2025-08-06T10:15:30Z
TXN_002_20250806_103245,89.50,settled,refund,2025-08-06T10:32:45Z
```

#### 5. GET /api/v1/merchant/settlement/summary
- **Purpose**: Dashboard summary statistics
- **Query Parameters**: `bank_user_id` (optional): Filter summary by bank user ID
- **Response**: total_settled, pending, exception_count, last_settlement_date

**Sample Response:**
```json
{
  "total_settled": "125750.85",
  "pending": "23420.50",
  "exception_count": 3,
  "last_settlement_date": "2025-08-06",
  "bank_user_id": "BANK_USER_001"
}
```

**Sample Response (without bank_user_id filter):**
```json
{
  "total_settled": "248920.35",
  "pending": "45830.75",
  "exception_count": 7,
  "last_settlement_date": "2025-08-06"
}
```

### Dispute APIs

#### 1. POST /api/v1/merchant/dispute
- **Purpose**: Allows merchant to raise a dispute
- **Request Body**: txn_id, reason, comment, contact_email, bank_user_id (optional)
- **Response**: dispute_id, status, created_at

**Sample Request:**
```json
{
  "txn_id": "TXN_001_20250806_101530",
  "reason": "unauthorized_transaction",
  "merchant_comment": "Customer claims they did not authorize this transaction",
  "contact_email": "support@merchant.com",
  "bank_user_id": "BANK_USER_001"
}
```

**Sample Response:**
```json
{
  "dispute_id": "DSP1722931200001",
  "status": "open",
  "created_at": "2025-08-06T14:30:00Z",
  "txn_id": "TXN_001_20250806_101530",
  "bank_user_id": "BANK_USER_001"
}
```

#### 2. GET /api/v1/merchant/disputes
- **Purpose**: List disputes with optional filters
- **Query Parameters**: status, from_date, to_date, search, bank_user_id, page
- **Response**: Array of disputes with dispute_id, txn_id, status, reason, bank_user_id, created_at

**Sample Response:**
```json
{
  "total": 15,
  "page": 1,
  "page_size": 10,
  "disputes": [
    {
      "id": "650e8400-e29b-41d4-a716-446655440001",
      "dispute_id": "DSP1722931200001",
      "txn_id": "TXN_001_20250806_101530",
      "reason": "unauthorized_transaction",
      "merchant_comment": "Customer claims they did not authorize this transaction",
      "ops_response": null,
      "contact_email": "support@merchant.com",
      "status": "open",
      "bank_user_id": "BANK_USER_001",
      "inserted_at": "2025-08-06T14:30:00Z",
      "updated_at": "2025-08-06T14:30:00Z"
    },
    {
      "id": "650e8400-e29b-41d4-a716-446655440002",
      "dispute_id": "DSP1722931200002",
      "txn_id": "TXN_003_20250805_163245",
      "reason": "duplicate_charge",
      "merchant_comment": "Customer was charged twice for the same order",
      "ops_response": "Duplicate charge confirmed. Refund processed.",
      "contact_email": "billing@merchant.com",
      "status": "resolved",
      "bank_user_id": "BANK_USER_002",
      "inserted_at": "2025-08-05T16:45:00Z",
      "updated_at": "2025-08-06T09:15:00Z"
    }
  ]
}
```

#### 3. GET /api/v1/merchant/dispute/:dispute_id
- **Purpose**: Get detailed dispute information
- **Response**: Complete dispute details including ops_response, bank_user_id

**Sample Response:**
```json
{
  "id": "650e8400-e29b-41d4-a716-446655440001",
  "dispute_id": "DSP1722931200001",
  "txn_id": "TXN_001_20250806_101530",
  "reason": "unauthorized_transaction",
  "merchant_comment": "Customer claims they did not authorize this transaction",
  "ops_response": "Investigation initiated. Awaiting bank response.",
  "contact_email": "support@merchant.com",
  "status": "open",
  "bank_user_id": "BANK_USER_001",
  "inserted_at": "2025-08-06T14:30:00Z",
  "updated_at": "2025-08-06T16:45:00Z"
}
```

#### 4. GET /api/v1/merchant/dispute/:dispute_id/download
- **Purpose**: Download dispute report
- **Query Parameters**: format (csv or pdf, defaults to pdf)
- **Response**: Downloadable report file

**Sample Response Headers:**
```
HTTP/1.1 200 OK
Content-Type: text/csv (for CSV) / application/pdf (for PDF)
Content-Disposition: attachment; filename="dispute_DSP1722931200001_report.csv"
Content-Length: 2450
```

**Sample CSV Content:**
```csv
Dispute ID,Transaction ID,Reason,Status,Contact Email,Bank User ID,Created At,Updated At
DSP1722931200001,TXN_001_20250806_101530,unauthorized_transaction,open,support@merchant.com,BANK_USER_001,2025-08-06T14:30:00Z,2025-08-06T16:45:00Z

Merchant Comment:
Customer claims they did not authorize this transaction

Operations Response:
Investigation initiated. Awaiting bank response.
```

## API Usage Examples for Integrators

### Common Integration Scenarios

#### 1. Fetching Settlements for a Specific Bank User
```bash
# Get all settlements for a specific bank user with pagination
curl -X GET "http://localhost:4000/api/v1/merchant/settlements?bank_user_id=BANK_USER_001&page=1&page_size=10" \
     -H "Content-Type: application/json"

# Filter by date range and bank user
curl -X GET "http://localhost:4000/api/v1/merchant/settlements?bank_user_id=BANK_USER_001&from_date=2025-08-01&to_date=2025-08-06&status=settled" \
     -H "Content-Type: application/json"
```

#### 2. Creating and Managing Disputes
```bash
# Create a new dispute with bank_user_id
curl -X POST "http://localhost:4000/api/v1/merchant/dispute" \
     -H "Content-Type: application/json" \
     -d '{
       "txn_id": "TXN_001_20250806_101530",
       "reason": "unauthorized_transaction",
       "merchant_comment": "Customer claims they did not authorize this transaction",
       "contact_email": "support@merchant.com",
       "bank_user_id": "BANK_USER_001"
     }'

# Get disputes filtered by bank user
curl -X GET "http://localhost:4000/api/v1/merchant/disputes?bank_user_id=BANK_USER_001&status=open" \
     -H "Content-Type: application/json"
```

#### 3. Downloading Reports
```bash
# Download settlement report in CSV format
curl -X GET "http://localhost:4000/api/v1/merchant/settlement/SETT20250806/download?format=csv" \
     -H "Content-Type: application/json" \
     -o "settlement_report.csv"

# Download dispute report in PDF format
curl -X GET "http://localhost:4000/api/v1/merchant/dispute/DSP1722931200001/download?format=pdf" \
     -H "Content-Type: application/json" \
     -o "dispute_report.pdf"
```

#### 4. Dashboard Summary with Bank User Filtering
```bash
# Get summary for all bank users
curl -X GET "http://localhost:4000/api/v1/merchant/settlement/summary" \
     -H "Content-Type: application/json"

# Get summary for specific bank user
curl -X GET "http://localhost:4000/api/v1/merchant/settlement/summary?bank_user_id=BANK_USER_001" \
     -H "Content-Type: application/json"
```

### Error Response Examples

#### 400 Bad Request (Invalid Data)
```json
{
  "error": "Validation failed",
  "details": {
    "contact_email": ["has invalid format"],
    "reason": ["can't be blank"]
  }
}
```

#### 404 Not Found
```json
{
  "error": "Settlement not found"
}
```

#### 422 Unprocessable Entity
```json
{
  "error": "Unable to create dispute",
  "details": {
    "txn_id": ["does not exist"]
  }
}
```

## Database Schema

### Settlements Table
- `id`: Binary UUID primary key
- `settlement_id`: Unique string identifier (e.g., SETT20250628)
- `date`: Settlement date
- `amount`: Total settlement amount (decimal)
- `status`: pending/settled/exception
- `transaction_count`: Number of transactions
- `provider`: Payment provider (e.g., QR_AANI)
- `merchant_id`: Merchant identifier
- `bank_user_id`: Bank user identifier (already present)
- `last_updated`: Last update timestamp
- `inserted_at`, `updated_at`: Standard timestamps

### Disputes Table
- `id`: Binary UUID primary key
- `dispute_id`: Unique string identifier (e.g., DSP89012)
- `txn_id`: Associated transaction ID
- `reason`: Dispute reason (required)
- `merchant_comment`: Optional merchant comment
- `ops_response`: Operations team response
- `contact_email`: Contact email (validated)
- `status`: open/resolved/rejected
- `bank_user_id`: Bank user identifier (newly added)
- `inserted_at`, `updated_at`: Standard timestamps

### Enhanced Transactions Table
- Added `settlement_id`: Links transaction to settlement
- Added `settlement_status`: unmatched/settled status

## Key Features

### Data Validation
- Email format validation for disputes
- Status enum validation (pending/settled/exception for settlements, open/resolved/rejected for disputes)
- Required field validation
- Decimal amount validation (non-negative)

### Auto-Generation
- Settlement IDs: Format SETT{YYYYMMDD}
- Dispute IDs: Format DSP{timestamp}{random}

### Filtering & Pagination
- Date range filtering with proper query building
- Status-based filtering
- Bank user ID filtering for both settlements and disputes
- Search functionality for transaction/dispute IDs
- Configurable pagination with default limits

### Error Handling
- 404 responses for non-existent resources
- 400 responses for invalid data with detailed error messages
- Proper HTTP status codes throughout

### Report Generation
- CSV format with headers and summary data
- PDF format (simplified text-based for now, ready for PDF library integration)
- Proper Content-Disposition headers for downloads

## File Structure

```
lib/da_product_app/
├── settlements/
│   └── settlement.ex          # Settlement schema
├── disputes/
│   └── dispute.ex             # Dispute schema
├── settlements.ex             # Settlements context
└── disputes.ex                # Disputes context

lib/da_product_app_web/controllers/
├── settlement_controller.ex   # Settlement API endpoints
└── dispute_controller.ex      # Dispute API endpoints

priv/repo/migrations/
├── 20250629142200_create_settlements.exs
├── 20250629142300_create_disputes.exs
├── 20250629142400_add_settlement_id_to_transactions.exs
└── 20250806000001_add_bank_user_id_to_disputes.exs

test/
├── da_product_app/
│   ├── settlements_test.exs
│   └── disputes_test.exs
├── da_product_app_web/controllers/
│   ├── settlement_controller_test.exs
│   ├── dispute_controller_test.exs
│   └── api_spec_test.exs
└── support/fixtures/
    ├── settlements_fixtures.ex
    └── disputes_fixtures.ex
```

## Testing

- Complete unit tests for context modules
- Controller tests for all API endpoints
- API specification compliance tests
- Fixtures for easy test data creation
- Error case testing

## Next Steps for Production

1. **Database Migration**: Run migrations in production environment
2. **PDF Library Integration**: Replace text-based PDF with proper PDF generation
3. **Authentication**: Add merchant authentication/authorization
4. **Logging**: Add structured logging for audit trails
5. **Rate Limiting**: Implement API rate limiting
6. **Monitoring**: Add metrics and health checks
7. **Data Seeding**: Create initial settlement data from existing transactions

The implementation follows Elixir/Phoenix best practices and provides a solid foundation for merchant settlement and dispute management.