Files
MatchLiveTv/backend/app/domain/sports/catalog.rb
Emiliano Frascaro e727069d43 Introduce architettura multi-sport con catalogo, engine scoring e overlay.
Catalogo sport in YAML, board implicito, engine per volley/basket/timed/racket/timer/generic, regia e app Android allineate.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-09 20:11:21 +02:00

95 lines
2.0 KiB
Ruby

# frozen_string_literal: true
module Sports
class Catalog
LEGACY_SPORT_MAP = {
"volleyball" => "pallavolo"
}.freeze
class << self
def all
@all ||= load_entries
end
def keys
all.keys
end
def find(key)
normalized = normalize_key(key)
entry = all[normalized]
raise KeyError, "Sport sconosciuto: #{key}" unless entry
entry.merge(key: normalized)
end
def find_optional(key)
normalized = normalize_key(key)
entry = all[normalized]
return nil unless entry
entry.merge(key: normalized)
end
def board_for(key)
find(key)[:board]
end
def overlay_for(key)
find(key)[:overlay]
end
def allowed_overlays_for(key)
find(key)[:allowed_overlays]
end
def default_rules_for(key)
deep_stringify_keys(find(key)[:default_rules] || {})
end
def normalize_key(key)
raw = key.to_s.strip
return "pallavolo" if raw.blank?
LEGACY_SPORT_MAP.fetch(raw, raw)
end
def as_api_list
all.map do |key, entry|
{
key: key,
label: entry[:label],
board: entry[:board],
overlay: entry[:overlay],
allowed_overlays: entry[:allowed_overlays],
default_rules: entry[:default_rules] || {}
}
end
end
private
def load_entries
path = Rails.root.join("config/sports.yml")
raw = YAML.safe_load(File.read(path), permitted_classes: [], aliases: true) || {}
raw.transform_keys(&:to_s).transform_values do |entry|
entry.deep_symbolize_keys
end.freeze
end
def deep_stringify_keys(value)
case value
when Hash
value.each_with_object({}) do |(k, v), h|
h[k.to_s] = deep_stringify_keys(v)
end
when Array
value.map { |v| deep_stringify_keys(v) }
else
value
end
end
end
end
end