"""Notification emission helpers. Provides async (for routers) and sync (for Celery tasks) entry points to create notification rows in the audit_log table. """ import logging import uuid from datetime import datetime from sqlalchemy import create_engine from sqlalchemy.orm import Session from sqlalchemy.ext.asyncio import AsyncSession from app.domains.notifications.models import AuditLog logger = logging.getLogger(__name__) _engine = None def _get_engine(): global _engine if _engine is None: from app.config import settings as app_settings _engine = create_engine(app_settings.database_url_sync) return _engine async def emit_notification( db: AsyncSession, *, actor_user_id: str | uuid.UUID | None = None, target_user_id: str | uuid.UUID | None = None, action: str, entity_type: str | None = None, entity_id: str | None = None, details: dict | None = None, ) -> None: """Create a notification (async — for use inside FastAPI routers).""" try: entry = AuditLog( user_id=str(actor_user_id) if actor_user_id else None, target_user_id=str(target_user_id) if target_user_id else None, action=action, entity_type=entity_type, entity_id=str(entity_id) if entity_id else None, details=details, notification=True, timestamp=datetime.utcnow(), ) db.add(entry) await db.commit() except Exception: logger.exception("Failed to emit notification (async)") await db.rollback() def emit_notification_sync( *, actor_user_id: str | uuid.UUID | None = None, target_user_id: str | uuid.UUID | None = None, action: str, entity_type: str | None = None, entity_id: str | None = None, details: dict | None = None, ) -> None: """Create a notification (sync — for use inside Celery tasks).""" engine = _get_engine() try: with Session(engine) as session: entry = AuditLog( user_id=str(actor_user_id) if actor_user_id else None, target_user_id=str(target_user_id) if target_user_id else None, action=action, entity_type=entity_type, entity_id=str(entity_id) if entity_id else None, details=details, notification=True, timestamp=datetime.utcnow(), ) session.add(entry) session.commit() except Exception: logger.exception("Failed to emit notification (sync)")