Job table as source of truth
Each automation run is a row with status, attempts, and payload summary. The UI never invents state the database does not know.
Automation
An operations team moved data between tools by hand. We built a console where approved jobs run with logs, retries, and a human pause switch.
Nightly copy-paste between CRM, spreadsheets, and a billing tool created inconsistent records. Failures were discovered days later when a customer noticed. Nobody could answer which run succeeded without reading chat history.
Each automation run is a row with status, attempts, and payload summary. The UI never invents state the database does not know.
Retries use idempotency keys so a double-click or crashed worker does not create duplicate CRM notes.
Writes that email customers or alter billing fields require an explicit confirm step until error rates are boring.
Next.js admin UI over API routes. Prisma job and attempt models. Workers claim jobs with leasing. Zod validates payloads at the edge. Structured logs include job id for traceability.
We implemented three high-frequency jobs first: contact sync, status reconciliation, and nightly digest. The console shows queue depth, last success, and failure reasons in plain language. Operators can pause a job type without redeploying.
Manual transfers dropped for the covered flows. Failures surface the same day with enough context to retry or escalate. The team gained a path to add jobs without inventing a new ops ritual each time.
Candidates include webhook-driven triggers, richer dead-letter handling, and per-tenant concurrency budgets.
Screenshots
Tell us about the workflow, the tools involved, and what “done” means for the first release.
Talk about an ops console