Client work · 2026
Court Operations Platform
A web platform that reads scanned court notices with OCR, links each one to the right client case, gives every client their own court date and plans each attorney's day in court. Built with a team that ships through pull requests and CI.
- Type
- Client work
- Year
- 2026
- Stack
- Next.jsTypeScriptPostgreSQLOCRCI
The client and real screens are confidential, so this case study is anonymized and uses diagrams instead of screenshots.
- unit tests in the codebase
- ~0unit tests in the codebase
- test layers: unit, real PostgreSQL, end-to-end
- 0test layers: unit, real PostgreSQL, end-to-end
- milestones owned end to end
- 0milestones owned end to end
Problem & context
A law firm's court dates arrive as scanned court notices. Staff read them by hand and had to keep dates, times, Zoom details and calendars right for many clients and attorneys. One notice could list two clients, and the old system gave them one shared hearing and one calendar event naming both, so a change for one client could affect the other.
My contribution
- Owned milestones end to end, inside a team that uses pull requests and CI.
- Per diem court scheduling: attorneys say which courts they can cover, and admins assign them.
- Attorney day papers: one place for each attorney's notes and documents for the day.
- One court date per client, replacing shared hearings.
- Night-before client messages (in progress): a view grouped by client, an editable SMS and email draft, and an optional automatic email.
- User guides, numbered test cases and walkthrough videos for each milestone.
How it works
Key technical work
Per diem scheduling
Attorneys respond for each court and admins assign coverage, so every court day has a clear owner.
Attorney day papers
Each attorney gets the notes and papers for their court day in one place.
One court date per client
Every client now has their own hearing and calendar entry, even when a notice lists several clients.
Night-before messages
Staff can review and edit the SMS or email each client receives before their court date. Automatic sending is optional and off by default.
Hard problems & how I solved them
- 01
Splitting shared hearings without losing anything
Moving to one hearing per client needed a database migration and a script that splits existing hearings without losing a single ticket, result, date history, attorney or calendar entry. I tested it from a clean database and made each migration step safe to run while the site is live.
- 02
Duplicate-free calendar entries
Each client's court date gets exactly one calendar entry. A change to the Zoom link or room adds a “Change in appearance” entry instead of a second copy of the event.
- 03
Two people editing at once
Linking a ticket and recording a result are serialized with database locks, so two staff members can't create two hearings or overwrite each other's result.
- 04
Never sending an email twice
The automatic email takes a claim record before it sends, so a crash or a second worker can't send it again. It never stores the message text or the passcode.
Testing & validation
- Around 4,000 unit tests across the codebase.
- Tests that run against a real PostgreSQL database, not a stand-in.
- End-to-end browser tests of the main flows.
- CI runs type checks, lint and safety rules for database migrations on every pull request.
- A numbered test-case list for each milestone, plus an AI-assisted risk and edge-case review before each PR.
Outcome & limitations
My milestones, including one court date per client and per diem scheduling, are merged into the team's development branch.
Client night-before messages are still in progress.