🐛 server: make card creation idempotent - #1082
Conversation
🦋 Changeset detectedLatest commit: 529376a The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
WalkthroughAdds getCards and a CardsResponse schema; POST /api/card now adopts the first active Panda orphan card after KYC approval or falls back to creating a new card, adds 409 card-limit handling, updates Sentry context, extends tests, and adds a changeset. ChangesOrphan Card Adoption Feature
Sequence DiagramsequenceDiagram
participant Client
participant CardAPI as POST /api/card
participant GetCards as getCards(pandaId)
participant PandaAPI as Panda /issuing/cards
participant CreateCard as panda.createCard
participant Database as cards table
Client->>CardAPI: POST /api/card (create signature card)
CardAPI->>GetCards: fetch existing cards for pandaId
GetCards->>PandaAPI: GET /issuing/cards?userId&limit=100
PandaAPI-->>GetCards: []{id,status,last4,...}
alt Active card exists
GetCards-->>CardAPI: [{status:"active",...}]
CardAPI->>Database: adopt orphan card by ID
CardAPI-->>Client: 200 with adopted card
Note over CardAPI: emit orphan-card-adopted warning
else No active card
GetCards-->>CardAPI: [] or [{status:"canceled",...}]
CardAPI->>CreateCard: create new card (with optional card_limit_usd)
CreateCard-->>CardAPI: {id,last4,...}
CardAPI->>Database: persist new card
CardAPI-->>Client: 200 with new card
else getCards fails
GetCards-->>CardAPI: error
CardAPI-->>Client: 500 error
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
✨ Simplify code
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. Comment |
There was a problem hiding this comment.
Code Review
This pull request makes card creation idempotent by checking for existing active cards before creating a new one. Specifically, it introduces a getCards utility to fetch a user's cards from the Panda API. If an active card (referred to as an "orphan") is found, it is adopted and returned instead of creating a duplicate, with a warning logged to Sentry. Otherwise, a new card is created as before. Comprehensive unit tests have been added to verify this behavior under various scenarios. No review comments were provided, so there is no feedback to address.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Code Review
This pull request makes card creation idempotent by checking for existing active cards before attempting to create a new one. It introduces a new getCards utility to fetch a user's cards, adopts an existing active card (logging a warning) if found, and only proceeds with createCard if no active cards are present. Comprehensive unit tests have been added to cover these adoption and creation scenarios. There are no review comments, and we have no additional feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e185c1d7f1
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: f41b44a6-f390-4df2-b515-81deda267399
📒 Files selected for processing (5)
.changeset/swift-pandas-reconcile.mdserver/api/card.tsserver/test/api/card.test.tsserver/test/utils/panda.test.tsserver/utils/panda.ts
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## base #1082 +/- ##
==========================================
+ Coverage 74.00% 74.99% +0.98%
==========================================
Files 244 245 +1
Lines 11712 11951 +239
Branches 4057 4171 +114
==========================================
+ Hits 8668 8963 +295
+ Misses 2704 2650 -54
+ Partials 340 338 -2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6ea72e2637
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
server/api/card.ts (1)
497-499:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftFilter adopted Panda cards to signature-compatible cards before persisting.
Line 498 adopts the first
activecard only, while Lines 539 and 577 persist/returnSIGNATURE_PRODUCT_ID. If Panda returns an active non-signature card first, local state and API response become inconsistent with the provider card that was adopted.fix sketch
-const card = await getCards(pandaId) - .then((pandaCards) => pandaCards.find(({ status }) => status === "active")) +const card = await getCards(pandaId) + .then((pandaCards) => + pandaCards.find( + ({ status, productId, type }) => + status === "active" && productId === SIGNATURE_PRODUCT_ID && type === "virtual", + ), + )Also extend
CardsResponseinserver/utils/panda.tsto includeproductIdandtypeso this filter is enforceable by schema.Also applies to: 537-540, 572-578
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: db30cc18-31b1-4d3d-a958-ab7703a4b76b
📒 Files selected for processing (6)
.changeset/swift-pandas-reconcile.mdserver/api/card.tsserver/test/api/card.test.tsserver/test/e2e.tsserver/test/utils/panda.test.tsserver/utils/panda.ts
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 529376ad8c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Summary by CodeRabbit
Bug Fixes
Tests
Chores