Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f6a80ee
feat: Mark Lane integration — FX liquidity bridge, KYC compliance pas…
devin-ai-integration[bot] Jun 16, 2026
1459e3f
Merge pull request #4 from munisp/devin/1781621244-marklane-integration
munisp Jun 19, 2026
c456681
feat: Phase 1 production hardening — fail-closed clients, SQL binding…
devin-ai-integration[bot] Jun 20, 2026
26a39f0
Merge pull request #6 from munisp/devin/1781950818-phase1-production-…
munisp Jun 20, 2026
8320b28
feat: Phase 3 — licensing templates, SOC 2 audit prep, production dep…
devin-ai-integration[bot] Jun 20, 2026
ef2403a
Merge pull request #8 from munisp/devin/1781952216-phase3-launch
munisp Jun 20, 2026
bfd1bf2
feat: multi-cloud deployment — Vultr, DigitalOcean, AWS Terraform + c…
devin-ai-integration[bot] Jun 20, 2026
d0bb199
Merge pull request #9 from munisp/devin/1781953736-multi-cloud-deploy
munisp Jun 20, 2026
6a1b3f0
feat: production readiness — sandbox tests, Dockerfiles, migrations, …
devin-ai-integration[bot] Jun 20, 2026
a77442e
Merge pull request #10 from munisp/devin/1781954498-production-gaps
munisp Jun 20, 2026
1c9f47b
fix: wire admin router into main app + fix migration CLI command routing
devin-ai-integration[bot] Jun 20, 2026
b7e0ab2
Merge pull request #11 from munisp/devin/1781956754-fix-escalations
munisp Jun 20, 2026
56ad23d
fix: close all 14 audit gaps in $35K CAD→NGN transfer flow
devin-ai-integration[bot] Jun 20, 2026
d726690
Merge pull request #12 from munisp/devin/1781965882-fix-all-audit-gaps
munisp Jun 20, 2026
5479055
fix: close 8 audit gaps across 20 transfer scenarios
devin-ai-integration[bot] Jun 20, 2026
2529902
Merge pull request #13 from munisp/devin/1781967721-fix-scenario-gaps
munisp Jun 20, 2026
f1d8524
feat: add CIPS rail support + enforce bi-directional corridors across…
devin-ai-integration[bot] Jun 20, 2026
98c540f
fix: eliminate hardcoded country values from ML fraud scorer + add gr…
devin-ai-integration[bot] Jun 20, 2026
675f618
Merge pull request #15 from munisp/devin/1781970121-fix-ml-fraud-hard…
munisp Jun 20, 2026
0aee74a
feat: close 10 UI/UX parity gaps — SendTo pages for China/Brazil/Indi…
devin-ai-integration[bot] Jun 20, 2026
a3baa07
Merge pull request #16 from munisp/devin/1781970796-ui-parity-gaps
munisp Jun 20, 2026
5eb1e78
feat: close 12 production readiness gaps — locales, legal pages, emai…
devin-ai-integration[bot] Jun 20, 2026
a964cd3
Merge pull request #17 from munisp/devin/1781972173-production-readin…
munisp Jun 20, 2026
d907beb
feat: optimize 9 infrastructure systems for 1M+ TPS
devin-ai-integration[bot] Jun 20, 2026
5c642ee
feat: add performance tuning for Fluvio, open-appsec, OpenSearch, Lak…
devin-ai-integration[bot] Jun 20, 2026
3d77e9e
feat: close 4 agent last-mile gaps — pickup codes, agent linking, loc…
devin-ai-integration[bot] Jun 20, 2026
0ed8593
fix: resolve 3 runtime SQL bugs in agent cash pickup endpoints
devin-ai-integration[bot] Jun 20, 2026
edb01ec
fix: close 8 fund flow safety gaps across Go, Rust, Python, TypeScript
devin-ai-integration[bot] Jun 20, 2026
11f2e7c
merge: resolve conflicts with base (fail-closed sanctions guard + add…
devin-ai-integration[bot] Jul 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions .env.production.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
###############################################################################
# RemitFlow — Production Environment Template
#
# Copy to .env.production and fill in real values.
# In Kubernetes, these map to k8s/secrets.yaml.
# In Vault-managed deployments, most values are fetched dynamically.
#
# REQUIRED = Must be set before production deploy
# OPTIONAL = Has sensible defaults or graceful degradation
# VAULT = Fetched from Vault in production (set here for local testing)
###############################################################################

# ── Core Application ─────────────────────────────────────────────────────────
NODE_ENV=production
PORT=3000
APP_URL=https://remitflow.app # REQUIRED: Public URL

# ── Database (VAULT in production) ───────────────────────────────────────────
DATABASE_URL= # REQUIRED: PostgreSQL connection string
# In production with PgBouncer:
# DATABASE_URL=postgresql://remitflow:${PG_PASSWORD}@pgbouncer:6432/remitflow?pgbouncer=true
PGBOUNCER_URL= # OPTIONAL: PgBouncer connection (port 6432)

# ── Redis ────────────────────────────────────────────────────────────────────
REDIS_URL=redis://redis:6379 # REQUIRED: Redis connection string
REDIS_PASSWORD= # OPTIONAL: Redis auth password

# ── Auth & Session ───────────────────────────────────────────────────────────
JWT_SECRET= # REQUIRED: min 64 chars, openssl rand -base64 64
SESSION_SECRET= # REQUIRED: min 64 chars

# ── HashiCorp Vault ──────────────────────────────────────────────────────────
VAULT_ADDR=http://vault:8200 # REQUIRED in production
VAULT_TOKEN= # Use for dev; in prod use AppRole or K8s auth
VAULT_ROLE_ID= # AppRole authentication
VAULT_SECRET_ID= # AppRole authentication
VAULT_NAMESPACE= # Enterprise namespaces (optional)
VAULT_SECRET_PATH=secret/data/remitflow # KV v2 path prefix

# ── Temporal Workflows ───────────────────────────────────────────────────────
TEMPORAL_ADDRESS=temporal:7233 # REQUIRED for saga execution
TEMPORAL_TASK_QUEUE=remitflow-main
TEMPORAL_NAMESPACE=default

# ── Payment Providers (VAULT) ────────────────────────────────────────────────
# Circle (USDC) — https://developers.circle.com/
CIRCLE_API_KEY= # REQUIRED: Circle API key
CIRCLE_ENTITY_SECRET= # REQUIRED: Entity secret for wallet operations
CIRCLE_ENV=production # production | sandbox

# Fireblocks (MPC Custody) — https://developers.fireblocks.com/
FIREBLOCKS_API_KEY= # REQUIRED for crypto custody
FIREBLOCKS_PRIVATE_KEY= # REQUIRED: RSA private key (PEM)
FIREBLOCKS_ENV=production # production | sandbox
FIREBLOCKS_VAULT_ACCOUNT_ID=0 # Default vault account

# Stripe — https://dashboard.stripe.com/apikeys
STRIPE_SECRET_KEY= # REQUIRED for card payments
STRIPE_WEBHOOK_SECRET= # REQUIRED for webhook verification
VITE_STRIPE_PUBLISHABLE_KEY= # REQUIRED for client-side

# Flutterwave — https://dashboard.flutterwave.com/settings/apis
FLUTTERWAVE_SECRET_KEY= # REQUIRED for Africa payments
FLUTTERWAVE_WEBHOOK_SECRET= # REQUIRED for webhooks

# ── KYC Providers (VAULT) ────────────────────────────────────────────────────
# Onfido — https://dashboard.onfido.com/
ONFIDO_API_KEY= # REQUIRED: Live API key
ONFIDO_ENV=production # production | sandbox
ONFIDO_WEBHOOK_SECRET= # Webhook signature verification

# Smile Identity — https://portal.smileidentity.com/
SMILE_PARTNER_ID= # REQUIRED for Africa KYC
SMILE_API_KEY= # REQUIRED for Africa KYC
SMILE_CALLBACK_URL= # Webhook callback URL

# ── Compliance (VAULT) ───────────────────────────────────────────────────────
# OFAC Screening
OFAC_API_KEY= # REQUIRED: Sanctions screening API key

# Chainalysis KYT — https://www.chainalysis.com/
CHAINALYSIS_API_KEY= # REQUIRED for on-chain risk scoring

# Notabene Travel Rule — https://notabene.id/
NOTABENE_API_KEY= # REQUIRED for FATF Travel Rule compliance (>$1K)

# ── Email ────────────────────────────────────────────────────────────────────
RESEND_API_KEY= # REQUIRED: Transactional email
EMAIL_FROM=noreply@remitflow.app

# ── Monitoring ───────────────────────────────────────────────────────────────
LOG_LEVEL=info # debug | info | warn | error
PROMETHEUS_ENABLED=true
JAEGER_ENDPOINT= # OPTIONAL: Distributed tracing

# PagerDuty
PAGERDUTY_ROUTING_KEY= # OPTIONAL: Critical alerts
PAGERDUTY_FINANCE_KEY= # OPTIONAL: Financial alerts

# ── CDN & Cache ──────────────────────────────────────────────────────────────
CLOUDFLARE_ZONE_ID= # OPTIONAL: CDN cache purge
CLOUDFLARE_API_TOKEN= # OPTIONAL: CDN cache purge
CLOUDFRONT_DISTRIBUTION_ID= # OPTIONAL: AWS CloudFront

# ── FX Rates ─────────────────────────────────────────────────────────────────
CURRENCYLAYER_API_KEY= # Live FX rate provider
OPENEXCHANGERATES_APP_ID= # Backup FX provider
FX_ENGINE_URL=http://fx-aggregator:8100 # Internal FX service

# ── Blockchain RPC ───────────────────────────────────────────────────────────
ETHEREUM_RPC_URL= # Ethereum mainnet RPC
POLYGON_RPC_URL= # Polygon mainnet RPC
BASE_RPC_URL= # Base L2 RPC
ARBITRUM_RPC_URL= # Arbitrum L2 RPC
94 changes: 94 additions & 0 deletions .env.sandbox
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
###############################################################################
# RemitFlow — Sandbox Environment Configuration
#
# Use this for integration testing against real sandbox/test APIs.
# All providers below offer free-tier sandbox access.
#
# Setup: Copy to .env and populate with your sandbox credentials.
# cp .env.sandbox .env
#
# Provider signup links and free-tier info noted below each section.
###############################################################################

NODE_ENV=development
PORT=3001

# ── Database (local Docker) ──────────────────────────────────────────────────
DATABASE_URL=postgresql://remitflow:remitflow_dev@localhost:5432/remitflow
REDIS_URL=redis://localhost:6379

# ── Auth ─────────────────────────────────────────────────────────────────────
JWT_SECRET=dev-sandbox-jwt-secret-do-not-use-in-production-min64chars-padding123456
SESSION_SECRET=dev-sandbox-session-secret-do-not-use-in-production-min64chars-padding12

# ── Circle USDC (Free sandbox) ───────────────────────────────────────────────
# Signup: https://developers.circle.com/ (instant access)
# Docs: https://developers.circle.com/circle-mint/docs/getting-started-with-the-circle-apis
CIRCLE_API_KEY=
CIRCLE_ENV=sandbox

# ── Onfido KYC (Free sandbox — 50 checks/month) ─────────────────────────────
# Signup: https://dashboard.onfido.com/signup
# Sandbox docs: https://documentation.onfido.com/#sandbox-testing
ONFIDO_API_KEY=
ONFIDO_ENV=sandbox

# ── Smile Identity (Africa KYC — Free sandbox) ──────────────────────────────
# Signup: https://portal.smileidentity.com/signup
# Docs: https://docs.smileidentity.com/
SMILE_PARTNER_ID=
SMILE_API_KEY=
SMILE_ENV=sandbox

# ── OFAC Screening (Free tier — 500 checks/month) ───────────────────────────
# Signup: https://www.ofac-api.com/signup
# Test names: "Kim Jong Un", "Vladimir Putin" (should return matches)
OFAC_API_KEY=

# ── Chainalysis KYT (Free sandbox) ──────────────────────────────────────────
# Signup: https://www.chainalysis.com/free-cryptocurrency-sanctions-screening-tools/
# Test addresses provided in sandbox docs
CHAINALYSIS_API_KEY=

# ── Notabene Travel Rule (Free sandbox) ──────────────────────────────────────
# Signup: https://notabene.id/product/travel-rule
# Docs: https://docs.notabene.id/
NOTABENE_API_KEY=

# ── Fireblocks MPC Custody (Sandbox — requires approval) ────────────────────
# Signup: https://www.fireblocks.com/developer-sandbox/
# Note: Requires business email; approval may take 1-3 days
FIREBLOCKS_API_KEY=
FIREBLOCKS_PRIVATE_KEY=
FIREBLOCKS_ENV=sandbox

# ── Stripe (Free sandbox) ───────────────────────────────────────────────────
# Signup: https://dashboard.stripe.com/register
# Test cards: https://docs.stripe.com/testing#cards
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
VITE_STRIPE_PUBLISHABLE_KEY=

# ── Flutterwave (Free sandbox) ──────────────────────────────────────────────
# Signup: https://dashboard.flutterwave.com/signup
# Docs: https://developer.flutterwave.com/docs/integration-guides/testing-helpers/
FLUTTERWAVE_SECRET_KEY=
FLUTTERWAVE_WEBHOOK_SECRET=

# ── HashiCorp Vault (Local dev server) ──────────────────────────────────────
# Start: docker compose --profile full up -d vault
# Dev token is auto-generated; in production use AppRole auth
VAULT_ADDR=http://localhost:8200
VAULT_TOKEN=remitflow-dev-token

# ── Temporal (Local Docker) ─────────────────────────────────────────────────
# Start: docker compose --profile full up -d temporal
# UI: http://localhost:8233
TEMPORAL_ADDRESS=localhost:7233
TEMPORAL_TASK_QUEUE=remitflow-main

# ── FX Rates (Free tier) ────────────────────────────────────────────────────
# CurrencyLayer: https://currencylayer.com/signup/free (250 req/month)
CURRENCYLAYER_API_KEY=
# OpenExchangeRates: https://openexchangerates.org/signup/free (1000 req/month)
OPENEXCHANGERATES_APP_ID=
160 changes: 160 additions & 0 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
name: Integration & E2E Tests

on:
workflow_dispatch:
inputs:
suite:
description: "Test suite to run"
required: true
type: choice
options:
- all
- sandbox
- e2e
- migrations
schedule:
- cron: "0 3 * * *" # Nightly at 3am UTC

env:
NODE_ENV: test

jobs:
# ── Sandbox Provider Integration Tests ──────────────────────────────────────
sandbox-tests:
if: inputs.suite == 'all' || inputs.suite == 'sandbox' || github.event_name == 'schedule'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"

- run: npm ci

- name: Run sandbox integration tests
env:
CIRCLE_API_KEY_SANDBOX: ${{ secrets.CIRCLE_API_KEY_SANDBOX }}
ONFIDO_API_KEY_SANDBOX: ${{ secrets.ONFIDO_API_KEY_SANDBOX }}
FLUTTERWAVE_SECRET_KEY_TEST: ${{ secrets.FLUTTERWAVE_SECRET_KEY_TEST }}
SMILE_PARTNER_ID_SANDBOX: ${{ secrets.SMILE_PARTNER_ID_SANDBOX }}
run: npx vitest run tests/integration/sandbox-providers.test.ts --reporter=verbose

- uses: actions/upload-artifact@v4
if: failure()
with:
name: sandbox-test-results
path: test-results/

# ── Database Migration Tests ────────────────────────────────────────────────
migration-tests:
if: inputs.suite == 'all' || inputs.suite == 'migrations' || github.event_name == 'schedule'
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: remitflow_test
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"

- run: npm ci

- name: Run migrations up
env:
DATABASE_URL: postgres://test:test@localhost:5432/remitflow_test
run: npx tsx drizzle/migrate.ts up

- name: Verify migration status
env:
DATABASE_URL: postgres://test:test@localhost:5432/remitflow_test
run: npx tsx drizzle/migrate.ts status

- name: Run migrations down (rollback test)
env:
DATABASE_URL: postgres://test:test@localhost:5432/remitflow_test
run: npx tsx drizzle/migrate.ts down

- name: Run migrations up again (idempotency)
env:
DATABASE_URL: postgres://test:test@localhost:5432/remitflow_test
run: npx tsx drizzle/migrate.ts up

# ── E2E Playwright Tests ────────────────────────────────────────────────────
e2e-tests:
if: inputs.suite == 'all' || inputs.suite == 'e2e'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"

- run: npm ci

- name: Install Playwright
run: npx playwright install --with-deps chromium

- name: Start dev server
run: npm run dev &
env:
DATABASE_URL: ${{ secrets.DATABASE_URL_STAGING }}

- name: Wait for server
run: npx wait-on http://localhost:3000 --timeout 30000

- name: Run E2E tests
run: npx playwright test tests/e2e/ --project=chromium
env:
BASE_URL: http://localhost:3000

- uses: actions/upload-artifact@v4
if: always()
with:
name: e2e-test-results
path: |
tests/e2e/test-results/
tests/e2e/playwright-report/

# ── Docker Build Verification ───────────────────────────────────────────────
docker-builds:
if: inputs.suite == 'all' || github.event_name == 'schedule'
runs-on: ubuntu-latest
strategy:
matrix:
service:
- { name: api, file: Dockerfile }
- { name: worker, file: Dockerfile.worker }
- { name: production, file: Dockerfile.production }
steps:
- uses: actions/checkout@v4

- name: Build Docker image
run: |
docker build -f ${{ matrix.service.file }} -t remitflow/${{ matrix.service.name }}:test .

- name: Verify image starts
run: |
docker run --rm -d --name test-${{ matrix.service.name }} \
-e NODE_ENV=test \
remitflow/${{ matrix.service.name }}:test || true
sleep 5
docker logs test-${{ matrix.service.name }} 2>&1 | head -20 || true
docker stop test-${{ matrix.service.name }} 2>/dev/null || true
Loading