feat: close 12 production readiness gaps — locales, legal pages, email templates, multi-region, webhooks, rate limiting#17
Merged
munisp merged 10 commits intoJun 20, 2026
Conversation
HIGH severity (4 gaps closed): - State machine AML check: CTR_REQUIRED and TRAVEL_RULE are now informational (non-blocking). Only SAR_REVIEW/EDD_REQUIRED block transfers ≥$10K. Previously ALL $10K+ transfers were auto-failed. - Payment rail failure: now fatal — transfer marked 'failed' with refund note if Mojaloop/PIX/UPI/SWIFT disbursement fails. Previously errors were swallowed and transfer marked 'partner_sent'. - TigerBeetle ledger: write is now awaited with critical audit log on failure, not fire-and-forget. Reconciliation alerts created. - Compliance auto-filing: new complianceAutoFiling module auto-triggers FINTRAC CTR, FATF Travel Rule (IVMS101), and NFIU inbound reports during transfer flow. Creates compliance_filings DB table. MEDIUM severity (6 gaps closed): - 2FA check: fail-closed when DB unavailable (was: skip 2FA entirely) - KYC tier limits: fail-closed when DB unavailable (was: skip limits) - Velocity check: fail-closed when DB unavailable (was: allow all) - Auto-completion removed: transfers stay in partner_sent until webhook confirmation from payment partner (was: auto-advance after delay) - Mark Lane FX bridge: CAD→African currencies now route through Mark Lane instead of generic Mojaloop for better FX rates + settlement - Reconciliation scheduler: automated daily reconciliation checks wallet balances, stuck transfers, failed transfers, ledger sync LOW severity (4 gaps closed): - Fee corridor: uses sender's actual country from currency mapping instead of hardcoded 'NG' (was: always NG regardless of sender) - FX rate locking: quote timestamp captured for audit trail - Idempotency guard: duplicate transfers rejected within 24h window when idempotencyKey provided - 2FA enrollment: required for transfers ≥$10K USD if user hasn't enabled TOTP yet 0 TypeScript errors. No test regressions. Co-Authored-By: Patrick Munis <pmunis@gmail.com>
HIGH severity (4 gaps closed): - State machine AML check: CTR_REQUIRED and TRAVEL_RULE are now informational (non-blocking). Only SAR_REVIEW/EDD_REQUIRED block transfers ≥$10K. Previously ALL $10K+ transfers were auto-failed. - Payment rail failure: now fatal — transfer marked 'failed' with refund note if Mojaloop/PIX/UPI/SWIFT disbursement fails. Previously errors were swallowed and transfer marked 'partner_sent'. - TigerBeetle ledger: write is now awaited with critical audit log on failure, not fire-and-forget. Reconciliation alerts created. - Compliance auto-filing: new complianceAutoFiling module auto-triggers FINTRAC CTR, FATF Travel Rule (IVMS101), and NFIU inbound reports during transfer flow. Creates compliance_filings DB table. MEDIUM severity (6 gaps closed): - 2FA check: fail-closed when DB unavailable (was: skip 2FA entirely) - KYC tier limits: fail-closed when DB unavailable (was: skip limits) - Velocity check: fail-closed when DB unavailable (was: allow all) - Auto-completion removed: transfers stay in partner_sent until webhook confirmation from payment partner (was: auto-advance after delay) - Mark Lane FX bridge: CAD→African currencies now route through Mark Lane instead of generic Mojaloop for better FX rates + settlement - Reconciliation scheduler: automated daily reconciliation checks wallet balances, stuck transfers, failed transfers, ledger sync LOW severity (4 gaps closed): - Fee corridor: uses sender's actual country from currency mapping instead of hardcoded 'NG' (was: always NG regardless of sender) - FX rate locking: quote timestamp captured for audit trail - Idempotency guard: duplicate transfers rejected within 24h window when idempotencyKey provided - 2FA enrollment: required for transfers ≥$10K USD if user hasn't enabled TOTP yet 0 TypeScript errors. No test regressions. Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Patrick Munis <pmunis@gmail.com>
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>
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: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Patrick Munis <pmunis@gmail.com>
… all rails CIPS (China Cross-Border Interbank Payment System): - Go: Enhanced go-cips-adapter to forward pacs.002 settlement callbacks to Node.js core - Rust: New rust-cips-crypto service for SM2/SM3 cryptographic signing (PBOC standard) - Python: New python-pboc-compliance engine (LTR/STR reporting, SAFE quota checks) - TypeScript: CIPS webhook handler (POST /api/webhooks/cips) with ACSC/RJCT handling - 16 CIPS corridor configs (US/CA/UK/EU/NG/KE/ZA/GH ↔ CN, all bi-directional) - CNY/CNH added to jurisdiction mapping, ML fraud scorer, fee calculator - PBoC inbound reporting (CNY >200K) + SAFE cross-border declaration Bi-directional corridors: - Added 24 missing reverse corridors (was 28 configs → now 64) - All 6 rails (Mojaloop, Mark Lane, PIX, UPI, SWIFT, CIPS) are fully bi-directional - Every A→B corridor now has a matching B→A corridor 0 TypeScript errors, 0 lint errors. Co-Authored-By: Patrick Munis <pmunis@gmail.com>
…aduated risk tiers
Fixes 7 issues in the ML fraud scoring pipeline:
1. Temporal fraud activity: source_country derived from input.fromCurrency
(was hardcoded "NG" — every sender scored as Nigerian)
2. Temporal gRPC fraud call: fromCountry derived dynamically (was "NG")
3. Temporal fraud activity: user_kyc_level looked up from DB (was hardcoded 1)
4. P2P instant: receiverCountry initialized to "XX" (was "NG")
5. detectCountryFromPhone(): expanded from 9 to 30 prefixes, default "XX"
(added CN, TZ, UG, ZM, MW, SN, CM, CI, RW, JP, KR, DE, FR, ES, IT,
NL, SE, NO, AU, NZ, AE, SA, EG)
6. buildFeatures(): corridor_fraud_rate_30d + corridor_avg_amount now
accepted as optional params (were static 0.02/800)
7. Country risk scoring: 4-tier graduated system replaces binary 85/20:
HIGH_RISK=85, ELEVATED_RISK=60, MODERATE_RISK=40, LOW_RISK=15
0 TypeScript errors, 0 lint errors.
Co-Authored-By: Patrick Munis <pmunis@gmail.com>
…coding
Fixes 7 issues in the ML fraud scoring pipeline:
1. Temporal fraud activity: source_country derived from input.fromCurrency
(was hardcoded "NG" — every sender scored as Nigerian)
2. Temporal gRPC fraud call: fromCountry derived dynamically (was "NG")
3. Temporal fraud activity: user_kyc_level looked up from DB (was hardcoded 1)
4. P2P instant: receiverCountry initialized to "XX" (was "NG")
5. detectCountryFromPhone(): expanded from 9 to 30 prefixes, default "XX"
(added CN, TZ, UG, ZM, MW, SN, CM, CI, RW, JP, KR, DE, FR, ES, IT,
NL, SE, NO, AU, NZ, AE, SA, EG)
6. buildFeatures(): corridor_fraud_rate_30d + corridor_avg_amount now
accepted as optional params (were static 0.02/800)
7. Country risk scoring: 4-tier graduated system replaces binary 85/20:
HIGH_RISK=85, ELEVATED_RISK=60, MODERATE_RISK=40, LOW_RISK=15
0 TypeScript errors, 0 lint errors.
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Patrick Munis <pmunis@gmail.com>
…a, graduated risk tiers, PBoC/SAFE compliance, currency support PWA (Web): - New SendToChina.tsx (CIPS corridor landing page) - New SendToBrazil.tsx (PIX corridor landing page) - New SendToIndia.tsx (UPI corridor landing page) - Routes wired in App.tsx (/send-to-china, /send-to-brazil, /send-to-india) - currency.ts: added CNY/CNH/BRL/INR/CAD/AUD/JPY symbols + locales - FraudDetectionV2: 4-tier graduated country risk reference card - ComplianceReporting: PBoC LTR, SAFE, NFIU STR, FINTRAC CTR report types + jurisdiction threshold table - Updated relatedCorridors on SendToNigeria, SendToKenya, SendToSouthAfrica React Native: - New SendToChinaScreen, SendToBrazilScreen, SendToIndiaScreen - All 15 SendTo screens registered in RootNavigator.tsx (was missing) Flutter: - New send_to_china_screen.dart, send_to_brazil_screen.dart, send_to_india_screen.dart - Country-specific content (CIPS/PIX/UPI info, payment methods, conversion) Backend: - productionV84.ts: expanded compliance report enum with PBOC_LTR, SAFE_CROSS_BORDER, NFIU_STR, FINTRAC_CTR 0 TypeScript errors. Co-Authored-By: Patrick Munis <pmunis@gmail.com>
PWA (Web): - New SendToChina.tsx (CIPS corridor landing page) - New SendToBrazil.tsx (PIX corridor landing page) - New SendToIndia.tsx (UPI corridor landing page) - Routes wired in App.tsx (/send-to-china, /send-to-brazil, /send-to-india) - currency.ts: added CNY/CNH/BRL/INR/CAD/AUD/JPY symbols + locales - FraudDetectionV2: 4-tier graduated country risk reference card - ComplianceReporting: PBoC LTR, SAFE, NFIU STR, FINTRAC CTR report types + jurisdiction threshold table - Updated relatedCorridors on SendToNigeria, SendToKenya, SendToSouthAfrica React Native: - New SendToChinaScreen, SendToBrazilScreen, SendToIndiaScreen - All 15 SendTo screens registered in RootNavigator.tsx (was missing) Flutter: - New send_to_china_screen.dart, send_to_brazil_screen.dart, send_to_india_screen.dart - Country-specific content (CIPS/PIX/UPI info, payment methods, conversion) Backend: - productionV84.ts: expanded compliance report enum with PBOC_LTR, SAFE_CROSS_BORDER, NFIU_STR, FINTRAC_CTR 0 TypeScript errors. Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Patrick Munis <pmunis@gmail.com>
…l templates, multi-region, webhooks, rate limiting CRITICAL: - Gap 1: Add Chinese (zh) and Hindi (hi) locale files (338/316 keys) - Gap 2: Create Terms of Service, Privacy Policy, Cookie Policy pages with routes - Gap 3: Create HTML email templates (transaction receipt, KYC status, security alert) with renderer - Gap 4: Add multi-region Terraform config (af-south-1 DR: VPC, EKS, RDS replica, Redis, S3, Global Accelerator) HIGH: - Gap 5: Expand pt.json from 101 to 340+ keys (8% → 80%+ coverage) - Gap 6: Add Mojaloop webhook forwarding from Go connector to Node.js core + TS handler - Gap 7: Add corridor kill switch API (disableCorridor/enableCorridor/corridorStates) - Gap 8: Add SWIFT gpi webhook handler (camt.054 ACSC/RJCT/ACSP notifications) MEDIUM: - Gap 9: Serve OpenAPI/Swagger docs at /api/docs and /api/docs.json - Gap 10: Wire offline queue into mobile SendMoney (RN: NetInfo+AsyncStorage, Flutter: SQLite) - Gap 11: Tune K8s HPA — 4 HPAs (API/transfer/webhook/fraud), custom metrics, load-test-derived thresholds - Gap 12: Add per-IP rate limiting (100/min) on all webhook endpoints with cleanup interval Co-Authored-By: Patrick Munis <pmunis@gmail.com>
Contributor
Author
Original prompt from Patrick
|
Contributor
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes 12 production readiness gaps identified during full platform audit (4 CRITICAL, 4 HIGH, 4 MEDIUM). 2,209 lines across 19 files, 0 TypeScript errors.
CRITICAL
client/src/locales/zh.json(338 keys),hi.json(316 keys) covering all 13 UI sectionsTermsOfService.tsx,PrivacyPolicy.tsx,CookiePolicy.tsxwired intoApp.tsxwith lazy-loaded routes (/terms-of-service,/privacy-policy,/cookie-policy)server/email-templates/{transaction-receipt,kyc-status,security-alert}.html+server/lib/emailTemplates.tsrenderer with{{VAR}}substitution:af-south-1(Cape Town) with VPC, EKS standby cluster (min 2 nodes), cross-region RDS read replica, ElastiCache Redis, S3 replication, Global Accelerator. Gated byvar.enable_multi_region.HIGH
services/mojaloop-connector/main.go) now callsforwardToCore(cfg, transferId, body)→POST /api/webhooks/mojaloopon Node.js core. New TS handler advancespartner_sent → completed/failed.featureFlags.disableCorridor({ from: "CAD", to: "CNY", reason })/enableCorridor/corridorStates/isCorridorActiveendpoints. In-memoryMap<string, CorridorState>for instant toggling without DB writes.POST /api/webhooks/swifthandlescamt.054notifications withACSC/ACCC → completed,RJCT → failed,ACSP → partner_sentmapping.MEDIUM
GET /api/docsserves Swagger UI,GET /api/docs.jsonserves OpenAPI 3.1 spec (dynamic import ofgenerateOpenApiSpec())NetInfoconnectivity check →enqueue()fromofflineQueue.ts. Flutter:InternetAddress.lookup→OfflineQueue.enqueue()fromoffline_queue.dart.http_requests_per_second,webhook_queue_depth,fraud_score_latency_p95). API: CPU 70→65%, min 2→3, max 20→25. Transfer: CPU 60→55%, min 2→3.webhookRateLimitermiddleware (100 req/min per IP, sliding window) applied to all/api/webhooks/*endpoints viaapp.use(). Stale entry cleanup every 5 min.Link to Devin session: https://app.devin.ai/sessions/64d054ae77da41e9a2b74d8593fa635c
Requested by: @munisp