Lambda Functions

This page details the five Lambda functions that make up the Underwriting Service, including their configurations, environment variables, IAM permissions, and operational characteristics.

Overview

The Underwriting Service consists of five Lambda functions that work together in an event-driven architecture:

Lambda Trigger Purpose Concurrency

API

API Gateway

REST API for eligibility checks and profile management

High (synchronous)

Rule Runner

SQS

Executes individual rule evaluations

Medium (async batch)

Result Runner

SQS

Aggregates rule outcomes into final decisions

Medium (async batch)

Float Created Handler

SQS (EventBridge)

Creates permanent evaluation records

Low (event-driven)

Profile Handler

SQS (EventBridge)

Creates default profiles for new users

Low (event-driven)

Request Flow

The following diagram shows how requests flow through the Lambda functions:

API Request Flow

Two Processing Paths:

  1. Synchronous (Cache Hit): API Lambda returns cached EvaluationResult immediately (HTTP 200)

  2. Asynchronous (Cache Miss): Returns HTTP 200, triggers Rule Runner and Result Runner via SQS, client polls for results

Common Configuration

All Lambdas Share:

  • Memory Size: 512 MB (configurable via local.lambda_memory_size)

  • Runtime: Go 1.20+

  • VPC: Deployed in private subnets (API and Rule Runner only)

  • Monitoring: Datadog integration enabled

  • Logging: CloudWatch Logs with structured logging (golflog)


API Lambda

Entry Point: [cmd/api/main.go](cmd/api/main.go)

Purpose

Serves as the REST API gateway for the Underwriting Service. Handles all synchronous requests for float/loan eligibility checks, profile management, and evaluation history retrieval.

Key Responsibilities

  1. Authentication & Authorization:

    • Validates AWS SigV4 signatures

    • Extracts user context from authorizer

  2. Float/Loan Eligibility Checks:

    • Routes: GET /{user_id}/float_check, /{user_id}/underwriting/eligibility, /{user_id}/underwriting/loan/check

    • Retrieves cached evaluations from DynamoDB

    • Applies bypass logic for data quality issues

    • Returns approval status with amounts and reasons

  3. Float Profile Management:

    • Routes: GET/POST /{user_id}/underwriting/profile, GET/POST /{user_id}/floats/temporary_profile

    • CRUD operations for float profiles

    • Temporary profile creation with TTL

  4. Evaluation History:

    • Routes: GET /{user_id}/underwriting/history, GET /{user_id}/underwriting/history/{evaluation_id}

    • Retrieves recent and historical evaluations

  5. Recalculation Requests:

    • Route: POST /{user_id}/recalculate

    • Publishes events to trigger async rule execution

  6. Rulebook Management:

    • Routes: GET /rulebooks, GET /rulebooks/changes

    • Retrieves active rulebooks and audit trails

Error Handling

  • Upstream Service Failures: Returns 500 with error details, implements circuit breaker patterns

  • DynamoDB Errors: Retries with exponential backoff (via AWS SDK)

  • Validation Errors: Returns 400 with detailed error messages

  • Not Found: Returns 404 for missing users/resources


Rule Runner Lambda

Entry Point: [cmd/rule-runner/main.go](cmd/rule-runner/main.go)

Purpose

Worker Lambda that executes individual rule evaluations. Fetches data from multiple services, runs rules against user data, and stores outcomes in DynamoDB.

Key Responsibilities

  1. Data Gathering:

    • Fetches user data from User Service

    • Retrieves transaction history from Transactions Service

    • Gets active floats from Float Service

    • Retrieves ML insights from Insight Service

    • Fetches subscription status from Subscriptions Service

    • Gets payment information from Payments Service

  2. Rule Execution:

    • Loads rulebooks from DynamoDB (with caching)

    • Filters rules by type (txns, insights, all)

    • Invokes individual Lambda rule functions

    • Collects rule results with features

  3. Outcome Storage:

    • Writes RuleOutcome to DynamoDB with 32-day TTL

    • Stores features map for debugging

    • Records calc_status (OK, NODATA, CALCERR)

  4. Result Runner Trigger:

    • Publishes event to Result Runner queue after all rules complete

Error Handling & Retry Strategy

  • Rule Execution Failures: Individual rules can fail without failing entire evaluation

  • Service Timeouts: Returns CALCERR status, bypasses with cached data

  • SQS Retry: Message returns to queue if Lambda fails (max 1 retry)

  • DLQ Processing: Failed messages moved to DLQ for manual investigation

  • Sagemaker Errors: Gracefully degrades, marks insights as unavailable


Result Runner Lambda

Entry Point: [cmd/result-runner/main.go](cmd/result-runner/main.go)

Purpose

Aggregates individual rule outcomes into final eligibility decisions. Applies rulebook priority, superseding logic, and A/B test filtering.

Key Responsibilities

  1. Outcome Retrieval:

    • Fetches all RuleOutcomes for user from DynamoDB

    • Loads rulebooks with caching

  2. Evaluation Algorithm (ProcessFloatCheck):

    • Filters rulebooks by type (float vs loan)

    • Applies A/B test filtering (apply_to percentage)

    • Sorts by priority (descending)

    • Evaluates sequentially until approval or superseding rulebook

  3. Result Storage:

    • Creates EvaluationResult with 32-day TTL

    • Stores rulebook_results array with individual outcomes

    • Records deciding_rulebook for approved users

    • Sets evaluation_status based on data quality

  4. CFI Evaluation:

    • Calculates float_rank and sub_rank

    • Determines eligible float tiers

    • Checks for limit increase eligibility

    • Updates FloatProfile if increase detected

  5. Event Publishing:

    • Publishes evaluation complete events

    • Triggers Segment tracking for CFI changes

Error Handling

  • Missing Outcomes: Returns NOEVAL status

  • Data Quality Issues: Sets appropriate status (NODATA, CALCERR)

  • Rulebook Errors: Logs and continues with available rulebooks

  • DynamoDB Errors: Retries with backoff, moves to DLQ on failure


Float Created Handler Lambda

Entry Point: [cmd/float-created-handler/main.go](cmd/float-created-handler/main.go)

Purpose

Event handler that creates permanent historical evaluation records when a float or loan is taken. Helps with compliance and preserves CFI calculations data.

Key Responsibilities

  1. Event Processing:

    • Receives float.created events from EventBridge via SQS

    • Extracts float_id, user_id, amount from event payload

  2. Historical Record Creation:

    • Retrieves corresponding EvaluationResult from DynamoDB

    • Creates HistoricalEvaluation entity (permanent, no TTL)

    • Stores complete evaluation snapshot:

      • Float/loan evaluation results

      • Rulebook outcomes

      • CFI state at time of float

      • Amount and product taken

  3. Compliance:

    • Preserves exact evaluation used for credit decision

    • Enables dispute resolution and auditing

  4. CFI Support:

    • Historical floats used to calculate float_rank

    • Enables "highest float ever taken" tracking

    • Supports reactivating user limit determination

Error Handling

  • Missing Evaluation: Logs warning, creates partial historical record

  • DynamoDB Errors: Retries with backoff

  • Malformed Events: Logs and moves to DLQ

  • Service Timeouts: Retries with exponential backoff


Profile Handler Lambda

Entry Point: [cmd/profile-handler/main.go](cmd/profile-handler/main.go)

Purpose

Creates default float profiles for newly signed-up users. Ensures all users have a starting configuration for float eligibility.

Key Responsibilities

  1. Event Processing:

    • Receives user.signup.completed events

    • Extracts user_id from event payload

  2. Profile Creation:

    • Checks if profile already exists (idempotency)

    • Creates default FloatProfile:

      • Floats $10 and $20 enabled

      • Floats $30-$100 disabled

      • Standard loan tiers

      • cfi_enabled: true

    • Writes to DynamoDB with timestamp

  3. Idempotency:

    • Skips creation if profile already exists

    • Prevents duplicate profiles from event replays

Error Handling

  • Duplicate Profile: Logs and continues (idempotent)

  • DynamoDB Errors: Retries with backoff

  • Malformed Events: Logs and moves to DLQ


Monitoring & Observability

CloudWatch Metrics

All Lambdas emit standard metrics:

  • Invocations: Total invocation count

  • Duration: Execution time (ms)

  • Errors: Error count

  • Throttles: Throttling events

  • ConcurrentExecutions: Active executions

Datadog Metrics

Custom metrics tracked:

  • underwriting.evaluation.duration - Evaluation processing time

  • underwriting.rule.execution.duration - Individual rule execution time

  • underwriting.cfi.limit.increased - CFI limit increase events

  • underwriting.cfi.limit.decreased - CFI limit decrease events

  • underwriting.sagemaker.latency - ML inference latency

  • underwriting.service.call.duration - Downstream service latency

CloudWatch Logs

Log Structure: * Level: DEBUG, INFO, WARN, ERROR * Request ID: AWS request ID for tracing * User ID: User being evaluated * Correlation ID: Event correlation across Lambdas

Key Log Events: * Rule execution start/completion * Service call requests/responses * DynamoDB operations * Error stack traces * CFI calculations

X-Ray Tracing

AWS X-Ray enabled on all Lambdas:

  • Request flow visualization

  • Service dependency map

  • Latency breakdown by segment

  • Error analysis


See Also