Initial commit: monorepo Match Live TV.

Rails API, app Flutter, infrastruttura Docker/MediaMTX, sito marketing e documentazione di deploy.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-26 17:45:37 +02:00
commit bba6df52c0
381 changed files with 20599 additions and 0 deletions

View File

@@ -0,0 +1 @@
# attr_encrypted uses per-model :key option (see YoutubeCredential, StreamSession)

View File

@@ -0,0 +1,9 @@
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins ENV.fetch("CORS_ORIGINS", "*").split(",")
resource "*",
headers: :any,
methods: %i[get post put patch delete options head],
expose: %w[Authorization]
end
end

View File

@@ -0,0 +1,4 @@
Rails.application.config.filter_parameters += [
:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn,
:stream_key, :password, :access_token, :refresh_token, :pairing_token
]

View File

@@ -0,0 +1,16 @@
# Be sure to restart your server when you modify this file.
# Add new inflection rules using the following format. Inflections
# are locale specific, and you may define rules for as many different
# locales as you wish. All of these examples are active by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.plural /^(ox)$/i, "\\1en"
# inflect.singular /^(ox)en/i, "\\1"
# inflect.irregular "person", "people"
# inflect.uncountable %w( fish sheep )
# end
# These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.acronym "RESTful"
# end

View File

@@ -0,0 +1,55 @@
module MatchLiveTv
class << self
def jwt_secret
ENV.fetch("JWT_SECRET", Rails.application.secret_key_base)
end
def mediamtx_api_url
ENV.fetch("MEDIAMTX_API_URL", "http://localhost:9997")
end
def mediamtx_rtmp_url
ENV.fetch("MEDIAMTX_RTMP_URL", "rtmp://localhost:1935")
end
def mediamtx_webhook_secret
ENV.fetch("MEDIAMTX_WEBHOOK_SECRET", "change_me")
end
def reconnect_timeout_seconds
ENV.fetch("RECONNECT_TIMEOUT_SECONDS", "300").to_i
end
def hls_public_url
ENV.fetch("HLS_PUBLIC_URL", "http://localhost:8888")
end
def mediamtx_hls_url
ENV.fetch("MEDIAMTX_HLS_URL", "http://mediamtx:8888")
end
def app_public_url
ENV.fetch("APP_PUBLIC_URL", "http://localhost:3000")
end
def stripe_secret_key
ENV["STRIPE_SECRET_KEY"].presence
end
def stripe_webhook_secret
ENV["STRIPE_WEBHOOK_SECRET"].presence
end
def stripe_premium_light_price_id
ENV.fetch("STRIPE_PREMIUM_LIGHT_PRICE_ID", ENV.fetch("STRIPE_PREMIUM_PRICE_ID", ""))
end
def stripe_premium_full_price_id
ENV.fetch("STRIPE_PREMIUM_FULL_PRICE_ID", ENV.fetch("STRIPE_PREMIUM_PRICE_ID", ""))
end
def stripe_enabled?
stripe_secret_key.present?
end
end
end

View File

@@ -0,0 +1,11 @@
class Rack::Attack
throttle("api/ip", limit: 300, period: 5.minutes) do |req|
req.ip if req.path.start_with?("/api/")
end
throttle("auth/ip", limit: 20, period: 5.minutes) do |req|
req.ip if req.path.include?("/auth/login")
end
end
Rails.application.config.middleware.use Rack::Attack if defined?(Rack::Attack)

View File

@@ -0,0 +1,9 @@
require "sidekiq/api"
Sidekiq.configure_server do |config|
config.redis = { url: ENV.fetch("REDIS_URL", "redis://localhost:6379/0") }
end
Sidekiq.configure_client do |config|
config.redis = { url: ENV.fetch("REDIS_URL", "redis://localhost:6379/0") }
end

View File

@@ -0,0 +1,2 @@
# Schedule CleanupExpiredSessionsJob hourly via host cron or Kamal:
# 0 * * * * cd /app && bundle exec rails runner "CleanupExpiredSessionsJob.perform_async"

View File

@@ -0,0 +1,3 @@
if MatchLiveTv.stripe_secret_key.present?
Stripe.api_key = MatchLiveTv.stripe_secret_key
end