Skip to content

🥅 server: handle misc panda errors from sentry#736

Merged
cruzdanilo merged 2 commits intomainfrom
panda
Feb 7, 2026
Merged

🥅 server: handle misc panda errors from sentry#736
cruzdanilo merged 2 commits intomainfrom
panda

Conversation

@cruzdanilo
Copy link
Member

@cruzdanilo cruzdanilo commented Feb 6, 2026

sentry issues:


Open with Devin

Summary by CodeRabbit

  • New Features

    • Added support for card tokenization webhook notifications.
  • Bug Fixes

    • Card endpoint returns a clear 403 when a linked panda user is missing; other failures surface as server errors.
  • Tests

    • Added tests for card endpoint (missing user, non-404 failures) and card notification handling (responses and side effects).
  • Chores

    • Updated release metadata/changelog entries.

@changeset-bot
Copy link

changeset-bot bot commented Feb 6, 2026

🦋 Changeset detected

Latest commit: 5fe25ec

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

This PR includes changesets to release 1 package
Name Type
@exactly/server 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

@gemini-code-assist
Copy link

Summary of Changes

Hello @cruzdanilo, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the server's ability to process Panda card tokenization webhooks. It introduces specific handling for card notification events, particularly those indicating provisioning declines, by updating the payload validation and user identification logic. The changes ensure that the system can correctly interpret and respond to these critical events, improving the overall reliability and functionality of the Panda integration.

Highlights

  • Panda Card Tokenization Webhook Handling: Introduced new logic to specifically handle 'card' resource webhooks with an 'notification' action, particularly for 'PROVISIONING_DECLINED' events from Panda.
  • Payload Validation Schema Update: Refactored the Payload validation schema in server/hooks/panda.ts to include a dedicated Card variant, improving type safety and clarity for card-related webhooks.
  • Dynamic Panda ID Extraction: Enhanced the pandaId extraction logic to correctly identify the associated user based on different resource and action types within the webhook payload, including the new card notification events.
  • Comprehensive Test Coverage: Added a new test suite for 'card notification' webhooks in server/test/hooks/panda.test.ts, covering various scenarios such as known, null, and unknown user IDs, and the presence or absence of a decisionReason.
Changelog
  • .changeset/warm-foxes-swim.md
    • Added a new changeset file to document the changes for the @exactly/server package.
  • server/hooks/panda.ts
    • Refactored the Payload validation schema to introduce a new Card variant, separating card-related payloads.
    • Added a new Card payload type for notification actions, specifically for PROVISIONING_DECLINED events, including an optional decisionReason field.
    • Updated the logic for extracting pandaId from webhook payloads to correctly handle card resources with updated and notification actions, ensuring the correct user is identified.
  • server/test/hooks/panda.test.ts
    • Added a new test suite for 'card notification' webhooks to validate the new handling logic.
    • Included test cases for PROVISIONING_DECLINED notifications with known, null, and unknown userId values.
    • Added a test case to verify correct handling of notifications without a decisionReason field.
Activity
  • The pull request was created by cruzdanilo.
  • The changes address a Sentry issue identified as SERVER-H7.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link

coderabbitai bot commented Feb 6, 2026

Walkthrough

Adds handling for missing Panda users in the card GET endpoint (returns 403 when panda user lookup yields 404), introduces a Card payload variant and notification handling in the Panda webhook flow with credential-based user resolution, and adds tests for both API and webhook behaviors.

Changes

Cohort / File(s) Summary
Changeset entries
\.changeset/gentle-panda-catch.md, \.changeset/warm-foxes-swim.md
Add patch changelog metadata for @exactly/server documenting Panda card/user handling changes.
Card endpoint
server/api/card.ts
GET card: wrap getUser to treat 404 as missing user, return 403 (code NO_PANDA) when no Panda user; construct displayName from returned user.
Panda webhook handler
server/hooks/panda.ts
Add Card payload variant and notification action; refactor non-transaction post-processing to derive pandaId from payload, query credentials for provider:"panda", and set user only when credential exists.
Card endpoint tests
server/test/api/card.test.ts
Add tests: assert 403 when getUser returns 404-like error; assert 500 when getUser throws non-404 error.
Webhook handler tests
server/test/hooks/panda.test.ts
Add "card notification" tests covering known/unknown/null userId and missing decisionReason; assert HTTP 200 { code: "ok" } and that setUser is invoked when appropriate.

Sequence Diagram(s)

sequenceDiagram
  rect rgba(220,220,255,0.5)
    participant Webhook as Webhook Receiver
    participant Handler as Panda Hook Handler
    participant Cred as Credentials Store
    participant Panda as Panda Service (getUser)
  end

  Webhook->>Handler: POST Card notification (resource/action/body)
  Handler->>Handler: derive pandaId from Card.notification or Transaction
  Handler->>Cred: query credential provider:"panda", providerId:pandaId
  alt credential found
    Handler->>Panda: getUser(pandaId)
    alt user found
      Panda->>Handler: user
      Handler->>Handler: process with user
    else user 404
      Panda->>Handler: 404
      Handler->>Handler: treat as missing user (no user)
    end
  else no credential
    Cred-->>Handler: no credential
    Handler->>Handler: skip user resolution
  end
  Handler->>Webhook: respond 200 { code: "ok" } or handle error
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • nfmelendez
🚥 Pre-merge checks | ✅ 1 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title uses a vague term 'misc panda errors' that doesn't clearly specify the main changes. While it references handling panda errors, the actual changes involve handling missing panda users, card tokenization webhooks, and error scenarios—which are not accurately conveyed by 'misc errors'. Consider a more specific title like '🥅 server: handle missing panda user and card webhook errors' to clearly reflect the main code changes in the pull request.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch panda

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 and usage tips.

@sentry
Copy link

sentry bot commented Feb 6, 2026

Sentry Issue: SERVER-H7

Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 3 additional findings.

Open in Devin Review

@sentry
Copy link

sentry bot commented Feb 6, 2026

Codecov Report

❌ Patch coverage is 81.81818% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.28%. Comparing base (8fc3c3a) to head (5fe25ec).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
server/hooks/panda.ts 71.42% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #736      +/-   ##
==========================================
+ Coverage   67.21%   67.28%   +0.07%     
==========================================
  Files         206      206              
  Lines        6902     6908       +6     
  Branches     2143     2147       +4     
==========================================
+ Hits         4639     4648       +9     
+ Misses       2081     2077       -4     
- Partials      182      183       +1     
Flag Coverage Δ
e2e 67.28% <81.81%> (+15.20%) ⬆️

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

☔ View full report in Codecov by Sentry.
📢 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.

@cruzdanilo cruzdanilo force-pushed the panda branch 2 times, most recently from 7131ed6 to 65a2c96 Compare February 6, 2026 23:36
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request successfully adds handling for the Panda card tokenization notification webhook. The changes include updating the payload validation schema to include the new notification action for the card resource, and adjusting the logic to correctly extract the user ID from various webhook payloads. New tests have been added to cover the new functionality, including cases with known, unknown, and null user IDs. My review includes one suggestion to improve the readability and maintainability of the logic that extracts the user ID.

@cruzdanilo cruzdanilo changed the title 🦺 server: handle panda card tokenization webhook 🥅 server: handle misc panda errors from sentry Feb 6, 2026
@sentry
Copy link

sentry bot commented Feb 6, 2026

Sentry Issue: SERVER-FF

@cruzdanilo
Copy link
Member Author

@cursor review

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@server/hooks/panda.ts`:
- Around line 222-234: The where clause in database.query.credentials.findFirst
uses a redundant and(eq(credentials.pandaId, pandaId)) wrapper; replace it with
the single predicate eq(credentials.pandaId, pandaId) directly (update the call
in the same block that computes pandaId and calls
database.query.credentials.findFirst) so the where option passes
eq(credentials.pandaId, pandaId) instead of and(...).

@cruzdanilo cruzdanilo force-pushed the panda branch 2 times, most recently from f48236b to 4f15be1 Compare February 7, 2026 00:36
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@server/test/hooks/panda.test.ts`:
- Around line 1259-1278: Spy on Sentry.setUser in the "returns ok with known
user" test, perform the request via appClient.index.$post as you already do,
then assert the spy was called with the credential id (e.g., { id: "cred" }) to
verify Sentry context enrichment; use Sentry.setUser spy/ mock and restore/reset
it after the test so other tests remain unaffected.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@server/test/hooks/panda.test.ts`:
- Around line 1281-1321: Add negative assertions to both "returns ok with null
userId" and "returns ok with unknown userId" tests to confirm setUser was not
called: after the existing response assertions in the it blocks (the ones that
expect status 200 and JSON { code: "ok" }), add
expect(setUser).not.toHaveBeenCalled() so the tests assert no user context is
set when card.userId is null or unresolvable.

Comment on lines +1281 to +1321
it("returns ok with null userId", async () => {
const response = await appClient.index.$post({
header: { signature: "panda-signature" },
json: {
resource: "card",
action: "notification",
id: "webhook-id",
body: {
id: "notification-id",
card: { id: "card", userId: null },
tokenWallet: "Apple",
reasonCode: "PROVISIONING_DECLINED",
decisionReason: { code: "WALLET_PROVIDER_RISK_THRESHOLD_EXCEEDED", description: "declined" },
},
},
});

expect(response.status).toBe(200);
await expect(response.json()).resolves.toStrictEqual({ code: "ok" });
});

it("returns ok with unknown userId", async () => {
const response = await appClient.index.$post({
header: { signature: "panda-signature" },
json: {
resource: "card",
action: "notification",
id: "webhook-id",
body: {
id: "notification-id",
card: { id: "card", userId: "unknown" },
tokenWallet: "Apple",
reasonCode: "PROVISIONING_DECLINED",
decisionReason: { code: "WALLET_PROVIDER_RISK_THRESHOLD_EXCEEDED", description: "declined" },
},
},
});

expect(response.status).toBe(200);
await expect(response.json()).resolves.toStrictEqual({ code: "ok" });
});
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider adding negative assertions for setUser in the null/unknown userId tests.

Tests 2 and 3 verify the 200 response but don't assert that setUser was not called. Adding expect(setUser).not.toHaveBeenCalled() would strengthen the tests by confirming no spurious user context is set when pandaId is null or unresolvable.

Proposed additions

For "returns ok with null userId" (after line 1299):

     expect(response.status).toBe(200);
     await expect(response.json()).resolves.toStrictEqual({ code: "ok" });
+    expect(setUser).not.toHaveBeenCalled();

For "returns ok with unknown userId" (after line 1320):

     expect(response.status).toBe(200);
     await expect(response.json()).resolves.toStrictEqual({ code: "ok" });
+    expect(setUser).not.toHaveBeenCalled();
🤖 Prompt for AI Agents
In `@server/test/hooks/panda.test.ts` around lines 1281 - 1321, Add negative
assertions to both "returns ok with null userId" and "returns ok with unknown
userId" tests to confirm setUser was not called: after the existing response
assertions in the it blocks (the ones that expect status 200 and JSON { code:
"ok" }), add expect(setUser).not.toHaveBeenCalled() so the tests assert no user
context is set when card.userId is null or unresolvable.

@cruzdanilo cruzdanilo merged commit 5fe25ec into main Feb 7, 2026
15 checks passed
@cruzdanilo cruzdanilo deleted the panda branch February 7, 2026 01:46
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