fix(bridge): align BridgeService withdrawal return shapes with GraphQL (ENG-352) - #396
fix(bridge): align BridgeService withdrawal return shapes with GraphQL (ENG-352)#396patoo0x wants to merge 1 commit into
Conversation
…L (ENG-352) The bridgeInitiateWithdrawal/bridgeWithdrawals resolvers return the BridgeService result directly with no resolver-level mapping, so the service is the source of truth for the public BridgeWithdrawal contract. Audit findings (ENG-352 svc half): - InitiateWithdrawalResult was missing `createdAt`, which is NonNull on the GraphQL BridgeWithdrawal type. A client selecting `createdAt` on the mutation payload hit a non-null violation (undefined). Now populated from `transfer.created_at`. - Added optional `failureReason` to both InitiateWithdrawalResult and WithdrawalResult to match the nullable GraphQL field; getWithdrawals now surfaces the persisted row's failureReason. - getWithdrawals filtered with `!== null || !== undefined` (always true), letting pending rows with no bridgeTransferId leak through and violate the NonNull `transferId` field. Corrected to `&&`. Adds focused unit tests asserting both withdrawal paths return every NonNull field required by the BridgeWithdrawal GraphQL type and do not leak the raw Bridge transfer shape.
|
⏸️ Hold for merge — depends on #387. PR #387 ( What changes after #387 lands:
Plan: merge #387 first, then rebase this PR and re-scope it to (1) the |
|
Closing this as superseded by #387. After #387 merged, the public
A fresh comparison of this branch against the updated base shows the stale diff would now conflict with and partially reverse #387 ( Verified on the updated base: TEST="test/flash/unit/services/bridge/return-shapes.spec.ts test/flash/unit/graphql/public/root/query/bridge-withdrawals.spec.ts test/flash/unit/graphql/public/types/object/bridge-contract.spec.ts" yarn test:unitResult: 3 suites passed, 7 tests passed. |
ENG-352 — NEW-1: Bridge service return shapes match GraphQL types (svc half)
Closes the service half of the GraphQL contract work. ENG-351/ENG-353 (PR #393) fixed the GraphQL-side types and error mapping but did not touch
src/services/bridge/, so the service-shape audit ENG-352 was scoped to was never actually completed.Why this matters
The
bridgeInitiateWithdrawalmutation andbridgeWithdrawalsquery resolvers return theBridgeServiceresult directly — there is no resolver-level field mapping. That makes the service the source of truth for the publicBridgeWithdrawalGraphQL type, which requirestransferId,amount,currency,state,createdAt(allNonNull) and exposes an optionalfailureReason.Findings & fixes
createdAtmissing on the initiate path (live bug).InitiateWithdrawalResultomittedcreatedAt. A client runningbridgeInitiateWithdrawal(...) { withdrawal { createdAt } }hit a non-null violation because the field resolved toundefinedagainstGT.NonNull(GT.String). Now populated fromtransfer.created_at.failureReasonnot surfaced. Added optionalfailureReasonto bothInitiateWithdrawalResultandWithdrawalResultto match the nullable GraphQL field;getWithdrawalsnow maps the persisted row'sfailureReason.getWithdrawals.w.bridgeTransferId !== null || w.bridgeTransferId !== undefinedis alwaystrue, letting pending rows with nobridgeTransferIdleak through and violate theNonNulltransferIdfield. Corrected to&&.Tests
New
test/flash/unit/services/bridge/return-shapes.spec.ts(5 tests, all passing) asserts both withdrawal paths:NonNullfield theBridgeWithdrawaltype requires (incl.createdAt),failureReasonthroughgetWithdrawals,transferId,id/status).Scope / hygiene
src/services/bridge/index.ts+ the new spec.getKycStatusleft untouched to keep the diff scoped).tsc --noEmitclean for both changed files.Linear: ENG-352