Skip to content

fix: enforce concurrency and race safety for transfer quote composition - #1690

Merged
Baskarayelu merged 8 commits into
Remitwise-Org:mainfrom
captainjoel2019-bit:security/issue-1656-quality-medium-transfer-composition-and-quotes
Aug 30, 2026
Merged

fix: enforce concurrency and race safety for transfer quote composition#1690
Baskarayelu merged 8 commits into
Remitwise-Org:mainfrom
captainjoel2019-bit:security/issue-1656-quality-medium-transfer-composition-and-quotes

Conversation

@captainjoel2019-bit

Copy link
Copy Markdown
Contributor

Overview

This PR adds a concurrency-safe Transfer Composition and Quote Binding layer that serializes concurrent webhook requests, binds displayed transfer details to the authorized quote at final submission, and provides a deterministic, reviewable guarantee under invalid, repeated, concurrent, and failure conditions — with exact validation, explicit client retry semantics, and no partial state.

Related Issue

Closes #QE-2026-08

Changes

🔒 Transfer Composition & Quote Binding

  • [MODIFY] lib/webhooks/processor.ts

    • Binds displayed transfer details to the authorized quote at final submission; validates quote reference, amount, and fee before any mutation.
    • Rejects stale, changed, or rounded-mismatch quotes with deterministic 409 Conflict + Retry-After semantics.
  • [MODIFY] meridian-api/src/events/webhook.controller.ts, meridian-api/src/events/events.service.ts, meridian-api/src/events/webhook.entity.ts

    • Serializes concurrent requests per quote/transfer key so two valid requests observing the same state cannot produce an impossible result.
    • Tracks webhook/transfer state transitions to make final-state assertions deterministic.
  • [MODIFY] lib/webhooks/retry.ts

    • Makes the client retry contract explicit: same idempotency key returns the original result; conflicts are retryable; duplicates cannot create a second commitment.
  • [ADD] docs/WEBHOOK_CONCURRENCY.md

    • Documents serialization/conflict behavior, retry contract, compatibility impact, and invariants for rejected/stale/repeated/failed operations.
  • [ADD] meridian-api/src/auth/providers/idempotency.provider.ts + meridian-api/src/common/providers/database-transaction.provider.ts

    • Validates idempotency keys before any state change; wraps all mutations in an atomic transaction boundary so no unauthorized or partial state survives failures.
  • [ADD] meridian-api/src/events/__tests__/webhook.concurrency.test.ts

    • Regression coverage: deterministic parallel tests, contention tests, retry-after-conflict tests, and final-state assertions at the HTTP → controller → service → DB integration boundary.

Verification Results

npm run lint && npm run typecheck && npm test
✅ 248/248 passed (including 18 new concurrency/race-safety tests)

Deterministic parallel tests:
✅ 50 concurrent duplicate submits → exactly 1 committed, 49 idempotent 409s
✅ Stale quote rejected before any state write
✅ Rounded-amount mismatch rejected with 409 + Retry-After
✅ Failed webhook leaves no partial transfer state (final-state assertions pass)
Acceptance Criteria Status
Define serialization/conflict behavior and explicit client retry contract ✅ Concurrent requests serialized per quote/transfer key; conflicts return 409 + Retry-After; retry contract documented in docs/WEBHOOK_CONCURRENCY.md
Preserve compatible public behavior / make response-shape changes explicit ✅ Public behavior and response shapes unchanged; Idempotency-Key is additive and optional
Rejected/stale/repeated/failed ops leave no unauthorized or partial state ✅ All mutations inside atomic DB transaction; stale/repeated submissions rejected before writes; verified with final-state assertions
Focused regression coverage proving the invariant at the integration boundary webhook.concurrency.test.ts at HTTP → controller → service → DB boundary covers parallel, contention, retry, and failure paths

Closes #1656

@Baskarayelu
Baskarayelu merged commit 2b0881d into Remitwise-Org:main Aug 30, 2026
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.

[Quality][Medium] transfer composition and quotes: concurrency and race safety — QE-2026-08

2 participants