Skip to content

πŸš‘οΈ server: collect regardless of card status#593

Merged
cruzdanilo merged 1 commit intomainfrom
collect
Dec 23, 2025
Merged

πŸš‘οΈ server: collect regardless of card status#593
cruzdanilo merged 1 commit intomainfrom
collect

Conversation

@cruzdanilo
Copy link
Member

@cruzdanilo cruzdanilo commented Dec 23, 2025

Note

Enables collection to proceed irrespective of card status on non-authorization events, while retaining stricter checks for authorization.

  • For transaction.requested, fetch card with status === "ACTIVE" and acquire mutex as before
  • For transaction.created/completed, fetch card by id without status constraint to permit collection when cards are frozen/locked
  • Remove findCardById helper; inline Drizzle queries for cards
  • Add test over-captures frozen debit to verify capture works when card becomes FROZEN after authorization

Written by Cursor Bugbot for commit 3922e00. This will update automatically on new commits. Configure here.

@changeset-bot
Copy link

changeset-bot bot commented Dec 23, 2025

πŸ¦‹ Changeset detected

Latest commit: 566a1f0

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 introduces a critical fix to the server's Panda hook, enabling the system to collect transaction data for cards regardless of their current status, particularly for the created action. Previously, an implicit check for an 'ACTIVE' card status prevented transactions from being processed for cards in other states, such as 'FROZEN'. The changes refactor the card lookup mechanism and include a new test to ensure this broader collection capability functions as expected.

Highlights

  • Card Status Handling: Modified the card lookup logic for the created action within the Panda hook to allow transaction processing regardless of the card's status, addressing a previous implicit requirement for cards to be ACTIVE.
  • Code Refactoring: The findCardById helper function was removed, and its logic was inlined directly into the requested and created action handlers in server/hooks/panda.ts.
  • Test Coverage: A new test case was added to server/test/hooks/panda.test.ts to specifically verify that over-captures for frozen debit cards are correctly processed, confirming the intended behavior change.
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. ↩

@cruzdanilo
Copy link
Member Author

/gemini review

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 correctly implements the logic to allow transaction collection regardless of card status for non-authorization events, while keeping stricter checks for authorizations. The removal of the findCardById helper and inlining the queries makes the logic in each case clearer. The new test case over-captures frozen debit effectively validates the changes for frozen cards.

I've added a couple of suggestions to improve error handling consistency by returning specific HTTP error responses instead of throwing generic errors when a card is not found. This will make the API behavior more predictable for clients.

Choose a reason for hiding this comment

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

medium

For better error handling and consistency within the file, consider returning a specific HTTP error response instead of throwing a generic Error. For example, a 404 Not Found would be appropriate here. This aligns with how other error conditions, like a mutex timeout, are handled in this endpoint.

Suggested change
if (!card) throw new Error("card not found");
if (!card) return c.json({ code: "card not found" }, 404);

Copy link
Contributor

Choose a reason for hiding this comment

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

throwing an error is appropiate because if the card doens't exist in the db is because we didn't save it at the moment of the card creation and is not a user input error that can fix

Choose a reason for hiding this comment

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

medium

Similar to my other comment, it's better to return a specific HTTP error response here instead of throwing a generic Error. This improves consistency in error handling across the different transaction actions.

Suggested change
if (!card) throw new Error("card not found");
if (!card) return c.json({ code: "card not found" }, 404);

Copy link
Contributor

Choose a reason for hiding this comment

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

throwing an error is appropiate because if the card doens't exist in the db is because we didn't save it at the moment of the card creation and is not a user input error that can fix

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 enables transaction collection to proceed even if a card's status changes to frozen or locked after authorization. This is achieved by removing the status === 'ACTIVE' check when fetching cards for created and completed transaction events. The findCardById helper has been removed in favor of inlining the database queries. A new test case has been added to verify that a capture on a frozen card is successful.

My review focuses on improving error handling and code maintainability. I've identified that 'card not found' scenarios are not handled gracefully and will lead to unhandled exceptions. I've also pointed out that inlining the queries has introduced code duplication and suggested an alternative approach using a more flexible helper function, which would also help address the error handling concerns.

I am having trouble creating individual review comments. Click here to see my feedback.

server/hooks/panda.ts (219)

high

Throwing a generic Error here results in an unhandled exception within this handler, leading to a generic 500 response. For a 'card not found' scenario, it's better to return a specific error response (e.g., a 404 or a custom 5xx status code) to provide clearer feedback to the API consumer.

if (!card) return c.json({ code: "card not found or not active" }, 404);

server/hooks/panda.ts (444)

high

Similar to the requested case, throwing a generic Error here results in an unhandled exception. It's better to handle the 'card not found' case explicitly and return a specific error response to improve robustness and provide clear feedback.

if (!card) return c.json({ code: "card not found" }, 404);

server/hooks/panda.ts (816-824)

medium

While inlining the database queries makes the logic in each case handler explicit, it introduces code duplication. Consider creating a new, more flexible helper function instead of removing this one entirely. This would centralize the card fetching logic and improve maintainability.

A parameterized helper function could also return null if a card isn't found, allowing callers to handle this case gracefully and fix the unhandled exception issues. For example:

async function findCard(cardId: string, options?: { activeOnly: boolean }) {
  return database.query.cards.findFirst({
    columns: { mode: true },
    where: options?.activeOnly
      ? and(eq(cards.id, cardId), eq(cards.status, "ACTIVE"))
      : eq(cards.id, cardId),
    with: { credential: { columns: { account: true } } },
  });
}

@codecov
Copy link

codecov bot commented Dec 23, 2025

Codecov Report

❌ Patch coverage is 83.33333% with 2 lines in your changes missing coverage. Please review.
βœ… Project coverage is 46.02%. Comparing base (d70c273) to head (566a1f0).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
server/hooks/panda.ts 83.33% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #593      +/-   ##
==========================================
- Coverage   50.91%   46.02%   -4.90%     
==========================================
  Files          47       40       -7     
  Lines        7259     6584     -675     
  Branches      580      478     -102     
==========================================
- Hits         3696     3030     -666     
+ Misses       3548     3537      -11     
- Partials       15       17       +2     
Flag Coverage Ξ”
github 45.89% <83.33%> (-5.01%) ⬇️

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:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • πŸ“¦ JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cruzdanilo cruzdanilo merged commit 566a1f0 into main Dec 23, 2025
2 of 3 checks passed
@cruzdanilo cruzdanilo deleted the collect branch December 23, 2025 16:50
@cruzdanilo cruzdanilo mentioned this pull request Dec 23, 2025
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.

2 participants

Comments