Aggiunge copertina sponsor custom solo Premium Full, con override in wizard e slate sui nodi di streaming.

Permette upload da portale e app con ereditarietà partita→squadra→società, generazione MP4 via ffmpeg e distribuzione su home lab e nodi CPX per pause e assenza segnale.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-19 23:47:17 +02:00
co-authored by Cursor
parent a51d5e8da5
commit 41d4235258
62 changed files with 1487 additions and 20 deletions
+1
View File
@@ -1,5 +1,6 @@
class Club < ApplicationRecord
include Brandable
include Coverable
include ClubBillingProfile
has_many :club_memberships, dependent: :destroy
+50
View File
@@ -0,0 +1,50 @@
module Coverable
extend ActiveSupport::Concern
COVER_IMAGE_TYPES = %w[image/png image/jpeg image/webp].freeze
MAX_COVER_BYTES = 5.megabytes
included do
has_one_attached :cover_image
has_one_attached :cover_slate
validate :cover_image_file_type, if: -> { cover_image.attached? && cover_image.blob&.new_record? }
validate :cover_image_file_size, if: -> { cover_image.attached? && cover_image.blob&.new_record? }
end
def cover_image_attached?
cover_image.attached?
end
def cover_url
return unless cover_image.attached?
Rails.application.routes.url_helpers.rails_blob_path(cover_image, only_path: true)
end
def effective_cover_url
if cover_image.attached?
cover_url
else
cover_parent&.effective_cover_url
end
end
private
def cover_parent
nil
end
def cover_image_file_type
return if cover_image.content_type.in?(COVER_IMAGE_TYPES)
errors.add(:cover_image, I18n.t("coverable.errors.invalid_type"))
end
def cover_image_file_size
return if cover_image.byte_size <= MAX_COVER_BYTES
errors.add(:cover_image, I18n.t("coverable.errors.too_large"))
end
end
+6
View File
@@ -1,4 +1,6 @@
class Match < ApplicationRecord
include Coverable
belongs_to :team
has_many :stream_sessions, dependent: :destroy
@@ -174,4 +176,8 @@ class Match < ApplicationRecord
rescue ArgumentError => e
errors.add(:scoring_rules, e.message)
end
def cover_parent
nil
end
end
+4
View File
@@ -84,6 +84,10 @@ class Plan < ApplicationRecord
feature("youtube_enabled") == true
end
def custom_cover_enabled?
feature("custom_cover") == true
end
def premium?
slug.in?(PREMIUM_SLUGS)
end
+5
View File
@@ -1,5 +1,6 @@
class Team < ApplicationRecord
include Brandable
include Coverable
belongs_to :club
has_many :user_teams, dependent: :destroy
@@ -99,6 +100,10 @@ class Team < ApplicationRecord
club
end
def cover_parent
club
end
def assign_slug
self.slug = Teams::GenerateSlug.call(self) if slug.blank?
end