UNPKG

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
# 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**