Creating workflows for every update of an entity

We handle users and contracts in our system, for every user there are multiple contracts …
On every contract change there might be side-effects like re-calculating an aggregated status on the user record based on the new list of contracts that he holds.

Some of the above re calculations might required contracting a 3rd party system and we wanted to have durability and asynchronicity to speed up the update process (it comes in bulk imports).
the bulk import is its own workflow and a single activity inside is to update each users contracts, which in turn will launch a contract-updated workflow for every one.

We have decided to launch a workflow per contract with the ID (contract-updated-123-445-65566)
we missed 2 facts (that are slightly connected):

  1. if another update comes while a workflow is running we will skip it since a workflow with the same id is already running
  2. if we have two different contract updating for a single user the will launch 2 separate workflows that will cause a race condition with regards who updates to which status.

Obviously the design is flawed, but i wonder how would you re-desing it.
I know Temporal does not support FIFO queueing of workflows (nor is design to…)
I really would like to avoid adding more components into the overall system like Rabbit, or SQS …

I had some thoughts … i will share them but i would really like your feedback first ! Thanks!

Send all signals to the user workflow and let it sequence child workflows according to whatever business logic you need. The bulk import would also signal each user workflow.

So let me see if I understood …
You suggest to use signal to a user workflow … so I assume we would use signal with start because we will not keep all users in our systems as running workflows in wait mode for signals …

And the import workflow should use signal with start for a user , the message will include the required data

The signal will be sent to the channel so if there are multiple updates we could process them one by one waiting on the activity to finnish. While allowing us handling all updates concurrently between different users

Am I correct assuming that signal Receive will block like a simple read from a channel ? So I would not run 2 update activities concurrently?

Yes, Channel.Receive blocks the same way normal go-channel reads do. Consider using ReceiveWithTimeout if you want to block a limited time.