DynamoDB Tables
The Float Service uses four DynamoDB tables. Three legacy tables (collection-history, locks, requirements-bypass) are accessed via the DYNAMO_LEGACY_REGION region and were created before the current single-table design was adopted. The primary table (site-float-service) uses a single-table design and is accessed via DYNAMO_REGION.
collection-history
Region: DYNAMO_LEGACY_REGION
An append-only audit log of every collection attempt. One record is written per attempt, regardless of outcome. Used by the collections engine to enforce attempt limits and reconstruct collection history via the API.
| Attribute | DynamoDB Tag | Description |
|---|---|---|
|
PK |
Float ID. Maps to |
|
SK |
Unix nanosecond timestamp of when the attempt was made. |
|
— |
Owning user’s ID. |
|
— |
The float’s original due date ( |
|
— |
The calendar date of the attempt ( |
|
— |
The collection stage that triggered this attempt. See Process Values. |
|
— |
Result of the attempt. See Outcome Values. |
|
— |
Payment processor confirmation ID for the attempt. Present when a payment was submitted. |
|
— |
(Optional) Whether the ACH routing ML model decision was manually overridden for this attempt. |
|
— |
(Optional) Version of the ACH routing ML model used. |
|
— |
(Optional) Map of feature name → value fed to the ML model for this attempt. |
|
— |
(Optional) The model’s predicted probability score for ACH success. |
Access Patterns
Query by float ID to retrieve all attempts for a given float:
GetByFloatID(ctx, floatID) → QueryByPK(loan_id = floatID)
Process Values
| Value | Description |
|---|---|
|
T-1 Day run — float due the next business day |
|
Due Date run — float due today |
|
Daily Retry run — float in RETRY status past its due date |
|
Income detection webhook run |
|
Manual status update via the API (e.g. |
Outcome Values
| Value | Description |
|---|---|
|
ACH debit was submitted to the payment processor. |
|
Collection was successful (pinless or ACH settled). |
|
ACH debit was returned by the bank (e.g. NSF, account closed). |
|
Float was marked as defaulted due to attempt limits or age threshold. |
locks
Region: DYNAMO_LEGACY_REGION (also accessible via dedicated DYNAMO_LOCK_REGION)
Distributed locking table used by all collection Lambdas to prevent concurrent collection attempts on the same user’s float. Backed by the cirello.io/dynamolock client.
| Attribute | DynamoDB Tag | Description |
|---|---|---|
|
PK |
Lock key in the format |
|
— |
Unix nanosecond timestamp (as bytes) of when the lock was acquired. |
|
— |
TTL timestamp for automatic record expiry. |
|
— |
Duration of the lock lease. |
|
— |
Identifier of the lock owner (Lambda instance). |
|
— |
Version counter used for optimistic locking to prevent split-brain. |
A lock is held with a 60-second lease and a 1-second heartbeat. If a lock cannot be acquired, the collection attempt is skipped without modifying the float’s status. This ensures only one Lambda instance processes a given user’s float at any time, even when scheduled and webhook paths fire simultaneously.
requirements-bypass
Region: DYNAMO_LEGACY_REGION
Stores per-user eligibility overrides. When a bypass record exists for a user and has not expired, the float creation flow skips the standard requirements check. Managed via the POST/GET/DELETE /{user_id}/bypass API endpoints.
| Attribute | DynamoDB Tag | Description |
|---|---|---|
|
PK |
Owning user’s ID. |
|
— |
Date the bypass expires ( |
|
— |
Internal note describing why the bypass was granted. |
prod-float-service (Single-Table Design)
Region: DYNAMO_REGION — table name from DYNAMO_TABLE env var (default: {environment}-float-service)
This table is currently not being used for anything.
Related Pages
-
Collections Engine — How collection logs and locks are used during collection flows
-
Bypass & Payback — How requirements bypass records are created and consumed
-
PostgreSQL Schema — Primary float records in RDS
-
Architecture — DynamoDB overview in the system context