Architecture
System Overview
The Underwriting Service is an event-driven microservice that evaluates user eligibility for float and loan products through a sophisticated rules engine. It exposes both synchronous REST API endpoints and processes asynchronous events from other Float services.
Key Capabilities
-
Rule Evaluation Engine: Executes complex rule sets to determine user eligibility
-
Float Profile Management: Stores and manages user float and loan settings, limits, and fee structures
-
Continuous Float Increase (CFI): Automatically adjusts float limits based on user behavior and history
-
Eligibility Determinization: Provides comprehensive decision-making for underwriting requests
-
Event-Driven Processing: Consumes and processes events from related services
High-Level Architecture
The system is divided into three layers: API Layer, Processing Layer, and Data Layer.
| Layer | Components |
|---|---|
API Layer |
REST API Gateway (AWS Lambda) - Receives eligibility check requests - Delegates to processing layer - Returns decisions to clients |
Processing Layer |
Event-driven workers communicating via SQS and processing results - Rule Runner: Executes rules and retrieves evaluation data - Result Runner: Aggregates rule outcomes into final decisions - Event Handlers: React to float creation, profile updates |
Data Layer |
Persistent storage and event stream - DynamoDB: Primary data store (profiles, rules, results) - SQS: Task queues for background processing - EventBridge: Event routing and notifications - Kinesis: Event streams for analytics and audit |
Component Interactions
The Underwriting Service integrates multiple AWS services in an event-driven architecture:
┌─────────────────────────────────────────────────────────────┐
│ External Clients │
│ (Mobile App, Backend Services) │
└───────────────────────┬─────────────────────────────────────┘
│ HTTP Requests
▼
┌───────────────────────────────┐
│ API Gateway │
│ (Authorization/Routing) │
└───────────────────┬───────────┘
│ Invoke
▼
┌───────────────────────────────┐
│ API Lambda │
│ ✓ Validate requests │
│ ✓ Fetch float profiles │
│ ✓ Determine eval strategy │
└────┬─────────────────┬────────┘
│ │
┌──────────┴──────┐ Query │
│ ▼ ▼
│ ┌──────────────────────┐
│ │ DynamoDB │
│ │ ✓ Profiles │
│ │ ✓ Rulebooks │
│ │ ✓ Evaluation Results│
│ │ ✓ Historical Evals │
│ │ ✓ Rule Outcomes │
│ └──────────────────────┘
│ ▲
│ │ Read/Write
│
Publish Task
│
▼
┌──────────────────┐
│ SQS Queue │
│ (Eval Tasks) │
└─────────┬────────┘
│ Consume
▼
┌──────────────────────────┐ ┌──────────────────┐
│ Rule Runner Lambda │ │ EventBridge │
│ ✓ Gather user data │──Results────▶│ ✓ Route events │
│ ✓ Execute rules │ │ ✓ Trigger │
│ ✓ Store outcomes │ │ handlers │
└──────────────────────────┘ └────────┬─────────┘
│ │
│ Queue aggregation │ Publish events
▼ │
┌──────────────────────────┐ │
│ Result Runner Lambda │ │
│ ✓ Aggregate outcomes │ │
│ ✓ Apply precedence │ ┌────────────┴──────────┐
│ ✓ Final decision │ │ │
│ ✓ Store evaluation │ ▼ ▼
└──────────────────────────┘ ┌──────────────────┐ ┌─────────────────┐
│ │ Float Created │ │ Profile Update │
│ │ Handler Lambda │ │ Handler Lambda │
└─────────────────┤ ✓ Create hist │ │ ✓ Invalidate │
│ eval │ │ cache │
│ ✓ Update state │ │ ✓ Notify │
└──────────────────┘ └─────────────────┘
Data Flow Summary: 1. Client requests eligibility check via API Gateway 2. API Lambda determines if evaluation can be cached or needs processing 3. For deferred evals: Task published to SQS queue 4. Rule Runner consumes task, executes rules, stores outcomes 5. Result Runner aggregates outcomes into final decision 6. Events trigger handlers for state updates (float creation, profile changes)
Request Flow: Float Eligibility Check
Here’s the typical flow when a client requests an eligibility check:
-
Client Request: Mobile app or backend service calls
/v1/{user_id}/underwriting/eligibility -
API Handler: API Lambda authenticates request and validates input parameters
-
Profile Lookup: Retrieves current user float profile from DynamoDB
-
Rule Retrieval: Fetches applicable rulebooks based on user characteristics (A/B testing, feature flags)
-
Evaluation:
-
Can be immediate (cached evaluation from previous check)
-
Or deferred (publishes task to SQS for background processing)
-
-
Result Determination: Aggregates rule outcomes to produce final eligibility decision
-
Response: Returns decision, approved amounts, CFI data, and other metadata
Asynchronous Processing Flow
For deferred evaluations, the system uses event-driven background processing:
Eligibility Check Request
↓
[Decision: Immediate or Deferred?]
├─→ IMMEDIATE: Return cached result
└─→ DEFERRED:
├─ Publish evaluation task to SQS
│
├─→ Rule Runner Lambda consumes task
│ ├ Gathers rule evaluation data
│ ├ Executes individual rules
│ └ Stores RuleOutcome entities
│
├─→ Result Runner Lambda aggregates results
│ ├ Retrieves all RuleOutcomes
│ ├ Applies priority/precedence logic
│ └ Creates EvaluationResult
│
└─→ Client polls for result
(or receives notification via callback)
Data Flow: Decision Determination
The flow from rules to final decision involves several processing stages:
| Stage | Input | Output |
|---|---|---|
Rule Execution |
Rule definition + User data |
Individual RuleOutcome (pass/fail/unknown) |
Result Aggregation |
Array of RuleOutcomes |
Intermediate decision state + metadata |
Priority Application |
Multiple rulebooks with priority order |
Superseding rulebook selection |
Final Decision |
Selected rulebook outcomes |
Approved/Denied + approved amounts |
See Rule Engine Guide for detailed flow diagrams.
External Service Integration
The Underwriting Service integrates with multiple external services:
| Service | Integration Type | Purpose |
|---|---|---|
User Service |
REST API calls |
Retrieve user demographics, history |
Float Service |
Event streams + REST APIs |
Float lifecycle coordination |
Transaction Service |
REST API calls |
Access transaction history, spending patterns |
Segment |
Event dispatch |
Analytics and event tracking |
Datadog |
Metrics/Logs |
Monitoring and observability |
Deployment Architecture
The service is deployed using Terraform for infrastructure management.
| Environment | Configuration |
|---|---|
Staging |
AWS managed services - Dedicated DynamoDB tables - Test rulebooks deployed - Separate SQS queues |
Production |
AWS managed services - High-availability configuration - Auto-scaling enabled - Encryption enabled - VPC isolation - Enhanced monitoring |
See Deployment Guide for detailed infrastructure setup.
Scalability & Performance Considerations
Horizontal Scaling
-
Lambda Functions: Auto-scale based on SQS queue depth
-
DynamoDB: Configured with auto-scaling read/write capacity
-
Queues: SQS provides built-in scaling for task distribution
Security Model
-
Authentication: API Gateway with authorization
-
Data Encryption:
-
In-transit: TLS/HTTPS required
-
At-rest: DynamoDB encryption enabled
-
Secrets: AWS Secrets Manager
-
-
IAM Permissions: Least-privilege roles per Lambda function
-
VPC Isolation: Optional private VPC deployment
Monitoring & Observability
The service is instrumented with comprehensive logging and metrics:
-
CloudWatch Logs: All Lambda executions logged
-
CloudWatch Metrics: Custom metrics for eligibility decisions, latency, errors
-
Datadog Integration: Centralized monitoring dashboard
-
Distributed Tracing: X-Ray for request tracing (optional)
See Monitoring section for dashboard setup.
See Also
-
Rule Engine - Evaluation pipeline details
-
Lambda Functions - Lambda configurations and responsibilities
-
DynamoDB Schema - Data storage and query patterns
-
Deployment Guide - Infrastructure and CI/CD