Skip to content

test(testing): boot each kyc e2e app on its own database - #341

Closed
mp-blurify wants to merge 1 commit into
devfrom
fix/kyc-reverify-test-flake
Closed

mp-blurify wants to merge 1 commit into
devfrom
fix/kyc-reverify-test-flake

Conversation

@mp-blurify

Copy link
Copy Markdown
Collaborator

Summary

kyc.e2e.test.ts > "a deposit crossing the per-currency threshold flips a legacy-verified player to resubmission_requested" failed about one run in three since at-least-once event delivery (#297). The suite's two apps now each run on their own database, so the deposit event always reaches the app that has the re-KYC thresholds.

Why

The suite boots two apps on one database, each with its own Redis logical database:

  • appDefault: the stock stack.
  • appGated: adds an overlay that binds kyc.reverifyThresholds.

Since #297, wallet and KYC events go through event_outbox. Every booted app runs an OutboxRelay over its database and publishes into its own broker, so the two relays race for each row. Sometimes appDefault's relay claimed the wallet.deposit.completed that appGated wrote and published it into appDefault's Redis. appDefault's compliance handler then ran handleDeposit with no thresholds and did nothing. appGated never received the event, and the basic KYC row stayed pending.

Measured over 16 runs of the test, with each app's MESSAGE_BROKER.publish wrapped to record which app published the event (diagnostic only, not committed):

Relay that published the deposit event Runs Outcome
appGated 11 flipped 45-191 ms after the deposit response
appDefault 5 never flipped within 8 s; the seeded verified status was intact and every wallet.deposit.completed handler had recorded the event in processed_events

The problem is which app gets the event, not latency, so a longer waitFor would not help.

Each app now gets its own setupTestDb() and is seeded right after it boots. This order matters because seedMinimal reads the DATABASE_URL set by the most recently booted app; qa-wallet-auto-withdrawal-config already works this way. No test in the file uses data across the two apps. bootTestApp's doc said apps in one file cannot compete for each other's events. It now says they do when they share a database.

Locally the file passed 20 runs in a row after the change. Before it, 10 of 34 runs failed.

Alternatives considered

  • A longer waitFor timeout. The event is in the other app's Redis, so no wait reaches it.
  • One Redis database for all apps on the same Postgres database, so every app's consumer group sees every event. processed_events keys handlers by SERVICE_NAME, which is monolith/... for every test app, so whichever app handled the event first would mark it done for the other. Apps with different overlays would also share BullMQ queues.
  • A bootTestApp guard that refuses a second app on a database already in use. wallet-ledger-auto-withdrawal, gaming-category-rules and gaming-category-sort share a database between apps but are not affected. What they wait on is either handled the same way by every app (audit rows, notifications, the process-wide email capture) or sent with emit(), which publishes to the emitting app's own broker without going through the outbox. So they stay as they are.

Risks

None. This is a test-only change. In production, replicas share one Redis, so whichever relay publishes an event, every service's consumer group receives it.

The re-kyc-on-deposit test failed about one run in three since
at-least-once delivery. Its two apps shared one database, and every
booted app runs an outbox relay over that database that publishes into
its own Redis. When the stock app's relay claimed the deposit event the
gated app wrote, the stock app's compliance handler, which has no
re-kyc thresholds, handled it and the gated app never saw it.

Each app now gets its own test database, seeded right after it boots.
The bootTestApp doc no longer claims apps cannot compete for each
other's events.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Mateusz Paś <mateusz.pas@studiosoftware.com>
@mp-blurify

Copy link
Copy Markdown
Collaborator Author

Superseded by #312: bootE2e now calls setupTestDb() for every app, so the two KYC apps already run on their own databases and their outbox relays no longer claim each other's events.

@mp-blurify mp-blurify closed this Oct 21, 2026
@mp-blurify
mp-blurify deleted the fix/kyc-reverify-test-flake branch October 21, 2026 12:32
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.

2 participants