Back to Feed

Building a Real-Time Operations Dashboard

I built a dashboard to watch my AI work. Here's how it works, what broke, and how I fixed it.

The Problem: Working Blind

When KARA works autonomously—generating content, researching topics, coding tools—I'm not there to watch. She's running scripts at 4 AM, making decisions I don't see, creating outputs I review hours later.

The old workflow was chaos:

  • Files scattered across folders I forgot existed
  • No visibility into what KARA decided vs. what I asked for
  • No approval gate before deployment
  • No way to track costs or usage

The moment I knew this was broken: I asked KARA to make a minor CSS update. She deployed three different "fixed" versions to production—none of them actually worked. I had to manually revert everything.

The Solution: KARA Command Dashboard

The dashboard has five core views:

1. Observatory (System Overview)

  • Real-time uptime counter (from Supabase, not browser)
  • Service health status (Supabase, Telegram bot, gateway)
  • Aggregated stats (tasks, shifts, content ready)

2. Kanban Board (Task Management)

  • Drag-and-drop between columns
  • Create/edit/delete tasks
  • Project filtering (Tech Tips, Magic Shop, Dreamwav)
  • Priority levels with visual indicators

3. Shift Output (Review Queue)

  • Calendar view of all autonomous work
  • Approve/reject/partial-approve workflows
  • Metrics tracking (tokens used, cost, duration)
  • Output previews before deployment

4. Content Queue (Blog Pipeline)

  • Draft → Review → Approved → Published flow
  • SEO editing before publish
  • Direct publish action from dashboard

The Tech Stack

What I chose:

  • Frontend: Vanilla HTML + Tailwind CSS + Lucide icons
  • Auth: Supabase Auth (JWT tokens, row-level security)
  • Database: Supabase PostgreSQL (real-time sync)
  • Hosting: Ionos SFTP (simple, cheap, works)

Why no frameworks?

I wanted KARA to be able to iterate on this without complex build processes. A static HTML file she can edit directly means faster iteration. No webpack, no npm install, no "it works on my machine."

What Went Wrong (And How I Fixed It)

Bug 1: Activity Log Empty

Symptom: Observatory showed "Loading from Supabase..." forever.

Root cause: The system_activity table was empty. The code expected pre-populated activity data.

Fix: Query actual tables (shifts, kanban_tasks, blog_posts) and build the activity feed dynamically. Now it always reflects real state.

Bug 2: Kanban Moves Not Saving

Symptom: Drag a task to "Done", refresh the page, back to "In Progress."

Root cause: The adrop event updated Supabase but didn't update the local state array. On re-render, it pulled stale data.

Fix: Update local array immediately after successful Supabase write:

// After Supabase update succeeds...
const task = allTasks.find(t => t.id === draggedTaskId);
    if (task) task.status = newStatus;
    renderTasks();

Bug 3: Blog Link Broken

Symptom: Clicking "Tech Tips Blog" from dashboard gave 404.

Root cause: Relative path ../tech-tips/blog/ worked locally but not deployed. The dashboard is at mykarabot.info, blog is at mykarabot.online/blog/.

Fix: Absolute URLs.

The Result

Now when KARA works, I can:

  1. See what she's working on in real-time
  2. Review her outputs before they go live
  3. Track costs and token usage per task
  4. Approve or reject with specific feedback

The dashboard didn't just solve a coordination problem. It changed how I think about AI collaboration—moving from "fire and forget" to "continuous visibility."

Want to build your own? The key insight: build what you need, not what you think you might need. I started with just a kanban board and added views as problems emerged. The dashboard evolved through use, not through planning.