Automatic Underwriting Tool

automatic-uw-tool automates the identity-verification and background-check steps of Payability’s supplier underwriting (KYC / KYB). It orchestrates external data vendors behind a uniform process abstraction, runs the slow vendor calls asynchronously on AWS Simple Workflow (SWF), persists results to DynamoDB and S3, and notifies the rest of the platform through EventBridge.

The golden rule: the Web API never calls a vendor API directly. It authenticates the caller, validates input, persists state, and starts an SWF workflow. All external verification I/O happens in handle tasks on the worker. This keeps HTTP requests fast and makes vendor latency and vendor failures a background concern.

What it does

Given a supplier and a person (a supplier owner), the tool runs one of four underwriting processes:

Process Vendor Purpose

validate_identity_document

Au10tix / Entrust

Verify that a government ID is authentic, unexpired, good quality, and matches the owner on record.

validate_personal_information

Thomson Reuters CLEAR (EIDV)

KYC — confirm the owner’s submitted PII matches vendor records, field by field.

download_personal_background_report

Thomson Reuters CLEAR

Criminal / bankruptcy / lien / lawsuit report, scored into access and advance verdicts.

download_business_background_report

Thomson Reuters CLEAR

Business-entity background report, archived as raw data.

Every process is a two-step pipeline: a synchronous request step served by the Web API, and an asynchronous handle step run by the SWF worker. The Entrust identity-verification flow is the one deliberate exception — its request step is a dedicated endpoint and its handle step is triggered by a vendor webhook. See Domain model: processes & tasks and Process catalog.

The 30-second model

  • Two containers, one repository. The Web API (web_api_app.py) and the SWF worker (swf_app.py) are built from the same code and deployed as separate ECS services.

  • Four layers. interface/ (HTTP) → task/ (domain) → components/ (integrations) → config/ + utils/ (cross-cutting).

  • One join key. A correlation_id ties the request step, the SWF payload, every persisted row, the S3 object, and the outbound events for a single execution.

  • Config is Dynaconf. settings_setup.py generates non-secret settings, config_setup.py pulls secrets from AWS Secrets Manager; app code only reads config.config.settings.

                 x-session-token
   Client  ─────────────────────────►  Web API (FastAPI, ECS)
                                              │  1. persist task (DynamoDB)
                                              │  2. set tool PENDING
                                              │  3. start workflow ──► B2B Task Manager ──► AWS SWF
                                              ▼
                                        {correlation_id}

   AWS SWF  ──poll activity task──►  SWF Worker (swf_app.py, ECS)
                                              │  call Au10tix / Entrust / Thomson Reuters
                                              │  write raw result to S3
                                              │  update final-status + tool tables
                                              ▼
                                        EventBridge (process finished, TR match / mismatch)
If you want… Read

The big picture, containers, layers

System architecture

How one request flows end to end

Request lifecycle

The domain: processes, tasks, factories, failure handling

Domain model: processes & tasks

What each process actually does, rule by rule

Process catalog

Every HTTP endpoint, its auth and its payloads

API overview

SWF orchestration and the outbound event catalog

SWF orchestration · EventBridge events

Table shapes, keys, S3 key conventions

DynamoDB tables · S3 datalake

Vendor, AWS and internal clients

Component layer

Running it locally, configuring it, shipping it

Local development · Configuration & secrets · Deployment

The rules new code must follow

Python standards · Testing

A term you do not recognise

Glossary

Repository layout

Path Contents

web_api_app.py

FastAPI application entry point (Web API container).

swf_app.py

SWF activity-worker entry point (worker container).

task/

Domain layer: processes and tasks — Domain model: processes & tasks.

components/

Integration layer: vendor, AWS and internal clients — Component layer.

interface/web_api/

Routers, endpoint handlers, pydantic schemas — API overview.

config/

Dynaconf entry point plus the generated settings.json / .secrets.json.

utils/

Small helpers (dict, string, time, metric, task utilities).

development/

unit_tests/, integration_tests/, e2e_tests/.

deployment/

Dockerfiles and docker-compose.yml.

artifacts/

ECS taskdef.json and CodeDeploy appspec.yaml.

examples/

Sample vendor responses used by tests and test mode.

buildspec.yml

AWS CodeBuild pipeline.

settings_setup.py, config_setup.py

Settings and secrets bootstrap.

docs/

This Antora documentation component.

Tech stack

Python 3.9 · FastAPI · boto3 · Dynaconf · AWS (SWF, DynamoDB, S3, EventBridge, ECS, CodeBuild/CodeDeploy, Secrets Manager, CloudWatch) · Sentry · pyb-sdk (internal) · hubspot-api-client.

Application version: 1.0.0 (version.py, also stamped onto every changelog row).