Skip to content

Implementing optimistic category and tag workspace violations #74389

Merged
cead22 merged 40 commits intoExpensify:mainfrom
Tony-MK:violaions
Nov 13, 2025
Merged

Implementing optimistic category and tag workspace violations #74389
cead22 merged 40 commits intoExpensify:mainfrom
Tony-MK:violaions

Conversation

@Tony-MK
Copy link
Contributor

@Tony-MK Tony-MK commented Nov 5, 2025

Explanation of Change

Created a new hook usePolicyData to fetch the policy categories, tags, and reports with their associated transactions and violations. policyData is used in the functions listed below to make them pure and optimistically show violations when the categories or tags used by expenses have changed.

/actions/ReportUtils.ts

  1. pushTransactionViolationsOnyxData()

/actions/Policy/Tag.ts

  1. setWorkspaceTagEnabled()

  2. setWorkspaceTagRequired()

  3. deletePolicyTags()

  4. enablePolicyTags()

  5. renamePolicyTag()

  6. setPolicyRequiresTag()

  7. setPolicyTagsRequired()

/actions/Policy/Category.ts

  1. deleteWorkspaceCategories()

  2. enablePolicyCategories()

  3. renamePolicyCategory()

  4. removePolicyCategoryReceiptsRequired()

  5. setPolicyCategoryReceiptsRequired()

  6. setWorkspaceCategoryEnabled()

  7. setWorkspaceRequiresCategory()

Fixed Issues

$ #62698
PROPOSAL:

Tests

Prerequisite for Test Cases 1 - 5: A Must tag expenses enabled workspace

Test Case 1: Enable and Disable Tag Feature

  1. Create an untagged expense.
  2. Wait for the network status bar to stop loading.
  3. Verify that a red dot on the Inbox tab is visible.
  4. Verify that a Missing Tag violation on the report preview is visible.
  5. Verify that a Missing Tag violation in the expense thread is visible.
  6. Navigate to the workspace feature page.
  7. Enable Force Offline.
  8. Disable the tag feature.
  9. Verify that the red dot on the Inbox tab is not visible.
  10. Verify that the Missing Tag violation on the report preview is not visible.
  11. Verify that the Missing Tag violation in the expense thread is not visible.
  12. Disable Force Offline.
  13. Wait for the network status bar to stop loading.
  14. Verify that the red dot on the Inbox tab is not visible.
  15. Verify that the Missing Tag violation on the report preview is not visible.
  16. Verify that the Missing Tag violation in the expense thread is not visible.
  17. Navigate to the workspace feature page.
  18. Enable Force Offline.
  19. Enable the tag feature.
  20. Verify that the red dot on the Inbox tab is not visible.
  21. Verify that the Missing Tag violation on the report preview is not visible.
  22. Verify that the Missing Tag violation in the expense thread is not visible.
  23. Disable Force Offline.
  24. Wait for the network status bar to stop loading.
  25. Verify that the red dot on the Inbox tab is not visible.
  26. Verify that the Missing Tag violation on the report preview is not visible.
  27. Verify that the Missing Tag violation in the expense thread is not visible.

Test Case 2: Enable and Disable Tag Requirement

  1. Create an untagged expense.
  2. Navigate to the expense thread.
  3. Wait for the network status bar to stop loading.
  4. Verify the Missing Tag violation is visible.
  5. Enable Force Offline.
  6. Navigate to the workspace's tags page.
  7. Disable the Must tag expenses setting.
  8. Navigate to the expense thread.
  9. Verify the Missing Tag violation is not visible.
  10. Disable Force Offline.
  11. Wait for the network status bar to stop loading.
  12. Verify the violation is not visible.
  13. Navigate back to the workspace's tags page.
  14. Enable Force Offline.
  15. Enable the Must tag expenses.
  16. Navigate back to the expense thread.
  17. Verify the Missing Tag violation is visible.
  18. Disable Force Offline.
  19. Wait for the network status bar to stop loading.
  20. Verify the violation persists.

Test Case 3: Enable and Disable Tag

  1. Create a tagged expense.
  2. Navigate to the expense thread.
  3. Wait for the network status bar to stop loading.
  4. Verify the expense has no violations.
  5. Navigate to the workspace's tags page.
  6. Enable Force Offline.
  7. Disable the tag used in the expense.
  8. Navigate back to the expense.
  9. Verify the Tag no longer valid violation is visible.
  10. Disable Force Offline.
  11. Wait for the network status bar to stop loading.
  12. Verify the violation persists.
  13. Enable Force Offline.
  14. Enable the tag used in the expense.
  15. Navigate back to the expense thread.
  16. Verify the tag violation is not visible.
  17. Disable Force Offline.
  18. Wait for the network status bar to stop loading.
  19. Verify the violation is not visible.

Test Case 4: Delete and Update Expense Tag

  1. Create a tagged expense.
  2. Navigate to the expense thread.
  3. Wait for the network status bar to stop loading.
  4. Verify the expense has no violations.
  5. Navigate to the workspace's tags page.
  6. Enable Force Offline.
  7. Delete the tag used to tag the expense.
  8. Navigate back to the expense.
  9. Verify the Tag no longer valid violation is visible.
  10. Disable Force Offline.
  11. Wait for the network status bar to stop loading.
  12. Verify the violation persists.
  13. Enable Force Offline.
  14. Update the expense's tag.
  15. Verify the violation is not visible.
  16. Disable Force Offline.
  17. Wait for the network status bar to stop loading.
  18. Verify the violation is not visible.

Test Case 5: Rename Tag

  1. Create a tagged expense.
  2. Navigate to the expense thread.
  3. Wait for the network status bar to stop loading.
  4. Verify the expense has no violations.
  5. Navigate to the workspace's tags page.
  6. Enable Force Offline.
  7. Rename the tag used to tag the expense in step 1.
  8. Navigate back to the expense.
  9. Verify the Tag no longer valid violation is visible.
  10. Disable Force Offline.
  11. Wait for the network status bar to stop loading.
  12. Verify the violation persists.
  13. Enable Force Offline.
  14. Revert the tag name to its original name
  15. Navigate back to the expense thread.
  16. Verify the violation is not visible.
  17. Disable Force Offline.
  18. Wait for the network status bar to stop loading.
  19. Verify the violation is not visible.

Prerequisite for Test Cases 6 - 11: A Must category expenses enabled workspace

Test Case 6: Enable and Disable Category Feature

  1. Create an uncategorized expense.
  2. Wait for the network status bar to stop loading.
  3. Verify that a red dot on the Inbox tab is visible.
  4. Verify that the Missing Category violation on the report preview is visible.
  5. Verify that the Missing Category violation in the expense thread is visible.
  6. Navigate to the workspace feature page.
  7. Enable Force Offline.
  8. Disable the category feature.
  9. Verify that the red dot on the Inbox tab is not visible.
  10. Verify that the Missing Category violation on the report preview is not visible.
  11. Verify that the Missing Category violation in the expense thread is not visible.
  12. Disable Force Offline.
  13. Wait for the network status bar to stop loading.
  14. Verify that the red dot on the Inbox tab is not visible.
  15. Verify that the Missing Category violation on the report preview is not visible.
  16. Verify that the Missing Category violation in the expense thread is not visible.
  17. Navigate to the workspace feature page.
  18. Enable Force Offline.
  19. Enable the category feature.
  20. Verify that the red dot on the Inbox tab is not visible.
  21. Verify that the Missing Category violation on the report preview is not visible.
  22. Verify that the Missing Category violation in the expense thread is not visible.
  23. Disable Force Offline.
  24. Wait for the network status bar to stop loading.
  25. Verify that the red dot on the Inbox tab is not visible.
  26. Verify that the Missing Category violation on the report preview is not visible.
  27. Verify that the Missing Category violation in the expense thread is not visible.

Test Case 7: Enable and Disable Category Requirement

  1. Create an uncategorized expense.
  2. Navigate to the expense thread.
  3. Wait for the network status bar to stop loading.
  4. Verify the Missing Category violation is visible.
  5. Enable Force Offline.
  6. Navigate to the workspace's categories page.
  7. Disable the Must category expenses setting.
  8. Navigate to the expense thread.
  9. Verify the Missing Category violation is not visible.
  10. Disable Force Offline.
  11. Wait for the network status bar to stop loading.
  12. Verify the violation is not visible.
  13. Navigate back to the workspace's categories page.
  14. Enable Force Offline.
  15. Enable the Must category expenses.
  16. Navigate back to the expense thread.
  17. Verify that the Missing Category violation is visible.
  18. Disable Force Offline.
  19. Wait for the network status bar to stop loading.
  20. Verify the violation persists.

Test Case 8: Enable and Disable Category

  1. Create a categorized expense.
  2. Navigate to the expense thread.
  3. Wait for the network status bar to stop loading.
  4. Verify the expense has no violations.
  5. Navigate to the workspace's categories page.
  6. Enable Force Offline.
  7. Disable the category used in the expense.
  8. Navigate back to the expense.
  9. Verify the Category no longer valid violation is visible.
  10. Disable Force Offline.
  11. Wait for the network status bar to stop loading.
  12. Verify the violation persists.
  13. Enable Force Offline.
  14. Enable the category used in the expense.
  15. Navigate back to the expense thread.
  16. Verify the category violation is not visible.
  17. Disable Force Offline.
  18. Wait for the network status bar to stop loading.
  19. Verify the violation is not visible.

Test Case 9: Delete Category and Update Expense Category

  1. Create a categorized expense.
  2. Navigate to the expense thread.
  3. Wait for the network status bar to stop loading.
  4. Verify the expense has no violations.
  5. Navigate to the workspace's categories page.
  6. Enable Force Offline.
  7. Delete the category used to categorize the expense.
  8. Navigate back to the expense.
  9. Verify the Category no longer valid violation is visible.
  10. Disable Force Offline.
  11. Wait for the network status bar to stop loading
  12. Verify the violation persists.
  13. Enable Force Offline.
  14. Change the expense's category.
  15. Verify the category violation is not visible.
  16. Disable Force Offline.
  17. Wait for the network status bar to stop loading.
  18. Verify the violation is not visible.

Test Case 10: Rename Category

  1. Create a categorized expense.
  2. Navigate to the expense thread.
  3. Wait for the network status bar to stop loading.
  4. Verify the expense has no violations.
  5. Navigate to the workspace's categories page.
  6. Enable Force Offline.
  7. Rename the category used to categorize the expense.
  8. Navigate back to the expense.
  9. Verify the Category no longer valid violation is visible.
  10. Disable Force Offline.
  11. Wait for the network status bar to stop loading.
  12. Verify the violation persists.
  13. Enable Force Offline.
  14. Revert the category name to its original name.
  15. Navigate back to the expense thread.
  16. Verify the violation is not visible.
  17. Disable Force Offline.
  18. Wait for the network status bar to stop loading.
  19. Verify the violation is not visible.

Test Case 11: Set Receipt Required Amount Rule

  1. Navigate the workspace feature page.
  2. Enable the Rules Feature.
  3. Set Receipt Required Amount with a random amount value.
  4. Create a category expense with the amount less than the Receipt Required Amount.
  5. Navigate to the expense thread.
  6. Wait for the network status bar to stop loading.
  7. Verify no violation is visible.
  8. Enable Force Offline.
  9. Navigate to the expense's category settings.
  10. Update Require receipts over to "Always require receipts".
  11. Navigate back to the expense thread.
  12. Verify the Receipt Required violation is visible.
  13. Disable Force Offline.
  14. Wait for the network status bar to stop loading.
  15. Verify the violation persists.
  16. Enable Force Offline.
  17. Navigate to the expense's category settings again.
  18. Update Require receipts over to "Never require receipts".
  19. Navigate back to the expense thread.
  20. Verify that the violation is not visible.
  21. Disable Force Offline.
  22. Wait for the network status bar to stop loading.
  23. Verify the violation is not visible.
  24. Enable Force Offline.
  25. Navigate to the expense's category settings again.
  26. Update Require receipts over to the initial default value.
  27. Navigate back to the expense thread.
  28. Verify the violation is not visible.
  29. Disable Force Offline.
  30. Wait for the network status bar to stop loading.
  31. Verify the violation is not visible.
  • Verify that no errors appear in the JS console

Offline tests

QA Steps

// TODO: These must be filled out, or the issue title must include "[No QA]."

Same as tests

  • Verify that no errors appear in the JS console

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
    • MacOS: Desktop
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I verified there are no new alerts related to the canBeMissing param for useOnyx
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product is localized by adding it to src/languages/* files and using the translation method
      • If any non-english text was added/modified, I used JaimeGPT to get English > Spanish translation. I then posted it in #expensify-open-source and it was approved by an internal Expensify engineer. Link to Slack message:
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.ts or at the top of the file that uses the constant) are defined as such
  • I verified that if a function's arguments changed that all usages have also been updated correctly
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If new assets were added or existing ones were modified, I verified that:
    • The assets are optimized and compressed (for SVG files, run npm run compress-svg)
    • The assets load correctly across all supported platforms.
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

Screenshots/Videos

Android: Native

Test Case 1: Tag Feature

Tag Feature

Test Case 2: Tag Requirement

Tag Requirement

Test Case 3: Enable and Disable Tag

Tag Enable:Disable

Test Case 4: Delete and Update Tag

Android.-.Native.mov

Test Case 5: Rename Tag

Tag Rename

Test Case 6: Category Feature

Catergory Feature Catergory Feature 2

Test Case 7: Category Requirement

Category Requirement Category Requirement 2

Test Case 8: Enable and Disable Category

Category Enable:Disable

Test Case 9: Delete and Update Category

Category Delete:Update Category Delete:Update 2

Test Case 10: Rename Category

Category Rename

Test Case 11: Set Receipt Required Amount Rule

Category Receipt
Android: mWeb Chrome

Test Case 1: Tag Feature

Tag.Feature.webm

Test Case 2: Tag Requirement

Tag.Requirement.webm

Test Case 3: Enable and Disable Tag

Tag.Enable.Disable.webm

Test Case 4: Delete and Update Tag

Tag.Delete.Update.webm

Test Case 5: Rename Tag

Tag.Rename.webm

Test Case 6: Category Feature

Category.Feature.webm

Test Case 7: Category Requirement

Category.Requirement.webm

Test Case 8: Enable and Disable Category

Category.Enable.Disable.webm

Test Case 9: Delete and Update Category

Category.Delete.Update.webm

Test Case 10: Rename Category

Category.Rename.webm

Test Case 11: Set Receipt Required Amount Rule

Category.Receipt.webm
iOS: Native

Test Case 1: Tag Feature

Tag.Feature.mp4

Test Case 2: Tag Requirement

Tag.Requirement.mp4

Test Case 3: Enable and Disable Tag

Tag.Enable.DIsable.mp4

Test Case 4: Delete and Update Tag

Tag.Delete.Update.mp4

Test Case 5: Rename Tag

Tag.Rename.mp4

Test Case 6: Category Feature

Category.Feature.mp4

Test Case 7: Category Requirement

Category.Requirement.mov

Test Case 8: Enable and Disable Category

Category.Enable.Disable.mp4

Test Case 9: Delete and Update Category

Category.Delete.Update.mp4

Test Case 10: Rename Category

Category.Rename.mp4

Test Case 11: Set Receipt Required Amount Rule

Category.Receipt.mp4
iOS: mWeb Safari

Test Case 1: Tag Feature

Tag.Feature.mp4

Test Case 2: Tag Requirement

Tag.Requirement.mp4

Test Case 3: Enable and Disable Tag

Tag.Enable.Disable.mp4

Test Case 4: Delete and Update Tag

Tag.Delete.Update.mp4

Test Case 5: Rename Tag

Tag.Rename.mp4

Test Case 6: Category Feature

Category.Feature.mp4

Test Case 7: Category Requirement

Category.Requirement.mp4

Test Case 8: Enable and Disable Category

Category.Enable.Disable.mp4

Test Case 9: Delete and Update Category

Category.Delete.Update.mp4

Test Case 10: Rename Category

Category.Rename.mp4

Test Case 11: Set Receipt Required Amount Rule

Category.Receipt.mp4
MacOS: Chrome / Safari

Test Case 1: Tag Feature

Tag.Feature.mov

Test Case 2: Tag Requirement

Enable.Disable.Requirement.mov

Test Case 3: Enable and Disable Tag

Enable.Disable.Tag.mov

Test Case 4: Delete and Update Tag

Tag.Delete.Update.mov

Test Case 5: Tag Rename

Tag.Rename.mov

Test Case 6: Category Feature

Category.Feature.mov

Test Case 7: Category Requirement

Category.Requirement.mov

Test Case 8: Enable and Disable Category

Category.Enable.Disable.mov

Test Case 9: Delete and Update Category

Catergory.Delete.Update.mov

Test Case 10: Rename Category

Category.Rename.mov

Test Case 11: Set Receipt Required Amount Rule

Category.Receipt.mov
MacOS: Desktop

Test Case 1: Tag Feature

Tag.Feature.mov

Test Case 2: Tag Requirement

Tag.Reqirement.mov

Test Case 3: Enable and Disable Tag

Enable.and.Disabled.Tag.mov

Test Case 4: Delete and Update Tag

Delete.and.Update.Tags.mov

Test Case 5: Rename Tag

Rename.Tag.mov

Test Case 6: Category Feature

Catergory.Feature.mov

Test Case 7: Category Requirement

Category.Requirement.mov

Test Case 8: Enable and Disable Category

Category.Enable.Disable.mov

Test Case 9: Delete and Update Category

Category.Delete.and.Update.mov

Test Case 10: Rename Category

Category.Rename.mov

Test Case 11: Set Receipt Required Amount Rule

Category.Receipt.Amount.mov

…lues and adjust transaction count in pushTransactionViolations test
@codecov
Copy link

codecov bot commented Nov 5, 2025

Codecov Report

❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.

Files with missing lines Coverage Δ
src/components/MoneyRequestConfirmationList.tsx 54.32% <ø> (ø)
src/hooks/usePolicyData/index.ts 100.00% <100.00%> (ø)
.../pages/iou/request/step/IOURequestStepCategory.tsx 0.00% <ø> (ø)
...ace/categories/CategoryRequireReceiptsOverPage.tsx 0.00% <ø> (ø)
...rc/pages/workspace/categories/EditCategoryPage.tsx 0.00% <ø> (ø)
...s/workspace/categories/WorkspaceCategoriesPage.tsx 60.66% <100.00%> (-0.33%) ⬇️
src/pages/workspace/tags/EditTagPage.tsx 0.00% <ø> (ø)
...pages/workspace/tags/WorkspaceTagsSettingsPage.tsx 0.00% <ø> (ø)
...ages/workspace/categories/CategorySettingsPage.tsx 0.00% <0.00%> (ø)
src/pages/workspace/WorkspaceMoreFeaturesPage.tsx 0.00% <0.00%> (ø)
... and 7 more
... and 3 files with indirect coverage changes

@cead22 cead22 requested review from cead22 and situchan November 5, 2025 22:52
@Tony-MK Tony-MK changed the title Implementing optimistic workspace violations Implementing optimistic category and tag workspace violations Nov 6, 2025
@Tony-MK Tony-MK marked this pull request as ready for review November 7, 2025 21:50
@Tony-MK Tony-MK requested review from a team as code owners November 7, 2025 21:50
@Tony-MK
Copy link
Contributor Author

Tony-MK commented Nov 13, 2025

Bump @cead22.

@cead22
Copy link
Contributor

cead22 commented Nov 13, 2025

I re-uploaded videos

@situchan On Case 2 on Mac OS the red circle on the LHN doesn't appear while you're offline, and then appears after going online. Is that expected?

@cead22 cead22 removed the request for review from allroundexperts November 13, 2025 21:06
@cead22
Copy link
Contributor

cead22 commented Nov 13, 2025

@Tony-MK for Test Case 1: Tag Feature, when tags are re-enabled, shouldn't the transaction thread show a tag field?

@situchan
Copy link
Contributor

On Case 2 on Mac OS the red circle on the LHN doesn't appear while you're offline, and then appears after going online. Is that expected?

I think Case 2 is flaky. #62627 (comment)
I will do one more test though.

@cead22
Copy link
Contributor

cead22 commented Nov 13, 2025

Thanks!

@situchan
Copy link
Contributor

situchan commented Nov 13, 2025

On Case 2 on Mac OS the red circle on the LHN doesn't appear while you're offline, and then appears after going online. Is that expected?

I think it's expected for now (when enable Must tag expenses)
Though it works correctly in reverse (when disable Must tag expenses setting. LHN RBR disappears)

Screen.Recording.2025-11-14.at.3.23.20.AM.mov

@cead22
Copy link
Contributor

cead22 commented Nov 13, 2025

@situchan thanks, can you share more details? Why is it expected for now, and why does the reverse case work but not the other one?

@situchan
Copy link
Contributor

situchan commented Nov 13, 2025

On Case 2 on Mac OS the red circle on the LHN doesn't appear while you're offline, and then appears after going online. Is that expected?

This was reported earlier. And @Tony-MK answered #62627 (comment) and handle as follow-up.

Though interesting why we cannot fix this like in-reverse behavior (red circle disappears when transaction thread has no violation)
cc: @Tony-MK

@Tony-MK
Copy link
Contributor Author

Tony-MK commented Nov 13, 2025

@Tony-MK for Test Case 1: Tag Feature, when tags are re-enabled, shouldn't the transaction thread show a tag field?

I believe so, because all tags stay disabled after the tag feature is re-enabled. In production, that is the case.

Sample.mov

On Case 2 on Mac OS the red circle on the LHN doesn't appear while you're offline, and then appears after going online. Is that expected?

This was reported earlier. And @Tony-MK answered #62627 (comment) and handle as follow-up.

Though interesting why we cannot fix this like in-reverse behavior (red circle disappears when transaction thread has no violation) cc: @Tony-MK

It is the ViolationsUtils.getViolationsOnyxData() function that is inconsistent with the BE. It was mentioned in the follow-up summary under Issue 2.

@cead22 cead22 merged commit 31ba7fe into Expensify:main Nov 13, 2025
26 checks passed
@OSBotify
Copy link
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

Comment on lines +58 to +59
policy: policy as OnyxValueWithOfflineFeedback<Policy>,
reports: Object.values(reports ?? {}) as Array<OnyxValueWithOfflineFeedback<Report>>,
Copy link
Contributor

Choose a reason for hiding this comment

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

This field is not properly typed in TS.

usePolicy returns Policy | undefined

And here, overriding the as OnyxValueWithOfflineFeedback<Policy> type causes this hook to ignore the possibility that policy may be undefined.

I suggest removing all as operators from this hook.

image image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Handled by #75238.

@OSBotify
Copy link
Contributor

🚀 Deployed to staging by https://github.com/cead22 in version: 9.2.59-0 🚀

platform result
🖥 desktop 🖥 success ✅
🕸 web 🕸 success ✅
🤖 android 🤖 failure ❌
🍎 iOS 🍎 success ✅

@jponikarchuk
Copy link

This PR is failing because of issue
This issue is reproducible in: Web, mWeb, Android app

@IuliiaHerets
Copy link

@Tony-MK Original issue also still reproduced by QA team, PR was failed

@Tony-MK
Copy link
Contributor Author

Tony-MK commented Nov 17, 2025

@Tony-MK Original issue also still reproduced by QA team, PR was failed

@IuliiaHerets, This will be handled by #75238.

@OSBotify
Copy link
Contributor

🚀 Deployed to production by https://github.com/grgia in version: 9.2.59-5 🚀

platform result
🖥 desktop 🖥 success ✅
🕸 web 🕸 success ✅
🤖 android 🤖 failure ❌
🍎 iOS 🍎 failure ❌

Comment on lines +2032 to +2033
const tagList = policyData.tags?.[tagListName];
const tags = tagList.tags ?? {};
Copy link
Contributor

Choose a reason for hiding this comment

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

There's an edge case of policyData.tags being an empty object after clearing cache and restart.
That led to crash in the next line (tagList.tags 💥 )

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.

10 participants