diff --git a/backend/app/helpers/public/tournaments_helper.rb b/backend/app/helpers/public/tournaments_helper.rb
index 176d224..b82cc5b 100644
--- a/backend/app/helpers/public/tournaments_helper.rb
+++ b/backend/app/helpers/public/tournaments_helper.rb
@@ -100,8 +100,8 @@ module Public
def tournament_public_board_state(match)
return :live if tournament_public_live_session(match)
return :replay if tournament_public_recording(match)
+ return :ended if match.played? || match.result_status.to_s.start_with?("walkover") || match.home_score.present?
return :scheduled if match.scheduled_upcoming?
- return :ended if match.played? || match.home_score.present?
:waiting
end
diff --git a/backend/app/models/recording.rb b/backend/app/models/recording.rb
index a1b1df8..fcf8f0a 100644
--- a/backend/app/models/recording.rb
+++ b/backend/app/models/recording.rb
@@ -146,14 +146,22 @@ class Recording < ApplicationRecord
end
def title_or_default
- title.presence || default_title
+ match = stream_session&.match
+ return title.presence || "Replay" unless match
+
+ generated = match.matchup_label
+ stored = title.to_s.strip
+ return generated if stored.blank?
+ return generated if stale_auto_title?(match, stored)
+
+ stored
end
def default_title
match = stream_session&.match
return "Replay" unless match
- "#{match.team.name} vs #{match.opponent_name}"
+ match.matchup_label
end
def recorded_at_or_fallback
@@ -222,6 +230,18 @@ class Recording < ApplicationRecord
private
+ def stale_auto_title?(match, stored)
+ return false unless match.tournament_match?
+
+ team_name = match.team&.name.to_s
+ return false if team_name.blank?
+
+ [
+ "#{team_name} vs #{match.opponent_name}",
+ "#{team_name} vs #{match.away_display_name}"
+ ].include?(stored)
+ end
+
def normalize_privacy_status
self.privacy_status = "public" if privacy_status == "private"
self.privacy_status = "unlisted" if privacy_status.blank?
diff --git a/backend/app/services/recordings/finalize_session.rb b/backend/app/services/recordings/finalize_session.rb
index 6a5dea6..ee7e2d3 100644
--- a/backend/app/services/recordings/finalize_session.rb
+++ b/backend/app/services/recordings/finalize_session.rb
@@ -73,7 +73,7 @@ module Recordings
def default_title
match = @session.match
- "#{match.team.name} vs #{match.opponent_name}"
+ match.matchup_label.presence || "Replay"
end
def privacy_from_session
diff --git a/backend/app/views/public/tournament_pages/_tab_risultati.html.erb b/backend/app/views/public/tournament_pages/_tab_risultati.html.erb
index ceb1b25..afd2e9a 100644
--- a/backend/app/views/public/tournament_pages/_tab_risultati.html.erb
+++ b/backend/app/views/public/tournament_pages/_tab_risultati.html.erb
@@ -52,8 +52,11 @@
▶
-
<%= rec.title.presence || match.matchup_label %>
-
<%= match.matchup_label %>
+ <% phase = [match.tournament_round&.name, match.tournament_group&.name].compact.first %>
+
<%= match.matchup_label %>
+
+ <%= [phase, rec.recorded_at_or_fallback && l(rec.recorded_at_or_fallback, format: :short)].compact.join(" · ") %>
+
<% end %>
<% end %>
diff --git a/backend/spec/models/recording_spec.rb b/backend/spec/models/recording_spec.rb
index cefb10b..523af0a 100644
--- a/backend/spec/models/recording_spec.rb
+++ b/backend/spec/models/recording_spec.rb
@@ -31,4 +31,45 @@ RSpec.describe Recording do
rec = described_class.create!(stream_session: session, team: team, status: "processing")
expect(rec.title_or_default).to eq("Team vs Rival")
end
+
+ it "usa le squadre del tabellone al posto della squadra di trasmissione" do
+ load Rails.root.join("db/seeds/plans.rb")
+ Billing::AssignPlan.call(club: club, plan_slug: "premium_full")
+ ClubMembership.create!(user: user, club: club, role: "owner")
+ tournament = Tournaments::Create.call(
+ club: club,
+ attrs: {
+ name: "Memorial",
+ sport_key: "pallavolo",
+ starts_on: Date.current,
+ ends_on: Date.current,
+ format_kind: "free"
+ }
+ )
+ home = tournament.participants.create!(name: "Gamma")
+ away = tournament.participants.create!(name: "Beta")
+ tournament_match = Tournaments::ScheduleMatch.call(
+ tournament: tournament,
+ attrs: {
+ home_participant_id: home.id,
+ away_participant_id: away.id,
+ scheduled_at: 1.hour.from_now
+ }
+ )
+ tournament_session = StreamSession.create!(
+ match: tournament_match,
+ user: user,
+ platform: "matchlivetv",
+ status: "ended",
+ privacy_status: "public"
+ )
+ rec = described_class.create!(
+ stream_session: tournament_session,
+ team: tournament.broadcast_team,
+ status: "ready",
+ title: "#{tournament.broadcast_team.name} vs Beta"
+ )
+ expect(rec.title_or_default).to eq("Gamma vs Beta")
+ expect(rec.default_title).to eq("Gamma vs Beta")
+ end
end
diff --git a/backend/spec/requests/public/tournaments_spec.rb b/backend/spec/requests/public/tournaments_spec.rb
index 18e1159..033273f 100644
--- a/backend/spec/requests/public/tournaments_spec.rb
+++ b/backend/spec/requests/public/tournaments_spec.rb
@@ -767,7 +767,7 @@ RSpec.describe "Tournaments", type: :request do
session.update_columns(status: "ended", ended_at: Time.current)
Recording.create!(
stream_session: session, team: tournament.broadcast_team, status: "ready", privacy_status: "public",
- title: "Replay Alfa-Beta",
+ title: "#{tournament.broadcast_team.name} vs #{away.name}",
storage_key: "teams/#{tournament.broadcast_team_id}/sessions/#{session.id}/replay.mp4"
)
@@ -775,9 +775,45 @@ RSpec.describe "Tournaments", type: :request do
expect(response.body).to include("Guarda replay")
expect(response.body).to include(public_replay_path(session.id))
expect(response.body).to include("tournament-live-status--replay")
- expect(response.body).to include("Replay Alfa-Beta")
+ expect(response.body).to include("#{home.name} vs #{away.name}")
+ expect(response.body).not_to include("#{tournament.broadcast_team.name} vs #{away.name}")
get public_club_tournaments_path(club)
expect(response.body).to include(public_tournament_page_path(tournament.slug))
end
+
+ it "marca Terminata una gara con risultato anche se l'orario è ancora futuro" do
+ assign_plan!("premium_full")
+ login!
+ tournament = Tournaments::Create.call(
+ club: club,
+ attrs: {
+ name: "Open Risultato Anticipato",
+ sport_key: "pallavolo",
+ starts_on: Date.current,
+ ends_on: Date.current + 1,
+ format_kind: "free",
+ courts: "Campo 1"
+ }
+ )
+ home = tournament.participants.create!(name: "Alfa")
+ away = tournament.participants.create!(name: "Delta")
+ match = Tournaments::ScheduleMatch.call(
+ tournament: tournament,
+ attrs: {
+ home_participant_id: home.id,
+ away_participant_id: away.id,
+ court: "Campo 1",
+ scheduled_at: 6.hours.from_now
+ }
+ )
+ Tournaments::RecordResult.call(match: match, home_score: 2, away_score: 0, source: "manual")
+ post public_publish_tournament_path(tournament)
+
+ get public_tournament_page_path(tournament.slug, tab: "risultati")
+ expect(response.body).to include("2–0")
+ expect(response.body).to include("tournament-live-status--ended")
+ expect(response.body).to include("Terminata")
+ expect(response.body).not_to include("tournament-live-status--scheduled")
+ end
end
diff --git a/backend/spec/services/recordings/finalize_session_spec.rb b/backend/spec/services/recordings/finalize_session_spec.rb
index b41ba3f..3560c51 100644
--- a/backend/spec/services/recordings/finalize_session_spec.rb
+++ b/backend/spec/services/recordings/finalize_session_spec.rb
@@ -28,6 +28,7 @@ RSpec.describe Recordings::FinalizeSession do
expect(rec.storage_policy).to eq("retained")
expect(rec.expires_at).to be > 29.days.from_now
expect(rec.metadata["auto_publish_youtube"]).to eq(false)
+ expect(rec.title).to eq("Team vs Rival")
end
it "skips free plan" do