Completa modulo Replay: S3, retention, sync YouTube e gestione società.

Streaming chunked da Garage, purge con delete YouTube, privacy sincronizzata,
archivio club migliorato, retention 30/90 separata da stato abbonamento.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-08 09:33:59 +02:00
parent ae36d17adb
commit 74eee24293
17 changed files with 385 additions and 34 deletions

View File

@@ -5,7 +5,10 @@ module Api
def update
authorize_manage!
@recording.update!(recording_update_attrs)
attrs = recording_update_attrs
privacy_changed = attrs.key?(:privacy_status) && attrs[:privacy_status] != @recording.privacy_status
@recording.update!(attrs)
Recordings::SyncYoutubePrivacyJob.perform_async(@recording.id) if privacy_changed && @recording.youtube_video_id.present?
render json: recording_json(@recording)
end
@@ -96,7 +99,10 @@ module Api
youtube_video_id: recording.youtube_video_id,
youtube_watch_url: recording.youtube_watch_url,
youtube_publish_enabled: ent.premium_full? && ent.youtube_enabled?,
source_platform: recording.source_platform,
source_platform_label: recording.source_platform_label,
expires_at: recording.expires_at,
days_until_expiry: recording.days_until_expiry,
metadata: recording.metadata
}
end

View File

@@ -42,6 +42,7 @@ module Api
recs = team.recordings.not_deleted
.where(status: %w[ready processing])
.where("expires_at IS NULL OR expires_at > ?", Time.current)
.includes(stream_session: :match)
.order(recorded_at: :desc, created_at: :desc)
.limit(50)
@@ -167,7 +168,10 @@ module Api
youtube_video_id: recording.youtube_video_id,
youtube_watch_url: recording.youtube_watch_url,
youtube_publish_enabled: ent.premium_full? && ent.youtube_enabled?,
source_platform: recording.source_platform,
source_platform_label: recording.source_platform_label,
expires_at: recording.expires_at,
days_until_expiry: recording.days_until_expiry,
metadata: recording.metadata
}
end

View File

@@ -2,7 +2,7 @@ module Public
class ClubRecordingsController < WebBaseController
before_action :require_login!
before_action :set_club
before_action -> { require_club_owner!(@club) }
before_action :require_club_recording_manager!
before_action :set_recording, only: %i[update destroy publish_youtube]
def index
@@ -11,17 +11,39 @@ module Public
.not_deleted
.includes(stream_session: { match: :team })
.order(recorded_at: :desc, created_at: :desc)
if params[:team_id].present?
@recordings = @recordings.where(team_id: params[:team_id])
end
if params[:status].present?
case params[:status]
when "ready"
@recordings = @recordings.ready
when "processing"
@recordings = @recordings.where(status: "processing")
when "expired"
@recordings = @recordings.where(
"recordings.status IN (?) OR (recordings.expires_at IS NOT NULL AND recordings.expires_at <= ?)",
%w[expired failed], Time.current
)
end
end
@teams = @club.teams.order(:name)
@filter_team_id = params[:team_id]
@filter_status = params[:status]
end
def update
privacy = params.require(:recording).permit(:privacy_status, :title)[:privacy_status]
permitted = params.require(:recording).permit(:privacy_status, :title)
attrs = {}
privacy = permitted[:privacy_status]
attrs[:privacy_status] = privacy if privacy.in?(Recording::PRIVACY_STATUSES)
title = params.dig(:recording, :title)
title = permitted[:title]
attrs[:title] = title if title.present?
privacy_changed = attrs.key?(:privacy_status) && attrs[:privacy_status] != @recording.privacy_status
@recording.update!(attrs)
redirect_to public_club_recordings_path(@club), notice: "Replay aggiornato"
Recordings::SyncYoutubePrivacyJob.perform_async(@recording.id) if privacy_changed && @recording.youtube_video_id.present?
redirect_to public_club_recordings_path(@club, team_id: params[:team_id], status: params[:status]),
notice: "Replay aggiornato"
rescue ActiveRecord::RecordInvalid => e
redirect_to public_club_recordings_path(@club), alert: e.record.errors.full_messages.join(", ")
end
@@ -45,11 +67,21 @@ module Public
private
def set_club
@club = current_user.owned_clubs.find(params[:club_id])
@club = Club.find(params[:club_id])
end
def require_club_recording_manager!
return if current_user.owned_clubs.exists?(id: @club.id)
return if current_user.manageable_teams.joins(:club).exists?(clubs: { id: @club.id })
redirect_to public_clubs_path, alert: "Non autorizzato"
end
def set_recording
@recording = Recording.for_club(@club).not_deleted.find(params[:id])
return if Recordings::AccessPolicy.new(@recording, viewer: current_user).manage_allowed?
raise ActiveRecord::RecordNotFound
end
end
end