Skip to content

Commit 238af77

Browse files
author
Faxbot Agent
committed
feat(events): emit real-time events for fax operations
- Emit FAX_QUEUED event when fax is created and queued - Emit FAX_SENT/FAX_DELIVERED/FAX_FAILED events based on provider response - Pass plugin_manager to ProviderHealthMonitor so it can discover configured providers - Events now appear in the Event Stream SSE in admin UI - Provider health will now show configured providers (sinch, humblefax, etc) This makes the Event Stream and Provider Health Status functional in diagnostics.
1 parent 5dc4e51 commit 238af77

File tree

1 file changed

+46
-2
lines changed

1 file changed

+46
-2
lines changed

api/app/main.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ async def v4_config_flush_cache(scope: Optional[str] = None):
477477
# Diagnostics router (SSE/recent events)
478478
try:
479479
from .routers import admin_diagnostics as _diag
480-
from .services.events import EventEmitter
480+
from .services.events import EventEmitter, EventType
481481
# Attach emitter if not present
482482
if not hasattr(app.state, "event_emitter") or app.state.event_emitter is None: # type: ignore[attr-defined]
483483
app.state.event_emitter = EventEmitter() # type: ignore[attr-defined]
@@ -495,7 +495,14 @@ async def v4_config_flush_cache(scope: Optional[str] = None):
495495
from .monitoring.health import ProviderHealthMonitor
496496
# Attach health monitor if not present
497497
if not hasattr(app.state, "health_monitor") or app.state.health_monitor is None: # type: ignore[attr-defined]
498-
app.state.health_monitor = ProviderHealthMonitor() # type: ignore[attr-defined]
498+
# Pass plugin_manager, event_emitter, and config_provider
499+
_emitter = getattr(app.state, "event_emitter", None)
500+
_config_prov = getattr(app.state, "hierarchical_config", None)
501+
app.state.health_monitor = ProviderHealthMonitor( # type: ignore[attr-defined]
502+
plugin_manager=plugin_manager,
503+
event_emitter=_emitter,
504+
config_provider=_config_prov
505+
)
499506
app.include_router(_providers.router)
500507
print("✅ Provider health router mounted at /admin/providers")
501508
except Exception as e:
@@ -4088,6 +4095,20 @@ async def send_fax(background: BackgroundTasks, to: str = Form(...), file: Uploa
40884095
if idempotency_key:
40894096
_idempotency_put(idempotency_key, job_id)
40904097
audit_event("FAX_QUEUED", job_id=job_id, backend=ob)
4098+
4099+
# Emit real-time event for SSE stream
4100+
try:
4101+
from .services.events import EventType as _EventType
4102+
emitter = get_event_emitter()
4103+
if emitter:
4104+
await emitter.emit_event(
4105+
_EventType.FAX_QUEUED,
4106+
job_id=job_id,
4107+
provider_id=ob,
4108+
payload_meta={"backend": ob, "to": to[:8] + "***"} # Mask phone for PHI
4109+
)
4110+
except Exception:
4111+
pass # Non-fatal
40914112

40924113
# Kick off fax sending based on backend
40934114
if not settings.fax_disabled:
@@ -4874,6 +4895,20 @@ async def _send_via_outbound_normalized(job_id: str, to: str, pdf_path: str, tif
48744895
job.updated_at = datetime.utcnow()
48754896
db.add(job)
48764897
db.commit()
4898+
4899+
# Emit status event
4900+
try:
4901+
from .services.events import EventType as _ET
4902+
emitter = get_event_emitter()
4903+
if emitter and status:
4904+
if status.upper() in {"SUCCESS", "COMPLETED"}:
4905+
await emitter.emit_event(_ET.FAX_DELIVERED, job_id=job_id, provider_id=backend)
4906+
elif status.upper() == "FAILED":
4907+
await emitter.emit_event(_ET.FAX_FAILED, job_id=job_id, provider_id=backend)
4908+
else:
4909+
await emitter.emit_event(_ET.FAX_SENT, job_id=job_id, provider_id=backend)
4910+
except Exception:
4911+
pass
48774912
except Exception as e:
48784913
with SessionLocal() as db:
48794914
job = db.get(FaxJob, job_id)
@@ -4884,6 +4919,15 @@ async def _send_via_outbound_normalized(job_id: str, to: str, pdf_path: str, tif
48844919
db.add(job)
48854920
db.commit()
48864921
audit_event("job_failed", job_id=job_id, error=str(e))
4922+
4923+
# Emit failure event
4924+
try:
4925+
from .services.events import EventType as _ET
4926+
emitter = get_event_emitter()
4927+
if emitter:
4928+
await emitter.emit_event(_ET.FAX_FAILED, job_id=job_id, provider_id=backend or ob)
4929+
except Exception:
4930+
pass
48874931

48884932

48894933
async def _send_via_signalwire(job_id: str, to: str, pdf_path: str):

0 commit comments

Comments
 (0)