Smart City
IoT device management and analytics for infrastructure operators
Overview
Smart City is the operator-facing platform behind a city's IoT device fleet — device provisioning and health, map-based sensor visualization, webhook-driven data ingestion, and a rule engine that turns raw sensor readings into alerts and automated actions. I joined after the first version had already shipped and spent a large part of my time modernizing a codebase that had fallen behind, alongside building out several of its core modules.
Key Features
- Device management for provisioning, monitoring, and tracking the health of connected IoT hardware
- Map-based visualization of live and historical sensor data across managed sites
- Webhook ingestion with ETL workflows that normalize incoming sensor payloads before they're stored
- A rule engine for threshold-based alerts and automated actions triggered by sensor data
- Per-app workspaces so operators can scope devices, rules, and dashboards to a given deployment
My Responsibilities
- Migrated a legacy class-component codebase to functional components with hooks, module by module, without breaking the dashboards still running on the old pattern
- Modernized the dependency tree to run on current Node.js LTS and fixed the compatibility breaks that surfaced along the way
- Built out the rule engine, device management, app management, and analytics modules
- Added map- and chart-based visualizations for sensor analytics, including device locations, historical readings, and alert states
- Raised test coverage and cleaned up patterns left over from the legacy codebase, improving both readability and runtime performance
Challenges & Solutions
The class-to-functional migration touched shared state that dozens of existing components still depended on — rewriting it in one pass risked breaking dashboards operators were actively using.
Migrated module by module behind the existing prop and context contracts, converting lifecycle methods to their hook equivalents one component at a time, and only removed the old patterns once every consumer was verified against the new implementation.
With hundreds of devices reporting on independent intervals, re-rendering the map on every incoming sensor reading made it noticeably laggy.
Decoupled marker updates from the raw data stream — readings are batched and a marker only re-renders when its value crosses a rule threshold or moves out of its last-rendered bucket, instead of on every tick.
Architecture
- Frontend
- React, migrated from class components to functional components with hooks during my time on the project
- State
- Redux for device, rule, and analytics state shared across modules
- Styling
- Tailwind CSS with chart and map components wrapped as reusable primitives
- Testing
- Jest coverage added incrementally during the migration, focused on the rule engine and data-transform logic
At a glance
- Core modules delivered
- 4
- Runtime
- Migrated to current Node.js LTS
- Codebase
- Class → functional components
Technologies
This is an enterprise project built for a company I've worked with, so I'm not able to share source code or a live demo here — happy to walk through the code and architecture in person.