case study · Full-Stack & Devices · 2026
DeviceLink Support Console
Remote diagnostics for deployed clinical devices
Problem
Deployed clinical devices fail in inconveniently varied ways: a camera stops responding, a USB peripheral vanishes, the network drops, log uploads silently fail, or a device simply goes dark. Without internal tooling, support means manually pulling logs, calling sites, and re-improvising the same troubleshooting steps with no consistent record of what was tried.
This work draws directly on professional experience supporting deployed clinical devices. DeviceLink is a self-contained, end-to-end build of the internal tool that work demands: fleet monitoring, log triage, remote commands, support cases, and a structured diagnostic report, with a device simulator standing in for hardware so the whole system runs live on any machine.
Constraints
- Devices sit behind clinic firewalls. Nothing can connect to a device; a device can only poll outward. Any "remote command" design has to respect that.
- Self-reported status cannot be trusted. A device that goes silent never sends an offline message. Offline is something the backend must infer.
- The fleet view must be cheap; the history must be complete. One query to render the dashboard, full time-series available for investigation.
- No hardware. The system had to be demonstrably alive, with commands that visibly change device behaviour, without a single physical device.
Decisions
A command is a database row. The dashboard inserts it as Pending; the device polls for work, acknowledges, executes, and reports back; the row walks a six-state lifecycle: Pending → Sent → Acknowledged → Completed / Failed / Expired. Dashboard and device never talk directly, which is exactly how real fleets behind firewalls work, and it lets the backend distinguish a delivery failure from an execution failure.
Status is computed, not stored. Online / Degraded / Offline is recomputed on every read from last-seen time and component health, so a silent device drifts to Offline on its own instead of reporting stale good news.
Hot record plus history table. Each device row carries its latest vitals so the fleet renders in a single cheap query, while an append-only snapshot table keeps the full telemetry time-series, the standard pattern for live state plus history.
Boundaries that hold. Controllers return DTOs, never EF entities. Enums persist as readable strings, with explicit value-set comparisons where ordering matters. The React frontend mirrors the API's shapes as TypeScript string-literal unions, so a status typo is a compile error rather than a runtime surprise.
Transparent diagnostics. The seven-section diagnostic report derives its suggested actions and escalation recommendation from plain, readable conditionals over component health and recurring-error counts, something a support team can audit and tune, not a black box.
A simulator with personalities. Three concurrent C# device agents: a healthy baseline; a clinic device with recurring camera timeouts and USB drops that a restart sometimes fixes; and one that keeps missing heartbeats and letting commands expire. Send a restart, watch the camera recover, or not.
Result
A working three-process system (React 18 and TypeScript dashboard, ASP.NET Core 8 Web API with Swagger docs, and the C# simulator) covering the full support loop: device generates an issue → telemetry is stored → an engineer investigates → a command is sent → the device responds → the fix is documented → a report is generated. The log explorer filters server-side by device, site, severity, component, error code, free text, and date range, with pagination. SQLite runs it with zero configuration, and the EF Core provider swaps to PostgreSQL or SQL Server in one line.
Honest limitations
- No authentication or role model yet: it's an internal-tool prototype, not a hardened deployment.
- The dashboard polls; real-time updates over WebSockets/SignalR are the planned upgrade.
- No automated test suite yet; it sits at the top of the roadmap. And the simulator, however characterful, is not real hardware on real serial links.