Normalize allocation_value to integer cents #16

Closed
opened 2026-03-21 12:05:48 +01:00 by myrmidex · 0 comments
Owner

Problem

allocation_value is stored as decimal:2 (dollars) while all other currency fields (starting_amount, Draw.amount, Inflow.amount, Outflow.amount) are stored as integers (cents). This unit mismatch causes PipelineAllocationService to treat getEffectiveCapacity() (dollars) as cents, producing wildly incorrect allocations (e.g., a $500 bucket only receives $5).

The preview endpoint (#12) surfaces this bug directly — users see wrong amounts.

Approach

Convert allocation_value to integer (cents) storage. All backend calculations happen on cent amounts. Only the API response layer converts cents→dollars (on the way out) and request handlers convert dollars→cents (on the way in).

Scope

  • Migration: Change allocation_value from decimal(10,2) to unsignedBigInteger, multiply existing values by 100
  • Bucket model: Update cast from 'decimal:2' to 'integer', update getEffectiveCapacity() to return cents
  • BucketFactory: Update fixedLimit() and percentage() values to cents
  • Validation: Update StoreBucketRequest / UpdateBucketRequest rules (accept dollars from frontend, convert to cents)
  • BucketController: Convert dollars→cents on input, cents→dollars on output
  • BucketResource: Expose allocation_value as dollars (divide by 100)
  • PipelineAllocationService: Should work correctly once all units are cents — verify calculateFixedAllocation and calculatePercentageAllocation
  • ProjectionController::preview(): Remove the cents workaround in remainingCapacity() — should be clean once units are consistent
  • Frontend: Verify forms send dollars (already the case), verify display reads dollars from API (already the case)
  • Tests: Update all test assertions for cent-based allocation_value

Acceptance criteria

  • All currency amounts stored as integer cents in the database
  • PipelineAllocationService produces correct allocations (e.g., $500 bucket receives $500 from a $3000 income, not $5)
  • Preview endpoint shows correct dollar amounts
  • No user-facing changes — frontend still works in dollars
## Problem `allocation_value` is stored as `decimal:2` (dollars) while all other currency fields (`starting_amount`, `Draw.amount`, `Inflow.amount`, `Outflow.amount`) are stored as integers (cents). This unit mismatch causes `PipelineAllocationService` to treat `getEffectiveCapacity()` (dollars) as cents, producing wildly incorrect allocations (e.g., a $500 bucket only receives $5). The preview endpoint (#12) surfaces this bug directly — users see wrong amounts. ## Approach Convert `allocation_value` to integer (cents) storage. All backend calculations happen on cent amounts. Only the API response layer converts cents→dollars (on the way out) and request handlers convert dollars→cents (on the way in). ## Scope - **Migration**: Change `allocation_value` from `decimal(10,2)` to `unsignedBigInteger`, multiply existing values by 100 - **Bucket model**: Update cast from `'decimal:2'` to `'integer'`, update `getEffectiveCapacity()` to return cents - **BucketFactory**: Update `fixedLimit()` and `percentage()` values to cents - **Validation**: Update `StoreBucketRequest` / `UpdateBucketRequest` rules (accept dollars from frontend, convert to cents) - **BucketController**: Convert dollars→cents on input, cents→dollars on output - **BucketResource**: Expose `allocation_value` as dollars (divide by 100) - **PipelineAllocationService**: Should work correctly once all units are cents — verify `calculateFixedAllocation` and `calculatePercentageAllocation` - **ProjectionController::preview()**: Remove the cents workaround in `remainingCapacity()` — should be clean once units are consistent - **Frontend**: Verify forms send dollars (already the case), verify display reads dollars from API (already the case) - **Tests**: Update all test assertions for cent-based `allocation_value` ## Acceptance criteria - All currency amounts stored as integer cents in the database - `PipelineAllocationService` produces correct allocations (e.g., $500 bucket receives $500 from a $3000 income, not $5) - Preview endpoint shows correct dollar amounts - No user-facing changes — frontend still works in dollars
myrmidex added this to the v0.2.0 milestone 2026-03-21 12:05:48 +01:00
myrmidex added the
bug
label 2026-03-21 12:05:48 +01:00
myrmidex self-assigned this 2026-03-21 12:05:48 +01:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lvl0/buckets#16
No description provided.