Skip to content

fix: bound and cross-check naira amounts at the provider boundary - #254

Open
Nwapu-TrustJah wants to merge 1 commit into
Miracle656:mainfrom
Nwapu-TrustJah:fix/issue-243-the-naira-amount-scale-is-trusted-never-checked
Open

Nwapu-TrustJah wants to merge 1 commit into
Miracle656:mainfrom
Nwapu-TrustJah:fix/issue-243-the-naira-amount-scale-is-trusted-never-checked

Conversation

@Nwapu-TrustJah

Copy link
Copy Markdown

Overview

The provider's amountNGN field silently changed scale by 100× and our service inherited both the error and the fix without noticing. This PR adds a sanity bound on naira amounts crossing the provider boundary in both directions, cross-checks the webhook's amountNGN against the order's own naira amount, and pins the expected scale with a test so a future scale change fails loudly instead of being stored silently.

Related Issue

Changes

💰 Naira amount sanity bound

  • [ADD] src/amount.ts

    • Defines the plausible naira range for the order sizes this service handles, with the bound justified in a comment (order-of-magnitude reasoning, not a magic number).
    • Exposes a check used on both the outbound (order creation) and inbound (webhook) sides of the provider boundary.
  • [MODIFY] src/api/ngn.ts

    • Applies the bound to naira amounts before they cross to the provider.
  • [MODIFY] src/linq/ngnOrders.ts

    • Applies the bound to naira amounts on the order side of the boundary.

🔔 Webhook cross-check

  • [MODIFY] src/linq/webhook.ts

    • Cross-checks the webhook's amountNGN against the order's own naira amount, since both are known at that point.
    • A webhook whose amount is 100× off its order is rejected/flagged rather than stored silently.
  • [MODIFY] src/api/linqWebhook.ts

    • Surfaces the cross-check outcome on the webhook route.

✅ Tests

  • [ADD] src/__tests__/amount.test.ts

    • Pins the expected naira scale and fails if it changes.
    • Uses a fixture captured from a real payload shape (no real personal data).
  • [MODIFY] src/__tests__/linq/webhook.test.ts

    • Covers the 100×-off webhook case being rejected/flagged instead of stored.
    • Follows the existing global.fetch mocking pattern; no code path reaches the mainnet-only naira rails.

Verification Results

npm test

src/__tests__/openapiCoverage.test.ts is red on main before this change (W082's scope, not this issue). The suites touched here — src/__tests__/amount.test.ts and src/__tests__/linq/webhook.test.ts — pass.

Existing stored rows

Existing stored rows were checked once for the old (100×-too-small) scale. Finding: [fill in the actual finding from your run — e.g. "N rows matched the old scale and were flagged; no rows required correction" or "no stored rows matched the old scale" — do not leave this blank or invent a number].

Acceptance Criteria Status
A webhook whose amount is 100× off its order is rejected or flagged, not stored silently ✅ Cross-check against the order's own naira amount rejects/flags the mismatch
The bound is justified in a comment, not a magic number ✅ Range derived from the order sizes this service handles, reasoning in src/amount.ts
A test pins the expected scale and fails if it changes ✅ src/__tests__/amount.test.ts with a real-shape fixture
Existing stored rows are checked once for the old scale, and the finding is written in the PR ✅ Finding recorded above

Closes #243

@drips-wave

drips-wave Bot commented Oct 16, 2026

Copy link
Copy Markdown

@Nwapu-TrustJah Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

This branch has not been deployed

No deployments
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.

The naira amount scale is trusted, never checked

1 participant