Packages
phoenix_kit
1.7.39
1.7.208
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/modules/tickets/events.ex
defmodule PhoenixKit.Modules.Tickets.Events do
@moduledoc """
PubSub events for PhoenixKit Tickets system.
Broadcasts ticket-related events for real-time updates in LiveViews.
Uses `PhoenixKit.PubSub.Manager` for self-contained PubSub operations.
## Topics
- `"tickets:all"` - All tickets (for admins)
- `"tickets:user:{user_id}"` - Tickets for specific user
- `"tickets:{id}"` - Specific ticket (for detail view)
## Events
### Ticket Events
- `{:ticket_created, ticket}` - New ticket created
- `{:ticket_updated, ticket}` - Ticket updated
- `{:ticket_status_changed, ticket, old_status, new_status}` - Status transition
- `{:ticket_assigned, ticket, old_assignee_id, new_assignee_id}` - Assignment change
- `{:ticket_priority_changed, ticket, old_priority, new_priority}` - Priority change
- `{:tickets_bulk_updated, tickets, changes}` - Bulk update operation
### Comment Events
- `{:comment_created, comment, ticket}` - Public comment added
- `{:internal_note_created, comment, ticket}` - Internal note added (staff only)
## Usage Examples
# Subscribe to all ticket events (admin view)
PhoenixKit.Modules.Tickets.Events.subscribe_to_all()
# Subscribe to user's tickets
PhoenixKit.Modules.Tickets.Events.subscribe_to_user_tickets(user_id)
# Subscribe to specific ticket (detail view)
PhoenixKit.Modules.Tickets.Events.subscribe_to_ticket(ticket_id)
# Handle in LiveView
def handle_info({:ticket_created, ticket}, socket) do
# Update UI
{:noreply, socket}
end
"""
alias PhoenixKit.PubSub.Manager
alias PhoenixKit.Users.Auth
@all_topic "tickets:all"
# ============================================================================
# TOPIC BUILDERS
# ============================================================================
@doc """
Returns the PubSub topic for a specific user's tickets.
"""
def user_topic(user_id) when is_integer(user_id) do
"tickets:user:#{user_id}"
end
def user_topic(user_id) when is_binary(user_id) do
# Resolve UUID to integer ID to ensure consistent topic names
case Integer.parse(user_id) do
{int_id, ""} ->
"tickets:user:#{int_id}"
_ ->
case Auth.get_user(user_id) do
%{id: int_id} -> "tickets:user:#{int_id}"
nil -> "tickets:user:unknown"
end
end
end
@doc """
Returns the PubSub topic for a specific ticket.
"""
def ticket_topic(ticket_id) when is_binary(ticket_id) do
"tickets:#{ticket_id}"
end
# ============================================================================
# SUBSCRIPTION FUNCTIONS
# ============================================================================
@doc """
Subscribes to all ticket events (for admin views).
"""
def subscribe_to_all do
Manager.subscribe(@all_topic)
end
@doc """
Alias for subscribe_to_all/0 for consistency with naming convention.
Subscribes to all ticket events (for admin views).
"""
def subscribe_tickets, do: subscribe_to_all()
@doc """
Subscribes to ticket events for a specific user.
"""
def subscribe_to_user_tickets(user_id) when is_integer(user_id) do
Manager.subscribe(user_topic(user_id))
end
def subscribe_to_user_tickets(user_id) when is_binary(user_id) do
Manager.subscribe(user_topic(user_id))
end
@doc """
Subscribes to events for a specific ticket (for detail views).
"""
def subscribe_to_ticket(ticket_id) when is_binary(ticket_id) do
Manager.subscribe(ticket_topic(ticket_id))
end
@doc """
Unsubscribes from all ticket events.
"""
def unsubscribe_from_all do
Manager.unsubscribe(@all_topic)
end
@doc """
Unsubscribes from a specific user's ticket events.
"""
def unsubscribe_from_user_tickets(user_id) when is_integer(user_id) do
Manager.unsubscribe(user_topic(user_id))
end
def unsubscribe_from_user_tickets(user_id) when is_binary(user_id) do
Manager.unsubscribe(user_topic(user_id))
end
@doc """
Unsubscribes from a specific ticket's events.
"""
def unsubscribe_from_ticket(ticket_id) when is_binary(ticket_id) do
Manager.unsubscribe(ticket_topic(ticket_id))
end
# ============================================================================
# TICKET BROADCASTS
# ============================================================================
@doc """
Broadcasts ticket created event.
"""
def broadcast_ticket_created(ticket) do
broadcast(@all_topic, {:ticket_created, ticket})
broadcast(user_topic(ticket.user_id), {:ticket_created, ticket})
broadcast(ticket_topic(ticket.uuid), {:ticket_created, ticket})
end
@doc """
Broadcasts ticket updated event.
"""
def broadcast_ticket_updated(ticket) do
broadcast(@all_topic, {:ticket_updated, ticket})
broadcast(user_topic(ticket.user_id), {:ticket_updated, ticket})
broadcast(ticket_topic(ticket.uuid), {:ticket_updated, ticket})
end
@doc """
Broadcasts ticket status changed event.
"""
def broadcast_ticket_status_changed(ticket, old_status, new_status) do
message = {:ticket_status_changed, ticket, old_status, new_status}
broadcast(@all_topic, message)
broadcast(user_topic(ticket.user_id), message)
broadcast(ticket_topic(ticket.uuid), message)
end
@doc """
Broadcasts ticket assigned event.
"""
def broadcast_ticket_assigned(ticket, old_assignee_id, new_assignee_id) do
message = {:ticket_assigned, ticket, old_assignee_id, new_assignee_id}
broadcast(@all_topic, message)
broadcast(user_topic(ticket.user_id), message)
broadcast(ticket_topic(ticket.uuid), message)
# Also broadcast to the new assignee's topic if assigned
if new_assignee_id do
broadcast(user_topic(new_assignee_id), message)
end
end
@doc """
Broadcasts ticket priority changed event.
"""
def broadcast_ticket_priority_changed(ticket, old_priority, new_priority) do
message = {:ticket_priority_changed, ticket, old_priority, new_priority}
broadcast(@all_topic, message)
broadcast(user_topic(ticket.user_id), message)
broadcast(ticket_topic(ticket.uuid), message)
end
@doc """
Broadcasts tickets bulk updated event.
"""
def broadcast_tickets_bulk_updated(tickets, changes) do
broadcast(@all_topic, {:tickets_bulk_updated, tickets, changes})
# Also broadcast to each affected user's topic
tickets
|> Enum.map(& &1.user_id)
|> Enum.uniq()
|> Enum.each(fn user_id ->
broadcast(user_topic(user_id), {:tickets_bulk_updated, tickets, changes})
end)
end
# ============================================================================
# COMMENT BROADCASTS
# ============================================================================
@doc """
Broadcasts public comment created event.
"""
def broadcast_comment_created(comment, ticket) do
message = {:comment_created, comment, ticket}
broadcast(@all_topic, message)
broadcast(user_topic(ticket.user_id), message)
broadcast(ticket_topic(ticket.uuid), message)
end
@doc """
Broadcasts internal note created event (staff only).
"""
def broadcast_internal_note_created(comment, ticket) do
message = {:internal_note_created, comment, ticket}
# Internal notes only broadcast to admin topic and ticket topic
# (not to user's personal topic since they shouldn't see internal notes)
broadcast(@all_topic, message)
broadcast(ticket_topic(ticket.uuid), message)
end
# ============================================================================
# PRIVATE HELPERS
# ============================================================================
defp broadcast(topic, message) do
Manager.broadcast(topic, message)
end
end