Four independent backend enhancements delivered in a single branch, each committed separately.
Motivation: Platforms integrating with Stargate need a push notification when a merchant's KYC review concludes so they can unlock features or notify the merchant without polling.
What changed:
db/migrations/009_merchant_kyc_testmode.sql— addskyc_status TEXT(pending|approved|rejected) andtest_mode BOOLEANcolumns tomerchants.WebhooksService.emitKycEvent— insertswebhook_deliveriesrows scoped to webhooks that have subscribed to the relevant event type.MerchantsService.updateKycStatus— setskyc_statusand clears/setskyb_verified_atatomically.AdminController(POST /admin/merchants/:id/kyc/approveand/reject) — JWT-guarded admin endpoints that update status and fire the webhook.- Webhook creation schema and
CreateWebhookDtoextended with the two new event types. test/kyc-webhooks.spec.ts— 3 unit tests.
Motivation: Kubernetes liveness/readiness probes and ops dashboards need a lightweight HTTP endpoint to check whether the reconciler is running without connecting to Redis or Postgres directly.
What changed:
reconciler/src/status.rs— minimal raw-TCP HTTP server.GET /statusreads thereconciler:statuskey from Redis and returns{"status": "running"}(or the current value). All other paths return 404.reconciler/src/main.rs— spawns the status server as a backgroundtokio::spawntask onRECONCILER_STATUS_PORT(default9090) before entering the stream loop..env.example— documentsRECONCILER_STATUS_PORT=9090.- Inline
#[test]verifying the JSON response shape.
Motivation: Authorised signers (ops tooling, multisig coordinators) need to submit a 32-byte transaction digest and receive a KMS-backed ECDSA signature without direct AWS SDK access.
What changed:
src/treasury/treasury.controller.ts—POST /treasury/sign(JWT-guarded). Validates the body contains a 32-byte hex digest, delegates toKmsSignerService.signDigest, and returns the signature as a hex string.src/treasury/treasury.module.ts— importsStellarModuleto consume the already-exportedKmsSignerService.TreasuryModuleregistered inAppModule.test/treasury.spec.ts— 3 unit tests covering missing digest, wrong-length digest, and the happy path.
Motivation: Merchants onboarding or integrating should be able to run end-to-end flows against Stellar testnet contracts without affecting mainnet state, controlled per-merchant rather than globally.
What changed:
PATCH /merchants/menow acceptstest_mode: boolean(added toupdateMerchantSchemaandUpdateMerchantDto).StellarService.buildPaymentXdraccepts an optionaltestModeparameter — whentrueit forcesNetworks.TESTNETpassphrase regardless of theSTELLAR_NETWORKenv var; whenfalseit forcesNetworks.PUBLIC.InvoicesService.getPublicincludesm.test_modein the JOIN query so the value is available at payment-preparation time.PaymentsService.prepareTxpassesinvoice.test_modetobuildPaymentXdrand reflects it in thenetworkfield of the response so the frontend knows which network to submit the XDR to.test/test-mode.spec.ts— 3 unit tests.
npm run typecheck # passes
npm test # 10/10 tests pass (4 suites)
cargo test --manifest-path reconciler/Cargo.tomlnpm run db:migrateMigration 009_merchant_kyc_testmode.sql is additive (two nullable/defaulted columns) and safe to run against an existing database with zero downtime.
-
npm run typecheckpasses -
npm testpasses - Migration is backward-compatible
- No secrets or credentials committed
-
.env.exampleupdated for new env var (RECONCILER_STATUS_PORT)