fix(queue): trigger websocket broadcast on vitals completion
Overview
This MR resolves a critical bug in the real-time queue update system where the consultation queue fails to refresh automatically when a patient transitions from the vitals stage. It ensures the WebSocket broadcast is correctly triggered by properly managing FastAPI background tasks.
What Does This MR Do and Why?
Previously, _auto_transition_queue_to_waiting instantiated BackgroundTasks() locally inside the function. Because this instance was not managed by the FastAPI dependency injection system, the tasks added to it (specifically the WebSocket broadcast) were never executed when the HTTP response was sent.
The fix injects the BackgroundTasks object at the API route level and passes it down through the service layer. This ties the WebSocket broadcast to the active request's lifecycle, ensuring it fires correctly after the database transaction is committed — eliminating the need for manual page refreshes at the doctor/consultation station.
Changes Made
| File | Change |
|---|---|
app/api/v1/routes/patient_routes.py |
Updated update_vitals_for_latest_visit_endpoint to accept and pass BackgroundTasks
|
app/services/patient_service.py |
Updated create_vital, update_vital, and _auto_transition_queue_to_waiting to propagate BackgroundTasks
|
tests/test_services/test_patient_service.py |
Updated all 48 test cases to accommodate the signature changes |
Technical Details
Root Cause: _auto_transition_queue_to_waiting instantiated BackgroundTasks() locally, outside FastAPI's dependency injection system. Tasks added to this local instance were silently discarded when the HTTP response was sent.
Fix: BackgroundTasks is now injected at the route level and propagated through the service layer, registering broadcasts with the active request lifecycle so they execute correctly on completion.
Type of Change
-
🐛 Bug fix (non-breaking change that fixes an issue) -
✨ New feature -
💥 Breaking change -
📝 Documentation update -
♻ ️ Refactor -
⚡ Performance improvement -
🧪 Test update -
🔧 Configuration change -
🚨 Security fix -
🗑 ️ Deprecation
Related Issues
- Related to: Patient Queue Real-time Sync Issue
How to Validate Locally
- Open two browser windows — one on the Consultation Queue and one on the Vitals Recording page.
- In the Vitals window, select a patient and save their vitals.
- Previous behavior: The patient would disappear from Vitals but not appear in Consultation until a manual refresh.
- New behavior: The patient should instantly appear in the Consultation Queue via WebSocket update.
Testing Done
-
Unit tests updated and passing -
API endpoint integration verified via static analysis
| Scenario | Expected Result | Status |
|---|---|---|
Complete vitals for patient in vitals_waiting
|
Patient moves to waiting and broadcast triggers |
|
| Update existing vitals | Patient status remains/updates and broadcast triggers | |
| Auto-transition failure | Error is logged but vital save completes |
# Run static analysis
ruff check app/services/patient_service.py
uv run mypy app/services/patient_service.py
Code Quality Checklist
Code Standards
-
Code follows project conventions (naming, structure, formatting) -
No debug statements or commented-out code left -
No unused imports, variables, or functions -
Type hints are properly defined -
Ruff checks pass
Python & FastAPI Best Practices
-
Functions follow single-responsibility principle -
Dependency injection used appropriately ( BackgroundTasks) -
Error handling is comprehensive
Documentation
-
Code comments explain complex logic (docstrings updated where necessary)
Known Limitations / Technical Debt
No new technical debt introduced.