feat(broadcasting): add ActionCable adapter + fix model broadcast anti-pattern
- Add Mozo::Broadcaster::ActionCable as drop-in Faye replacement - Fix model_broadcast.rb: delegate to Mozo directly instead of ApplicationController.new (memory-unsafe anti-pattern) - Add Broadcastable concern for clean model-side broadcasting - ActionCable config: async adapter, cable.yml, WebSocket endpoint - MozoChannel with per-entity authorization (user/supplier/employee) - Connection auth via auth_token (matches existing auth pattern) - Mount /cable WebSocket in routes - Add broadcasting-migration.md with Faye→ActionCable guide
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Base channel. Streams are set up dynamically by clients subscribing
|
||||
# to their entity channel (user_123, supplier_456, etc.).
|
||||
#
|
||||
# The server broadcasts TO these channels via:
|
||||
# ActionCable.server.broadcast("user_123", { event: "...", data: {...} })
|
||||
#
|
||||
# Clients connect and subscribe via:
|
||||
# consumer.subscriptions.create({ channel: "MozoChannel", id: "user_123" })
|
||||
#
|
||||
class MozoChannel < ApplicationCable::Channel
|
||||
def subscribed
|
||||
stream_name = params[:id]
|
||||
if authorized?(stream_name)
|
||||
stream_from stream_name
|
||||
else
|
||||
reject
|
||||
end
|
||||
end
|
||||
|
||||
def unsubscribed
|
||||
# cleanup
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def authorized?(stream_name)
|
||||
prefix, id = stream_name.to_s.split('_', 2)
|
||||
case prefix
|
||||
when 'user'
|
||||
connection.current_entity_type == :user && connection.current_user.id.to_s == id
|
||||
when 'supplier'
|
||||
connection.current_entity_type == :supplier && connection.current_user.id.to_s == id
|
||||
when 'employee'
|
||||
connection.current_entity_type == :employee && connection.current_user.id.to_s == id
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user