Agency operations dashboard
A dashboard for an agency's WordPress client sites, with a connector plugin on each one and the hosting accounts behind them.
- Role
- Lead developer
- Scale
- About 25 client sites across 26 cPanel accounts
- Stack
- Laravel 12, Next.js 16, React 19, custom WordPress connector plugin, WHM and cPanel APIs, Docker on Hetzner
- Client
- A Dallas digital agency, name withheld
The situation
About 25 client sites on shared hosts, with outages found by clients and plugin updates waiting for someone to notice them.
The sites needed one place to check their health, and a safe way to act on them without FTP or SSH.
What I built
- A WordPress connector plugin on every site. Requests are signed with HMAC-SHA256, with a 5-minute timestamp window and replay protection. It handles updates, restore points, cache purges and one-click login with single-use tokens.
- Uptime and SSL checks every 5 minutes, pending updates every 15, and disk, bandwidth and inode use from WHM.
- A 3-strike rule that stopped false alert storms, plus a guard that raises one connectivity alert when half the fleet fails at once.
- AI blog drafts that are scored, re-prompted on weak spots and pushed to WordPress as drafts, with auto-publish behind a quality score.
- Login by emailed one-time code: no passwords, lockout after 5 wrong codes, and every action in an audit log.
- An emergency PHP CVE mitigation across 26 of 27 hosting accounts in one pass, with a backup per account and a probe to confirm it applied.
What was hard
A job that crashed silently for a month
A background job needed 186 MB against a 128 MB limit and died with no error logged. It had blocked every maintenance run, with 435 plugin updates stuck across 23 sites. I fixed it and added a test that pins it.
An update that reported success and did nothing
The update call said it had worked while installing nothing and switching the plugin off. Now I check an update against the version on disk and the rendered page, not the API's answer.
100% uptime during a four-day outage
The host's block had whitelisted our monitor while the public saw a 403. I traced the block to a malware binary hidden outside the web root, removed it and checked all 26 accounts.