Flow
Narrowing the scope for each store
What changes between the original request and each store's run.
1Copy the filters
Keep the tags and search text exactly as the person set them
2Replace the stores
Swap the full store list for the single store being served
3Name the attempt
Shared prefix from the click plus the store, so runs group but stay distinguishable
4Run and attach
The workflow generates one attachment that holds only that store's rows
Flow
Outcome to status mapping
Each outcome of a send and the status my route returns for it.
1Nothing failed, something sent
Success, with per-store results and counts
2Any store failed
Bad gateway, error text names the failing stores
3Nothing sent
Conflict, because from the person's view nothing was delivered
4Store has no workflow
Conflict before any send, listing the uncovered stores
5No key or no stores
Forbidden with a specific code, or a client error
Every store has its own list in my task tracker, and no store team wants a PDF full of another store's discounts. That's what shaped the new send button on my sale report.
The report shows what's on sale in the stores you pick, with tag filters and a search box. The new button sends that same view to the tracker. Before it does anything, it checks for the person's own tracker key and at least one store. If the key is missing, it sends back a forbidden error with a specific code and a message saying to set your key.
Workflows own the delivery
I don't put destinations in the route. A saved workflow says which list to use, what the task says, which file to attach, and who gets assigned. Mine attaches a PDF, updates a task with the same name instead of making a new one, and starts out disabled. Its rules name the stores it covers, and a store with nothing to send gets skipped. The script that saves it does a dry run unless you go out of your way to apply it.
Why one store without a workflow stops the whole click
When more than one workflow exists, the picker gets an extra "all selected stores" choice. Picking it splits the job. First, match every store to a workflow. If any store has none, stop and name it. Don't send to the stores you can and shrug about the rest. Then each store runs by itself.
Each store gets its own run, with the store list cut down to that one store.
Each team's PDF now holds only its own rows. Give each run a label from the click plus the store so you can trace it later.
How the counts become a status code
Count sent, skipped and failed, and pick the status from the counts. Any failure is an error that names the stores. Nothing sent is a conflict. Otherwise it's a success, and the button says how many stores went and how many were skipped.
The timeout that left run records stuck
The same day, I fixed a bug where a timeout in the tracker call skipped the code that closes out the run records, so they looked stuck forever. Now any throw becomes a normal failure and the records close.
What I'd still fix
Sends go one at a time with no undo, so a failure halfway leaves the earlier stores sent. A long list can also hit the request timeout. Repeated store IDs aren't removed, and if two workflows claim one store, the first wins without a warning.