Class: Spree::Admin::System::WaitingRoomSessionsController

Inherits:
BaseController
  • Object
show all
Defined in:
app/controllers/spree/admin/system/waiting_room_sessions_controller.rb

Constant Summary collapse

GUESTS_PER_PAGE_OPTIONS =
[25, 50, 100, 200, 500, 1000].freeze
GUESTS_DEFAULT_PER_PAGE =
50

Instance Method Summary collapse

Instance Method Details

#guestObject

GET .../waiting_room_sessions/guest -- the click target for a row's "Raw" button. Not part of the cached list/poll cycle: a lone extra Firestore read only when an admin actually wants the full document, instead of shipping every field of every row (up to MAX_DOCS of them) in the guests_status response whether anyone looks at it or not.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'app/controllers/spree/admin/system/waiting_room_sessions_controller.rb', line 91

def guest
  # This is the one place in the tab meant to show the truth of this instant, not a
  # 10s-old cached snapshot -- an admin opens it specifically to check a guest's current
  # state. expires_now stops the browser from ever serving a previous click's response
  # back for the same doc_id (e.g. reopening the same row after its state changed).
  expires_now

  date = params[:date].presence || Time.zone.today.strftime('%Y-%m-%d')
  doc_id = params[:doc_id]
  result = SpreeCmCommissioner::WaitingRoom::Guests::Find.call(date: date, doc_id: doc_id)
  error = result.error.to_s unless result.success?

  render partial: 'guest_raw', locals: { guest: result.value&.[](:guest), error: error }, layout: false
end

#guestsObject

Only resolves date/doc_id for the form + the frame's src URL. The actual Firestore read happens in #guests_status, once the browser loads that src -- never here, or every full-page load would pay for a read whose result is thrown away unrendered.



31
32
33
34
35
36
# File 'app/controllers/spree/admin/system/waiting_room_sessions_controller.rb', line 31

def guests
  @date = params[:date].presence || Time.zone.today.strftime('%Y-%m-%d')
  @doc_id = params[:doc_id].presence
  @per_page = guests_per_page
  @in_queue_only = guests_in_queue_only?
end

#guests_statusObject

GET .../waiting_room_sessions/guests_status -- the poll target, mirroring SeatLockable#seat_lock_status: a standalone endpoint the async-operation-status Stimulus controller reloads every 10s, kept separate from guests so the initial full-page load never has to guess whether it's being polled.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'app/controllers/spree/admin/system/waiting_room_sessions_controller.rb', line 42

def guests_status
  date = params[:date].presence || Time.zone.today.strftime('%Y-%m-%d')
  doc_id = params[:doc_id].presence
  in_queue_only = guests_in_queue_only?
  error = nil

  guests =
    if doc_id
      # A direct doc-id lookup always finds the doc regardless of status -- an admin
      # searching a specific id almost certainly wants to know its state (including
      # Admitted/Left), not have it hidden by the same filter that shapes the plain list.
      result = SpreeCmCommissioner::WaitingRoom::Guests::Find.call(date: date, doc_id: doc_id)
      error = result.error.to_s unless result.success?
      [result.value&.[](:guest)].compact
    else
      # Cached for the same span as the client's poll interval so N concurrently open admin
      # tabs (each polling every 10s) collapse into one Firestore read per date per 10s,
      # instead of one per open tab. Keyed by filter too -- "in queue" and "all" are
      # different Firestore queries, not a client-side slice of the same result.
      #
      # A failed fetch (e.g. a missing Firestore composite index for in_queue_only's
      # where+order combination) is never cached: caching `[]` would make the next 10s
      # poll -- and the one after that -- believe the queue is empty instead of retrying.
      cache_key = "admin/waiting_room_guests/#{date}/#{in_queue_only}"
      docs = Rails.cache.read(cache_key)

      if docs.nil?
        result = SpreeCmCommissioner::WaitingRoom::Guests::List.call(date: date, in_queue_only: in_queue_only)
        if result.success?
          docs = result.value[:guests]
          Rails.cache.write(cache_key, docs, expires_in: 10.seconds)
        else
          error = result.error.to_s
          docs = []
        end
      end

      Kaminari.paginate_array(docs).page(params[:page]).per(guests_per_page)
    end

  render partial: 'guests_table',
         locals: { guests: guests, doc_id_search: doc_id.present?, date: date, frontier_position: frontier_position, error: error },
         layout: false
end

#indexObject



8
9
10
11
12
13
14
15
# File 'app/controllers/spree/admin/system/waiting_room_sessions_controller.rb', line 8

def index
  @filter = params[:filter] if params[:filter] == 'load_test'

  sessions = SpreeCmCommissioner::WaitingRoomSession.active
  sessions = sessions.load_test if @filter == 'load_test'

  @waiting_room_sessions = sessions.order(created_at: :desc).page(params[:page]).per(50)
end

#killObject

Kills only the sessions the admin checked (Gmail-style select + delete), instead of the room's whole active set. Firebase's active_sessions/full reflect this only on the next Admission::CallGuests run (they're a once-a-minute mirror, not live).



20
21
22
23
24
25
26
# File 'app/controllers/spree/admin/system/waiting_room_sessions_controller.rb', line 20

def kill
  ids = Array(params[:ids])
  count = SpreeCmCommissioner::WaitingRoomSession.kill_by_ids!(ids)
  flash[:success] = "Killed #{count} waiting-room session(s)."

  redirect_back fallback_location: admin_system_waiting_room_sessions_path
end