Stabilizza regia, live web e sync punteggi app nativa.

Corregge scadenza token regia oltre le 8h, tabellone HTML sulla pagina live,
pulsanti pausa/ripresa in regia, link admin e broadcast ActionCable diretto.
App Android: overlay branding, sync score da regia via WebSocket con reconnect e poll.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-08 09:30:43 +02:00
parent 08e800120a
commit ae36d17adb
55 changed files with 2819 additions and 285 deletions

View File

@@ -2,11 +2,16 @@ class Match < ApplicationRecord
belongs_to :team
has_many :stream_sessions, dependent: :destroy
has_one_attached :opponent_logo_file
ACTIVE_SESSION_STATUSES = %w[live connecting reconnecting paused].freeze
DEFAULT_OPPONENT_COLOR = "#1E3A8A"
validates :opponent_name, presence: true
validates :sets_to_win, numericality: { greater_than: 0, less_than: 6 }
validates :opponent_primary_color, format: { with: Brandable::HEX_COLOR }, allow_blank: true
validate :scoring_rules_shape, if: -> { scoring_rules.present? }
validate :opponent_logo_file_type, if: -> { opponent_logo_file.attached? }
# category: campionato / descrizione torneo (facoltativo, es. "Serie C").
@@ -63,6 +68,16 @@ class Match < ApplicationRecord
stream_sessions.where(status: %w[ended error]).exists?
end
def opponent_logo_url
return unless opponent_logo_file.attached?
Rails.application.routes.url_helpers.rails_blob_path(opponent_logo_file, only_path: true)
end
def effective_opponent_primary_color
opponent_primary_color.presence || DEFAULT_OPPONENT_COLOR
end
# Hub app coach: dirette da riprendere o partite programmate future.
# Le bozze «Avversario» abbandonate (senza sessione) non compaiono.
def coach_hub_visible?
@@ -77,6 +92,12 @@ class Match < ApplicationRecord
private
def opponent_logo_file_type
return if opponent_logo_file.content_type.in?(%w[image/png image/jpeg image/webp])
errors.add(:opponent_logo_file, "deve essere PNG, JPEG o WebP")
end
def scoring_rules_shape
rules = scoring_rules.is_a?(Hash) ? scoring_rules : {}
%w[points_per_set points_deciding_set min_point_lead].each do |key|