← all projects
Full-Stack App

Watchdog

Real-time uptime monitoring platform with SCADA-inspired dashboard. Scheduled HTTP health checks, consecutive failure tracking, and service lifecycle management.

Full-stack monitoring tool with 15 API endpoints, in-process timer engine for scheduled checks, and industrial dark-themed dashboard with telemetry and diagnostics.

React
TypeScript
Node.js
Express
MongoDB
Tailwind

Problem Statement

Developers running HTTP services need to know the moment an endpoint goes down — but most uptime tools are either heavyweight SaaS with per-monitor pricing or require standing up Prometheus/Grafana-style infrastructure. The need: a self-hostable, no-friction monitor that schedules health checks, tracks failures intelligently (one blip ≠ an outage), and shows it all on a dashboard you'd actually want to look at.

Proposed Solution

Watchdog is a full-stack uptime monitor. You add an endpoint (method, headers, body, interval), and the backend schedules recurring HTTP checks, records every result, and escalates status through up → warning → down based on consecutive failures rather than a single miss. The frontend is a React 19 dashboard with a deliberately distinctive SCADA / industrial aesthetic — neon-green-on-black, telemetry panels, response-time charts, and incident logs.

Full Solution Details

  • Service lifecycle — create (3-step wizard: endpoint → settings → confirm), test-before-create, edit, pause/resume, delete (with history cleanup).
  • Monitoring engine — on boot, loads all active services and starts one setInterval per service, tracked in a Map<nodeId, Timeout>. Each tick fires the configured HTTP request, records a HealthCheck document (status code, response time, success/fail), increments consecutive-failure count, flips to warning at 2 and down at threshold, and resets on success.
  • Dashboard — system health matrix, telemetry, diagnostics, and alerts, cached 30s.
  • Service detail — metrics, response-time chart, full health-check log, incidents.
  • Auth — register (with password-strength meter), login, JWT sessions.

Technical Documentation

Backend — Node + TypeScript + Express 5 + MongoDB (Mongoose 9), built as a strict 4-layer architecture: Controller → Service → Repository → Model. Services return a ServiceResult (ServiceSuccess<T> | ServiceError) and never throw — controllers never wrap service calls in try/catch, which keeps the HTTP layer thin and error handling uniform. JWT + bcrypt auth, express-validator request chains, node-cache for the 30s dashboard TTL, rate limiting, and graceful shutdown that stops all timers. 15 REST endpoints.

Frontend — React 19 + Vite + TypeScript on Feature-Sliced Design (features/{auth,dashboard,services,entrypoint} each with api/ hooks/ screen/parts/ types/, plus shared/ and ui/ shells). All HTTP goes through a single typed apiClient; all localStorage through a namespaced storageAdapter; all Lucide icons through one @icons re-export. No global state library — React state + context + TanStack Query's cache, with mutations invalidating related query keys to keep views in sync. Conditional rendering uses the author's own Meemaw <Show> component instead of ternaries. Theme is Tailwind CSS v4 via the @theme directive; GSAP + three.js power the industrial visuals.

Tech Stack

React 19, TypeScript, Vite, Tailwind CSS v4, TanStack Query, Meemaw, GSAP, three.js (frontend); Node.js, Express 5, TypeScript, MongoDB/Mongoose 9, JWT, bcrypt, node-cache, express-validator (backend).

System Design

            ┌──────────────── Frontend (React 19, FSD) ────────────────┐
            │  apiClient ── TanStack Query cache ── SCADA dashboard     │
            └──────────────────────────┬───────────────────────────────┘
                                        │ JWT
                                        ▼
   Controller → Service (ServiceResult) → Repository → Mongoose Model
                                        │
                  ┌─────────────────────┴─────────────────────┐
                  ▼                                             ▼
         MonitoringEngine                                  MongoDB
         Map<nodeId, Timeout>                          users / nodes /
         setInterval per service                       health-checks
             │  each tick: HTTP check
             ▼  record result, track consecutive failures
         up → warning(2) → down(threshold) → reset on success

Smart Architectural Decisions

  • ServiceResult instead of exceptions. The service layer returns success/error objects and never throws; controllers stay free of try/catch and error shape is consistent across the whole API — a deliberate, disciplined error-handling contract.
  • In-process timer engine, no cron/queue. One setInterval per service in a Map, started/stopped on create/pause/resume/delete, keeps the system dependency-free and the timer lifecycle tightly coupled to service state.
  • Consecutive-failure escalation (warning at 2, down at threshold) avoids alert noise from transient blips — a real reliability-engineering nuance.
  • Dogfooding Meemaw — the author uses his own published utility library (<Show>) in a real product, closing the loop between his OSS and his apps.
  • Single choke points for HTTP (apiClient), storage (storageAdapter), and icons (@icons) — enforced module boundaries that make the FSD codebase easy to reason about.

Impacts

A self-hostable uptime monitor with a memorable, professional industrial UI, 15 endpoints, smart failure escalation, and a clean 4-layer backend — deployed live at watchdog.devferanmi.xyz.

Demonstrated Skills

Full-stack TypeScript; disciplined backend architecture (layered, Result-type error handling, repository pattern); scheduling/timer lifecycle management; React 19 + Feature-Sliced Design; TanStack Query cache invalidation strategy; Tailwind v4 theming and distinctive UI/visual design (GSAP, three.js); auth/security; dogfooding own OSS.

Notes

  • Visual identity: the SCADA/industrial neon-on-black dashboard is instantly memorable and signals strong product/UI sensibility — most monitoring tools look generic.
  • Backend rigor: the ServiceResult no-throw contract + Controller→Service→Repository→Model layering is the kind of discipline you'd expect in a senior codebase, not a side project.
  • Reliability nuance: consecutive-failure escalation (warning→down) shows the author understands real monitoring semantics, not just "ping and alert."
  • Self-consistent ecosystem: dogfoods his own meemaw library inside the app.
  • Live, working demo with React 19 + Tailwind v4 (bleeding-edge versions) and a no-external-infra timer engine.
Ask me anything