namespace :recordings do desc "Elimina replay scaduti (DB + storage)" task purge_expired: :environment do Recordings::PurgeExpiredJob.new.perform puts "Purge replay scaduti completata" end desc "Invia email di avviso scadenza replay (7 giorni)" task expiry_warnings: :environment do Recordings::ExpiryWarningJob.new.perform puts "Avvisi scadenza replay inviati" end desc "Rimuove segmenti MediaMTX locali di sessioni terminate (libera disco)" task cleanup_local: :environment do result = Recordings::CleanupLocal.new.call puts "Pulizia segmenti locali: rimossi=#{result.removed} " \ "liberati=#{result.freed_bytes} byte saltati=#{result.skipped}" orphan = Mediamtx::CleanupOrphanPaths.new.call puts "Path MediaMTX orfani rimossi: #{orphan.removed} (saltati: #{orphan.skipped})" end desc "Elimina copie temporanee YouTube scadute (solo storage, non soft-delete)" task purge_temporary: :environment do count = Recordings::PurgeTemporaryMediaJob.new.perform puts "Purge temporary replays: processed=#{count}" end desc "Audit dry-run: recording YouTube con ancora MP4 in Garage (duplicati storici). " \ "Cleanup solo se APPLY=1 (non implementato di default — solo report)." task audit_youtube_duplicates: :environment do apply = ENV["APPLY"].to_s == "1" scope = Recording.not_deleted .where.not(youtube_video_id: [nil, ""]) .where.not(storage_key: [nil, ""]) .where("youtube_video_id NOT LIKE 'mock_%'") puts "Audit YouTube duplicates (dry-run=#{!apply}): count=#{scope.count}" scope.find_each do |rec| puts [ "id=#{rec.id}", "policy=#{rec.storage_policy}", "key=#{rec.storage_key}", "yt=#{rec.youtube_video_id}", "purged_at=#{rec.local_media_purged_at.inspect}", "temp_expires=#{rec.temp_expires_at.inspect}" ].join(" ") end if apply puts "APPLY=1 richiesto ma cleanup storico automatico NON eseguito " \ "(fuori scope; solo dry-run supportato)." end end end