DynamoDB Tables

The Float Service uses four DynamoDB tables, configured by three distinct region variables (not interchangeable): collection-history, locks, and requirements-bypass clients resolve DYNAMO_LEGACY_REGION, except the lock client, which is constructed separately from DYNAMO_LOCK_REGION (same region value, distinct variable — see locks); the site-float-service single table is configured by DYNAMO_REGION + DYNAMO_TABLE.

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 to serve collection history via the API.

Attribute DynamoDB Tag Description

loan_id

PK

Float ID. Maps to loan_id in the RDS floats table.

run_time

SK

Unix nanosecond timestamp of when the attempt was made.

user_id

—

Owning user’s ID.

due_date

—

The float’s original due date (YYYY-MM-DD).

run_date

—

The calendar date of the attempt (YYYY-MM-DD). Used by daily attempt limit checks.

process

—

The collection run or flow that made this attempt. See Process Values.

outcome

—

Result of the attempt. See Outcome Values.

confirmation_id

—

Payment processor confirmation ID for the attempt. Present when a payment was submitted.

reason

—

Optional context for the row. Daily Retry blind attempts record why the balance was untrusted (STALEDATA / PLAIDLINK / INVALIDPLAID); balance-webhook ACH rows carry the ACH submission window (SAMEDAYACH / ACHFIRST); rows for the second and later floats a webhook event walks carry SUBSEQUENTFLOAT. Absent on ordinary rows.

available_balance_cents

—

Bank-reported available balance, in cents, the run evaluated (0 when the bank reported none). Present, with the other balance_* attributes, only on rows written with a balance in hand — see Balance snapshot.

current_balance_cents

—

Bank-reported current balance, in cents.

calc_available_balance_cents

—

The miner’s calculated-available fallback (current minus pending), in cents. Absent when the miner computed none.

balance_used

—

Which balance the run gated on: AVAILABLE, CALC_AVAILABLE or CURRENT (shared balance selection).

balance_updated_at

—

When Plaid last updated the balance (RFC3339, UTC). Absent when txn-service carried no parseable timestamp.

partial_auth_balance_cents

—

The card’s available balance, in cents, the processor reported on an insufficient-funds (code 51) pinless decline where a partial approval would have been possible (payments-service available_funds_cents). Absent on every other row, including declines the processor reported no balance for.

Access Patterns

GetByFloatID(ctx, floatID)  →  QueryByPK(loan_id = floatID)

Process Values

Value Written by

TOMORROW

Day-before ACH run (T-1) — float due the next business day. See Day-Before ACH.

TOMORROW_FIRST_FLOAT

Day-before ACH run — attempt routed by the first-or-second-float ACH rule.

TOMORROW_RETURNING_FLOAT

Day-before ACH run — attempt routed by the 7-or-more-float-rank ACH rule.

TODAY6AM

Due Date run — float due today.

RETRY

Daily Retry run — overdue float past its due date.

RETRY_EVENING

Evening blind Daily Retry run — blind pinless attempt on an overdue float. See Evening blind run.

WEBHOOKS_BALANCE

Balance-update webhook run.

WEBHOOKS_PLAID_DISCONNECT

Plaid connection lost/revoked webhook run. See Plaid Disconnected.

MANUAL

Manual payback via POST /{user_id}/floats/{float_id}/payback.

REACTIVATION

Reactivation payback via POST /{user_id}/floats/payback/reactivate.

Check-ach-cleared

ACH handler — settlement callback processing. See ACH Processing.

Chargeback-detector

ACH handler — chargeback detection.

BATCH

Batch worker — bulk float operations.

SUPPORT

Manual status update via the API (e.g. PATCH /{user_id}/floats/{float_id}). Refused updates write no log entry — see Support Debit Edit.

Source: pkg/dynamo/process.go

Outcome Values

outcome records the result of an attempt (ACHSENT, COMPLETED, RETURNED, DEFAULTED) or, on rows without a confirmation_id, why a run declined to attempt. Skip outcome values and their precedence are documented in Collections — Skip Outcomes.

locks

Region: DYNAMO_LOCK_REGION — the lock client’s own region variable (set to the same region value as DYNAMO_LEGACY_REGION)

Distributed locking table used by all collection components to prevent concurrent collection attempts on the same user’s float. Backed by the cirello.io/dynamolock client.

Attribute DynamoDB Tag Description

PartitionKey

PK

Lock key in the format loan-processing:user_id:{userID}.

data

—

Unix nanosecond timestamp (as bytes) of when the lock was acquired.

deleteOn

—

TTL timestamp for automatic record expiry.

leaseDuration

—

Duration of the lock lease.

owner

—

Identifier of the lock owner (worker instance).

recordVersionNumber

—

Version counter used for optimistic locking.

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; only one instance processes a given user’s float at a time.

requirements-bypass

Region: DYNAMO_LEGACY_REGION

Stores per-user eligibility overrides. When an unexpired bypass record exists for a user, the float creation flow skips the standard requirements check. Managed via the POST/GET/DELETE /{user_id}/bypass API endpoints. See Requirements Bypass.

Attribute DynamoDB Tag Description

user_id

PK

Owning user’s ID.

expiration_date

—

Date the bypass expires (YYYY-MM-DD). The bypass is inactive after this date.

reason

—

Internal note describing why the bypass was granted.

Access Patterns

Get(ctx, userID)               →  GetItem(user_id = userID)
Save(ctx, bypass)              →  PutItem
Remove(ctx, userID)            →  DeleteItem(user_id = userID)

site-float-service (Single-Table Design)

Region: DYNAMO_REGION — table name from the DYNAMO_TABLE env var (default: {environment}-float-service)

Provisioned and wired into the API via DYNAMO_TABLE, but no code path reads or writes it.