Workflow Tracker. Hundreds of event tasks, zero silently dropped.
- Status
- Live — the company’s working tool
- Client
- M4U Events (~30 staff)
- Stack
- Next.js · Prisma · Postgres · Slack API · QStash
- Scale
- 24 API routes · 14 data models · 126-test gate
- Year
- 2026

An events company runs on checklists: load-in, sound check, photo proof, teardown — per event, per crew, every weekend. Spreadsheets and memory meant tasks slipped silently, and the founder chased people by text. The failure mode wasn’t missed work — it was missed work nobody noticed until the event.
- ◆A real workflow engine — tasks with linear prerequisites and branching triggers: completing one task can spawn or unblock others, transactionally.
- ◆Photo verification — some tasks require photo proof, converted server-side and stored in a private bucket.
- ◆A Slack bot that escalates — overdue tasks DM the owner; keep ignoring them and the tone escalates, with per-rule throttles so nobody gets spammed.
- ◆Three-role access control — admin / manager / staff scopes enforced on every route, with audit-logged edits.
- ◆Booking sync — bookings flow in from the company’s booking platform, with a dry-run mode that reports what it would create before it touches anything.
- 1A booking arrives — its event gets a workflow from a template
- 2Tasks unlock as prerequisites complete; triggers spawn follow-ons
- 3Owners see their queue; some tasks demand photo proof
- 4An hourly cron sweeps for overdue work → Slack escalation
- 5A dead-man switch alerts if the sweep itself ever stops running
Concurrency and trust. Two people closing related tasks at once must not corrupt the chain, so status updates are TOCTOU-safe — the database enforces the precondition in the same statement that applies the change. Access control went through a real IDOR pass (can user A touch user B’s task by guessing an ID? — now provably no).
And because the escalation bot messages real staff, its inputs are sanitized against Slack-injection and its cron is watched by a dead-man switch: if the hourly sweep stops, the system tells on itself instead of failing silently.
- ✓126-test gate on the engine, scope policy, and sync paths.
- ✓Booking-sync dry run against live data: 89 fetched → 17 to create → 42 held for review → 0 errors.
- ✓Write-only audit trail on every edit.
Live as the company’s working tool at its own domain. The founder stopped being the escalation system — the software nags so leadership doesn’t have to.
I reviewed the engine design change by change across 90 commits, each one gated on the test suite. Claude Code wrote the code. How I work →
Run an events business? I built Ajna for you.
AI automation for wedding & event vendors — quotes in minutes instead of days, a human always in the loop.