Skip to content

Feature: Real-time app notifications for ESP32 progress and ML completion #14

Description

@Alimedhat000

Goal

Add a real-time push channel between backend and mobile app so users receive immediate progress notifications instead of relying only on polling.

Why

Today the app must poll test/group endpoints to know whether:

  • the ESP32 finished uploading subtests, and
  • ML inference has completed.

This adds latency, unnecessary request load, and a weaker UX. We already use SSE internally for server->ESP32 commands; we should provide a similar server->app channel.

Scope (MVP)

  • Add mobile notification stream endpoint (SSE first; WebSocket optional follow-up)
  • Push events when:
    • ESP32 uploads a tremor subtest (POST /api/tests/<id>/tremor success)
    • Test ML inference transitions to completed/failed
    • Group overall inference transitions to completed/failed
  • Keep existing polling endpoints for backward compatibility
  • Add tests + API docs

Proposed Implementation

1) Transport choice

  • Implement SSE for MVP (text/event-stream) because app only needs server->client push
  • Keep WebSocket as a future extension if bidirectional app messaging is required

2) New endpoint

  • GET /api/notifications/stream
    • Auth: JWT Bearer token
    • Long-lived SSE connection
    • Events include heartbeat and connected messages

3) Event model

Use a consistent envelope for all events:

{
  "event": "test_ml_completed",
  "timestamp": "2026-04-08T12:00:00Z",
  "payload": { ... }
}

Suggested event types:

  • connected
  • heartbeat
  • tremor_subtest_uploaded
  • test_ml_completed
  • test_ml_failed
  • group_ml_completed
  • group_ml_failed

4) Publishing points

  • In upload route after successful tremor subtest save/commit
  • In ML worker (run_inference) after session status update
  • In group overall scoring path after group status update

5) Multi-process safety

  • Reuse Redis pub/sub pattern (similar to ESP32 connection manager)
  • Route notifications by user_id so only the owner receives events

6) Payload examples

  • tremor_subtest_uploaded payload:
    • test_id, group_id, subtest, hand, uploaded_count, expected_count
  • test_ml_completed payload:
    • test_id, group_id, test_type, ml_score
  • group_ml_completed payload:
    • group_id, overall_score

Acceptance Criteria

  • Authenticated mobile client can open /api/notifications/stream and receive SSE events
  • A successful tremor subtest upload emits tremor_subtest_uploaded for the correct user
  • ML completion/failure emits session/group events for the correct user
  • Existing polling behavior still works unchanged
  • Unit/integration tests cover stream auth, publish paths, and user isolation
  • API routes docs include event contract and reconnection guidance

Out of Scope

  • Replacing all polling in mobile immediately
  • Full WebSocket migration for all clients
  • Guaranteed delivery/history replay (can be a separate enhancement)

Notes

This should be designed as additive, low-risk infrastructure: real-time notifications improve UX while preserving current REST workflows.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions