I’ve been reading about Cloudflare’s Durable Objects feature, effectively a key-value store or light database that persists even when a Worker has gone back to sleep. There’s a fantastic YouTube tutorial by one of their dev-rel guys where he spins up a real time video chat on the free tier and then joins just by hitting the URL. Pretty great!
So it got me thinking today after I was pondering more on the flow of handling an incoming notice from a court, What happens when two users are on the same case? Which, honestly, happens all the time: I deliberately copy my secretary on the NEFs in every federal court where I have filing privileges, because she’ll get the case documents and download them to our document management system (thank God because I hate using it). If we were both DocketView customers, my Email Worker would get two identical emails with different users but the same URL for the same document filing in the same case.
Wouldn’t it make more sense to parse the email, check to see if it had been already downloaded or logged into the database, and if it has then just associate the user to the case information (unless that’s already happened, in which case do nothing). This will save on compute time in not having to re-download a PDF, or series of PDFs for motions that have attachments and exhibits and a proof of service. And it saves on storage space since I’m only saving one copy of the PDFs themselves. And I have fewer database writes and reads, since I can simply check on the users-cases table and see which ones go with which user.
And yes, the Worker could just consult the database and see. But again, that’s expensive in terms of using up my database reads for the month and I believe also quite slow and probably stresses the database if there’s a lot of action at that time. It also just sort of offends my sense of efficiency, I’d like to be more elegant and thoughtful generally.
The ready solution seems to be a Durable Object. Instead of writing to the database, I’ll have the Email Worker parse the incoming email and extract that data to a JavaScript class and have the DO take that same class and return the value, checking it against the database to see if it’s already written. Meanwhile the Email Worker is off to handle the next incoming email or has just gone to sleep. If the DO hasn’t seen this document before, it’ll add the information from those classes.
This was actually suggested by Claude earlier when I asked it a random question about Durable Objects a couple of week ago, after seeing some tweets about it. Instead of firing up a new chat, I apparently (and almost certainly accidentally) asked it inside my DocketView Project so it assumed I was thinking of doing something with a DO.
Here’s Claude’s suggestion:
Each active court case could have its own Durable Object instance, identified by a combination of the court and case number. This object would maintain the current state of the case's document list and coordinate all updates to it.
When your email Worker receives a new NEF, it would:
- Route the request to the appropriate case's Durable Object
- The Durable Object would validate that this document hasn't already been processed
- Coordinate the storage of the PDF and metadata
- Update the case's document index atomically
This approach provides several benefits. First, it ensures consistency - you'll never have duplicate document entries or lost updates. Second, it allows for real-time features - if you later want to add functionality like notifying users when new documents arrive, the Durable Object can maintain WebSocket connections to interested clients. Third, it provides a natural way to handle rate limiting and queuing if needed.
I didn’t do anything with this suggestion back then but I saw it today in my notes and spent an hour or so having Claude figure it out. Had to rewrite the original Email Worker, which made it simpler and shorter, and spin up a new Durable Object. Also had to adjust the database schema because it didn’t quite mesh. An underrated feature of the Claude Projects is uploading the Email Worker code, the database schema, and the Wrangler.toml file. So from my first prompt, Claude had a pretty decent context already. Makes the copy-pasta easier if it already knows your userID, for example.
After quite a bit of testing and tweaking, it’s working now. One step closer to a finished back-end! My next module is the Worker to handle downloading the PDFs, checking the database, and saving to the R2 bucket. Shouldn’t be too hard I’m anticipating, but we shall see. I still need to integrate Stripe and then dust off my prototype of the front end. I just want to make sure it works first, though. Just automatically downloading PDFs would be a huge help.