feat: extract workflow notifications phase 3

This commit is contained in:
2026-04-07 09:57:39 +02:00
parent 160c198bb3
commit 98b3eadcb2
6 changed files with 291 additions and 63 deletions
@@ -227,6 +227,90 @@ def _resolve_output_mime_type(output_path: str) -> str:
return "image/png"
def _extract_render_error(render_log: dict[str, Any] | None) -> str | None:
if not isinstance(render_log, dict):
return None
error_value = render_log.get("error") or render_log.get("stderr", "")
if not error_value:
return None
return str(error_value)[:300]
def emit_order_line_render_notifications(
*,
success: bool,
order_line_id: str,
order_id: str | None = None,
order_number: str | None = None,
order_creator_id: str | None = None,
tenant_id: str | None = None,
product_name: str,
output_type_name: str,
render_log: dict[str, Any] | None = None,
session: Session | None = None,
line: OrderLine | None = None,
emit_websocket: bool = True,
emit_activity: bool = True,
activity_entity_id: str | None = None,
) -> None:
"""Emit the legacy websocket and activity notifications for an order-line render."""
resolved_order_id = order_id or (str(line.order_id) if line is not None else None)
resolved_entity_id = activity_entity_id if activity_entity_id is not None else resolved_order_id
if session is not None and resolved_order_id and (order_creator_id is None or order_number is None):
order_row = session.execute(
select(Order.created_by, Order.order_number).where(Order.id == resolved_order_id)
).one_or_none()
if order_row:
if order_creator_id is None:
order_creator_id = str(order_row[0])
if order_number is None:
order_number = order_row[1]
if emit_websocket and tenant_id:
try:
from app.core.websocket import publish_event_sync
publish_event_sync(
tenant_id,
{
"type": "render_complete" if success else "render_failed",
"order_line_id": order_line_id,
"order_id": resolved_order_id,
"status": "completed" if success else "failed",
},
)
except Exception:
logger.debug("WebSocket publish skipped (non-fatal)")
if not emit_activity or not order_creator_id:
return
try:
from app.services.notification_service import CHANNEL_ACTIVITY, emit_notification_sync
details: dict[str, Any] = {
"order_number": order_number,
"product_name": product_name,
"output_type": output_type_name,
}
error_message = _extract_render_error(render_log)
if not success and error_message:
details["error"] = error_message
emit_notification_sync(
actor_user_id=None,
target_user_id=order_creator_id,
action="render.completed" if success else "render.failed",
entity_type="order",
entity_id=resolved_entity_id,
details=details,
channel=CHANNEL_ACTIVITY,
)
except Exception:
logger.exception("Failed to emit render activity event")
def persist_order_line_output(
session: Session,
line: OrderLine,