@Falco Ei, encontrei alguns problemas reproduzĂveis enquanto testava a versĂŁo atualizada do resenha. Compartilhando as descobertas + os patches que estou usando localmente, caso sejam Ăşteis upstream.
1. A UI de Admin descarta silenciosamente room_type; os quartos de estágio nunca conseguem manter o tipo
app/controllers/resenha/admin_rooms_controller.rb:65 (room_params) omite :room_type da lista de permissões, e admin_room_serializer.rb nunca o serializa.
Toda atribuição de estágio feita através da UI de admin é descartada; os quartos são criados como abertos e “regridem” para abertos em qualquer edição posterior de admin. Confirmado via logs de produção; o controller voltado ao usuário permite, apenas o caminho de admin o perdeu.
# admin_rooms_controller.rb — adicione :room_type à lista de permissões, então:
if permitted.key?(:room_type)
value = Resenha::Room::ROOM_TYPES[permitted[:room_type].to_s]
raise Discourse::InvalidParameters.new(:room_type) if value.nil?
permitted[:room_type] = value
end
# admin_room_serializer.rb — serialize room_type para que o formulário inicialize corretamente
2. room_type inválido cai silenciosamente para aberto
app/controllers/resenha/rooms_controller.rb:575 — ROOM_TYPES[...] || ROOM_TYPE_OPEN.
Qualquer room_type malformado/obsoleto em uma edição de quarto válida silenciosamente transforma um quarto de estágio em aberto. Um 400 torna visĂvel o chamador mal-comportado em vez de corromper o quarto.
value = Resenha::Room::ROOM_TYPES[permitted[:room_type].to_s]
raise Discourse::InvalidParameters.new(:room_type) if value.nil?
permitted[:room_type] = value
3. Heartbeat ressuscita um usuário que acabou de sair (presença fantasma)
rooms_controller.rb:234 (heartbeat) re-adiciona presença incondicionalmente, então um heartbeat em voo quando leave (:220) processa chega em segundo lugar e re-cria o usuário que partiu.
O fantasma persiste até a reaplicação do TTL, que não faz broadcast — os clientes o mostram “no quarto” por até um minuto.
Reproduzido em dispositivo; kick tem a exposição idêntica.
# ParticipantTracker: lápide de 15s
def mark_left(room_id, user_id) = redis.setex(left_key(room_id, user_id), 15, "1")
def recently_left?(room_id, user_id) = redis.exists?(left_key(room_id, user_id))
# leave/kick → mark_left; join/livekit_token → clear_left; heartbeat:
return head :no_content if Resenha::ParticipantTracker.recently_left?(@room.id, current_user.id)
4. Webhook participant_left obsoleto faz kick fantasma em uma sessĂŁo nova
livekit_webhooks_controller.rb:37/57 — partidas são combinadas apenas pela identidade do usuário.
Em uma desconexĂŁo/reconexĂŁo rápida, o participant_left da sessĂŁo substituĂda chega atrasado e expira a presença da nova sessĂŁo (usuário “expulso” ~3s apĂłs reconectar, de volta ~15s depois).
Reproduzido em dispositivo; a heurĂstica gone_at nĂŁo consegue distinguir as sessões quando a reconexĂŁo antecede a desconexĂŁo da sessĂŁo antiga.
# participant_joined → registre o SID vivo
Resenha::ParticipantTracker.set_livekit_sid(room.id, user_id, event.dig("participant", "sid"))
# expire_participant → pule a partida de uma sessĂŁo substituĂda
known = Resenha::ParticipantTracker.livekit_sid(room.id, user_id)
return if sid.present? && known.present? && sid != known
5. DeleteRoom 404 apĂłs a Ăşltima saĂda inunda os logs
lib/resenha/livekit/room_service_client.rb:84 alerta em qualquer nĂŁo-200.
O SFU fecha automaticamente um quarto no momento em que fica vazio, entĂŁo o DeleteRoom da Ăşltima saĂda rotineiramente compete com ele — “quarto solicitado nĂŁo existe” Ă© o estado final desejado, nĂŁo uma falha.
Ele cai no Logster em toda Ăşltima saĂda.
elsif method == "DeleteRoom" && response.status == 404
Rails.logger.debug("[resenha-livekit] DeleteRoom no-op para quarto #{room.id}: já foi embora")
true
Posso enviar um pull request se vocĂŞ desejar.
Como disse anteriormente, não conheço sua direção em detalhes, mas você pode dar uma olhada na minha, já que fiz um post aqui → Discourse Desktop Mac App - #10 by nicolsdennis