self-serve-integration-service
Version:
Self-Serve Integration Service for managing multiple funder integrations including REST APIs, SOAP APIs, and UI automation
545 lines (432 loc) โข 15.2 kB
Markdown
# Self-Serve Integration Service
A comprehensive integration service that provides a unified API for multiple vehicle finance funders including LEX, ALPHABET, and future funders.
## ๐ Features
- **Multi-Funder Support**: Unified API for LEX, ALPHABET, and extensible for additional funders
- **Environment Support**: Both SANDBOX and LIVE environments for each funder
- **Common Request Structure**: Standardized request/response format across all funders
- **๐ Dynamic Retry Mechanism**: Configurable retry logic with exponential backoff for all funder API calls
- **Comprehensive Logging**: Full integration logging and monitoring
- **Database Persistence**: Complete quote and proposal data storage
- **Customer Management**: Automatic customer and vehicle data management
- **Proposal Generation**: Convert quotes to proposals with additional customer details
- **JWT Authentication**: Secure API access with RS256 token verification
## ๐๏ธ Architecture
### Database Schema
The service uses a well-designed database schema that supports:
- **Multiple Funders**: Each funder has its own configuration and credentials
- **Customer Management**: Centralized customer data with flexible address/employment info
- **Vehicle Management**: Comprehensive vehicle data with funder-specific identifiers
- **Quote Lifecycle**: Complete quote generation, storage, and status tracking
- **Proposal Management**: Proposal generation and decision tracking
- **Integration Logging**: Full audit trail of all API interactions
### Service Architecture
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Integration Service โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ
โ โ LEX Service โ โ Alphabet Service โ โ Future... โ โ
โ โ (SANDBOX) โ โ (SANDBOX) โ โ โ โ
โ โ (LIVE) โ โ (LIVE) โ โ โ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Base Funder Service โ
โ (Common functionality & logging) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Database Layer (Prisma) โ
โ (PostgreSQL with full schema) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
## ๐ API Endpoints
### Main Integration API
All endpoints are prefixed with `/api/integration`
#### Quote Generation
```http
POST /api/integration/quotes/generate
```
**Request Body:**
```json
{
"customerDetails": {
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"phone": "+44 7700 900001",
"dateOfBirth": "1985-06-20",
"address": {
"line1": "123 Main Street",
"line2": "Apartment 4B",
"city": "London",
"postcode": "SW1A 1AA",
"country": "UK"
},
"employment": {
"employerName": "Tech Solutions Ltd",
"jobTitle": "Software Engineer",
"employmentType": "FULL_TIME",
"monthlyIncome": 4500
}
},
"vehicleDetails": {
"make": "BMW",
"model": "3 Series",
"variant": "320d M Sport",
"year": 2024,
"price": 38000,
"mileage": 0,
"fuelType": "DIESEL",
"transmission": "AUTOMATIC",
"capId": "12345",
"capCode": "BMW320DMS"
},
"contractDetails": {
"term": 36,
"deposit": 2500,
"annualMileage": 12000,
"quoteType": "PERSONAL_CONTRACT_HIRE",
"balloonPayment": 8000,
"maintenanceIncluded": true
},
"funderName": "LEX",
"environment": "SANDBOX",
"source": "SELF_SERVE_APP"
}
```
**Response:**
```json
{
"success": true,
"data": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"funderName": "LEX",
"status": "GENERATED",
"monthlyPayment": 450.00,
"totalAmount": 16200.00,
"apr": 4.9,
"balloonPayment": 8000.00,
"externalQuoteId": "Q12345",
"externalReference": "LEX-2024-001",
"validUntil": "2024-12-31T23:59:59Z",
"createdAt": "2024-08-26T10:20:54.000Z",
"updatedAt": "2024-08-26T10:20:54.000Z"
},
"message": "Quote generated successfully with LEX"
}
```
#### Quote Status
```http
GET /api/integration/quotes/{quoteId}/status
```
#### Proposal Generation
```http
POST /api/integration/proposals/generate
```
**Request Body:**
```json
{
"quoteId": "123e4567-e89b-12d3-a456-426614174000",
"additionalCustomerDetails": {
"address": {
"line1": "123 Main Street",
"city": "London",
"postcode": "SW1A 1AA"
},
"employment": {
"employerName": "Tech Solutions Ltd",
"jobTitle": "Software Engineer",
"employmentType": "FULL_TIME",
"monthlyIncome": 4500
}
},
"additionalDocuments": {
"drivingLicense": "base64-encoded-data",
"proofOfAddress": "base64-encoded-data"
}
}
```
#### Proposal Status
```http
GET /api/integration/proposals/{proposalId}/status
```
#### Available Funders
```http
GET /api/integration/funders
```
#### Test Funder Connection
```http
POST /api/integration/funders/{funderName}/test
```
#### Customer Quotes
```http
GET /api/integration/customers/{email}/quotes
```
#### Customer Proposals
```http
GET /api/integration/customers/{email}/proposals
```
## ๐ Authentication
The Integration Service uses JWT (JSON Web Token) authentication with RS256 algorithm for secure API access.
### Authentication Flow
1. Obtain JWT token from Auth Service
2. Include token in Authorization header: `Authorization: Bearer <token>`
3. Integration Service verifies token using public key
4. User context is extracted and available in route handlers
### Protected Routes
The following routes require authentication:
- All `/api/integration/*` endpoints
- All `/api/vehicles` endpoints
- All `/api/customers` endpoints
- All `/api/quotes` endpoints
- All `/api/proposals` endpoints
- All `/api/funders` endpoints
### Public Routes
The following routes do NOT require authentication:
- `/health` - Health check
- `/webhooks/*` - Webhook endpoints (validated via signatures)
- `/api-docs` - API documentation
### Usage Example
```bash
# Get token from Auth Service (example)
TOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
# Make authenticated request
curl -X POST http://localhost:3003/api/integration/quotes/generate \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customerDetails": {...},
"vehicleDetails": {...},
"contractDetails": {...}
}'
```
### JWT Configuration
Required environment variables:
```bash
# JWT Configuration (RS256 public key)
JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n"
JWT_ISSUER=self-serve-platform
JWT_AUDIENCE=self-serve-users
```
For detailed authentication documentation, see [JWT_AUTHENTICATION.md](./docs/JWT_AUTHENTICATION.md)
## ๐ Retry Mechanism
The Integration Service includes a robust retry mechanism for all funder API calls to handle transient failures automatically.
### Features
- **Exponential Backoff**: Intelligent delay strategy to avoid overwhelming failing services
- **Configurable**: Fully customizable via environment variables
- **Funder-Specific**: Different retry settings per funder (LEX, Alphabet, etc.)
- **Global Control**: Enable/disable retries with a single flag
- **Comprehensive Logging**: All retry attempts tracked in IntegrationLog table
### Configuration
```bash
# Global retry configuration
API_RETRY_ENABLED=true # Enable/disable retries
API_MAX_RETRIES=3 # Maximum retry attempts
API_RETRY_BASE_DELAY=1000 # Base delay in milliseconds
API_RETRY_MAX_DELAY=10000 # Maximum delay cap
API_RETRY_BACKOFF_MULTIPLIER=2 # Exponential multiplier
# Funder-specific overrides (optional)
LEX_MAX_RETRIES=3
LEX_RETRY_BASE_DELAY=1000
ALPHABET_MAX_RETRIES=5
ALPHABET_RETRY_BASE_DELAY=2000
```
### How It Works
```
Delay = min(BASE_DELAY ร MULTIPLIER^(attempt-1), MAX_DELAY)
```
**Example with default settings (3 retries):**
- Attempt 1: Immediate (0ms delay)
- Attempt 2: 1000ms delay
- Attempt 3: 2000ms delay
- Attempt 4: 4000ms delay
**Total maximum time:** ~7 seconds for 3 retries
### Monitoring
All retry attempts are logged in the `IntegrationLog` table:
```sql
SELECT
operation,
status,
"retryCount",
"responseTime"
FROM "IntegrationLog"
WHERE status IN ('RETRY', 'FAILED')
ORDER BY "createdAt" DESC;
```
For complete documentation, see:
- [RETRY_MECHANISM.md](./docs/RETRY_MECHANISM.md) - Complete guide
- [RETRY_MECHANISM_SUMMARY.md](./RETRY_MECHANISM_SUMMARY.md) - Quick reference
## ๐ง Configuration
### Environment Variables
Copy `env.example` to `.env` and configure:
```bash
# Database
DATABASE_URL="postgresql://username:password@localhost:5432/self_serve_integration"
# LEX Configuration
LEX_APP_ID=6B7b5D1GnPG
LEX_SHARED_SECRET=5bxZBDwTQpYXIuKNzZKAZFGXQGRdtHRqOkf8Dg==
LEX_DEALER_ID_MAJOR=514244
LEX_DEALER_ID_MINOR=FLCSW7X4
LEX_JWT_EXPIRY_HOURS=24
# ALPHABET Configuration
ALPHABET_API_KEY=Egyml2M52BTKw72hB0
ALPHABET_SANDBOX_URL=https://demoservices.codeweavers.net
ALPHABET_LIVE_URL=https://services.codeweavers.net
```
### Database Setup
1. **Create Database:**
```bash
createdb self_serve_integration
```
2. **Run Migrations:**
```bash
npx prisma migrate dev
```
3. **Seed Database:**
```bash
npx prisma db seed
```
## ๐ Getting Started
### Prerequisites
- Node.js 18+
- PostgreSQL 13+
- npm or yarn
### Installation
1. **Install Dependencies:**
```bash
npm install
```
2. **Setup Environment:**
```bash
cp env.example .env
# Edit .env with your configuration
```
3. **Setup Database:**
```bash
npx prisma migrate dev
npx prisma db seed
```
4. **Start Development Server:**
```bash
npm run dev
```
The service will be available at `http://localhost:3003`
### Production Deployment
1. **Build Application:**
```bash
npm run build
```
2. **Run Production Server:**
```bash
npm start
```
## ๐ Funder Integrations
### LEX Integration
- **Authentication**: JWT tokens with HS256 algorithm
- **Environments**: SANDBOX and LIVE
- **API Flow**: Single API call for quote generation
- **Features**: Quote generation, proposal submission, status tracking
### ALPHABET Integration
- **Authentication**: API Key (X-CW-ApiKey header)
- **Environments**: SANDBOX and LIVE
- **API Flow**: 3-step process (Vehicle Details โ Finance Defaults โ Calculate Quote)
- **Features**: Quote generation, proposal submission, status tracking
### Adding New Funders
To add a new funder:
1. **Create Service Class:**
```typescript
export class NewFunderService extends BaseFunderService {
readonly funderName = 'NEW_FUNDER';
readonly supportedQuoteTypes = ['PERSONAL_CONTRACT_HIRE'];
readonly supportedProposalTypes = ['PERSONAL_CONTRACT_HIRE'];
async generateQuote(request: QuoteRequest): Promise<QuoteResponse> {
// Implementation
}
// ... other methods
}
```
2. **Add to Integration Service:**
```typescript
// In integrationService.ts
const newFunderSandbox = new NewFunderService('SANDBOX');
const newFunderLive = new NewFunderService('LIVE');
this.funderServices.set('NEW_FUNDER_SANDBOX', newFunderSandbox);
this.funderServices.set('NEW_FUNDER_LIVE', newFunderLive);
```
3. **Add Database Entry:**
```typescript
// In seed.ts
const newFunder = await prisma.funder.create({
data: {
name: 'NEW_FUNDER',
code: 'NEW_FUNDER',
displayName: 'New Funder',
// ... configuration
}
});
```
## ๐ Monitoring & Logging
### Integration Logs
All API interactions are logged to the `IntegrationLog` table with:
- Request/response data
- Performance metrics
- Error details
- Retry information
- Correlation IDs
### Health Checks
```http
GET /api/health
```
Returns service health status and funder connectivity.
### Metrics
The service provides comprehensive metrics for:
- Quote generation success rates
- API response times
- Error rates by funder
- Retry statistics
## ๐งช Testing
### Unit Tests
```bash
npm test
```
### Integration Tests
```bash
npm run test:integration
```
### Test Funder Connections
```bash
# Test LEX SANDBOX
curl -X POST http://localhost:3003/api/integration/funders/LEX/test \
-H "Content-Type: application/json" \
-d '{"environment": "SANDBOX"}'
# Test ALPHABET SANDBOX
curl -X POST http://localhost:3003/api/integration/funders/ALPHABET/test \
-H "Content-Type: application/json" \
-d '{"environment": "SANDBOX"}'
```
## ๐ Security
- **No Credentials in Database**: All credentials stored in environment variables
- **JWT Token Management**: Automatic token generation and refresh
- **API Key Security**: Secure API key handling
- **Request Validation**: Comprehensive input validation
- **Error Handling**: Secure error responses without sensitive data exposure
## ๐ Performance
- **Retry Mechanism**: Exponential backoff with configurable limits
- **Connection Pooling**: Efficient database connections
- **Caching**: Optional Redis integration for caching
- **Rate Limiting**: Built-in rate limiting per funder
- **Monitoring**: Real-time performance metrics
## ๐ค Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests
5. Submit a pull request
## ๐ License
This project is licensed under the MIT License.
## ๐ Support
For issues and questions:
1. Check the logs in the `IntegrationLog` table
2. Review the health check endpoint
3. Test individual funder connections
4. Contact the development team
---
**Built with โค๏ธ for the Self-Serve Application**