feat(transactions): add amount rounding for currency in transaction p…#502
feat(transactions): add amount rounding for currency in transaction p…#502sundayonah wants to merge 4 commits into
Conversation
…rocessing - Introduced a new utility function `roundAmountForCurrency` to round transaction amounts to two decimal places for consistency with user-facing values. - Updated the transaction POST route to utilize this new function, ensuring that both `amount_sent` and `amount_received` are rounded before being stored in the database.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds parseValidTransactionAmount and roundAmountForCurrency utilities; the transactions POST route now validates incoming amount fields, rejects invalid values, rounds valid amounts to 2 decimals, and stores/tracks the rounded values. ChangesTransaction Amount Precision
Sequence DiagramsequenceDiagram
participant Client
participant TransactionsRoute
participant Supabase
participant Analytics
Client->>TransactionsRoute: POST /api/v1/transactions { amountSent, amountReceived, ... }
TransactionsRoute->>TransactionsRoute: parseValidTransactionAmount(amountSent/Received)
alt invalid
TransactionsRoute-->>Client: 400 Bad Request
else valid
TransactionsRoute->>TransactionsRoute: roundAmountForCurrency(parsed amounts)
TransactionsRoute->>Supabase: insert transactions { amount_sent, amount_received, ... }
TransactionsRoute->>Analytics: trackTransactionEvent('Transaction Created', { amount_sent, amount_received, ... })
Supabase-->>TransactionsRoute: insert result
TransactionsRoute-->>Client: 200 Created (or relevant response)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (2 warnings, 1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
app/utils.ts (1)
172-178: ⚡ Quick winConsider potential floating-point precision issues in currency rounding.
The
Math.round(amount * factor) / factorapproach can produce unexpected results for certain decimal values due to IEEE 754 floating-point representation. For example,Math.round(1.005 * 100) / 100might not yield exactly1.01.For financial calculations where precision is critical, consider using integer-based arithmetic (convert to smallest unit like cents) or a decimal library.
💰 Alternative approach using integer cents
export function roundAmountForCurrency(amount: number): number { if (typeof amount !== "number" || !Number.isFinite(amount)) { return 0; } - const factor = 10 ** 2; // 2 decimal places - return Math.round(amount * factor) / factor; + // Convert to cents, round, convert back to avoid floating-point issues + const cents = Math.round(amount * 100); + return cents / 100; }Note: This still has the same limitation but makes the intent clearer. For true decimal precision, consider a library like
decimal.jsorbig.js.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/utils.ts` around lines 172 - 178, The current roundAmountForCurrency function uses Math.round(amount * factor) / factor which can mis-round due to floating-point precision; update roundAmountForCurrency to avoid FP errors by converting the amount to integer smallest units (e.g., cents) before rounding or switch to a decimal library (e.g., decimal.js/big.js) for exact arithmetic: multiply amount by 100 and use integer math (Math.round on the integer) then divide back to units, or replace the implementation to use a Decimal class for all operations to ensure correct results for values like 1.005; keep the function signature and return type unchanged and ensure NaN/Infinity guard remains.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/api/v1/transactions/route.ts`:
- Around line 152-153: Validate the incoming amount fields before calling
roundAmountForCurrency: check that body.amountSent and body.amountReceived exist
and parse to finite numbers (e.g., using Number(body.amountSent) and
Number.isFinite or isFinite) and reject the request (throw/return a 4xx) if they
are missing or non-numeric; only then set const amountSent =
roundAmountForCurrency(parsedAmountSent) and const amountReceived =
roundAmountForCurrency(parsedAmountReceived). Ensure the validation is performed
in the same route handler (the function that computes amountSent/amountReceived)
so invalid inputs are not silently converted to 0.
---
Nitpick comments:
In `@app/utils.ts`:
- Around line 172-178: The current roundAmountForCurrency function uses
Math.round(amount * factor) / factor which can mis-round due to floating-point
precision; update roundAmountForCurrency to avoid FP errors by converting the
amount to integer smallest units (e.g., cents) before rounding or switch to a
decimal library (e.g., decimal.js/big.js) for exact arithmetic: multiply amount
by 100 and use integer math (Math.round on the integer) then divide back to
units, or replace the implementation to use a Decimal class for all operations
to ensure correct results for values like 1.005; keep the function signature and
return type unchanged and ensure NaN/Infinity guard remains.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 7e516f98-f058-4e6e-a0df-ea51b79e3eac
📒 Files selected for processing (2)
app/api/v1/transactions/route.tsapp/utils.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/utils.ts`:
- Around line 186-192: roundAmountForCurrency currently uses Math.round(amount *
100) / 100 which misrounds due to IEEE-754; replace it with a stable 2-decimal
rounding strategy inside roundAmountForCurrency: either (a) convert to integer
cents (multiply by 100, use a robust integer round, operate in cents, then
divide by 100) or (b) implement the exponential shift trick (shift with string
exponential notation to avoid floating imprecision when shifting, round, then
shift back), or preferably switch to a decimal library (Decimal.js/Big.js) for
financial accuracy; update the implementation of roundAmountForCurrency and any
related tests to use the chosen approach and keep the function signature the
same.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: b9bf5282-06b6-4626-bbdf-be5ac319871b
📒 Files selected for processing (2)
app/api/v1/transactions/route.tsapp/utils.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- app/api/v1/transactions/route.ts
roundAmountForCurrencyto round transaction amounts to two decimal places for consistency with user-facing values.amount_sentandamount_receivedare rounded before being stored in the database.Description
References
Testing
Checklist
mainBy submitting a PR, I agree to Paycrest's Contributor Code of Conduct and Contribution Guide.
Summary by CodeRabbit