How would you prevent stale results in an async upload job UI?

I have a programming question about modeling state for a long-running browser workflow.

The flow is:

  1. User selects one local media file.
  2. Client uploads it and receives a server-side job id.
  3. Client polls until processing is done or failed.
  4. Result screen shows two generated preview files.
  5. Save controls should be enabled only for the current completed job.

The bug I want to avoid is stale UI state. For example, a user starts job A, then quickly starts job B. If job A finishes after job B has started, the preview/save controls must not show job A’s outputs as if they belonged to the current file.

My current approach is to store a single active job object on the client:

  • uploadId
  • jobId
  • sourceFileName
  • status: idle, uploading, processing, completed, failed
  • startedAt
  • completedAt
  • outputs

Every polling response is ignored unless its jobId matches the active jobId. Starting a new upload clears outputs and creates a new active job. Save buttons are disabled unless status is completed and both expected outputs belong to the active job. ai-vocal-remover.com

Is that enough, or would you also add a monotonically increasing client request version so late promises cannot update state even when a job id is accidentally reused or a component remounts during polling?

I am especially interested in simple patterns for keeping async UI state correct without overengineering it. No link or product review is needed; this is a state-management question for an upload, processing, preview, and save flow.