Problem
Wearable data is only useful if the whole chain holds: a device that streams reliably, a backend that stores and orchestrates, a model that turns raw signal into something readable, and clients that agree with the backend about what is true. Any weak link and it becomes a chart nobody trusts.
What I built
Nabda is my senior graduation project: a cardiac-monitoring platform split into six deployable services - C++ firmware on an ESP8266-based wearable, a Java/Spring Boot backend, a Python ML report API, a Python chatbot, a Flutter mobile app, and a TypeScript web client - documented end to end in a LaTeX thesis.
Architecture / system design
The backend is the hub: firmware streams sensor data in, the backend persists it and orchestrates the report and chatbot services behind REST boundaries, and both clients read from that same API. Keeping the ML and chatbot as separate Python services means the Java backend never carries model dependencies — and either can be redeployed without touching the other.
Failure modes / what broke
The hard parts live at the seams, not inside any one service: a wearable drops connectivity, the report model is slow or unavailable, and two separate clients can drift out of sync with backend state. The service split is what keeps a slow model from taking the whole product down with it.
Proof / metrics / tests
The proof is a working end-to-end path - wearable to backend to report to app - across six services in five languages, with the design written up in a peer-reviewable thesis rather than left implicit in the code.
Lessons learned
The model that writes the report is the smallest part of a health product. Almost all of the engineering is the boundaries around it: transport, persistence, orchestration, and making a degraded service look like a degraded feature instead of a broken app.