Skip to content
All work

Case study 01 · Web app

OneView Compression

Founding front-end developer on a web app that puts a mixed-vendor compressor fleet into one standardized view.

Role
Founding developer → front-end lead
When
2025–Present
Where
Detechtion.AI
Platforms
Web · React · Maps & charts
fleet-map clustering, roughly linear for typical fleetsAll-pairs grouping replaced by grid bucketing above a size cutoff.
O(n²) → ~O(n)
concurrent requests: the browser's per-origin limit, found by experiment
6
from empty repo to a working prototype, AI-assisted
~2.5 weeks
public product launch
Feb 2026

Overview

A browser dashboard that brings compressor data from different vendors and telemetry systems into one standardized view: run status, measurements, alarms and downtime. It has a fleet overview with status filters, a clustered map of the whole fleet and per-asset pages for live readings, trends, downtime and optional optimization analytics.

I made the first commit and built the first working version by directing an AI coding agent. Then I made the architecture calls, rewrote the prototype into maintainable code with the team and wrote the conventions that later contributors (human and AI) follow. The product launched publicly in February 2026.

My part. I've led the front end since March 2026: architecture, technical direction, standards, code review and mentoring. Before that, as its founding front-end developer on a small team, I built the core surfaces: fleet map, fleet table, asset vitals and trends, range-bar and optimization gauges, organization switching and reporting. I also wrote the architecture guide and the context files that steer AI assistants in the codebase, and was primary author of the styling guide.

Try it

Fleet Console

A synthetic fleet on an invented map. Race naive clustering against grid buckets, push a request scheduler past the browser's connection limit and break a gauge's data feed to see it fall back to “unknown”.

  • Clustering benchmark up to 10,000 units
  • Concurrency playground with a real promise pool
  • Alarm-zone gauges with negative ranges
  • URL-synced table state
Booting demo…

Engineering stories

Problem, approach, outcome.

  1. 01

    Keeping a fleet map responsive as fleets grow

    • Spatial hashing
    • React performance
    • Leaflet
    • State preservation

    Problem

    The map plots every compressor as a status-coloured marker, grouped into clusters. The first clustering approach compared every marker with every other one, so its cost grew with the square of the fleet size, and zooming and panning got sluggish on large fleets. The map also lost its zoom and cluster state whenever someone opened an asset and came back.

    Approach

    • Rewrote clustering as a hybrid: small sets keep exact pairwise grouping; above a size cutoff, markers drop into grid cells and only neighbouring cells are compared.
    • A quick pass over the data's spread picks the cluster threshold for each zoom level.
    • Memoized derived data, rendered only on-screen clusters when there are many, debounced interactions and cut unnecessary DOM updates.
    • Added click-to-zoom on clusters, a reset-zoom that re-clusters and state preservation across asset drill-downs. The status KPI cards and filters now drive the markers.

    Outcome

    Clustering cost dropped from quadratic to roughly linear for typical fleets, and the map stayed responsive as fleets grew. It became one of the product's core screens.

    • O(n²) → ~O(n) clustering
    • Zoom + cluster state survives drill-down
  2. 02

    Hitting the browser's connection limit, and tuning around it

    • Browser networking
    • Async concurrency
    • Empirical performance testing

    Problem

    Loading sensor time series for every asset in a large fleet fired so many parallel requests that the browser rejected them with a resource-exhaustion error, and readings never loaded.

    Approach

    • Worked it out by experiment in one evening. Firing every request at once failed outright.
    • Identified the browser's per-origin connection limit as the real constraint, then tried progressively smaller caps to see whether more parallelism paid off. It didn't.
    • Settled on 6 and grouped work into batches.
    • Wrote a small reusable worker-pool helper that returns the same result shape as Promise.allSettled, plus one app-wide limiter so every caller shares a single cap.

    Outcome

    Sensor data loads reliably for large fleets, and both data-loading paths share the helper and the limiter.

    • Unbounded → 6 concurrent requests
    • 1 shared limiter across 2 loading paths
  3. 03

    Making hundreds of sensor readings readable

    • Data visualization
    • SVG
    • Statistics in the UI
    • Time-zone correctness

    Problem

    Engineers scan hundreds of readings per compressor to spot what's abnormal relative to alarm limits and downtime history. Time zones and number formatting kept producing bugs.

    Approach

    • Built a resizable split view: a reading list with sparklines, range bars that place each value between its low and high alarm setpoints, and average, variance and z-score columns.
    • Beside it, a trend chart with a secondary axis, shaded downtime overlays, and preset and custom ranges with cached 24h / 7d / 30d windows.
    • Reworked the half-circle alarm gauge to handle negative ranges and zone logic, and to show “unknown” instead of a false “normal” when data is missing.
    • Wrote down the team's time rule (UTC to the API, local time for display) and introduced a shared helper for parsing thousands separators, which guarded against a class of bug that could read “1,518 RPM” as 1.

    Outcome

    These screens became the core asset-detail experience.

  4. 04

    Switching organizations cleanly across tabs

    • React Context architecture
    • AbortController
    • BroadcastChannel
    • Multi-org UX

    Problem

    Some users work across more than one organization. A switch had to reset the whole app, with no leftover screens or late responses from the previous organization, and every other open tab had to stay consistent.

    Approach

    • Data providers wait until the active organization is resolved before loading.
    • On a switch, every in-flight request is cancelled through the shared HTTP client and the providers reload.
    • BroadcastChannel tells other open tabs so they can prompt a refresh; a user on an asset page returns to the fleet root.
    • Organization logos fall back to deterministic, hash-coloured avatars showing the organization's initials, with proper empty and no-access states.

    Outcome

    Shipped to production and documented as a core pattern in the team's architecture guide.

  5. 05

    From AI-agent prototype to maintainable production code

    • AI-accelerated prototyping
    • Architecture decisions
    • Coding standards

    Problem

    The team needed a front end it could demo quickly, and AI-generated prototypes rarely hold up as a long-term codebase.

    Approach

    • Directed an AI coding agent to build the whole shell in about two and a half weeks: sidebar shell, fleet overview, map, downtime timeline, asset detail, first gauges.
    • Made the architecture calls: JavaScript with JSDoc (agreed with the team), front end only, one shared HTTP client, Context plus hooks instead of a state library, consistent file naming.
    • Rewrote the prototype code over the following months with the team. Wrote the architecture guide and the AI-assistant context files and was primary author of the styling guide, so later contributors follow the same rules.

    Outcome

    Very little prototype-era code survives unchanged. The conventions did: they are the team's reference for new work.

  6. 06

    Splitting one overloaded colour into meanings

    • Design tokens
    • WCAG contrast
    • Large-scale refactoring

    Problem

    A new design specification gave separate colours to roles the code had carried in a single “primary” colour: actions, links, destructive states and more. Swapping the variable would have quietly recoloured badges, links and panels with the wrong meaning.

    Approach

    • Worked with an AI pair programmer to compare the spec with the code and plan the migration in phases, keeping product decisions apart from mechanical edits.
    • Audited about 90 usages and classified each by meaning before changing anything.
    • Contrast checks showed some proposed status hues fell well below WCAG AA as text on tinted backgrounds, so darker text shades were kept and lighter hues reserved for fills, borders and icons.
    • Documented every deliberate deviation in the style guide and consolidated table rows onto one shared style.

    Outcome

    The migration landed as one reviewable changeset with a clean build, plus a written list of what was adopted and what wasn't.

    Done with an AI pair programmer; I directed the plan, made the product calls and reviewed every change.

More highlights

  • Saved, user-configurable table column views with unsaved-changes protection on both browser and in-app navigation.
  • A report of assets that have stopped reporting, with page, sort and rows-per-page kept in the URL, plus copy and CSV download.
  • Bulk CSV import/export with correct escaping, and a cap on how many readings a user can chart at once.
  • Optimization analytics on asset pages: per-cylinder and utilization gauges, diagnostic flags and batched trend requests.
  • A light/dark theme and a design-token migration, audited for WCAG contrast.

Stack

Front end
ReactViteJavaScript + JSDocTailwind CSSRadix UI / shadcnFramer Motion
Data & viz
HighchartsLeafletCustom clusteringSVG gauges
Platform
Axios + AbortControllerBroadcastChannelURL-synced stateCI/CD + static hosting

What I took away

  • An AI agent can get you to a demo fast. The architecture decisions and the conventions you write down are what make it last.
  • Before you tune a number, find the constraint that actually sets it. Here it was the browser's connection limit.
  • When data is missing, show “unknown”. A false “normal” is the most dangerous state a monitoring UI can display.

Public info

What the company itself has published about this product. It's linked, not copied.

Esc

↑↓ to move ↵ to select