Architecture

System Context

QA Automation is deployed as a single AWS Lambda function (test-qa-automation-api) in the test environment (us-west-2), fronted by an API Gateway HTTP API (v2) secured with AWS Signature V4. The Lambda orchestrates calls to every major FloatMe internal service as well as Auth0, Plaid, Iterable, and GrowthBook to set up test users and drive financial simulations. A TypeScript/Cucumber runner calls both the QA API and individual service APIs directly (with SigV4 signing) to assert on expected state.

system context qa automation

Inbound Traffic

Source Description

API Gateway (IAM SigV4)

All requests to the QA Lambda are authenticated with AWS Signature V4. Internal callers (CI runners, manual QA engineers) assume the test-postman-qa-role via STS before signing requests.

Cucumber runner

The TypeScript test runner assumes test-postman-qa-role (15-minute STS session) in BeforeAll, then signs every request to the QA API using aws4fetch.

Manual invocation

Engineers can call any endpoint directly from the AWS console, Postman, or curl with valid SigV4 credentials for ad-hoc user creation or simulation.

Outbound Integrations

Destination Description

Auth0

Creates and manages test user accounts via the Auth0 Management API; credentials fetched from Secrets Manager at startup.

Plaid

Configures bank account overrides for test users to simulate specific balance and transaction scenarios.

User Service

Creates user profiles and retrieves user data during setup.

Float Service

Creates floats for test users; also read by Cucumber step definitions for assertion.

Subscription Service

Creates subscriptions and retrieves subscription state; also called directly by Cucumber for assertions.

LOC Service

Creates Line of Credit loans; also read by Cucumber for loan balance assertions.

Payments Service

Creates payment records; also queried by Cucumber for payment assertion steps.

Underwriting Service

Evaluates underwriting eligibility; results queried by Cucumber underwriting assertion steps.

Insight Service

Retrieves user insight data used in certain user-creation flows.

Iterable

Queries marketing event history for a test user (mobile and server API keys both initialized at startup).

GrowthBook

Feature flag client initialized at startup; used to gate behaviour during user creation and simulation.

DynamoDB (bypass rules + subscriptions)

Writes bypass rules (BYPASS_TABLE_NAME) and subscription records (SUBSCRIPTION_TABLE_NAME) during user setup.

RDS (PostgreSQL)

Read-only queries against the floats and loans tables in the test RDS instance; connection initialized from Secrets Manager credentials.

SQS

Sends messages to subscription and float collection queues to trigger real asynchronous collection processing; seven distinct queue URLs are injected via environment variables.

Kinesis

Injects test events into Kinesis streams via POST /qa/test/event for diagnostic and integration scenarios.

Go API Lambda

The test-qa-automation-api Lambda is a Go binary started with ddlambda.WrapFunction and lambda.StartWithOptions, fronted by aws-lambda-go-api-proxy which adapts API Gateway proxy events to a standard net/http handler. Routing is handled by go-chi/chi; the handler struct is generated from the OpenAPI spec (spec/qa_api.yaml) via oapi-codegen.

Responsibilities

  • User creation orchestrationPOST /qa/integration/user (38 predefined states, plus any sub_overdue_<N>d variant) and POST /qa/integration/custom-user (fully configurable) drive a sequential chain: Auth0 account → Plaid bank account override → User Service profile → Float Service floats → Subscription Service subscriptions → LOC Service loans → DynamoDB bypass rules.

  • Simulation triggering — Subscription daily/webhook/notifier and float daily/webhook endpoints send SQS messages to real service queues, causing actual asynchronous collection processing.

  • Event injectionPOST /qa/test/event places arbitrary events on Kinesis streams or SQS queues for lower-level integration scenarios.

  • Iterable queriesGET /qa/iterable/user and GET /qa/iterable/user/events proxy to Iterable’s API using both mobile and server API keys.

Dependency Injection

All dependencies are constructed in cmd/api/main.go and wired into api.NewServer(). The Server struct (defined in pkg/api/server.go) holds:

Field Provided by

Auth0Client

auth0.NewAuth0ManagementClient — credentials from Secrets Manager (SM_AUTH0_NAME)

Plaid

plaid.NewClient — credentials from Secrets Manager (SM_PLAID_NAME)

UserClient, AdminClient, InsightClient

fmsdk/clients/user, admin, insight — URL + region from env vars

FloatClient, SubscriptionClient, LocClient

fmsdk/clients/float, subscription, loc — URL + region from env vars

PaymentsClient, UnderwritingClient, TxnClient

fmsdk/clients/payments, underwriting, txns — URL + region from env vars

BypassRepo

dynamo.NewDDBBypassRepository — DynamoDB table from BYPASS_TABLE_NAME

SubRepo

dynamo.NewDDBSubscriptionRepository — DynamoDB table from SUBSCRIPTION_TABLE_NAME

FloatRepo

rds.NewDBFloat — PostgreSQL pool from Secrets Manager RDS credentials

SqsClient, KinesisClient

aws-sdk-go-v2 clients constructed from the default AWS config

IterableClientMobile, IterableClientServer

qaIterable.New — separate keys from SM_ITERABLE_MOBILE_NAME and SM_ITERABLE_NAME

Growthbook

growthbook.NewClient — key + host from Secrets Manager (SM_GROWTHBOOK_NAME)

Cucumber Test Runner

The TypeScript/Cucumber test runner lives in the cucumber/ directory and executes BDD scenarios defined in .feature files imported from Jira (Xray). Tests run 5 scenarios in parallel with 1 automatic retry.

See Cucumber Framework for full detail on the World context, step-definition patterns, and authentication flow.

The runner interacts with the platform at two levels:

  1. Via QA API — Given/When steps call POST /qa/integration/custom-user and simulation endpoints to set up state.

  2. Direct service calls — Then steps call service APIs directly (User, Float, Subscription, LOC, Payments, Underwriting) with SigV4 signing to assert expected state without going through the QA Lambda.

Data Storage

DynamoDB

The Lambda reads and writes to four DynamoDB tables (all pre-existing, looked up via data sources in Terraform — not owned by this service):

Table (env var) Purpose

BYPASS_TABLE_NAME

Stores per-user bypass rules written during user creation; consumed by production services to skip real collection logic in the test environment.

SUBSCRIPTION_TABLE_NAME

Stores subscription records created for test users; used by simulation endpoints to locate subscriptions to collect.

UNDERWRITING_TABLE_NAME

Underwriting decision records read and written during underwriting flow tests.

billing-activity-history

Historical billing activity; queried during subscription history assertions.

RDS (PostgreSQL)

The Lambda holds a read-only connection pool (pkg/rds) to the test environment’s PostgreSQL instance. It queries the floats and loans tables to retrieve records needed for Cucumber assertion steps via GET endpoints. Connection credentials are fetched from Secrets Manager at startup (SM_RDS_MAIN_NAME).