Float Profiles

A Float Profile is the user’s configuration for available float and loan products. It defines which float tiers are enabled, the fee schedule mapping, loan settings, and any temporary profile overrides.

Overview

Each user has a Float Profile stored in DynamoDB that controls:

  • Enabled float tiers - Which of the 7 float amounts are available ($10, $20, $30, $40, $50, $80, $100, optionally $200)

  • Float settings - Enable/disable each tier independently

  • Associated fees - Fee per float tier ($1, $3, $4, $5, $6, or $7 depending on tier)

  • Loan settings - Available loan amounts ($200-$350)

  • CFI status - Whether Continuous Float Increase is enabled

  • Temporary profiles - Short-lived overrides for promotions or testing

Default Float Profile

When a user first interacts with the system, if no profile exists, a default is created:

Amount ID Default Enabled

$10

1

✓ Yes

$20

2

✓ Yes

$30

3

✗ No

$40

4

✗ No

$50

5

✗ No

$80

6

✗ No

$100

7

✗ No

$200

(special)

✗ No (rare, only for elite users)

New users start with $10-$20 enabled. As they build history and meet CFI thresholds, the profile is updated to enable higher tiers.

Float Settings

Each float tier has a corresponding setting:

FloatSetting Structure:

{
  "id": "2",           // Unique identifier (1-7)
  "amount": 2000,      // Amount in cents ($20)
  "is_enabled": true   // Can user take this amount?
}

Float Tiers & Fees

Tier Amount Fee Use Case

1

$10

$1

Emergency only - very short term

2

$20

$3

New users, regular use

3

$30

$4

Established users

4

$40

$5

Comfortable borrowers

5

$50

$5

Advanced tier (no fee increase)

6

$80

$6

Premium tier

7

$100

$7

Elite tier

Special

$200

$7

Exclusive (historical $200 repayment required)

Fee Mapping

The fee schedule is defined globally and applied consistently:

FloatFeeSchedule = {
  10:   1,     // $10 costs $1 fee ($11.00 total)
  20:   3,     // $20 costs $3 fee ($23.00 total)
  30:   4,     // $30 costs $4 fee ($34.00 total)
  40:   5,     // $40 costs $5 fee ($45.00 total)
  50:   5,     // $50 costs $5 fee ($55.00 total)
  80:   6,     // $80 costs $6 fee ($86.00 total)
  100:  7,     // $100 costs $7 fee ($107.00 total)
  200:  7,     // $200 costs $7 fee ($207.00 total)
}
Example calculation
  • User takes a $30 float

  • Fee is $4 (from schedule)

  • User gets $30, repays $34 at due date

  • Fee percentage: 4/3000 = 0.13% (very low compared to alternatives)

Loan Settings

Loans are similar to floats but larger amounts with different term structures.

LoanSetting Structure:

{
  "id": "1",
  "amount_cents": 20000,  // Amount in cents ($200)
  "is_enabled": true
}

Available Loan Tiers

ID Amount Fee Structure

1

$200

Based on term and credit profile

2

$250

Based on term and credit profile

3

$300

Based on term and credit profile

4

$350

Based on term and credit profile

Loan fees are retrieved from GrowthBook feature flags and vary by: * User’s credit profile * Loan term length * External loan history (EWA - External Weather Alerts)

FloatProfile Data Structure

Complete FloatProfile as stored in DynamoDB:

{
  "pk": "USER#user-12345",
  "sk": "PROFILE#2024-02-10T14:30:00Z",
  "user_id": "user-12345",
  "is_float_enabled": true,
  "is_loan_enabled": true,
  "cfi_enabled": true,
  "created_on": "2024-02-10T14:30:00Z",
  "reason": "Initial profile creation",
  "notes": "Standard user profile",
  "floats": [
    {
      "id": "1",
      "amount": 1000,
      "is_enabled": true
    },
    {
      "id": "2",
      "amount": 2000,
      "is_enabled": true
    },
    {
      "id": "3",
      "amount": 3000,
      "is_enabled": false
    },
    ...
  ],
  "loans": [
    {
      "id": "1",
      "amount_cents": 20000,  // Amount in cents ($200)
      "is_enabled": true
    },
    ...
  ]
}

Field Descriptions

Field Type Description

user_id

string

User’s unique identifier

is_float_enabled

bool

Can user take floats at all?

is_loan_enabled

bool

Can user take loans at all?

cfi_enabled

bool

Can float limits auto-increase? (CFI)

created_on

ISO8601

Profile creation timestamp

reason

string

Why profile was created (note field)

notes

string

Additional context

floats

array

Array of FloatSetting objects

loans

array

Array of LoanSetting objects

Temporary Float Profiles

Temporary float profiles allow time-limited overrides for promotions, testing, or special cases.

Use Cases: * Promotional campaigns - "$30 for 2 weeks" promotion * A/B testing new float amounts * VIP onboarding - Early access to higher tiers * Compliance hold - Temporarily reduce available amounts

Temporary Profile Structure

{
  "pk": "USER#user-12345",
  "sk": "TEMP_FLOAT_PROFILE#EXPIRES#2024-02-17T00:00:00Z",
  "user_id": "user-12345",
  "created_on": "2024-02-10T14:30:00Z",
  "expires_on": "2024-02-17T00:00:00Z",
  "reason": "Promotional offer - Presidents Day campaign",
  "floats": [
    {
      "id": "1",
      "amount": 1000,
      "is_enabled": true
    },
    {
      "id": "2",
      "amount": 2000,
      "is_enabled": true
    },
    {
      "id": "3",
      "amount": 3000,
      "is_enabled": true     // Promotional override
    },
    {
      "id": "4",
      "amount": 4000,
      "is_enabled": true     // Promotional override
    }
  ]
}

Lifecycle

┌─────────────────────────────┐
│ Temporary Profile Created   │
│ - Promotional tier unlocked │
│ - Expiry set to N days out  │
└────────────┬────────────────┘
             │
             ▼
┌─────────────────────────────┐
│ User Takes Float            │
│ - Can use new tiers         │
│ - Float recorded normally   │
└────────────┬────────────────┘
             │
        ┌────┴────┐
        │          │
    ┌───┴────┐    │
    │ Before │    │ After
    │Expiry? │    │Expiry?
    └───┬────┘    │
        │         ▼
        ├──→ ┌──────────────────────┐
        │    │ Temp profile ignored │
        │    │ - Reverts to regular │
        │    │   profile settings   │
        │    │ - New floats use old │
        │    │   limits             │
        │    └──────────────────────┘
        │
        ▼
    ┌────────────────────────────┐
    │ Take from regular profile  │
    └────────────────────────────┘

Profile Querying

Getting Latest Profile

When a user checks their profile, the system:

  1. Query by user_id

    • Get the latest FloatProfile (by created_on timestamp)

    • Include unexpired TemporaryFloatProfile if present

  2. Profile priority

    • If valid temporary profile exists: Use it

    • Otherwise: Use latest regular profile

  3. Default handling

    • If no profiles exist: Return default profile

    • No database write needed for defaults

Profile Update Timeline

┌──────────────────────────────────────┐
│ 2024-01-01 - Initial Profile         │
│ Floats: $10, $20 enabled             │
└────────────┬─────────────────────────┘
             │
        User acquires float history
             │
             ▼
┌──────────────────────────────────────┐
│ 2024-02-10 - CFI Update #1           │
│ Floats: $10, $20, $30 enabled        │
│ Reason: "User reached float rank 3"  │
└────────────┬─────────────────────────┘
             │
        User builds subscription history
             │
             ▼
┌──────────────────────────────────────┐
│ 2024-03-05 - CFI Update #2           │
│ Floats: $10, $20, $30, $40, $50 en.  │
│ Reason: "User reached sub rank 6"    │
└──────────────────────────────────────┘

Loan Profiles

Loan settings control available loan products:

LoanFeeSchedule

Retrieved from GrowthBook with loan fees by term:

{
  "term_label": {
    "loan_type": {
      "type": "fixed" or "percentage",
      "fee_cents": 1500,
      "fee_percent": 2.5
    }
  }
}
Example
{
  "4_weeks": {
    "loan_200": {
      "type": "fixed",
      "fee_cents": 1500,
      "fee_percent": 0.0
    }
  }
}

Loan Enabling/Disabling

Loans can be disabled system-wide or per-user:

  • System-wide: Set in GrowthBook (all users affected)

  • Per-user: Update FloatProfile is_loan_enabled flag

  • Feature flags: Use RequiresFeatureFlag for new loan products

    Reasons to disable
  • User exceeded debt-to-income ratio

  • Risk scoring below threshold

  • Regulatory hold

  • User requested pause

API Response Format

When returning a float profile to the API client:

{
  "is_float_enabled": true,
  "is_loan_enabled": true,
  "floats": [
    {
      "id": "1",
      "amount": 1000,
      "is_enabled": true,
      "fee": 100      // Added by API layer
    },
    {
      "id": "2",
      "amount": 2000,
      "is_enabled": true,
      "fee": 300
    },
    {
      "id": "3",
      "amount": 3000,
      "is_enabled": true,
      "fee": 400
    }
  ],
  "loans": [
    {
      "id": "1",
      "amount": 20000,
      "is_enabled": true,
      "fee": {
        "type": "fixed",
        "amount": 1500
      }
    }
  ]
}

The API layer enriches stored profiles with: * Calculated fees based on FloatFeeSchedule * Loan fees from GrowthBook * Default values if none exist * Formatted amounts for client consumption

See Also