Skip to content

fix: close 8 audit gaps across 20 transfer scenarios (PIX/UPI webhooks, compliance jurisdictions, corridor configs)#13

Merged
munisp merged 1 commit into
devin/1781956754-fix-escalationsfrom
devin/1781967721-fix-scenario-gaps
Jun 20, 2026
Merged

fix: close 8 audit gaps across 20 transfer scenarios (PIX/UPI webhooks, compliance jurisdictions, corridor configs)#13
munisp merged 1 commit into
devin/1781956754-fix-escalationsfrom
devin/1781967721-fix-scenario-gaps

Conversation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

Summary

Closes all 8 gaps found in the 20-scenario audit (2 CRITICAL, 2 HIGH, 2 MEDIUM, 2 LOW).

CRITICAL — all 20 scenarios affected:

  • Raw SQL queries used SUM(from_amount) but the actual Drizzle column name is "fromAmount" (camelCase). Fixed 13 occurrences in routers.ts + 2 raw admin dashboard queries that also referenced created_at"createdAt".
  • ML fraud scorer hardcoded source_country: "NG" for all senders regardless of currency. Now derives from CURRENCY_TO_COUNTRY_ML[input.fromCurrency] (CAD→CA, USD→US, GBP→GB, etc).

HIGH — PIX/UPI corridors stuck in partner_sent forever:

  • New server/payment-rail-webhooks.ts — POST /api/webhooks/pix (handles ACSC/RJCT/CANC) and POST /api/webhooks/upi (handles SUCCESS/FAILURE/DEEMED). Both look up the transaction via metadata->>'partnerReference' and call advanceTransferState("completed").
  • Also added the same advanceTransferState call to the existing Mojaloop webhook handler (mojaloop.webhook.ts) which was missing it.

MEDIUM — compliance blind spots:

  • Added 8 currencies to CURRENCY_TO_JURISDICTION: BRL→BR, INR→IN, TZS→TZ, UGX→UG, XOF→SN, XAF→CM, MWK→MW, ZMW→ZM.
  • Added inbound reporting for 6 destination jurisdictions with local thresholds: KE (CBK, KES 1M), GH (BoG, GHS 20K), ZA (FIC, ZAR 25K), TZ (BoT, TZS 10M), BR (COAF, BRL 50K), IN (RBI, INR 1M).
  • Added travel rule thresholds for GH, KE, ZA, BR, IN, TZ, UG.

LOW:

  • Expanded CORRIDOR_CONFIGS from 10 → 28 corridors (18 new: CA→NG/KE/GH/ZA/TZ/UG, US→KE/GH/ZA/BR/IN, UK→KE/GH/ZA, EU→KE/GH/ZA/BR).
  • Velocity check catch-block: { allowed: true, attemptsInWindow: 0 }{ allowed: false, attemptsInWindow: maxAttempts } (fail-closed on DB errors).

7 files changed, 347 insertions, 17 deletions. 0 TypeScript errors.

Link to Devin session: https://app.devin.ai/sessions/64d054ae77da41e9a2b74d8593fa635c
Requested by: @munisp

CRITICAL:
- Fix from_amount column reference in all raw SQL queries (SUM(from_amount) → SUM("fromAmount"))
- Fix ML fraud scorer hardcoded source_country: "NG" → derive from sender currency

HIGH:
- Add PIX webhook handler for Brazil corridor settlement completion
- Add UPI webhook handler for India corridor settlement completion
- Add advanceTransferState call to Mojaloop webhook on COMMITTED

MEDIUM:
- Add 8 missing jurisdictions to compliance auto-filing (BRL, INR, TZS, UGX, XOF, XAF, MWK, ZMW)
- Add inbound reporting for KE (CBK), GH (BoG), ZA (FIC), TZ (BoT), BR (COAF), IN (RBI)
- Add travel rule thresholds for 8 new jurisdictions

LOW:
- Add 18 missing corridor fee configs (CA, US, UK, EU diaspora corridors + PIX/UPI)
- Fix velocity check catch-block fail-open → fail-closed on DB query errors

Co-Authored-By: Patrick Munis <pmunis@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author
Original prompt from Patrick

https://drive.google.com/file/d/14K-94cZoOVgiYCUA-VympU-4_8IBqv2d/view?usp=sharing
extract the contents of the archive. List all the features of the platform

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@munisp munisp merged commit 2529902 into devin/1781956754-fix-escalations Jun 20, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Test Results — PR #13: 8 Audit Gap Fixes

9/9 tests passed. Ran dev server locally against PostgreSQL, tested via live curl requests (runtime) and vitest/structural verification.

Devin session

Runtime Tests (3/3 passed)
Test Gap Method Result
SUM("fromAmount") SQL fix H (CRITICAL) curl dashboard.summary — executes 8+ aggregate queries PASSED — HTTP 200, sentThisMonth: 9953.64 (old code → 500 "column from_amount does not exist")
PIX webhook handler B (HIGH) curl POST /api/webhooks/pix PASSED — Missing endToEndId → 400; valid unmatched → {"received":true,"matched":false}
UPI webhook handler C (HIGH) curl POST /api/webhooks/upi PASSED — Missing transactionId → 400; valid unmatched → {"received":true,"matched":false}
Vitest Tests (9/9 passed, 817ms)
Test Gap Assertion Result
Jurisdiction mapping D (MEDIUM) BRL→BR, INR→IN, TZS→TZ, UGX→UG, XOF→SN, XAF→CM, MWK→MW, ZMW→ZM PASSED
Travel rule thresholds D (MEDIUM) GH, KE, ZA, BR, IN, TZ, UG all have entries PASSED
CA→NG corridor F (LOW) exists, feeMultiplier=1.05, isActive=true PASSED
US→BR corridor F (LOW) exists, feeMultiplier=1.1 (PIX) PASSED
US→IN corridor F (LOW) exists, isActive=true (UPI) PASSED
UK→KE corridor F (LOW) exists, isActive=true PASSED
EU→ZA corridor F (LOW) exists, feeMultiplier=1.2 PASSED
Undefined corridors F (LOW) ZA→BR and IN→US return null PASSED
Total corridor count F (LOW) 28 (was 10) PASSED
Structural Verification (4/4 passed)
Test Gap Assertion Result
ML fraud scorer A (CRITICAL) CURRENCY_TO_COUNTRY_ML at L1325, mlSourceCountry derived from input.fromCurrency, zero remaining source_country: "NG" PASSED
Inbound reporting E (MEDIUM) CBK_CTR (KE, 1M), BOG_CTR (GH, 20K), FIC_CTR (ZA, 25K), BOT_CTR (TZ, 10M), COAF_CTR (BR, 50K), RBI_CTR (IN, 1M) all present PASSED
Velocity fail-closed G (LOW) catch → { allowed: false, attemptsInWindow: maxAttempts } PASSED
Mojaloop advanceTransferState Bonus advanceTransferState("completed") called on COMMITTED at L153 PASSED

Escalations: None.

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.

1 participant