Simulation Flows

These endpoints let tests trigger the same async collection and processing pipelines that run in production, but scoped to specific test users. Simulations are the bridge between test setup (creating users via /qa/integration/custom-user) and assertions (calling service APIs directly). Each endpoint sends messages to SQS queues for downstream Lambda consumption, directly invokes a Lambda function, or injects events into a Kinesis stream — closely mirroring what production schedulers do. The POST /qa/test/event endpoint supports direct Kinesis injection for lower-level integration scenarios.

Subscription Simulations

Daily Collections (POST /qa/simulate/subscriptions/daily)

Simulates the nightly scheduled job that collects subscription payments. The endpoint accepts a list of user IDs, fetches each user’s subscription records from the Subscription Service, and routes them into one of three SQS queues based on their current status. The queues are then consumed by the production Subscription Service Lambda workers.

Async: Yes — SQS messages are sent and the endpoint returns immediately. The caller must poll or wait before asserting on downstream state.

Request body:

{
  "user_ids": ["uuid-1", "uuid-2"]
}

Behavior by subscription status:

Status SQS Queue (env var) Consumer

SCHEDULED

SubscriptionCollectionsScheduledQueueURL

Subscription Service scheduled-collections Lambda

PAUSED

SubscriptionCollectionsPausedQueueURL

Subscription Service paused-collections Lambda

ERROR (retry)

SubscriptionCollectionsRetryQueueURL

Subscription Service retry-collections Lambda

Eligibility rules:

  • SCHEDULED and PAUSED subscriptions must have a subscription_date strictly before the current time.

  • ERROR subscriptions are eligible for retry only if they fall within the last 30 days.

  • Subscriptions that do not meet eligibility are silently skipped.

Flow:

Caller → POST /qa/simulate/subscriptions/daily
  → Fetch subscriptions for each user_id (Subscription Service)
  → Sort into buckets: SCHEDULED / PAUSED / ERROR
  → Filter by eligibility (date < now; ERROR within 30 days)
  → SQS: scheduled-queue / paused-queue / retry-queue
    → Subscription Service Lambda consumes each queue

Webhook Collection (POST /qa/simulate/subscriptions/webhook)

Simulates inbound payment processor webhook events that trigger subscription collection. Instead of routing by status bucket, this endpoint creates a CloudWatchEvent payload per user and sends all of them to a single SQS webhook queue. It is used to test the webhook-driven collection path independently from the daily scheduler path.

Async: Yes — SQS messages are sent and the endpoint returns immediately.

Request body:

{
  "users": [
    { "user_id": "uuid-1", "amount": 9.99 },
    { "user_id": "uuid-2", "amount": 14.99 }
  ]
}

Eligibility: Each user must have at least one subscription in SCHEDULED or ERROR status that was created within the last 2 months. Users that do not meet this requirement are rejected and an error is returned for those entries.

SQS target: SubscriptionCollectionsWebhookQueueURL

Subscription Notifier (POST /qa/simulate/subscriptions/notifier)

Simulates the three-day advance notification job that alerts users their subscription payment is upcoming. The endpoint accepts a list of user IDs, fetches their subscriptions from the Subscription Service, and for each subscription in SCHEDULED status it constructs an fmsdk event with type three_day_notification (version v1) keyed by subscription_id. All events are sent as a batch to the subscription notifier SQS queue.

Async: Yes — SQS batch message is sent and the endpoint returns immediately.

Request body:

{
  "user_ids": ["uuid-1", "uuid-2"]
}

Eligibility: Only subscriptions with SCHEDULED status produce notification events. Subscriptions in any other status are silently skipped.

SQS target: SubscriptionNotifierWorkerQueueURL

Use case: Test that users receive pre-payment notification emails/push alerts before the scheduled collection date.

Float Simulations

Daily Collections (POST /qa/simulate/floats/daily)

Simulates the daily float (cash advance) collection job. The endpoint accepts a list of user IDs, calls the Float Service GetActiveFloats for each, filters floats by collectibility, and sends a FloatCollectionEvent per float to the daily collection SQS queue.

Async: Yes — SQS messages are sent and the endpoint returns immediately.

Request body:

{
  "user_ids": ["uuid-1", "uuid-2"]
}

Process types and eligibility:

Float Status Eligible Condition Process value sent in event

SCHEDULING

Due today or earlier (not yet overdue)

TOMORROW or TODAY6AM (based on timing)

RETRY

Always collectable regardless of date

RETRY

SQS target: FloatCollectionsDailyQueueURL

Each event payload is a FloatCollectionEvent containing the Process type, the Float record, and a Runtime timestamp.

Flow:

Caller → POST /qa/simulate/floats/daily
  → GetActiveFloats per user_id (Float Service)
  → Filter: SCHEDULING (due ≤ today) or RETRY (always)
  → Build FloatCollectionEvent{Process, Float, Runtime}
  → SQS: float-collections-daily-queue
    → Float Service daily-collections Lambda consumes

Webhook Collection (POST /qa/simulate/floats/webhook)

Simulates inbound webhook events that trigger float collection outside the daily scheduler. Creates a FloatCollectionWebhookEvent{user_id} for each supplied user and sends them to the webhook collection SQS queue.

Async: Yes — SQS messages are sent and the endpoint returns immediately.

Request body:

{
  "user_ids": ["uuid-1", "uuid-2"]
}

SQS target: FloatCollectionsWebhookQueueURL

Use case: Test the webhook-driven repayment path (e.g., bank ACH return callbacks) without waiting for the daily scheduler window.

LOC Collections (POST /qa/simulate/loc/collections)

Simulates the Line of Credit collection job by directly invoking the LOC Service Lambda function. Unlike the subscription and float simulations, this endpoint does not send SQS messages — it performs a synchronous (fire-and-forget) async Lambda invocation using InvocationType: Event. The Lambda executes independently; the endpoint returns immediately after the invocation is dispatched.

Async: Fire-and-forget Lambda invoke — the endpoint returns 200 after the invocation is dispatched, before the Lambda completes.

Request body:

{
  "process": "due",
  "look_ahead_days": 3
}

Process types:

process value Meaning

upcoming

Collect payments that will become due within look_ahead_days days

due

Collect payments due today

overdue

Collect payments past their due date

retry

Retry previously failed collection attempts

look_ahead_days: Optional integer. Relevant for the upcoming process type to control how far ahead the job looks for due payments. Ignored for other process types.

Target Lambda: test-loc-service-loc-collections-job

Use case: Trigger LOC collection processing against specific test accounts without waiting for the production CloudWatch scheduled event.

Event Injection (POST /qa/test/event)

A low-level utility endpoint that injects arbitrary JSON payloads directly into Kinesis streams or SQS queues. This is used for debugging, for simulating third-party callback events (such as payment processor webhooks arriving on a Kinesis stream), and for driving any queue-consuming Lambda that does not have a dedicated simulation endpoint.

Request body:

{
  "service": "kinesis",
  "target": "prod-payments-stream",
  "event": { "type": "payment.completed", "amount": 9.99 },
  "partition_key": "user-uuid-1"
}

Parameters:

Field Type Required Description

service

kinesis | sqs

Yes

Destination service type

target

string

Yes

Stream name (Kinesis) or queue name (SQS)

event

object

Yes

Arbitrary JSON payload — sent as-is

partition_key

string

No

Kinesis shard partition key; ignored for SQS

Routing by service type:

service How target is resolved SDK call used

kinesis

Used directly as the stream name in PutRecord

kinesis.PutRecord(streamName, event, partitionKey)

sqs

Queue URL constructed from AWS account + region + queue name

sqs.SendMessage(constructedURL, event)

Use cases:

  • Inject a Kinesis payment callback event to test the payments processing pipeline end-to-end.

  • Send a crafted message to an SQS queue to exercise a specific Lambda error-handling branch.

  • Reproduce a production event shape in a test environment without waiting for a real external trigger.