Skip to content

feat(transactions): add amount rounding for currency in transaction p…#502

Open
sundayonah wants to merge 4 commits into
mainfrom
fix/noblocks-round-transaction-amounts
Open

feat(transactions): add amount rounding for currency in transaction p…#502
sundayonah wants to merge 4 commits into
mainfrom
fix/noblocks-round-transaction-amounts

Conversation

@sundayonah
Copy link
Copy Markdown
Collaborator

@sundayonah sundayonah commented May 18, 2026

  • 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.

Description

Describe the purpose of this PR along with any background information and the impacts of the proposed change. For the benefit of the community, please do not assume prior context.

Provide details that support your chosen implementation, including: breaking changes, alternatives considered, changes to the API, contracts etc.

References

Include any links supporting this change such as a:

If there are no references, simply delete this section.

Testing

Describe how this can be tested by reviewers. Be specific about anything not tested and reasons why. If this project has unit and/or integration testing, tests should be added for new functionality and existing tests should complete without errors.

Please include any manual steps for testing end-to-end or functionality not covered by unit/integration tests.

Also include details of the environment this PR was developed in (language/platform/browser version).

image
  • This change adds test coverage for new/changed/fixed functionality

Checklist

  • I have added documentation and tests for new/changed functionality in this PR
  • All active GitHub checks for tests, formatting, and security are passing
  • The correct base branch is being used, if not main

By submitting a PR, I agree to Paycrest's Contributor Code of Conduct and Contribution Guide.

Summary by CodeRabbit

  • Bug Fixes
    • Transaction amounts are now consistently rounded to 2 decimal places when stored and reported for accurate currency display.
    • API now validates sent/received amounts and returns a 400 error for missing or invalid values to prevent bad transactions.

Review Change Stack

…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.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 18, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fa4f87b2-6856-4224-bec6-d87eda3ec844

📥 Commits

Reviewing files that changed from the base of the PR and between 4eacf01 and 772a5d9.

📒 Files selected for processing (1)
  • app/utils.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/utils.ts

📝 Walkthrough

Walkthrough

Adds 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.

Changes

Transaction Amount Precision

Layer / File(s) Summary
Parsing and rounding utilities
app/utils.ts
parseValidTransactionAmount(value) coerces an unknown input to a non-negative finite number or returns null. roundAmountForCurrency(amount) returns 0 for non-finite inputs and otherwise rounds to exactly 2 decimal places.
POST route: validate, round, persist, track
app/api/v1/transactions/route.ts
Imports rounding utility, parses body.amountSent/body.amountReceived with parseValidTransactionAmount (400 on invalid), computes rounded amountSent/amountReceived via roundAmountForCurrency, uses rounded values for Supabase transactions insert and in trackTransactionEvent('Transaction Created', ...) payload.

Sequence Diagram

sequenceDiagram
  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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • chibie
  • 5ran6
  • onahprosper

Poem

🐰 I hop through cents both bright and small,
I parse each number, heed the call.
Two decimals snug, I round with care,
The ledger hums — the sums are fair.
Track the tale I leave in air.

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The linked issue #407 concerns recipient name editability and verification, which is unrelated to the current PR about amount rounding for transactions. The PR appears to address a different feature (amount rounding) than the linked issue #407 (recipient name editability). Verify the correct issue link or provide the relevant issue for amount rounding.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The PR description includes high-level summary of changes but lacks detailed information in several required template sections (References, Testing details, and test coverage confirmation). Add missing References section with issue numbers, provide detailed Testing section with manual steps and environment details, and confirm whether test coverage was added for the new utility functions.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(transactions): add amount rounding for currency in transaction p…' is directly related to the main changeset, which introduces rounding functionality for transaction amounts.
Out of Scope Changes check ✅ Passed All changes (new utility functions and transaction route updates) are focused on amount rounding and directly support the PR's stated objective of rounding transaction amounts to two decimal places.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/noblocks-round-transaction-amounts

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
app/utils.ts (1)

172-178: ⚡ Quick win

Consider potential floating-point precision issues in currency rounding.

The Math.round(amount * factor) / factor approach can produce unexpected results for certain decimal values due to IEEE 754 floating-point representation. For example, Math.round(1.005 * 100) / 100 might not yield exactly 1.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.js or big.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

📥 Commits

Reviewing files that changed from the base of the PR and between f81c0bf and d905799.

📒 Files selected for processing (2)
  • app/api/v1/transactions/route.ts
  • app/utils.ts

Comment thread app/api/v1/transactions/route.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between d905799 and 4eacf01.

📒 Files selected for processing (2)
  • app/api/v1/transactions/route.ts
  • app/utils.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/api/v1/transactions/route.ts

Comment thread app/utils.ts
@SarahSync SarahSync linked an issue May 25, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add amount rounding for currency in transaction confirmation mail

1 participant