Expensify / App

Welcome to New Expensify: a complete re-imagination of financial collaboration, centered around chat. Help us build the next generation of Expensify by sharing feedback and contributing to the code.
https://new.expensify.com
MIT License
3.12k stars 2.61k forks source link

[HOLD for payment 2024-07-10] [HOLD for payment 2024-07-02] LOW: [$250] Stop using `reportAction.originalMessage` or `reportAction.message.text` #39797

Open quinthar opened 3 months ago

quinthar commented 3 months ago

Problem:

Each comment in the server database is stored in reportAction.message in HTML form. However, for some reason lost to time, when we send that same comment out as an Onyx update, we:

  1. Rename the original message in the database to reportAction.originalMessage in the update (which is confusing)
  2. Create a new message object that contains a copy of the html message, as well as a stripped text version.
  3. Put the message object inside a totally unnecessary one-element array

That means every comment is actually sent out three times (four, if you include the update to the report object, but that's out of scope for now). This is clearly wasteful in a number of ways:

  1. It requires postprocessing on the server to do this extraneous operation
  2. It increases network bandwidth by 3x
  3. It increases RAM use 3x
  4. It increases on-device storage 3x
  5. It's confusing AF

Additionally, it's particularly problematic when sending Onyx updates out via UrbanAirship, which is extremely limited in the payload sizes allowed -- with anything over a certain limit just dropped quietly and never delivered, causing "gaps" in our update stream (which require more network calls to "backfill" the Onyx data on app open, which makes things slow). Basically, this was just a mistake introduced for reasons we can't remember, but that we want to undo.

Solution:

To solve this, please:

  1. Phase 1 (External / clientside): Stop using originalMessage, start using array-message
    1. Update every instance of originalMessage.html to use message.html || message[0].html
    2. Update every instance of message.text to dynamically strip the text from message.html || message[0].html
    3. Update every key within originalMessage to use the original message
  2. Phase 2 (Internal / serverside): Once we've confirmed the client no longer uses originalMessage or message.text or any other key within originalMessage:
    1. Stop sending originalMessage
    2. Start sending message without an array
  3. Phase 3 (External / clientside): Remove checking for "array message"

This issue is for phase 1 and phase 3.

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~01856d1399295ef760
  • Upwork Job ID: 1776729925881405440
  • Last Price Increase: 2024-04-06
  • Automatic offers:
    • cubuspl42 | Reviewer | 0
Issue OwnerCurrent Issue Owner: @puneetlath
melvin-bot[bot] commented 3 months ago

Job added to Upwork: https://www.upwork.com/jobs/~01856d1399295ef760

melvin-bot[bot] commented 3 months ago

Triggered auto assignment to Contributor-plus team member for initial proposal review - @cubuspl42 (External)

maxim-grin commented 3 months ago

Hey I’m going to investigate why the payload is so big in Onyx storage. Possibly track what change exactly caused the problem. Then either revert that piece of change or use one of suggestions by @thienlnam

Contributor details Your Expensify account email: maxim.grin@gmail.com Upwork Profile Link: https://www.upwork.com/freelancers/~01fb7b172c01252917

melvin-bot[bot] commented 3 months ago

πŸ“£ @maxim-grin! πŸ“£ Hey, it seems we don’t have your contributor details yet! You'll only have to do this once, and this is how we'll hire you on Upwork. Please follow these steps:

  1. Make sure you've read and understood the contributing guidelines.
  2. Get the email address used to login to your Expensify account. If you don't already have an Expensify account, create one here. If you have multiple accounts (e.g. one for testing), please use your main account email.
  3. Get the link to your Upwork profile. It's necessary because we only pay via Upwork. You can access it by logging in, and then clicking on your name. It'll look like this. If you don't already have an account, sign up for one here.
  4. Copy the format below and paste it in a comment on this issue. Replace the placeholder text with your actual details. Screen Shot 2022-11-16 at 4 42 54 PM Format:
    Contributor details
    Your Expensify account email: <REPLACE EMAIL HERE>
    Upwork Profile Link: <REPLACE LINK HERE>
maxim-grin commented 3 months ago

Hey I’m going to investigate why the payload is so big in Onyx storage. Possibly track what change exactly caused the problem. Then either revert that piece of change or use one of suggestions by @thienlnam

Contributor details Your Expensify account email: maxim.grin@gmail.com Upwork Profile Link: https://www.upwork.com/freelancers/~01fb7b172c01252917

melvin-bot[bot] commented 3 months ago

βœ… Contributor details stored successfully. Thank you for contributing to Expensify!

ShridharGoel commented 3 months ago

Proposal

Please re-state the problem that we are trying to solve in this issue.

We don't need to use text from reportAction, it would be better to use originalMessage.html.

What is the root cause of that problem?

New change.

text from message in reportAction is being used at multiple places.

What changes do you think we should make in order to solve the problem?

We have text defined here:

https://github.com/Expensify/App/blob/f1502291a14d4e15e04249b241109f146bdb512f/src/types/onyx/ReportAction.ts#L18-L19

Example usage:

https://github.com/Expensify/App/blob/f1502291a14d4e15e04249b241109f146bdb512f/src/components/ReportActionItem/ReportPreview.tsx#L173

We can change this to:

const parser = new ExpensiMark();
const actionMessage = parser.htmlToText(action.message?.[0]?.html ?? '');

Add the above in a common method getActionMessagePostParsing in ReportUtils. Similarly, check all usages and update them to use the method mentioned above.

Finally, we can remove text.

There's one instance of originalMessage?.html in ReportUtils.ts which also needs to be updated to use the common method.

if (ReportActionsUtils.isWhisperAction(reportAction)) {
    // Allow flagging welcome message whispers as they can be set by any room creator
    if (report?.description && !isCurrentUserAction && isOriginalMessageHaveHtml && `getActionMessagePostParsing(reportAction)` === report.description) {
        return true;
    }

    // Disallow flagging the rest of whisper as they are sent by us
    return false;
}
cubuspl42 commented 2 months ago

@ShridharGoel

Similarly, check all usages and update them

Are you saying to literally repeat this code snippet in all places? Couldn't we refactor the code to avoid this repetition?

As the scope of the issue is well-defined and rather narrow, I believe this part of the plan can be a part of the proposal.

@nkdengineer

Aren't you quoting browser-specific local notifications code? πŸ€” As I understand it, the ultimate goal is to optimize the payload size of remote push notifications.

ShridharGoel commented 2 months ago

Proposal

Updated. @cubuspl42 We can add a method in ReportUtils, updated the proposal.

cubuspl42 commented 2 months ago

@quinthar

Would you summarize the Expensify notifications architecture in a few sentences so that we can be more confident with proposal preparation and review?

As I understand that most (if not all?) notification processing on mobile Native is server-side (push-based), and we're talking about optimizing the pushed payload size. But I'm not 100% confident how that relates to the Onyx schema.

Also, there were some doubts about the scope...

I'm assuming here that we're only omitting the text from reportActions in urban airship native updates, if we're going to remove text in Pusher update too, then we need to populate the text in the Pusher report actions updates by htmlToText.

Would you clarify this too? My intuition was that we wanted to nuke all usage of the text property client-side, also removing it from the typing. But it would be good to be sure about it.

quinthar commented 2 months ago

Great question. I've updated the original post with a more detailed description of the problem and solutions. Thanks!

ShridharGoel commented 2 months ago

Proposal

Updated

quinthar commented 2 months ago

Updated the proposal again (sorry!!!) in light of message being in this weird one-element array. Thanks for your understanding and help in cleaning up this mess!

cubuspl42 commented 2 months ago

@nkdengineer I think your proposal shows more preparation. How is your capacity, though? Would you be able to start working on this within 24-48 hours?

cubuspl42 commented 2 months ago

I approve the proposal by @nkdengineer

C+ reviewed πŸŽ€ πŸ‘€ πŸŽ€

melvin-bot[bot] commented 2 months ago

Triggered auto assignment to @thienlnam, see https://stackoverflow.com/c/expensify/questions/7972 for more details.

melvin-bot[bot] commented 2 months ago

πŸ“£ @cubuspl42 πŸŽ‰ An offer has been automatically sent to your Upwork account for the Reviewer role πŸŽ‰ Thanks for contributing to the Expensify app!

Offer link Upwork job

melvin-bot[bot] commented 2 months ago

πŸ“£ @nkdengineer You have been assigned to this job! Please apply to the Upwork job and leave a comment on the Github issue letting us know when we can expect a PR to be ready for review πŸ§‘β€πŸ’» Once you apply to this job, your Upwork ID will be stored and you will be automatically hired for future jobs! Keep in mind: Code of Conduct | Contributing πŸ“–

cubuspl42 commented 2 months ago

Hm, it's likely because the issue is missing the "High priority" label. But I'm not sure if the "HIGH:" prefix and the "High priority" label represent the same concept πŸ€”

quinthar commented 2 months ago

Great work! What's your ETA for submitting the PR for review?

cubuspl42 commented 2 months ago

@nkdengineer Just so we're on the same page, phase 1 must be deployed to production first. Also, some time has to pass, so Native users have the time to update. So we're not blocked by phase 2 in any way.

quinthar commented 2 months ago

Great! @cubuspl42 what is your ETA for review?

cubuspl42 commented 2 months ago

I'm on it πŸ™‚

quinthar commented 2 months ago

Great, what is your ETA for review?

cubuspl42 commented 2 months ago

It was yesterday. I raised concerns about whether we actually covered the whole scope of the Phase 1. I even pinged you πŸ™‚ We can continue the dialogue on the PR.

melvin-bot[bot] commented 2 months ago

Triggered auto assignment to Contributor Plus for review of internal employee PR - @parasharrajat (Internal)

mallenexpensify commented 2 months ago

@parasharrajat reassigning, please take over as C+. If you don't have bandwidth, unassign yourself. Thanks. PR is

parasharrajat commented 2 months ago

Sorry, I don't have the bandwidth to work on this. I was OOO since Thursday. let me request someone to push this forward.

parasharrajat commented 2 months ago

@c3024 will review this.

mallenexpensify commented 2 months ago

Thanks @parasharrajat , πŸ‘‹ @c3024 @c3024 commented on the PR earlier today

melvin-bot[bot] commented 1 month ago

This issue has not been updated in over 15 days. @thienlnam, @c3024, @nkdengineer eroding to Monthly issue.

P.S. Is everyone reading this sure this is really a near-term priority? Be brave: if you disagree, go ahead and close it out. If someone disagrees, they'll reopen it, and if they don't: one less thing to do!

mallenexpensify commented 1 month ago

@c3024 looks like the PR is awaiting an action from you

c3024 commented 1 month ago

@thienlnam @quinthar

The issue talks about only text and html

Phase 1 (External / clientside): Stop using originalMessage, start using array-message Update every instance of originalMessage.html to use message.html || message[0].html Update every instance of message.text to dynamically strip the text from message.html || message[0].html

but originalMessage has many more fields like reason, resolution, IOUTransactionID, events, oldName, newName, participantAccountIDs, etc. which are not present in message. So this phase 1 should be to update every instance of originalMessage (not just fields of html or text) with array message

Also in phase 2

Phase 2 (Internal / serverside): Once we've confirmed the client no longer uses originalMessage or message.text: Stop sending originalMessage Start sending message without an array

message should be sent including all the above mentioned other fields to completely deprecate originalMessage.

Can you please update phase 1 and 2 of the issue description to include these?

melvin-bot[bot] commented 1 month ago

Triggered auto assignment to @puneetlath (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.

mallenexpensify commented 1 month ago

Added Bug to assign a BZ. @quinthar @thienlnam , can you address @c3024 's request above when you have a min https://github.com/Expensify/App/issues/39797#issuecomment-2130753109

thienlnam commented 1 month ago

I've updated the description

roryabraham commented 1 month ago

I did some exploratory work on this topic in https://github.com/Expensify/App/pull/41872 - maybe useful for you @nkdengineer @c3024 @thienlnam.

The main idea is that we make ReportAction take a generic param for the type, and that determines the originalMessage it will have. This helps ensure that we correctly and safely narrow the ReportAction type to ensure the originalMessage is as we expect before trying to access any of its properties

roryabraham commented 1 month ago

self-assigning as I've been pulled into the PR for review

melvin-bot[bot] commented 1 month ago

@puneetlath, @thienlnam, @roryabraham, @c3024, @nkdengineer Whoops! This issue is 2 days overdue. Let's get this updated quick!

melvin-bot[bot] commented 1 month ago

@puneetlath, @thienlnam, @roryabraham, @c3024, @nkdengineer Huh... This is 4 days overdue. Who can take care of this?

melvin-bot[bot] commented 3 weeks ago

@puneetlath, @thienlnam, @roryabraham, @c3024, @nkdengineer Now this issue is 8 days overdue. Are you sure this should be a Daily? Feel free to change it!

puneetlath commented 3 weeks ago

@nkdengineer @c3024 how is this going? Are we almost done?

muttmuure commented 2 weeks ago

Is this being worked on?

thienlnam commented 2 weeks ago

Still in review - pending a review from @roryabraham. Dropping my assignment since I'm not adding much value as a reviewer here

melvin-bot[bot] commented 2 weeks ago

⚠️ Looks like this issue was linked to a Deploy Blocker here

If you are the assigned CME please investigate whether the linked PR caused a regression and leave a comment with the results.

If a regression has occurred and you are the assigned CM follow the instructions here.

If this regression could have been avoided please consider also proposing a recommendation to the PR checklist so that we can avoid it in the future.

melvin-bot[bot] commented 1 week ago

⚠️ Looks like this issue was linked to a Deploy Blocker here

If you are the assigned CME please investigate whether the linked PR caused a regression and leave a comment with the results.

If a regression has occurred and you are the assigned CM follow the instructions here.

If this regression could have been avoided please consider also proposing a recommendation to the PR checklist so that we can avoid it in the future.

melvin-bot[bot] commented 1 week ago

⚠️ Looks like this issue was linked to a Deploy Blocker here

If you are the assigned CME please investigate whether the linked PR caused a regression and leave a comment with the results.

If a regression has occurred and you are the assigned CM follow the instructions here.

If this regression could have been avoided please consider also proposing a recommendation to the PR checklist so that we can avoid it in the future.

melvin-bot[bot] commented 1 week ago

⚠️ Looks like this issue was linked to a Deploy Blocker here

If you are the assigned CME please investigate whether the linked PR caused a regression and leave a comment with the results.

If a regression has occurred and you are the assigned CM follow the instructions here.

If this regression could have been avoided please consider also proposing a recommendation to the PR checklist so that we can avoid it in the future.

melvin-bot[bot] commented 1 week ago

⚠️ Looks like this issue was linked to a Deploy Blocker here

If you are the assigned CME please investigate whether the linked PR caused a regression and leave a comment with the results.

If a regression has occurred and you are the assigned CM follow the instructions here.

If this regression could have been avoided please consider also proposing a recommendation to the PR checklist so that we can avoid it in the future.

melvin-bot[bot] commented 1 week ago

Reviewing label has been removed, please complete the "BugZero Checklist".