Skip to content
All work

Case study. Next.js / 3D / DevOps.

Mission Control

One screen for the health of every app, job and deployment you run

Role
Full-stack: source adapters, grading rules, alerting, auth, UX research and onboarding
Status
v1.1.0MITpersonal
Context
2026
Consoles, one sign-in
4

Posit Connect, shinyapps.io, Vercel, Databricks

Refresh, per source
30 s

cache time-to-live

Failure to phone push
60 s

ntfy alert engine

Unit tests on the rules
118

plus Playwright on two browsers

Mission Control Overview: a red banner reading "8 assets need attention", one row per source with counts and freshness, and the list of failed and warning assets
  • A source tab: status row reading Failing, filter chips, category sections and one glowing failed card
  • The log modal showing the last run's output with Copy logs
  • The same source tab in the light theme
  • The optional 3D map: one node per asset, failing ones larger and glowing
  • The Overview on a phone: banner, source rows and the needs-attention list stacked

The problem

Production analytics rarely live in one place: Shiny apps and scheduled jobs on a corporate Posit Connect server, personal apps on shinyapps.io, web apps on Vercel, pipelines on Databricks, each with its own console and none of them calling you when something breaks. Checking on everything meant four logins and a dig through run histories, so the people who depend on the apps usually found the failures first.

Architecture

  1. 1.Fetch
    • Posit Connect · shinyapps.io
    • Vercel · Databricks
  2. 2.Cache
    • 30 s per source
    • Last good copy if down
  3. 3.Grade
    • One Asset shape
    • Healthy · Warning · Failed · Idle
  4. 4.Show
    • Overview · tabs · logs
    • Acknowledge with Undo
  5. 5.Alert
    • Desktop + badge
    • ntfy push on transitions
Mission Control — how a status is madeStatus is colour, icon and word together, with a reason line; freshness comes from the data, never the clock.

What it does

Mission Control reads the four consoles with your own tokens, normalises everything into one Asset shape and grades each one Healthy, Warning, Failed or Idle with a one-line reason. The home page is an Overview: a fleet banner with one sentence, one row per source with honest freshness, and the list of what needs attention with logs one click away.

Numbers you can trust

  • Freshness comes from the data: 'Checked 2m ago · Data from 14:02'. A console that cannot be reached shows its last good copy with the real fetch time; it never reads 'just now'
  • Every count has its total and scope; every status is colour, icon and word; every empty state says why (filtered out, nothing on the source, request failed) and offers the next action
  • Sample data is labelled everywhere and never alerts; the grading rules are pure functions with 118 unit tests

Alerts and acknowledgement

  • A server-side engine checks every minute and pushes to your phone through ntfy on the change into Failed, then once on recovery; a Postgres baseline means restarts neither miss nor repeat transitions
  • Desktop notification, sound and a tab badge while the dashboard is open
  • Acknowledge an asset from its card for 15 minutes to 24 hours with a note; the toast offers Undo and the status stays visible. Admins can Run now on Connect jobs behind a confirmation that names the job

Designed with a UX audit, shipped with a guide

  • A 16-finding evaluation against data-app UX contracts (status first, KPI with reference and n, honest freshness, typed empty states, WCAG 2.2) drove version 1.1: a calmer glass cockpit where only failures glow
  • A public single-file onboarding page explains why the dashboard exists and walks new users through reading status, finding failures, acting and setting up alerts, with checkpoints that track progress
  • Credentialed access, two roles, server-side sessions with instant revocation, lockout plus per-IP throttles, a full audit log, CSP and hardened headers

Stack

  • Next.js 15
  • React 19
  • TypeScript
  • TanStack Query
  • React Three Fiber
  • Auth.js v5
  • Prisma
  • PostgreSQL (Neon)
  • ntfy
  • Playwright

Related work