1633 lines
56 KiB
Python
1633 lines
56 KiB
Python
"""
|
|
Event publishing service for the notification system.
|
|
Creates Event records that can trigger notifications.
|
|
"""
|
|
from typing import Any, Optional, Dict, Set
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from channels.db import database_sync_to_async
|
|
|
|
from core.models.events import Event
|
|
from core.models.enums import EventTypeChoices
|
|
from core.services.metadata import MetadataEnricher
|
|
|
|
|
|
# Mission-critical events that are ALWAYS created (regardless of notification rules)
|
|
# These events are essential for audit trails, compliance, and business operations
|
|
MISSION_CRITICAL_EVENTS: Set[EventTypeChoices] = {
|
|
# Service delivery (customer-facing)
|
|
EventTypeChoices.SERVICE_COMPLETED,
|
|
EventTypeChoices.SERVICE_CANCELLED,
|
|
EventTypeChoices.SERVICE_SESSION_CLOSED,
|
|
|
|
# Project milestones
|
|
EventTypeChoices.PROJECT_COMPLETED,
|
|
EventTypeChoices.PROJECT_CANCELLED,
|
|
EventTypeChoices.PROJECT_SESSION_CLOSED,
|
|
|
|
# Issues requiring attention
|
|
EventTypeChoices.ACCOUNT_PUNCHLIST_CREATED,
|
|
EventTypeChoices.PROJECT_PUNCHLIST_CREATED,
|
|
EventTypeChoices.PUNCHLIST_STATUS_CHANGED,
|
|
|
|
# Financial events (compliance/audit)
|
|
EventTypeChoices.INVOICE_GENERATED,
|
|
EventTypeChoices.INVOICE_SENT,
|
|
EventTypeChoices.INVOICE_PAID,
|
|
EventTypeChoices.INVOICE_OVERDUE,
|
|
EventTypeChoices.INVOICE_CANCELLED,
|
|
EventTypeChoices.LABOR_RATE_CREATED,
|
|
EventTypeChoices.LABOR_RATE_UPDATED,
|
|
EventTypeChoices.LABOR_RATE_DELETED,
|
|
EventTypeChoices.REVENUE_RATE_CREATED,
|
|
EventTypeChoices.REVENUE_RATE_UPDATED,
|
|
EventTypeChoices.REVENUE_RATE_DELETED,
|
|
|
|
# Reporting & documentation (legal/compliance)
|
|
EventTypeChoices.REPORT_SUBMITTED,
|
|
EventTypeChoices.REPORT_APPROVED,
|
|
EventTypeChoices.SESSION_IMAGE_UPLOADED,
|
|
EventTypeChoices.SESSION_VIDEO_UPLOADED,
|
|
|
|
# Account & access management (security/audit)
|
|
EventTypeChoices.CUSTOMER_CREATED,
|
|
EventTypeChoices.CUSTOMER_DELETED,
|
|
EventTypeChoices.CUSTOMER_STATUS_CHANGED,
|
|
EventTypeChoices.ACCOUNT_CREATED,
|
|
EventTypeChoices.ACCOUNT_DELETED,
|
|
EventTypeChoices.ACCOUNT_STATUS_CHANGED,
|
|
EventTypeChoices.TEAM_PROFILE_CREATED,
|
|
EventTypeChoices.TEAM_PROFILE_DELETED,
|
|
EventTypeChoices.TEAM_PROFILE_ROLE_CHANGED,
|
|
EventTypeChoices.CUSTOMER_PROFILE_CREATED,
|
|
EventTypeChoices.CUSTOMER_PROFILE_DELETED,
|
|
EventTypeChoices.CUSTOMER_PROFILE_ACCESS_GRANTED,
|
|
EventTypeChoices.CUSTOMER_PROFILE_ACCESS_REVOKED,
|
|
|
|
# Schedule changes (operational impact)
|
|
EventTypeChoices.SCHEDULE_CREATED,
|
|
EventTypeChoices.SCHEDULE_DELETED,
|
|
EventTypeChoices.SCHEDULE_FREQUENCY_CHANGED,
|
|
EventTypeChoices.SERVICES_BULK_GENERATED,
|
|
}
|
|
|
|
|
|
class EventPublisher:
|
|
"""
|
|
Service for publishing events to the event management system.
|
|
Events are stored in the database and can trigger notifications via Celery tasks.
|
|
"""
|
|
|
|
@staticmethod
|
|
async def publish(
|
|
event_type: EventTypeChoices,
|
|
entity_type: str,
|
|
entity_id: str,
|
|
triggered_by: Optional[Any] = None,
|
|
metadata: Optional[Dict[str, Any]] = None
|
|
) -> Optional[Event]:
|
|
"""
|
|
Publish an event to the event management system.
|
|
|
|
For mission-critical events, the event is always created.
|
|
For non-critical events, the event is only created if there are active notification rules.
|
|
|
|
Args:
|
|
event_type: Type of event (from EventTypeChoices enum)
|
|
entity_type: Type of entity (e.g., 'Project', 'Report', 'Invoice')
|
|
entity_id: UUID of the entity that triggered this event
|
|
triggered_by: Profile instance (TeamProfile or CustomerProfile) that triggered the event
|
|
metadata: Additional event metadata (e.g., old_status, new_status, changed_fields)
|
|
|
|
Returns:
|
|
Event: The created Event instance, or None if event was skipped
|
|
|
|
Example:
|
|
await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_CREATED,
|
|
entity_type='Project',
|
|
entity_id=project.id,
|
|
triggered_by=team_profile,
|
|
metadata={'status': 'ACTIVE'})
|
|
"""
|
|
# Check if event is mission-critical
|
|
is_critical = event_type in MISSION_CRITICAL_EVENTS
|
|
|
|
# For non-critical events, check if there are any active notification rules
|
|
if not is_critical:
|
|
from core.models.events import NotificationRule
|
|
|
|
has_rules = await database_sync_to_async(
|
|
lambda: NotificationRule.objects.filter(
|
|
is_active=True,
|
|
event_types__contains=[event_type]
|
|
).exists()
|
|
)()
|
|
|
|
if not has_rules:
|
|
# Skip event creation - no rules configured for this event type
|
|
return None
|
|
|
|
# Enrich metadata with domain-appropriate fields
|
|
enriched_metadata = await MetadataEnricher.enrich(
|
|
event_type=event_type,
|
|
entity_type=entity_type,
|
|
entity_id=entity_id,
|
|
existing_metadata=metadata
|
|
)
|
|
|
|
event_data = {
|
|
'event_type': event_type,
|
|
'entity_type': entity_type,
|
|
'entity_id': entity_id,
|
|
'metadata': enriched_metadata,
|
|
}
|
|
|
|
# Set a generic foreign key for triggered_by if provided
|
|
if triggered_by:
|
|
content_type = await database_sync_to_async(ContentType.objects.get_for_model)(triggered_by)
|
|
event_data['triggered_by_content_type'] = content_type
|
|
event_data['triggered_by_object_id'] = triggered_by.id
|
|
|
|
# Create the event
|
|
event = await database_sync_to_async(Event.objects.create)(**event_data)
|
|
|
|
# Queue notification processing task
|
|
# Note: .delay() is non-blocking and doesn't need sync_to_async wrapping
|
|
from core.tasks.notifications import process_event_notifications
|
|
process_event_notifications.delay(str(event.id))
|
|
|
|
return event
|
|
|
|
@staticmethod
|
|
def publish_sync(
|
|
event_type: EventTypeChoices,
|
|
entity_type: str,
|
|
entity_id: str,
|
|
triggered_by: Optional[Any] = None,
|
|
metadata: Optional[Dict[str, Any]] = None
|
|
) -> Optional[Event]:
|
|
"""
|
|
Synchronous version of publish() for use in non-async contexts.
|
|
|
|
For mission-critical events, the event is always created.
|
|
For non-critical events, the event is only created if there are active notification rules.
|
|
|
|
Args:
|
|
event_type: Type of event (from EventTypeChoices enum)
|
|
entity_type: Type of entity (e.g., 'Project', 'Report', 'Invoice')
|
|
entity_id: UUID of the entity that triggered this event
|
|
triggered_by: Profile instance (TeamProfile or CustomerProfile) that triggered the event
|
|
metadata: Additional event metadata
|
|
|
|
Returns:
|
|
Event: The created Event instance, or None if event was skipped
|
|
"""
|
|
# Check if event is mission-critical
|
|
is_critical = event_type in MISSION_CRITICAL_EVENTS
|
|
|
|
# For non-critical events, check if there are any active notification rules
|
|
if not is_critical:
|
|
from core.models.events import NotificationRule
|
|
|
|
has_rules = NotificationRule.objects.filter(
|
|
is_active=True,
|
|
event_types__contains=[event_type]
|
|
).exists()
|
|
|
|
if not has_rules:
|
|
# Skip event creation - no rules configured for this event type
|
|
return None
|
|
|
|
event_data = {
|
|
'event_type': event_type,
|
|
'entity_type': entity_type,
|
|
'entity_id': entity_id,
|
|
'metadata': metadata or {},
|
|
}
|
|
|
|
# Set a generic foreign key for triggered_by if provided
|
|
if triggered_by:
|
|
content_type = ContentType.objects.get_for_model(triggered_by)
|
|
event_data['triggered_by_content_type'] = content_type
|
|
event_data['triggered_by_object_id'] = triggered_by.id
|
|
|
|
# Create the event
|
|
event = Event.objects.create(**event_data)
|
|
|
|
# Queue notification processing task
|
|
from core.tasks.notifications import process_event_notifications
|
|
process_event_notifications.delay(str(event.id))
|
|
|
|
return event
|
|
|
|
|
|
# ========================================
|
|
# Convenience functions for common event types
|
|
# ========================================
|
|
|
|
# Customer events
|
|
async def publish_customer_created(customer_id: str, triggered_by=None, metadata=None):
|
|
"""Publish CUSTOMER_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.CUSTOMER_CREATED,
|
|
entity_type='Customer',
|
|
entity_id=customer_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_customer_updated(customer_id: str, triggered_by=None, metadata=None):
|
|
"""Publish CUSTOMER_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.CUSTOMER_UPDATED,
|
|
entity_type='Customer',
|
|
entity_id=customer_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_customer_deleted(customer_id: str, triggered_by=None, metadata=None):
|
|
"""Publish CUSTOMER_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.CUSTOMER_DELETED,
|
|
entity_type='Customer',
|
|
entity_id=customer_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_customer_status_changed(customer_id: str, old_status: str, new_status: str, triggered_by=None):
|
|
"""Publish CUSTOMER_STATUS_CHANGED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.CUSTOMER_STATUS_CHANGED,
|
|
entity_type='Customer',
|
|
entity_id=customer_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'old_status': old_status, 'new_status': new_status}
|
|
)
|
|
|
|
|
|
# Account events
|
|
async def publish_account_created(account_id: str, triggered_by=None, metadata=None):
|
|
"""Publish ACCOUNT_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.ACCOUNT_CREATED,
|
|
entity_type='Account',
|
|
entity_id=account_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_account_updated(account_id: str, triggered_by=None, metadata=None):
|
|
"""Publish ACCOUNT_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.ACCOUNT_UPDATED,
|
|
entity_type='Account',
|
|
entity_id=account_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_account_deleted(account_id: str, triggered_by=None, metadata=None):
|
|
"""Publish ACCOUNT_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.ACCOUNT_DELETED,
|
|
entity_type='Account',
|
|
entity_id=account_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_account_status_changed(account_id: str, old_status: str, new_status: str, triggered_by=None):
|
|
"""Publish ACCOUNT_STATUS_CHANGED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.ACCOUNT_STATUS_CHANGED,
|
|
entity_type='Account',
|
|
entity_id=account_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'old_status': old_status, 'new_status': new_status}
|
|
)
|
|
|
|
|
|
# Service events
|
|
async def publish_service_created(service_id: str, triggered_by=None, metadata=None):
|
|
"""Publish SERVICE_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SERVICE_CREATED,
|
|
entity_type='Service',
|
|
entity_id=service_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_service_updated(service_id: str, triggered_by=None, metadata=None):
|
|
"""Publish SERVICE_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SERVICE_UPDATED,
|
|
entity_type='Service',
|
|
entity_id=service_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_service_deleted(service_id: str, triggered_by=None, metadata=None):
|
|
"""Publish SERVICE_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SERVICE_DELETED,
|
|
entity_type='Service',
|
|
entity_id=service_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_service_status_changed(service_id: str, old_status: str, new_status: str, triggered_by=None):
|
|
"""Publish SERVICE_STATUS_CHANGED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SERVICE_STATUS_CHANGED,
|
|
entity_type='Service',
|
|
entity_id=service_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'old_status': old_status, 'new_status': new_status}
|
|
)
|
|
|
|
|
|
async def publish_service_completed(service_id: str, triggered_by=None, metadata=None):
|
|
"""Publish SERVICE_COMPLETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SERVICE_COMPLETED,
|
|
entity_type='Service',
|
|
entity_id=service_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_service_cancelled(service_id: str, triggered_by=None, metadata=None):
|
|
"""Publish SERVICE_CANCELLED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SERVICE_CANCELLED,
|
|
entity_type='Service',
|
|
entity_id=service_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_service_team_assigned(service_id: str, team_member_id: str, team_member_name: str, triggered_by=None):
|
|
"""Publish SERVICE_TEAM_ASSIGNED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SERVICE_TEAM_ASSIGNED,
|
|
entity_type='Service',
|
|
entity_id=service_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'team_member_id': team_member_id, 'team_member_name': team_member_name}
|
|
)
|
|
|
|
|
|
async def publish_service_team_unassigned(service_id: str, team_member_id: str, team_member_name: str, triggered_by=None):
|
|
"""Publish SERVICE_TEAM_UNASSIGNED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SERVICE_TEAM_UNASSIGNED,
|
|
entity_type='Service',
|
|
entity_id=service_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'team_member_id': team_member_id, 'team_member_name': team_member_name}
|
|
)
|
|
|
|
|
|
async def publish_service_dispatched(service_id: str, triggered_by=None, metadata=None):
|
|
"""Publish SERVICE_DISPATCHED event (admin assigned to service)"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SERVICE_DISPATCHED,
|
|
entity_type='Service',
|
|
entity_id=service_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_services_bulk_generated(account_id: str, count: int, month: str, triggered_by=None):
|
|
"""Publish SERVICES_BULK_GENERATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SERVICES_BULK_GENERATED,
|
|
entity_type='Account',
|
|
entity_id=account_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'count': count, 'month': month}
|
|
)
|
|
|
|
|
|
# Schedule events
|
|
async def publish_schedule_created(schedule_id: str, triggered_by=None, metadata=None):
|
|
"""Publish SCHEDULE_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SCHEDULE_CREATED,
|
|
entity_type='Schedule',
|
|
entity_id=schedule_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_schedule_updated(schedule_id: str, triggered_by=None, metadata=None):
|
|
"""Publish SCHEDULE_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SCHEDULE_UPDATED,
|
|
entity_type='Schedule',
|
|
entity_id=schedule_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_schedule_deleted(schedule_id: str, triggered_by=None, metadata=None):
|
|
"""Publish SCHEDULE_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SCHEDULE_DELETED,
|
|
entity_type='Schedule',
|
|
entity_id=schedule_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_schedule_frequency_changed(schedule_id: str, old_frequency: str, new_frequency: str, triggered_by=None):
|
|
"""Publish SCHEDULE_FREQUENCY_CHANGED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SCHEDULE_FREQUENCY_CHANGED,
|
|
entity_type='Schedule',
|
|
entity_id=schedule_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'old_frequency': old_frequency, 'new_frequency': new_frequency}
|
|
)
|
|
|
|
|
|
# Project events
|
|
async def publish_project_created(project_id: str, triggered_by=None, metadata=None):
|
|
"""Publish PROJECT_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_CREATED,
|
|
entity_type='Project',
|
|
entity_id=project_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_project_updated(project_id: str, triggered_by=None, metadata=None):
|
|
"""Publish PROJECT_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_UPDATED,
|
|
entity_type='Project',
|
|
entity_id=project_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_project_status_changed(project_id: str, old_status: str, new_status: str, triggered_by=None):
|
|
"""Publish PROJECT_STATUS_CHANGED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_STATUS_CHANGED,
|
|
entity_type='Project',
|
|
entity_id=project_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'old_status': old_status, 'new_status': new_status}
|
|
)
|
|
|
|
|
|
async def publish_project_completed(project_id: str, triggered_by=None, metadata=None):
|
|
"""Publish PROJECT_COMPLETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_COMPLETED,
|
|
entity_type='Project',
|
|
entity_id=project_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_project_cancelled(project_id: str, triggered_by=None, metadata=None):
|
|
"""Publish PROJECT_CANCELLED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_CANCELLED,
|
|
entity_type='Project',
|
|
entity_id=project_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_project_dispatched(project_id: str, triggered_by=None, metadata=None):
|
|
"""Publish PROJECT_DISPATCHED event (admin assigned to project)"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_DISPATCHED,
|
|
entity_type='Project',
|
|
entity_id=project_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_project_deleted(project_id: str, triggered_by=None, metadata=None):
|
|
"""Publish PROJECT_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_DELETED,
|
|
entity_type='Project',
|
|
entity_id=project_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
# Team profile events
|
|
async def publish_team_profile_created(profile_id: str, triggered_by=None, metadata=None):
|
|
"""Publish TEAM_PROFILE_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.TEAM_PROFILE_CREATED,
|
|
entity_type='TeamProfile',
|
|
entity_id=profile_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_team_profile_updated(profile_id: str, triggered_by=None, metadata=None):
|
|
"""Publish TEAM_PROFILE_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.TEAM_PROFILE_UPDATED,
|
|
entity_type='TeamProfile',
|
|
entity_id=profile_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_team_profile_deleted(profile_id: str, triggered_by=None, metadata=None):
|
|
"""Publish TEAM_PROFILE_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.TEAM_PROFILE_DELETED,
|
|
entity_type='TeamProfile',
|
|
entity_id=profile_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_team_profile_role_changed(profile_id: str, old_role: str, new_role: str, triggered_by=None):
|
|
"""Publish TEAM_PROFILE_ROLE_CHANGED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.TEAM_PROFILE_ROLE_CHANGED,
|
|
entity_type='TeamProfile',
|
|
entity_id=profile_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'old_role': old_role, 'new_role': new_role}
|
|
)
|
|
|
|
|
|
# Customer profile events
|
|
async def publish_customer_profile_created(profile_id: str, triggered_by=None, metadata=None):
|
|
"""Publish CUSTOMER_PROFILE_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.CUSTOMER_PROFILE_CREATED,
|
|
entity_type='CustomerProfile',
|
|
entity_id=profile_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_customer_profile_updated(profile_id: str, triggered_by=None, metadata=None):
|
|
"""Publish CUSTOMER_PROFILE_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.CUSTOMER_PROFILE_UPDATED,
|
|
entity_type='CustomerProfile',
|
|
entity_id=profile_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_customer_profile_deleted(profile_id: str, triggered_by=None, metadata=None):
|
|
"""Publish CUSTOMER_PROFILE_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.CUSTOMER_PROFILE_DELETED,
|
|
entity_type='CustomerProfile',
|
|
entity_id=profile_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_customer_profile_access_granted(profile_id: str, customer_id: str, triggered_by=None):
|
|
"""Publish CUSTOMER_PROFILE_ACCESS_GRANTED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.CUSTOMER_PROFILE_ACCESS_GRANTED,
|
|
entity_type='CustomerProfile',
|
|
entity_id=profile_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'customer_id': customer_id}
|
|
)
|
|
|
|
|
|
async def publish_customer_profile_access_revoked(profile_id: str, customer_id: str, triggered_by=None):
|
|
"""Publish CUSTOMER_PROFILE_ACCESS_REVOKED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.CUSTOMER_PROFILE_ACCESS_REVOKED,
|
|
entity_type='CustomerProfile',
|
|
entity_id=profile_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'customer_id': customer_id}
|
|
)
|
|
|
|
|
|
# Report events
|
|
async def publish_report_created(report_id: str, triggered_by=None, metadata=None):
|
|
"""Publish REPORT_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.REPORT_CREATED,
|
|
entity_type='Report',
|
|
entity_id=report_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_report_updated(report_id: str, triggered_by=None, metadata=None):
|
|
"""Publish REPORT_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.REPORT_UPDATED,
|
|
entity_type='Report',
|
|
entity_id=report_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_report_deleted(report_id: str, triggered_by=None, metadata=None):
|
|
"""Publish REPORT_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.REPORT_DELETED,
|
|
entity_type='Report',
|
|
entity_id=report_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_report_submitted(report_id: str, triggered_by=None, metadata=None):
|
|
"""Publish REPORT_SUBMITTED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.REPORT_SUBMITTED,
|
|
entity_type='Report',
|
|
entity_id=report_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_report_approved(report_id: str, triggered_by=None, metadata=None):
|
|
"""Publish REPORT_APPROVED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.REPORT_APPROVED,
|
|
entity_type='Report',
|
|
entity_id=report_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
# Invoice events
|
|
async def publish_invoice_generated(invoice_id: str, triggered_by=None, metadata=None):
|
|
"""Publish INVOICE_GENERATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.INVOICE_GENERATED,
|
|
entity_type='Invoice',
|
|
entity_id=invoice_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_invoice_sent(invoice_id: str, triggered_by=None, metadata=None):
|
|
"""Publish INVOICE_SENT event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.INVOICE_SENT,
|
|
entity_type='Invoice',
|
|
entity_id=invoice_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_invoice_paid(invoice_id: str, triggered_by=None, metadata=None):
|
|
"""Publish INVOICE_PAID event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.INVOICE_PAID,
|
|
entity_type='Invoice',
|
|
entity_id=invoice_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_invoice_overdue(invoice_id: str, triggered_by=None, metadata=None):
|
|
"""Publish INVOICE_OVERDUE event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.INVOICE_OVERDUE,
|
|
entity_type='Invoice',
|
|
entity_id=invoice_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
|
|
async def publish_invoice_cancelled(invoice_id: str, triggered_by=None, metadata=None):
|
|
"""Publish INVOICE_CANCELLED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.INVOICE_CANCELLED,
|
|
entity_type='Invoice',
|
|
entity_id=invoice_id,
|
|
triggered_by=triggered_by,
|
|
metadata=metadata
|
|
)
|
|
|
|
# Service Session events
|
|
async def publish_service_session_opened(session_id: str, service_id: str, triggered_by=None):
|
|
"""Publish SERVICE_SESSION_OPENED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SERVICE_SESSION_OPENED,
|
|
entity_type='ServiceSession',
|
|
entity_id=session_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'service_id': service_id}
|
|
)
|
|
|
|
|
|
async def publish_service_session_closed(session_id: str, service_id: str, triggered_by=None, metadata=None):
|
|
"""Publish SERVICE_SESSION_CLOSED event"""
|
|
event_metadata = {'service_id': service_id}
|
|
if metadata:
|
|
event_metadata.update(metadata)
|
|
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SERVICE_SESSION_CLOSED,
|
|
entity_type='ServiceSession',
|
|
entity_id=session_id,
|
|
triggered_by=triggered_by,
|
|
metadata=event_metadata
|
|
)
|
|
|
|
|
|
async def publish_service_session_reverted(session_id: str, service_id: str, triggered_by=None):
|
|
"""Publish SERVICE_SESSION_REVERTED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SERVICE_SESSION_REVERTED,
|
|
entity_type='ServiceSession',
|
|
entity_id=session_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'service_id': service_id}
|
|
)
|
|
|
|
|
|
async def publish_service_task_completed(task_id: str, service_id: str, task_name: str, triggered_by=None):
|
|
"""Publish SERVICE_TASK_COMPLETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SERVICE_TASK_COMPLETED,
|
|
entity_type='TaskCompletion',
|
|
entity_id=task_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'service_id': service_id, 'task_name': task_name}
|
|
)
|
|
|
|
|
|
async def publish_service_task_uncompleted(task_id: str, service_id: str, task_name: str, triggered_by=None):
|
|
"""Publish SERVICE_TASK_UNCOMPLETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SERVICE_TASK_UNCOMPLETED,
|
|
entity_type='TaskCompletion',
|
|
entity_id=task_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'service_id': service_id, 'task_name': task_name}
|
|
)
|
|
|
|
|
|
# Project Session events
|
|
async def publish_project_session_opened(session_id: str, project_id: str, triggered_by=None):
|
|
"""Publish PROJECT_SESSION_OPENED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_SESSION_OPENED,
|
|
entity_type='ProjectSession',
|
|
entity_id=session_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'project_id': project_id}
|
|
)
|
|
|
|
|
|
async def publish_project_session_closed(session_id: str, project_id: str, triggered_by=None, metadata=None):
|
|
"""Publish PROJECT_SESSION_CLOSED event"""
|
|
event_metadata = {'project_id': project_id}
|
|
if metadata:
|
|
event_metadata.update(metadata)
|
|
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_SESSION_CLOSED,
|
|
entity_type='ProjectSession',
|
|
entity_id=session_id,
|
|
triggered_by=triggered_by,
|
|
metadata=event_metadata
|
|
)
|
|
|
|
|
|
async def publish_project_session_reverted(session_id: str, project_id: str, triggered_by=None):
|
|
"""Publish PROJECT_SESSION_REVERTED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_SESSION_REVERTED,
|
|
entity_type='ProjectSession',
|
|
entity_id=session_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'project_id': project_id}
|
|
)
|
|
|
|
|
|
async def publish_project_task_completed(task_id: str, project_id: str, task_name: str, triggered_by=None):
|
|
"""Publish PROJECT_TASK_COMPLETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_TASK_COMPLETED,
|
|
entity_type='ProjectTaskCompletion',
|
|
entity_id=task_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'project_id': project_id, 'task_name': task_name}
|
|
)
|
|
|
|
|
|
async def publish_project_task_uncompleted(task_id: str, project_id: str, task_name: str, triggered_by=None):
|
|
"""Publish PROJECT_TASK_UNCOMPLETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_TASK_UNCOMPLETED,
|
|
entity_type='ProjectTaskCompletion',
|
|
entity_id=task_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'project_id': project_id, 'task_name': task_name}
|
|
)
|
|
|
|
|
|
# Punchlist events
|
|
async def publish_account_punchlist_created(punchlist_id: str, account_id: str, triggered_by=None, metadata=None):
|
|
"""Publish ACCOUNT_PUNCHLIST_CREATED event"""
|
|
meta = metadata or {}
|
|
meta['account_id'] = account_id
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.ACCOUNT_PUNCHLIST_CREATED,
|
|
entity_type='AccountPunchlist',
|
|
entity_id=punchlist_id,
|
|
triggered_by=triggered_by,
|
|
metadata=meta
|
|
)
|
|
|
|
|
|
async def publish_account_punchlist_updated(punchlist_id: str, account_id: str, triggered_by=None, metadata=None):
|
|
"""Publish ACCOUNT_PUNCHLIST_UPDATED event"""
|
|
meta = metadata or {}
|
|
meta['account_id'] = account_id
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.ACCOUNT_PUNCHLIST_UPDATED,
|
|
entity_type='AccountPunchlist',
|
|
entity_id=punchlist_id,
|
|
triggered_by=triggered_by,
|
|
metadata=meta
|
|
)
|
|
|
|
|
|
async def publish_account_punchlist_deleted(punchlist_id: str, account_id: str, triggered_by=None, metadata=None):
|
|
"""Publish ACCOUNT_PUNCHLIST_DELETED event"""
|
|
meta = metadata or {}
|
|
meta['account_id'] = account_id
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.ACCOUNT_PUNCHLIST_DELETED,
|
|
entity_type='AccountPunchlist',
|
|
entity_id=punchlist_id,
|
|
triggered_by=triggered_by,
|
|
metadata=meta
|
|
)
|
|
|
|
|
|
async def publish_project_punchlist_created(punchlist_id: str, project_id: str, triggered_by=None, metadata=None):
|
|
"""Publish PROJECT_PUNCHLIST_CREATED event"""
|
|
meta = metadata or {}
|
|
meta['project_id'] = project_id
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_PUNCHLIST_CREATED,
|
|
entity_type='ProjectPunchlist',
|
|
entity_id=punchlist_id,
|
|
triggered_by=triggered_by,
|
|
metadata=meta
|
|
)
|
|
|
|
|
|
async def publish_project_punchlist_updated(punchlist_id: str, project_id: str, triggered_by=None, metadata=None):
|
|
"""Publish PROJECT_PUNCHLIST_UPDATED event"""
|
|
meta = metadata or {}
|
|
meta['project_id'] = project_id
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_PUNCHLIST_UPDATED,
|
|
entity_type='ProjectPunchlist',
|
|
entity_id=punchlist_id,
|
|
triggered_by=triggered_by,
|
|
metadata=meta
|
|
)
|
|
|
|
|
|
async def publish_project_punchlist_deleted(punchlist_id: str, project_id: str, triggered_by=None, metadata=None):
|
|
"""Publish PROJECT_PUNCHLIST_DELETED event"""
|
|
meta = metadata or {}
|
|
meta['project_id'] = project_id
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_PUNCHLIST_DELETED,
|
|
entity_type='ProjectPunchlist',
|
|
entity_id=punchlist_id,
|
|
triggered_by=triggered_by,
|
|
metadata=meta
|
|
)
|
|
|
|
|
|
async def publish_punchlist_status_changed(punchlist_id: str, entity_type: str, old_status: str, new_status: str, triggered_by=None):
|
|
"""Publish PUNCHLIST_STATUS_CHANGED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PUNCHLIST_STATUS_CHANGED,
|
|
entity_type=entity_type,
|
|
entity_id=punchlist_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'old_status': old_status, 'new_status': new_status}
|
|
)
|
|
|
|
|
|
async def publish_punchlist_priority_changed(punchlist_id: str, entity_type: str, old_priority: str, new_priority: str, triggered_by=None):
|
|
"""Publish PUNCHLIST_PRIORITY_CHANGED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PUNCHLIST_PRIORITY_CHANGED,
|
|
entity_type=entity_type,
|
|
entity_id=punchlist_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'old_priority': old_priority, 'new_priority': new_priority}
|
|
)
|
|
|
|
|
|
# Session Media events
|
|
async def publish_session_image_uploaded(image_id: str, session_id: str, is_internal: bool, triggered_by=None):
|
|
"""Publish SESSION_IMAGE_UPLOADED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SESSION_IMAGE_UPLOADED,
|
|
entity_type='SessionImage',
|
|
entity_id=image_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'session_id': session_id, 'is_internal': is_internal}
|
|
)
|
|
|
|
|
|
async def publish_session_image_updated(image_id: str, session_id: str, triggered_by=None, metadata=None):
|
|
"""Publish SESSION_IMAGE_UPDATED event"""
|
|
meta = metadata or {}
|
|
meta['session_id'] = session_id
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SESSION_IMAGE_UPDATED,
|
|
entity_type='SessionImage',
|
|
entity_id=image_id,
|
|
triggered_by=triggered_by,
|
|
metadata=meta
|
|
)
|
|
|
|
|
|
async def publish_session_image_deleted(image_id: str, session_id: str, triggered_by=None):
|
|
"""Publish SESSION_IMAGE_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SESSION_IMAGE_DELETED,
|
|
entity_type='SessionImage',
|
|
entity_id=image_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'session_id': session_id}
|
|
)
|
|
|
|
|
|
async def publish_session_video_uploaded(video_id: str, session_id: str, is_internal: bool, triggered_by=None):
|
|
"""Publish SESSION_VIDEO_UPLOADED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SESSION_VIDEO_UPLOADED,
|
|
entity_type='SessionVideo',
|
|
entity_id=video_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'session_id': session_id, 'is_internal': is_internal}
|
|
)
|
|
|
|
|
|
async def publish_session_video_updated(video_id: str, session_id: str, triggered_by=None, metadata=None):
|
|
"""Publish SESSION_VIDEO_UPDATED event"""
|
|
meta = metadata or {}
|
|
meta['session_id'] = session_id
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SESSION_VIDEO_UPDATED,
|
|
entity_type='SessionVideo',
|
|
entity_id=video_id,
|
|
triggered_by=triggered_by,
|
|
metadata=meta
|
|
)
|
|
|
|
|
|
async def publish_session_video_deleted(video_id: str, session_id: str, triggered_by=None):
|
|
"""Publish SESSION_VIDEO_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SESSION_VIDEO_DELETED,
|
|
entity_type='SessionVideo',
|
|
entity_id=video_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'session_id': session_id}
|
|
)
|
|
|
|
|
|
async def publish_session_media_internal_flagged(media_id: str, media_type: str, session_id: str, triggered_by=None):
|
|
"""Publish SESSION_MEDIA_INTERNAL_FLAGGED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SESSION_MEDIA_INTERNAL_FLAGGED,
|
|
entity_type=media_type,
|
|
entity_id=media_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'session_id': session_id}
|
|
)
|
|
|
|
|
|
# Session Notes events
|
|
async def publish_session_note_created(note_id: str, session_id: str, triggered_by=None):
|
|
"""Publish SESSION_NOTE_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SESSION_NOTE_CREATED,
|
|
entity_type='SessionNote',
|
|
entity_id=note_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'session_id': session_id}
|
|
)
|
|
|
|
|
|
async def publish_session_note_updated(note_id: str, session_id: str, triggered_by=None):
|
|
"""Publish SESSION_NOTE_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SESSION_NOTE_UPDATED,
|
|
entity_type='SessionNote',
|
|
entity_id=note_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'session_id': session_id}
|
|
)
|
|
|
|
|
|
async def publish_session_note_deleted(note_id: str, session_id: str, triggered_by=None):
|
|
"""Publish SESSION_NOTE_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SESSION_NOTE_DELETED,
|
|
entity_type='SessionNote',
|
|
entity_id=note_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'session_id': session_id}
|
|
)
|
|
|
|
|
|
# Customer Address & Contact events
|
|
async def publish_customer_address_created(address_id: str, customer_id: str, triggered_by=None):
|
|
"""Publish CUSTOMER_ADDRESS_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.CUSTOMER_ADDRESS_CREATED,
|
|
entity_type='CustomerAddress',
|
|
entity_id=address_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'customer_id': customer_id}
|
|
)
|
|
|
|
|
|
async def publish_customer_address_updated(address_id: str, customer_id: str, triggered_by=None):
|
|
"""Publish CUSTOMER_ADDRESS_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.CUSTOMER_ADDRESS_UPDATED,
|
|
entity_type='CustomerAddress',
|
|
entity_id=address_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'customer_id': customer_id}
|
|
)
|
|
|
|
|
|
async def publish_customer_address_deleted(address_id: str, customer_id: str, triggered_by=None):
|
|
"""Publish CUSTOMER_ADDRESS_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.CUSTOMER_ADDRESS_DELETED,
|
|
entity_type='CustomerAddress',
|
|
entity_id=address_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'customer_id': customer_id}
|
|
)
|
|
|
|
|
|
async def publish_customer_contact_created(contact_id: str, customer_id: str, triggered_by=None):
|
|
"""Publish CUSTOMER_CONTACT_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.CUSTOMER_CONTACT_CREATED,
|
|
entity_type='CustomerContact',
|
|
entity_id=contact_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'customer_id': customer_id}
|
|
)
|
|
|
|
|
|
async def publish_customer_contact_updated(contact_id: str, customer_id: str, triggered_by=None):
|
|
"""Publish CUSTOMER_CONTACT_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.CUSTOMER_CONTACT_UPDATED,
|
|
entity_type='CustomerContact',
|
|
entity_id=contact_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'customer_id': customer_id}
|
|
)
|
|
|
|
|
|
async def publish_customer_contact_deleted(contact_id: str, customer_id: str, triggered_by=None):
|
|
"""Publish CUSTOMER_CONTACT_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.CUSTOMER_CONTACT_DELETED,
|
|
entity_type='CustomerContact',
|
|
entity_id=contact_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'customer_id': customer_id}
|
|
)
|
|
|
|
|
|
# Account Address & Contact events
|
|
async def publish_account_address_created(address_id: str, account_id: str, triggered_by=None):
|
|
"""Publish ACCOUNT_ADDRESS_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.ACCOUNT_ADDRESS_CREATED,
|
|
entity_type='AccountAddress',
|
|
entity_id=address_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'account_id': account_id}
|
|
)
|
|
|
|
|
|
async def publish_account_address_updated(address_id: str, account_id: str, triggered_by=None):
|
|
"""Publish ACCOUNT_ADDRESS_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.ACCOUNT_ADDRESS_UPDATED,
|
|
entity_type='AccountAddress',
|
|
entity_id=address_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'account_id': account_id}
|
|
)
|
|
|
|
|
|
async def publish_account_address_deleted(address_id: str, account_id: str, triggered_by=None):
|
|
"""Publish ACCOUNT_ADDRESS_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.ACCOUNT_ADDRESS_DELETED,
|
|
entity_type='AccountAddress',
|
|
entity_id=address_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'account_id': account_id}
|
|
)
|
|
|
|
|
|
async def publish_account_contact_created(contact_id: str, account_id: str, triggered_by=None):
|
|
"""Publish ACCOUNT_CONTACT_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.ACCOUNT_CONTACT_CREATED,
|
|
entity_type='AccountContact',
|
|
entity_id=contact_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'account_id': account_id}
|
|
)
|
|
|
|
|
|
async def publish_account_contact_updated(contact_id: str, account_id: str, triggered_by=None):
|
|
"""Publish ACCOUNT_CONTACT_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.ACCOUNT_CONTACT_UPDATED,
|
|
entity_type='AccountContact',
|
|
entity_id=contact_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'account_id': account_id}
|
|
)
|
|
|
|
|
|
async def publish_account_contact_deleted(contact_id: str, account_id: str, triggered_by=None):
|
|
"""Publish ACCOUNT_CONTACT_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.ACCOUNT_CONTACT_DELETED,
|
|
entity_type='AccountContact',
|
|
entity_id=contact_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'account_id': account_id}
|
|
)
|
|
|
|
|
|
# Scope events
|
|
async def publish_scope_created(scope_id: str, account_id: str, triggered_by=None):
|
|
"""Publish SCOPE_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SCOPE_CREATED,
|
|
entity_type='Scope',
|
|
entity_id=scope_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'account_id': account_id}
|
|
)
|
|
|
|
|
|
async def publish_scope_updated(scope_id: str, account_id: str, triggered_by=None):
|
|
"""Publish SCOPE_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SCOPE_UPDATED,
|
|
entity_type='Scope',
|
|
entity_id=scope_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'account_id': account_id}
|
|
)
|
|
|
|
|
|
async def publish_scope_deleted(scope_id: str, account_id: str, triggered_by=None):
|
|
"""Publish SCOPE_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SCOPE_DELETED,
|
|
entity_type='Scope',
|
|
entity_id=scope_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'account_id': account_id}
|
|
)
|
|
|
|
|
|
async def publish_area_created(area_id: str, scope_id: str, triggered_by=None):
|
|
"""Publish AREA_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.AREA_CREATED,
|
|
entity_type='Area',
|
|
entity_id=area_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'scope_id': scope_id}
|
|
)
|
|
|
|
|
|
async def publish_area_updated(area_id: str, scope_id: str, triggered_by=None):
|
|
"""Publish AREA_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.AREA_UPDATED,
|
|
entity_type='Area',
|
|
entity_id=area_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'scope_id': scope_id}
|
|
)
|
|
|
|
|
|
async def publish_area_deleted(area_id: str, scope_id: str, triggered_by=None):
|
|
"""Publish AREA_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.AREA_DELETED,
|
|
entity_type='Area',
|
|
entity_id=area_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'scope_id': scope_id}
|
|
)
|
|
|
|
|
|
async def publish_task_created(task_id: str, area_id: str, triggered_by=None):
|
|
"""Publish TASK_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.TASK_CREATED,
|
|
entity_type='Task',
|
|
entity_id=task_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'area_id': area_id}
|
|
)
|
|
|
|
|
|
async def publish_task_updated(task_id: str, area_id: str, triggered_by=None):
|
|
"""Publish TASK_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.TASK_UPDATED,
|
|
entity_type='Task',
|
|
entity_id=task_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'area_id': area_id}
|
|
)
|
|
|
|
|
|
async def publish_task_deleted(task_id: str, area_id: str, triggered_by=None):
|
|
"""Publish TASK_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.TASK_DELETED,
|
|
entity_type='Task',
|
|
entity_id=task_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'area_id': area_id}
|
|
)
|
|
|
|
|
|
async def publish_task_completion_recorded(completion_id: str, task_id: str, service_id: str, triggered_by=None):
|
|
"""Publish TASK_COMPLETION_RECORDED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.TASK_COMPLETION_RECORDED,
|
|
entity_type='TaskCompletion',
|
|
entity_id=completion_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'task_id': task_id, 'service_id': service_id}
|
|
)
|
|
|
|
|
|
# Scope Template events
|
|
async def publish_scope_template_created(template_id: str, triggered_by=None):
|
|
"""Publish SCOPE_TEMPLATE_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SCOPE_TEMPLATE_CREATED,
|
|
entity_type='ScopeTemplate',
|
|
entity_id=template_id,
|
|
triggered_by=triggered_by,
|
|
metadata={}
|
|
)
|
|
|
|
|
|
async def publish_scope_template_updated(template_id: str, triggered_by=None):
|
|
"""Publish SCOPE_TEMPLATE_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SCOPE_TEMPLATE_UPDATED,
|
|
entity_type='ScopeTemplate',
|
|
entity_id=template_id,
|
|
triggered_by=triggered_by,
|
|
metadata={}
|
|
)
|
|
|
|
|
|
async def publish_scope_template_deleted(template_id: str, triggered_by=None):
|
|
"""Publish SCOPE_TEMPLATE_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SCOPE_TEMPLATE_DELETED,
|
|
entity_type='ScopeTemplate',
|
|
entity_id=template_id,
|
|
triggered_by=triggered_by,
|
|
metadata={}
|
|
)
|
|
|
|
|
|
async def publish_scope_template_instantiated(scope_id: str, template_id: str, account_id: str, triggered_by=None):
|
|
"""Publish SCOPE_TEMPLATE_INSTANTIATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.SCOPE_TEMPLATE_INSTANTIATED,
|
|
entity_type='Scope',
|
|
entity_id=scope_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'template_id': template_id, 'account_id': account_id}
|
|
)
|
|
|
|
|
|
async def publish_area_template_created(template_id: str, scope_template_id: str, triggered_by=None):
|
|
"""Publish AREA_TEMPLATE_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.AREA_TEMPLATE_CREATED,
|
|
entity_type='AreaTemplate',
|
|
entity_id=template_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'scope_template_id': scope_template_id}
|
|
)
|
|
|
|
|
|
async def publish_area_template_updated(template_id: str, scope_template_id: str, triggered_by=None):
|
|
"""Publish AREA_TEMPLATE_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.AREA_TEMPLATE_UPDATED,
|
|
entity_type='AreaTemplate',
|
|
entity_id=template_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'scope_template_id': scope_template_id}
|
|
)
|
|
|
|
|
|
async def publish_area_template_deleted(template_id: str, scope_template_id: str, triggered_by=None):
|
|
"""Publish AREA_TEMPLATE_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.AREA_TEMPLATE_DELETED,
|
|
entity_type='AreaTemplate',
|
|
entity_id=template_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'scope_template_id': scope_template_id}
|
|
)
|
|
|
|
|
|
async def publish_task_template_created(template_id: str, area_template_id: str, triggered_by=None):
|
|
"""Publish TASK_TEMPLATE_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.TASK_TEMPLATE_CREATED,
|
|
entity_type='TaskTemplate',
|
|
entity_id=template_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'area_template_id': area_template_id}
|
|
)
|
|
|
|
|
|
async def publish_task_template_updated(template_id: str, area_template_id: str, triggered_by=None):
|
|
"""Publish TASK_TEMPLATE_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.TASK_TEMPLATE_UPDATED,
|
|
entity_type='TaskTemplate',
|
|
entity_id=template_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'area_template_id': area_template_id}
|
|
)
|
|
|
|
|
|
async def publish_task_template_deleted(template_id: str, area_template_id: str, triggered_by=None):
|
|
"""Publish TASK_TEMPLATE_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.TASK_TEMPLATE_DELETED,
|
|
entity_type='TaskTemplate',
|
|
entity_id=template_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'area_template_id': area_template_id}
|
|
)
|
|
|
|
|
|
# Project Scope events
|
|
async def publish_project_scope_created(scope_id: str, project_id: str, triggered_by=None):
|
|
"""Publish PROJECT_SCOPE_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_SCOPE_CREATED,
|
|
entity_type='ProjectScope',
|
|
entity_id=scope_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'project_id': project_id}
|
|
)
|
|
|
|
|
|
async def publish_project_scope_updated(scope_id: str, project_id: str, triggered_by=None):
|
|
"""Publish PROJECT_SCOPE_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_SCOPE_UPDATED,
|
|
entity_type='ProjectScope',
|
|
entity_id=scope_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'project_id': project_id}
|
|
)
|
|
|
|
|
|
async def publish_project_scope_deleted(scope_id: str, project_id: str, triggered_by=None):
|
|
"""Publish PROJECT_SCOPE_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_SCOPE_DELETED,
|
|
entity_type='ProjectScope',
|
|
entity_id=scope_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'project_id': project_id}
|
|
)
|
|
|
|
|
|
async def publish_project_scope_category_created(category_id: str, scope_id: str, triggered_by=None):
|
|
"""Publish PROJECT_SCOPE_CATEGORY_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_SCOPE_CATEGORY_CREATED,
|
|
entity_type='ProjectScopeCategory',
|
|
entity_id=category_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'scope_id': scope_id}
|
|
)
|
|
|
|
|
|
async def publish_project_scope_category_updated(category_id: str, scope_id: str, triggered_by=None):
|
|
"""Publish PROJECT_SCOPE_CATEGORY_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_SCOPE_CATEGORY_UPDATED,
|
|
entity_type='ProjectScopeCategory',
|
|
entity_id=category_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'scope_id': scope_id}
|
|
)
|
|
|
|
|
|
async def publish_project_scope_category_deleted(category_id: str, scope_id: str, triggered_by=None):
|
|
"""Publish PROJECT_SCOPE_CATEGORY_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_SCOPE_CATEGORY_DELETED,
|
|
entity_type='ProjectScopeCategory',
|
|
entity_id=category_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'scope_id': scope_id}
|
|
)
|
|
|
|
|
|
async def publish_project_scope_task_created(task_id: str, category_id: str, triggered_by=None):
|
|
"""Publish PROJECT_SCOPE_TASK_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_SCOPE_TASK_CREATED,
|
|
entity_type='ProjectScopeTask',
|
|
entity_id=task_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'category_id': category_id}
|
|
)
|
|
|
|
|
|
async def publish_project_scope_task_updated(task_id: str, category_id: str, triggered_by=None):
|
|
"""Publish PROJECT_SCOPE_TASK_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_SCOPE_TASK_UPDATED,
|
|
entity_type='ProjectScopeTask',
|
|
entity_id=task_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'category_id': category_id}
|
|
)
|
|
|
|
|
|
async def publish_project_scope_task_deleted(task_id: str, category_id: str, triggered_by=None):
|
|
"""Publish PROJECT_SCOPE_TASK_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_SCOPE_TASK_DELETED,
|
|
entity_type='ProjectScopeTask',
|
|
entity_id=task_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'category_id': category_id}
|
|
)
|
|
|
|
|
|
async def publish_project_scope_template_instantiated(scope_id: str, template_id: str, project_id: str, triggered_by=None):
|
|
"""Publish PROJECT_SCOPE_TEMPLATE_INSTANTIATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.PROJECT_SCOPE_TEMPLATE_INSTANTIATED,
|
|
entity_type='ProjectScope',
|
|
entity_id=scope_id,
|
|
triggered_by=triggered_by,
|
|
metadata={'template_id': template_id, 'project_id': project_id}
|
|
)
|
|
|
|
|
|
# Labor & Revenue events
|
|
async def publish_labor_rate_created(rate_id: str, triggered_by=None):
|
|
"""Publish LABOR_RATE_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.LABOR_RATE_CREATED,
|
|
entity_type='LaborRate',
|
|
entity_id=rate_id,
|
|
triggered_by=triggered_by,
|
|
metadata={}
|
|
)
|
|
|
|
|
|
async def publish_labor_rate_updated(rate_id: str, triggered_by=None):
|
|
"""Publish LABOR_RATE_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.LABOR_RATE_UPDATED,
|
|
entity_type='LaborRate',
|
|
entity_id=rate_id,
|
|
triggered_by=triggered_by,
|
|
metadata={}
|
|
)
|
|
|
|
|
|
async def publish_labor_rate_deleted(rate_id: str, triggered_by=None):
|
|
"""Publish LABOR_RATE_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.LABOR_RATE_DELETED,
|
|
entity_type='LaborRate',
|
|
entity_id=rate_id,
|
|
triggered_by=triggered_by,
|
|
metadata={}
|
|
)
|
|
|
|
|
|
async def publish_revenue_rate_created(rate_id: str, triggered_by=None):
|
|
"""Publish REVENUE_RATE_CREATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.REVENUE_RATE_CREATED,
|
|
entity_type='RevenueRate',
|
|
entity_id=rate_id,
|
|
triggered_by=triggered_by,
|
|
metadata={}
|
|
)
|
|
|
|
|
|
async def publish_revenue_rate_updated(rate_id: str, triggered_by=None):
|
|
"""Publish REVENUE_RATE_UPDATED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.REVENUE_RATE_UPDATED,
|
|
entity_type='RevenueRate',
|
|
entity_id=rate_id,
|
|
triggered_by=triggered_by,
|
|
metadata={}
|
|
)
|
|
|
|
|
|
async def publish_revenue_rate_deleted(rate_id: str, triggered_by=None):
|
|
"""Publish REVENUE_RATE_DELETED event"""
|
|
return await EventPublisher.publish(
|
|
event_type=EventTypeChoices.REVENUE_RATE_DELETED,
|
|
entity_type='RevenueRate',
|
|
entity_id=rate_id,
|
|
triggered_by=triggered_by,
|
|
metadata={}
|
|
)
|