Skip to content

feat(bridge): add KYC tier ceiling error code (ENG-354)#394

Merged
islandbitcoin merged 2 commits into
tmp/bridge-rebase-pr-readyfrom
eng-354/kyc-tier-ceiling-error
Jun 8, 2026
Merged

feat(bridge): add KYC tier ceiling error code (ENG-354)#394
islandbitcoin merged 2 commits into
tmp/bridge-rebase-pr-readyfrom
eng-354/kyc-tier-ceiling-error

Conversation

@patoo0x
Copy link
Copy Markdown
Contributor

@patoo0x patoo0x commented Jun 6, 2026

Summary

Adds a distinct BRIDGE_KYC_TIER_CEILING_EXCEEDED GraphQL error code for when Bridge rejects a withdrawal because the amount exceeds the user's KYC-tier cap.

Changes

  • src/services/bridge/errors.ts: Added BridgeKycTierCeilingExceededError class + detection in mapBridgeHttpError for Bridge API 422/400 responses containing KYC tier ceiling errors
  • src/graphql/error-map.ts: Mapped BridgeKycTierCeilingExceededErrorBRIDGE_KYC_TIER_CEILING_EXCEEDED
  • **docs/bridge-integration/API.md: Added error code to the table
  • **test/flash/unit/graphql/bridge-error-map.spec.ts: Added GQL mapping test for the new error + 5 mapBridgeHttpError detection tests

Verification

  • 37 bridge error-map tests pass
  • 3 bridge contract tests pass
  • Prettier clean
  • yarn check:sdl clean
  • No schema regeneration needed (error mapping only)

@linear
Copy link
Copy Markdown

linear Bot commented Jun 6, 2026

ENG-354

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Bridge-specific GraphQL error code intended to distinguish “KYC tier ceiling exceeded” withdrawal failures from generic Bridge API errors, and documents/tests the mapping.

Changes:

  • Introduced BridgeKycTierCeilingExceededError plus detection logic in mapBridgeHttpError for Bridge 400/422 responses.
  • Mapped BridgeKycTierCeilingExceededError to the new GraphQL error code BRIDGE_KYC_TIER_CEILING_EXCEEDED.
  • Updated Bridge integration docs and extended unit tests for mapping/detection.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/services/bridge/errors.ts Adds a new domain error and attempts to detect it from Bridge HTTP response bodies.
src/graphql/error-map.ts Maps the new domain error to a distinct GraphQL error code.
docs/bridge-integration/API.md Documents the new error code in the Bridge error table.
test/flash/unit/graphql/bridge-error-map.spec.ts Adds unit tests for the new GraphQL mapping and mapBridgeHttpError detection heuristics.
Comments suppressed due to low confidence (1)

src/services/bridge/errors.ts:151

  • mapBridgeHttpError is not referenced anywhere in src/ (it only appears in this file and the new unit test), so the new KYC-tier ceiling detection and error class mapping will never be produced by runtime Bridge requests. As a result, withdrawals that exceed the KYC tier ceiling will still surface as generic BridgeApiError / BRIDGE_API_ERROR unless Bridge request error handling is updated to call this mapper (e.g., in the Bridge client request wrapper or in the withdrawal orchestration catch path).
export const mapBridgeHttpError = (
  statusCode: number,
  response?: unknown,
): BridgeError => {
  // Bridge returns 422/400 with a specific error type for KYC tier ceiling violations.
  if (
    (statusCode === 422 || statusCode === 400) &&
    typeof response === "object" &&
    response !== null
  ) {
    const resp = response as Record<string, unknown>
    const errorObj = (resp.error ?? resp) as Record<string, unknown> | undefined
    const errorType = String(errorObj?.type ?? "").toLowerCase()
    const errorMessage = String(errorObj?.message ?? resp?.message ?? "").toLowerCase()

    if (
      errorType.includes("kyc_tier_limit") ||
      errorType.includes("kyc_limit") ||
      errorType.includes("tier_ceiling") ||
      (errorMessage.includes("kyc") &&
        (errorMessage.includes("limit") ||
          errorMessage.includes("ceiling") ||
          errorMessage.includes("tier")))
    ) {
      const message = typeof resp.message === "string" ? resp.message : undefined
      return new BridgeKycTierCeilingExceededError(message)
    }
  }

  switch (statusCode) {
    case 404:
      return new BridgeCustomerNotFoundError()
    case 429:
      return new BridgeRateLimitError()
    case 408:
      return new BridgeTimeoutError()
    default:
      return new BridgeApiError("Bridge API error", statusCode, response)
  }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/services/bridge/errors.ts Outdated
Comment on lines +137 to +138
const message = typeof resp.message === "string" ? resp.message : undefined
return new BridgeKycTierCeilingExceededError(message)
… eng-354/kyc-tier-ceiling-error

# Conflicts:
#	src/services/bridge/errors.ts
@islandbitcoin islandbitcoin merged commit 7e321f2 into tmp/bridge-rebase-pr-ready Jun 8, 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.

4 participants