Skip to content

✨ server: add bridge kyb - #1302

Open
aguxez wants to merge 1 commit into
panda-b2b-approvalsfrom
bridge-b2b
Open

aguxez wants to merge 1 commit into
panda-b2b-approvalsfrom
bridge-b2b

Conversation

@aguxez

@aguxez aguxez commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

summary

add bridge kyb for business credentials: on approval, create the bridge business customer with the minimum fields and send the user to the bridge hosted kyc link.

stacked on #1209.

changes

  • accept scope: "bridge" with acceptedTermsId in POST /kyc, create the bridge business customer idempotently, persist bridgeId, and return { kycLink, status: "pending" }
  • add bridge.createBusinessCustomer and send account-type: business on customer creation, tos links, and kyc links
  • read the credential salt in ramp routes to resolve the business account type, and reject bridge business onboarding there
  • return already onboarded when the credential already has a bridge id
  • merge panda inquiry fields with the completed business account fields instead of only filling gaps

test plan

  • pnpm nx test:vi server
  • follow a business credential through POST /kyc in sandbox and verify the returned bridge kyc link

Summary by CodeRabbit

  • New Features
    • Added Bridge business onboarding through KYC applications, including terms acceptance, customer creation, KYC links, pending status, retry handling, and duplicate-onboarding protection.
    • Added business account support for provider, customer, agreement, and external-account operations.
  • Bug Fixes
    • Improved business application data mapping and blank-field handling.
    • Updated the Persona business verification template.
  • Limitations
    • Business onboarding through the ramp API is not supported.

@changeset-bot

changeset-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d28280b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@exactly/server Minor
@exactly/mobile Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The PR adds Bridge business customer creation and KYC submission. It propagates business account types through Bridge ramp operations, updates business-field mapping, and expands test coverage.

Changes

Bridge business KYB

Layer / File(s) Summary
Bridge business customer service
server/utils/ramps/bridge.ts, server/test/utils/bridge.test.ts
Bridge supports business customer creation, account-type headers, terms links, KYC links, provider states, external accounts, response validation, and business payload typing.
Bridge KYC submission
server/api/index.ts, server/api/kyc.ts, server/utils/panda.ts, server/utils/persona.ts, server/test/api/kyc.test.ts, server/test/hooks/persona.test.ts, .changeset/quiet-bridges-kyb.md
The KYC route accepts Bridge applications, requires terms, creates and stores business customers, retries selected failures, returns KYC links or pending status, and rejects already onboarded credentials.
Business account ramp routing
server/api/ramp.ts, server/test/api/ramp.test.ts
Ramp endpoints derive Bridge account type from credential salts, pass it to Bridge calls, and reject business onboarding through the existing ramp onboarding endpoint.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant KYCRoute
  participant BridgeService
  participant BridgeAPI
  participant Database
  Client->>KYCRoute: Submit bridge business application
  KYCRoute->>BridgeService: Create business customer
  BridgeService->>BridgeAPI: POST /customers
  BridgeAPI-->>BridgeService: Customer id
  KYCRoute->>Database: Store bridgeId
  KYCRoute->>BridgeService: Fetch business KYC link
  BridgeService->>BridgeAPI: GET customer kyc_link
  BridgeAPI-->>KYCRoute: KYC link
  KYCRoute-->>Client: Pending status and kycLink
Loading

Suggested reviewers: cruzdanilo

Merge Risk: 🟡 Moderate · up to 8492a

Clients polling a successfully submitted Bridge KYB application receive an incorrect “not started” response. The Bridge status path should be implemented before merge.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: adding Bridge KYB support to the server. It is concise and related to the pull request scope.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bridge-b2b
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch bridge-b2b

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: ca6a698a-c307-4057-a3ff-9debf4b4b20c

📥 Commits

Reviewing files that changed from the base of the PR and between 343b0a2 and 5103f03.

📒 Files selected for processing (12)
  • .changeset/quiet-bridges-kyb.md
  • .changeset/quiet-kybs-map.md
  • server/api/index.ts
  • server/api/kyc.ts
  • server/api/ramp.ts
  • server/test/api/kyc.test.ts
  • server/test/api/ramp.test.ts
  • server/test/hooks/persona.test.ts
  • server/test/utils/bridge.test.ts
  • server/utils/panda.ts
  • server/utils/persona.ts
  • server/utils/ramps/bridge.ts

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

Comment thread server/test/api/kyc.test.ts Outdated
Comment thread server/utils/panda.ts Outdated
Comment thread server/utils/persona.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (1)
server/api/kyc.ts (1)

896-899: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Make application status provider-aware.

The Bridge submission calls panda.businessApplication only to build request data, creates a Bridge customer, stores credentials.bridgeId, and returns "pending" without creating a Panda company application. GET /application then calls only panda.getCompanyApplication(credentialId) and returns "not started" when that application is absent. Resolve Bridge status from bridgeId, or expose a separate provider-specific Bridge status endpoint.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 1bf53970-b5bf-4d9c-aa75-7bb1f01e0409

📥 Commits

Reviewing files that changed from the base of the PR and between 5103f03 and 0dbda10.

📒 Files selected for processing (6)
  • server/api/kyc.ts
  • server/api/ramp.ts
  • server/test/api/kyc.test.ts
  • server/test/api/ramp.test.ts
  • server/test/utils/bridge.test.ts
  • server/utils/ramps/bridge.ts

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

Comment thread server/api/kyc.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 66f0a626-c698-4b20-90d0-3f929289658c

📥 Commits

Reviewing files that changed from the base of the PR and between 0dbda10 and 3089a8a.

📒 Files selected for processing (5)
  • server/api/kyc.ts
  • server/test/api/kyc.test.ts
  • server/test/utils/bridge.test.ts
  • server/test/utils/panda.test.ts
  • server/utils/panda.ts

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

Comment thread server/api/kyc.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (1)

🟠 Major · Return Bridge KYB status for Bridge customers. · server/api/kyc.ts:894-897

894-897: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Return Bridge KYB status for Bridge customers.

The Bridge submission path stores credentials.bridgeId, but GET /application does not select bridgeId or handle it before the Panda branch. For a Bridge credential without a Panda company application, panda.getCompanyApplication(credentialId) returns no application and the endpoint returns HTTP 400 with "not started".

Select bridgeId, call the exposed bridge.getCustomer(bridgeId, "business"), and map its CustomerResponse.status to the endpoint status before querying Panda. Add a regression test that submits a Bridge application and then retrieves its status.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 28839f0d-65b6-4d83-bed8-f977c2511c78

📥 Commits

Reviewing files that changed from the base of the PR and between 3c44b4d and 8492a9d.

📒 Files selected for processing (2)
  • server/api/kyc.ts
  • server/test/api/kyc.test.ts

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8492a9d163

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread server/api/ramp.ts Outdated
Comment thread server/api/kyc.ts Outdated
Comment thread server/api/kyc.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 01df67fcd5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread server/utils/ramps/bridge.ts Outdated
Comment thread server/utils/persona.ts Outdated
Comment thread server/api/kyc.ts Outdated
Comment thread server/api/kyc.ts Outdated
@codecov

codecov Bot commented Sep 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.63%. Comparing base (0ba51fa) to head (d28280b).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@                   Coverage Diff                   @@
##           panda-b2b-approvals    #1302      +/-   ##
=======================================================
+ Coverage                74.47%   74.63%   +0.15%     
=======================================================
  Files                      298      298              
  Lines                    12523    12557      +34     
  Branches                  4474     4488      +14     
=======================================================
+ Hits                      9327     9372      +45     
+ Misses                    2956     2942      -14     
- Partials                   240      243       +3     
Flag Coverage Δ
e2e 71.47% <90.24%> (-0.75%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9a00e6e893

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread server/utils/ramps/bridge.ts Outdated
Comment thread server/api/kyc.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b93b785ca9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread server/api/ramp.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4bb019cc2d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread server/api/kyc.ts
Comment thread server/api/kyc.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cf0c3a2b3b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread server/utils/ramps/bridge.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0eff588d0c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread server/api/kyc.ts

**Business KYB**

Business requests are identified by the \`account-type: business\` request header and require a business credential (non-zero salt), otherwise the endpoint returns \`400 { "code": "not supported" }\`. The body must be exactly one of two variants:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Document the actual business-routing mechanism

This OpenAPI description tells integrators that account-type: business identifies a business request, but the header validator does not declare that header and the handler routes exclusively by comparing the authenticated credential's salt to businessSalt. Consequently, adding the documented header to a personal credential has no effect, while a business credential succeeds without it. Either define and consume the header or describe the salt-derived credential behavior accurately so generated documentation does not advertise a nonexistent request control. .agents/rules/server.mdL23-L25

Useful? React with 👍 / 👎.

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.

1 participant