Approval flows look simple in product meetings, then get weird fast in code. A reviewer clicks Approve, the UI updates, a follow-up email should go out, and somehow the same action fires twice after a refetch or tab restore. I have seen this happen in otherwise clean React apps, and it nearly always comes from mixing user intent with rendering side effects.
The fix that holds up best is boring in a good way: treat "approve request" as an explicit event, then let the backend own whether an email should be sent. Once I started separating those two concerns, the frontend got easier to reason about and the backend logs started making sense again.
Why approval flows trigger duplicate emails
The risky version usually looks like this:
User clicks Approve.






