This is a neat use of Cloudflare workers. Is there a reason you chose D1 and KV over using Durable Objects?
I mostly use KV for storing flags specific to each project (which gets replicated automatically). Everything else goes to D1 (replication isn't needed here).
Cloudflare queues was something I might consider for async workflows.