Fix duplicate Expensify Card transactions on draft reports#93646
Open
KioCoan wants to merge 5 commits into
Open
Fix duplicate Expensify Card transactions on draft reports#93646KioCoan wants to merge 5 commits into
KioCoan wants to merge 5 commits into
Conversation
|
@tylerkaraszewski Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Explanation of Change
When an Expensify Card authorization settles, the backend creates a separate posted/clearing transaction (carrying
parentTransactionID= the root pending auth'stransactionID), moves the original pending auth to the hidden report (reportID = -4), and sends a real-time OnyxMERGE_COLLECTIONnull to clear the pending from clients.The problem is on a fresh load: the report-transaction query only returns
reportID > 0, so a hidden pending is simply absent from theOpenReportresponse (never sent as a null), andOpenReportwrites transactions additively viaMERGE_COLLECTIONand never reconciles stale rows. So a client that was offline or closed when the card settled (the common case, since cards settle 1-3 days later) misses the real-time null and keeps the stale pending in local Onyx with its old draftreportID, rendering it as a duplicate beside the posted row. Expensify Classic has no persistent client store, so it always reflects the current DB state, which is why it is unaffected.This PR adds a value-based deduplication at the single report-scoped aggregation chokepoint (
getAllNonDeletedTransactions). When a posted Expensify Card transaction is present, any pending card auth on the same chain (matched byparentTransactionID/transactionID) is filtered out before render. The guard is conservative: it only ever hides a pending row when a posted sibling from the same chain exists. Genuinely pending rows with no posted counterpart, non-card transactions, and splits are all left untouched. Totals are unaffected because the header reads the server-authoritativereport.total, not a client sum of the list.A backend follow-up (Auth) will purge the stale pending at the source on
OpenReport; this client-side fix is what closes the deploy blocker because it also covers offline/stale clients that never re-fetch.Fixed Issues
#93321
Tests
Pendingcard row with the draftreportID, plus aPostedcard row whoseparentTransactionIDis the pending'stransactionID).Offline tests
QA Steps
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
Before (duplicate pending + posted rows):

After (single posted row):
