namespace :matches do desc "Pulizia bozze abbandonate e sessioni idle obsolete (hub coach). DRY_RUN=1 per anteprima." task cleanup_stale: :environment do dry = ENV["DRY_RUN"] == "1" cutoff_abandoned = ENV.fetch("ABANDONED_DAYS", "1").to_i.days.ago cutoff_idle = ENV.fetch("IDLE_HOURS", "48").to_i.hours.ago abandoned = Match .where(scheduled_at: nil) .where.missing(:stream_sessions) .where("matches.created_at < ?", cutoff_abandoned) stale_idle_sessions = StreamSession .where(status: "idle") .where("stream_sessions.updated_at < ?", cutoff_idle) puts "DRY RUN — nessuna modifica" if dry puts "Bozze abbandonate (senza sessione, > #{cutoff_abandoned}): #{abandoned.count}" abandoned.find_each do |match| label = "#{match.team.name} vs #{match.opponent_name} (#{match.id})" if dry puts " would delete match #{label}" else match.destroy! puts " deleted match #{label}" end end puts "Sessioni idle obsolete (> #{cutoff_idle}): #{stale_idle_sessions.count}" stale_idle_sessions.find_each do |session| match = session.match label = "#{match.team.name} vs #{match.opponent_name} session=#{session.id}" if dry puts " would end idle session #{label}" else session.end_stream! puts " ended idle session #{label}" end end hidden_completed = Match.includes(:stream_sessions).select do |m| m.stream_completed? && m.active_stream_session.nil? end puts "Partite concluse (già nascoste dall'hub): #{hidden_completed.size}" if ENV["DELETE_COMPLETED"] == "1" hidden_completed.each do |match| session_ids = match.stream_sessions.pluck(:id) next if Recording.where(stream_session_id: session_ids).exists? label = "#{match.team.name} vs #{match.opponent_name} (#{match.id})" if dry puts " would delete completed #{label}" else match.destroy! puts " deleted completed #{label}" end end end end end