The Board v0.1.5: Dispatch UX Overhaul
v0.1.5 is the biggest dispatch UX update since the original build. The core workflow — stepping through a roster, triaging offers, moving on — got rethought from scratch. Alongside that: a job-scoped replies page, a CSV export that actually reflects how dispatch works, SMS reliability fixes, and a round of infrastructure hardening that's been on the list for a while.
Context
The Board has run in production at a stagehands' union local — dispatchers using it to send offers, track responses, and fill positions for real shows. At that scale, the old "click into a worker, decide, click back" flow shows its friction fast. This release is largely about making that loop faster without changing what's actually happening underneath.
What shipped
Dispatch UX
- New tinder-style roster dispatch mode with a fixed bottom action bar — accept, decline, or mark no-response without leaving the current view
- Prev/next worker navigation with directional slide transitions and fade animations — stepping through the roster feels like paging, not clicking around
- Keyboard shortcuts for offer triage: standard accept/decline keys plus T to mark timeout/no-response
- Adjacent workers prefetched in the background so navigation stays instant even on slower connections
- Pending quick-filter chip added to the roster header for fast access to workers awaiting a response
- Streamlined compose drawer UX in the worker conversation panel
Reply triage and bulk operations
- Job-scoped Replies triage page for dispatch — see all unprocessed replies for a job in one place instead of hunting through conversations
- Bulk cancel a date with a worker notification flow — cancel one date across the job and let workers know automatically
- Full job activity log now visible for large and all-member calls in the dispatch log
Roster CSV export
- Call-type columns replace the old Day 1..13 columns — the export now maps to how dispatch actually thinks about a job, not just a date range
- Conflict detection in the CSV is now time-aware per call type, including overnight shift handling
- Offer timestamps converted from UTC to Pacific time in the export
- Response column stays blank for still-pending offers instead of showing a placeholder
- Offer timestamp only appears on positions that were actually offered
SMS reliability
- Prevented duplicate offers from concurrent batch sends — a race condition that could fire multiple offers to the same worker
- Send button disabled while a batch is active; concurrent-batch rejection is now softer rather than hard-erroring
- YakChat webhook calls staggered with retry on network errors
- Default header and footer notes on SMS templates now blank — no more boilerplate text auto-injected into messages
- Offer and confirmation message formatting aligned for consistency
- Calling sheet date parsing repaired alongside the template defaults fix
Roster fixes and infrastructure
- Fixed recurring unavailability falsely blocking workers in the roster — a long-standing issue that showed workers as unavailable when they weren't
- Database backups moved from GitHub artifact storage to Cloudflare R2, with gzip compression, SQLite header validation, and stale incomplete-backup cleanup on startup
- Database maintenance endpoint added with admin dashboard UI for on-demand health checks
- Baseline migrations to skip legacy migration steps on fresh installs, with comprehensive schema alignment for new deployments
- Multi-day vacations rendered correctly as all-day blocks instead of garbage time bands on the worker timeline
- Hard availability blocks now show as a blocked badge instead of "Available"
Total scope for this release: 16 features and around 50 bug fixes. A lot of the fixes are in the CSV, the migration system, and the SMS layer — areas where the details matter more than the headlines.
Why it matters
The dispatch UX changes are the most visible thing here, but the reliability work underneath is probably just as important. Duplicate SMS offers going out to workers, recurring unavailability incorrectly blocking someone from being offered a call, backups not being validated before they're stored — these are the kinds of bugs that erode trust in a production tool. Getting them fixed matters more than any new feature.
The CSV rework is worth calling out separately. The old Day 1..13 column format was a structural mismatch with how dispatch actually works. Call types — load-in, show, strike — are what matter, not raw date indices. The new format is more useful to anyone reading the export after the fact.
What's next
The dispatch UX is in a much better place now but there's still more to do in the triage flow. I'm also continuing to work through the edges in the CS integration as they surface. The infrastructure work this cycle — R2 backups, maintenance endpoints, baseline migrations — sets up better footing for the next stretch of features.
The light stays on.