Users & Data Model

The User Service uses a single DynamoDB table (prod-user-service-users) for most entities, plus two legacy DynamoDB tables and a PostgreSQL RDS instance for user profile data. Multiple entity types share the primary table, differentiated by key prefixes and the db_type attribute.

Primary Table: prod-user-service-users

Region: us-east-2

User

Attribute Description

PK

USERS#<user_id>

SK

USER_INFORMATION#<date_updated> (Unix timestamp)

GSI1PK

USER_EMAIL#<email> — enables lookup by email

GSI1SK

USER_INFORMATION#<date_updated>

GSI2PK

USER_PHONE#<phone> — enables lookup by phone number

GSI2SK

USER_INFORMATION#<date_updated>

db_type

USER

user_id

Auth0-generated user identifier

user_email

User’s email address

user_first_name

First name

user_last_name

Last name

user_address

Street address

user_city

City

user_state

State

user_zip_code

Zip code

user_phone

Sanitized 10-digit phone number

user_status

See User Status

user_install_id

Firebase messaging install ID

user_firebase_instance_id

Firebase instance ID for push notifications

user_appsflyer_id

AppsFlyer attribution ID

user_app_platform

Mobile platform (ios, android)

user_date_joined

Timestamp when user record was created

user_date_updated

Timestamp of last update

tags

Map of tag name → Tag object (denormalized cache; canonical records stored separately)

User Status

Status Description

PROCESSING

User has created an Auth0 account. Default status on creation. User is not yet eligible to be billed or take out floats.

ACTIVE

User has linked a Plaid account, has an active debit card, and has an activated subscription and membership. User is eligible for floats and billing.

PAUSED

User has cancelled or been moved to paused state. User can log in but is shown a reactivation screen. Not billed.

INVESTIGATE

Set by MX operations. User cannot take out floats and is not billed.

BANNED

Set by MX operations or triggered automatically on a chargeback. User cannot log in. MX can unban, but user must still reactivate.

user status

Membership

Attribute Description

PK

USERS#<user_id>

SK

TIER#<start_date>

db_type

MEMBERSHIP

membership_user_id

User identifier

membership_tier

Membership tier name (e.g. plus, premium)

membership_tier_version

Version of the tier at time of creation (e.g. v1)

membership_term

Billing term: MONTHLY or ANNUAL

membership_status

See Membership Status

membership_event_source

Which system or actor triggered this membership record

membership_event_type

See Membership Event Types

membership_confirmation_id

Payment confirmation ID from the Payment Service

membership_subscription_id

Subscription ID from the Subscription Service

membership_is_pending_downgrade

true if a downgrade has been initiated but not yet finalized

membership_downgrade_date

Timestamp when the downgrade was scheduled

membership_start_date

When this membership record became effective

membership_reactivation_date

Timestamp of the most recent reactivation

membership_pause_date

Date when the membership will be fully paused (first skipped payment)

membership_unpause_date

Date when the membership was resumed

membership_pause_duration_months

Number of months the pause was requested for

Membership Status

An empty status string means the membership is in good standing.

Status Description

(empty)

Good standing — active, billing normally

PENDING_CANCELLATION

Cancellation scheduled; subscription is winding down

CANCELLED

Membership has been cancelled

SUB_PENDING_PAUSE

Pause has been requested; not yet in effect

SUB_PAUSED

Membership is paused; user is not billed

SUB_PENDING_RESUME

Resume has been requested; not yet in effect

SUB_RESUMED

Membership has been resumed from a pause

SUB_ACTIVE

Subscription is active

Membership Event Types

Event Type Description

CANCEL

User initiated cancellation

CLOSEACCOUNT

Account closure

RETRACT

Pending membership change was retracted

REACTIVATE

MX-initiated reactivation

MANUAL_REACTIVATION

User-initiated reactivation

MX_UNBLOCK

MX enabled reactivation for a banned user

SUB_PAUSED

Subscription paused event recorded

UNPAUSE

Membership unpause

UNPAUSE_CHARGE

Membership unpaused with a charge

SUB_RESUMED

Subscription resumed event recorded

BANNED

User banned

INVESTIGATE

User flagged for investigation

PAYNOW

On-demand payment collected

MEMBERSHIP_UPGRADE

Tier upgraded mid-cycle

MEMBERSHIP_DOWNGRADE

Tier downgrade initiated (pending)

MEMBERSHIP_DOWNGRADE_FINALIZED

Pending downgrade applied at billing cycle

MEMBERSHIP_RETRACT

Pending tier change retracted

Tag

Tags are arbitrary key/value attributes attached to a user account. They are stored as individual items in the primary table and also denormalized into the User item’s tags map.

Attribute Description

PK

USERS#<user_id>

SK

TAG#<tag_name>

db_type

TAG

tag_name

Tag identifier

tag_value

Tag value (string)

tag_archived

true if the tag has been soft-deleted

added_on

RFC3339 timestamp of when the tag was added

Common Tags

Tag Name Values Description

START_DATE

RFC3339 timestamp

Set at account creation. Records when the user first signed up.

MEMBERSHIP_PAUSE_STATUS

SUB_PENDING_PAUSE, SUB_PAUSED, SUB_PENDING_RESUME, SUB_RESUMED

Tracks the current pause state of the membership, updated by the subscription worker.

PAUSE_SUB_DISABLED

Boolean string

When present and true, disables the pause functionality for this user.

is_employee

Boolean string

Reserved for Floatme employees. Bypasses things like subscription fee collections.

is_military

Boolean string

The military status for a user. Assigned after an MLA lookup request.

MLA Lookup Record

MLA lookup results are stored in the primary table for audit and compliance purposes.

Attribute Description

PK

USERS#<user_id>

SK

MLA_LOOKUP#<timestamp> (nanosecond precision RFC3339, to prevent collisions)

db_type

MLA_LOOKUP

user_id

User identifier

message_number

Response code from Experian (e.g. 1203 = covered borrower)

message_text

Human-readable response text from Experian

experian_transaction_id

Experian’s transaction reference ID

is_military

true if Experian returned a covered borrower result

timestamp

When the lookup was performed

Attribute Description

PK

USERS#<user_id>

SK

CONSENT#<consent_key>#<timestamp>

GSI1PK

CONSENT#<consent_key>#<timestamp> — reverse index for consent-first lookups

GSI1SK

USERS#<user_id>

user_id

User identifier

item_id

Item associated with the consent (e.g. Plaid item)

consent_key

Identifier for the consent type (e.g. terms_of_service, sms)

sms_active

Whether SMS consent is active

sms_agreement_timestamp

When SMS consent was accepted

agreement_timestamp

When this consent was accepted

agreement_ip_address

IP address at time of acceptance

agreement_app_version

App version at time of acceptance

agreement_approval_date

Date of approval as provided by the client

For full details on how these event types flow through the system, see Event-Driven Flows.

Legacy Table: user-phone-numbers

Region: us-east-1

Dedicated table for phone number storage and deduplication.

Attribute Description

user_id

Primary key — user identifier

phone_number

Sanitized 10-digit phone number

last_updated

Timestamp of last update

is_opted_out

Whether the user has opted out of SMS

is_phone_verified

Whether the phone number has been verified

GSI: phone_number-index on phone_number — used to check for duplicate phone numbers across users.

Legacy Table: user-balance-settings

Region: us-east-1

Stores user-configured low balance alert thresholds.

Attribute Description

user_id

Primary key — user identifier

created_at

Timestamp when the record was created

low_balance_alert

Alert threshold in cents (e.g. 5000 = $50.00)

RDS: FloatMeAPI_usermodel

Region: us-east-2 — PostgreSQL (ebdb database)

Stores user profile data. Accessed via a read replica for reads and a primary instance for writes.

Column Type Description

user_id

string

Primary key — Auth0-generated user identifier

first_name

string

First name

last_name

string

Last name

email

string

Email address

address

string

Street address

city

string

City

state

string

State

zip_code

string

Zip code

date_joined

timestamp

When the user record was created

date_updated

timestamp

When the user record was last updated

employment_validation

string

User status (mirrors user_status in DynamoDB): PROCESSING, ACTIVE, PAUSED, BANNED, INVESTIGATE

install_id

string

Firebase messaging install ID

firebase_instance_id

string

Firebase instance ID

appsflyer_id

string

AppsFlyer attribution ID

app_platform

string

Mobile platform (ios, android)