Files
qlockify-backend-deployment/apps/notifications/services/membership_events.py

147 lines
4.8 KiB
Python

from apps.notifications.services.store import RedisNotificationStore
def _actor_name(actor) -> str:
full_name = getattr(actor, "full_name", "").strip()
if full_name and full_name != "Anonymous":
return full_name
return getattr(actor, "mobile", str(actor))
def _role_label(role_enum, role_value: str) -> str:
try:
return str(role_enum(role_value).label).lower()
except Exception:
pass
with_labels = getattr(role_enum, "labels", None)
if isinstance(with_labels, dict):
return str(with_labels.get(role_value, role_value)).lower()
return str(role_value).replace("_", " ").lower()
def _should_skip(actor, recipient) -> bool:
return not recipient or str(actor.id) == str(recipient.id)
def _notify_user(recipient, payload: dict) -> None:
RedisNotificationStore.add(str(recipient.id), payload)
def _workspace_action_url(workspace) -> str:
return f"/workspaces/{workspace.id}"
def notify_workspace_membership_added(*, actor, recipient, workspace, role: str) -> None:
if _should_skip(actor, recipient):
return
actor_display = _actor_name(actor)
role_label = _role_label(recipient.workspace_memberships.model.Role, role)
_notify_user(
recipient,
{
"type": "workspace_membership_added",
"title": "Added to workspace",
"message": (
f"{actor_display} added you to {workspace.name} as {role_label}."
),
"level": "info",
"action_url": _workspace_action_url(workspace),
"entity_type": "workspace",
"entity_id": str(workspace.id),
"meta": {
"workspace_id": str(workspace.id),
"workspace_name": workspace.name,
"actor_id": str(actor.id),
"actor_name": actor_display,
"new_role": role,
},
},
)
def notify_workspace_membership_role_changed(
*, actor, recipient, workspace, previous_role: str, new_role: str
) -> None:
if _should_skip(actor, recipient) or previous_role == new_role:
return
actor_display = _actor_name(actor)
previous_role_label = _role_label(recipient.workspace_memberships.model.Role, previous_role)
new_role_label = _role_label(recipient.workspace_memberships.model.Role, new_role)
_notify_user(
recipient,
{
"type": "workspace_membership_role_changed",
"title": "Workspace role changed",
"message": (
f"{actor_display} changed your role in {workspace.name} "
f"from {previous_role_label} to {new_role_label}."
),
"level": "info",
"action_url": _workspace_action_url(workspace),
"entity_type": "workspace",
"entity_id": str(workspace.id),
"meta": {
"workspace_id": str(workspace.id),
"workspace_name": workspace.name,
"actor_id": str(actor.id),
"actor_name": actor_display,
"previous_role": previous_role,
"new_role": new_role,
},
},
)
def notify_workspace_membership_deactivated(*, actor, recipient, workspace, role: str) -> None:
if _should_skip(actor, recipient):
return
actor_display = _actor_name(actor)
_notify_user(
recipient,
{
"type": "workspace_membership_deactivated",
"title": "Workspace access deactivated",
"message": f"{actor_display} deactivated your access to {workspace.name}.",
"level": "warning",
"action_url": _workspace_action_url(workspace),
"entity_type": "workspace",
"entity_id": str(workspace.id),
"meta": {
"workspace_id": str(workspace.id),
"workspace_name": workspace.name,
"actor_id": str(actor.id),
"actor_name": actor_display,
"previous_role": role,
},
},
)
def notify_workspace_membership_removed(*, actor, recipient, workspace, role: str) -> None:
if _should_skip(actor, recipient):
return
actor_display = _actor_name(actor)
_notify_user(
recipient,
{
"type": "workspace_membership_removed",
"title": "Removed from workspace",
"message": f"{actor_display} removed you from {workspace.name}.",
"level": "warning",
"action_url": _workspace_action_url(workspace),
"entity_type": "workspace",
"entity_id": str(workspace.id),
"meta": {
"workspace_id": str(workspace.id),
"workspace_name": workspace.name,
"actor_id": str(actor.id),
"actor_name": actor_display,
"previous_role": role,
},
},
)