refactor: rename timer db column
This commit is contained in:
parent
13acbad55f
commit
e9ef73c230
|
|
@ -173,14 +173,14 @@ class TournamentsController < ApplicationController
|
|||
|
||||
def timer_params
|
||||
{
|
||||
timer_end: params[:timer_end],
|
||||
timestamp: params[:timestamp],
|
||||
timer_mode: params[:timer_mode]
|
||||
}
|
||||
end
|
||||
|
||||
def serialize_timer_state(tournament)
|
||||
{
|
||||
timestamp: tournament.timer_end&.iso8601,
|
||||
timestamp: tournament.timestamp&.iso8601,
|
||||
timer_mode: tournament.timer_mode
|
||||
}
|
||||
end
|
||||
|
|
@ -344,7 +344,7 @@ class TournamentsController < ApplicationController
|
|||
status: :unprocessable_entity
|
||||
end
|
||||
|
||||
params[:timer_end] = nil
|
||||
params[:timestamp] = nil
|
||||
params[:timer_mode] = nil
|
||||
return
|
||||
end
|
||||
|
|
@ -372,7 +372,7 @@ class TournamentsController < ApplicationController
|
|||
return render json: { error: 'Timestamp must be in the future for countdown mode' }, status: :unprocessable_entity if timestamp_seconds <= 0
|
||||
|
||||
parsed_time = Time.zone.now + timestamp_seconds
|
||||
params[:timer_end] = parsed_time
|
||||
params[:timestamp] = parsed_time
|
||||
params[:timer_mode] = 'countdown'
|
||||
elsif timestamp.present?
|
||||
begin
|
||||
|
|
@ -383,13 +383,13 @@ class TournamentsController < ApplicationController
|
|||
return render json: { error: 'Timestamp must be in the future for countdown mode' }, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
params[:timer_end] = parsed_time
|
||||
params[:timestamp] = parsed_time
|
||||
params[:timer_mode] = timer_mode.presence || 'countdown'
|
||||
rescue ArgumentError
|
||||
return render json: { error: 'Invalid timestamp format' }, status: :unprocessable_entity
|
||||
end
|
||||
elsif timer_mode == 'countup'
|
||||
params[:timer_end] = Time.zone.now
|
||||
params[:timestamp] = Time.zone.now
|
||||
elsif timer_mode.present?
|
||||
return render json: { error: 'timer_mode requires timestamp, timestamp_seconds, or clear_timer' },
|
||||
status: :unprocessable_entity
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ class Tournament < ApplicationRecord
|
|||
end
|
||||
|
||||
def saved_change_to_timer_state?
|
||||
saved_change_to_timer_end? || saved_change_to_timer_mode?
|
||||
saved_change_to_timestamp? || saved_change_to_timer_mode?
|
||||
end
|
||||
|
||||
def broadcast_timer_state_change
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class TournamentSerializer < SimpleTournamentSerializer
|
|||
has_many :team_action_lists
|
||||
|
||||
attribute :timestamp do
|
||||
object.timer_end&.iso8601
|
||||
object.timestamp&.iso8601
|
||||
end
|
||||
|
||||
attribute :timer_mode
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class TournamentSnapshotBuilder
|
|||
|
||||
def build
|
||||
payload = tournament.attributes.symbolize_keys.slice(*ROOT_ATTRIBUTES)
|
||||
payload[:timestamp] = tournament.timer_end&.iso8601
|
||||
payload[:timestamp] = tournament.timestamp&.iso8601
|
||||
payload[:timer_mode] = tournament.timer_mode
|
||||
payload[:sync_generated_at] = Time.current.iso8601(6)
|
||||
payload[:teams] = teams_payload
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class TournamentSnapshotImporter
|
|||
def update_tournament!
|
||||
root_attrs = snapshot.slice(*ROOT_ATTRIBUTES)
|
||||
root_attrs[:code] = tournament.code if code_taken_by_another_tournament?(root_attrs[:code])
|
||||
root_attrs[:timer_end] = parse_time(snapshot[:timestamp])
|
||||
root_attrs[:timestamp] = parse_time(snapshot[:timestamp])
|
||||
root_attrs[:timer_mode] = snapshot[:timer_mode]
|
||||
root_attrs[:sync_source_tournament_id] = snapshot[:id]
|
||||
root_attrs[:sync_last_imported_snapshot_at] = snapshot_generated_at
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class TournamentSyncSchema
|
|||
playoff_teams_amount
|
||||
instant_finalists_amount
|
||||
intermediate_round_participants_amount
|
||||
timer_end
|
||||
timestamp
|
||||
timer_mode
|
||||
].freeze,
|
||||
ignored: %w[
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ class TournamentTimerBroadcastPayload
|
|||
{
|
||||
type: 'timer.updated',
|
||||
tournament_id: tournament.id,
|
||||
timestamp: tournament.timer_end&.iso8601,
|
||||
timestamp: tournament.timestamp&.iso8601,
|
||||
timer_mode: tournament.timer_mode
|
||||
}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RenameTimerEndToTimestampOnTournaments < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
rename_column :tournaments, :timer_end, :timestamp
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
# This file is auto-generated from the current state of the database. Instead
|
||||
# of editing this file, please use the migrations feature of Active Record to
|
||||
# incrementally modify your database, and then regenerate this schema definition.
|
||||
#
|
||||
# This file is the source Rails uses to define your schema when running `bin/rails
|
||||
# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
|
||||
# be faster and is potentially less error prone than running all of your
|
||||
# migrations from scratch. Old migrations may fail to apply correctly if those
|
||||
# migrations use external dependencies or application code.
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[7.0].define(version: 2026_04_24_120000) do
|
||||
create_table "beamers", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.string "display_state", default: "matches_all", null: false
|
||||
t.boolean "is_default", default: false
|
||||
t.string "qr_code_url"
|
||||
t.string "logo_url"
|
||||
t.integer "tournament_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "sync_source_id"
|
||||
t.index ["tournament_id", "name"], name: "index_beamers_on_tournament_id_and_name", unique: true
|
||||
t.index ["tournament_id"], name: "index_beamers_on_tournament_id"
|
||||
end
|
||||
|
||||
create_table "bets", force: :cascade do |t|
|
||||
t.integer "user_id", null: false
|
||||
t.integer "match_id", null: false
|
||||
t.integer "team_id"
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
t.datetime "updated_at", precision: nil, null: false
|
||||
t.index ["match_id"], name: "index_bets_on_match_id"
|
||||
t.index ["team_id"], name: "index_bets_on_team_id"
|
||||
t.index ["user_id"], name: "index_bets_on_user_id"
|
||||
end
|
||||
|
||||
create_table "group_scores", force: :cascade do |t|
|
||||
t.integer "group_points", default: 0
|
||||
t.integer "scored_points", default: 0
|
||||
t.integer "received_points", default: 0
|
||||
t.integer "team_id", null: false
|
||||
t.integer "group_id", null: false
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
t.datetime "updated_at", precision: nil, null: false
|
||||
t.integer "position", default: 0
|
||||
t.integer "sync_source_id"
|
||||
t.index ["group_id"], name: "index_group_scores_on_group_id"
|
||||
t.index ["team_id"], name: "index_group_scores_on_team_id"
|
||||
end
|
||||
|
||||
create_table "groups", force: :cascade do |t|
|
||||
t.integer "number"
|
||||
t.integer "stage_id", null: false
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
t.datetime "updated_at", precision: nil, null: false
|
||||
t.integer "sync_source_id"
|
||||
t.index ["stage_id"], name: "index_groups_on_stage_id"
|
||||
end
|
||||
|
||||
create_table "match_scores", force: :cascade do |t|
|
||||
t.integer "points", default: 0
|
||||
t.integer "match_id", null: false
|
||||
t.integer "team_id", null: false
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
t.datetime "updated_at", precision: nil, null: false
|
||||
t.integer "hidden_points", default: 0, null: false
|
||||
t.integer "sync_source_id"
|
||||
t.index ["match_id"], name: "index_match_scores_on_match_id"
|
||||
t.index ["team_id"], name: "index_match_scores_on_team_id"
|
||||
end
|
||||
|
||||
create_table "matches", force: :cascade do |t|
|
||||
t.integer "state", default: 0
|
||||
t.integer "position"
|
||||
t.integer "stage_id"
|
||||
t.integer "group_id"
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
t.datetime "updated_at", precision: nil, null: false
|
||||
t.boolean "decider", default: false, null: false
|
||||
t.integer "sync_source_id"
|
||||
t.index ["group_id"], name: "index_matches_on_group_id"
|
||||
t.index ["stage_id"], name: "index_matches_on_stage_id"
|
||||
end
|
||||
|
||||
create_table "stages", force: :cascade do |t|
|
||||
t.integer "level"
|
||||
t.integer "state", default: 0
|
||||
t.integer "tournament_id", null: false
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
t.datetime "updated_at", precision: nil, null: false
|
||||
t.integer "sync_source_id"
|
||||
t.index ["tournament_id"], name: "index_stages_on_tournament_id"
|
||||
end
|
||||
|
||||
create_table "team_action_items", force: :cascade do |t|
|
||||
t.integer "team_action_list_id", null: false
|
||||
t.integer "team_id", null: false
|
||||
t.boolean "completed", default: false, null: false
|
||||
t.datetime "completed_at"
|
||||
t.integer "sync_source_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["sync_source_id"], name: "index_team_action_items_on_sync_source_id"
|
||||
t.index ["team_action_list_id", "team_id"], name: "index_team_action_items_on_team_action_list_id_and_team_id", unique: true
|
||||
t.index ["team_action_list_id"], name: "index_team_action_items_on_team_action_list_id"
|
||||
t.index ["team_id"], name: "index_team_action_items_on_team_id"
|
||||
end
|
||||
|
||||
create_table "team_action_lists", force: :cascade do |t|
|
||||
t.integer "tournament_id", null: false
|
||||
t.string "name", null: false
|
||||
t.string "key", null: false
|
||||
t.string "action_name", null: false
|
||||
t.string "source", null: false
|
||||
t.integer "sync_source_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["sync_source_id"], name: "index_team_action_lists_on_sync_source_id"
|
||||
t.index ["tournament_id", "key"], name: "index_team_action_lists_on_tournament_id_and_key", unique: true
|
||||
t.index ["tournament_id"], name: "index_team_action_lists_on_tournament_id"
|
||||
end
|
||||
|
||||
create_table "teams", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.integer "tournament_id"
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
t.datetime "updated_at", precision: nil, null: false
|
||||
t.integer "sync_source_id"
|
||||
t.index ["tournament_id"], name: "index_teams_on_tournament_id"
|
||||
end
|
||||
|
||||
create_table "tournament_sync_queue_entries", force: :cascade do |t|
|
||||
t.integer "tournament_id", null: false
|
||||
t.text "snapshot_json", null: false
|
||||
t.datetime "next_attempt_at", null: false
|
||||
t.datetime "last_attempt_at"
|
||||
t.datetime "locked_at"
|
||||
t.string "lock_token"
|
||||
t.integer "attempts", default: 0, null: false
|
||||
t.string "status", default: "pending", null: false
|
||||
t.string "last_error"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["next_attempt_at"], name: "index_tournament_sync_queue_entries_on_next_attempt_at"
|
||||
t.index ["status"], name: "index_tournament_sync_queue_entries_on_status"
|
||||
t.index ["tournament_id"], name: "index_tournament_sync_queue_entries_on_tournament_id", unique: true
|
||||
end
|
||||
|
||||
create_table "tournaments", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.string "code", null: false
|
||||
t.string "description"
|
||||
t.boolean "public", default: true
|
||||
t.integer "playoff_teams_amount", default: 0
|
||||
t.integer "instant_finalists_amount", default: 0
|
||||
t.integer "intermediate_round_participants_amount", default: 0
|
||||
t.integer "user_id", null: false
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
t.datetime "updated_at", precision: nil, null: false
|
||||
t.datetime "timestamp"
|
||||
t.boolean "read_only_mode", default: false, null: false
|
||||
t.string "sync_target_url"
|
||||
t.string "sync_auth_token"
|
||||
t.integer "sync_source_tournament_id"
|
||||
t.datetime "sync_last_pushed_at"
|
||||
t.string "sync_last_push_error"
|
||||
t.datetime "sync_last_imported_snapshot_at"
|
||||
t.string "timer_mode"
|
||||
t.index ["code"], name: "index_tournaments_on_code", unique: true
|
||||
t.index ["user_id"], name: "index_tournaments_on_user_id"
|
||||
end
|
||||
|
||||
create_table "users", force: :cascade do |t|
|
||||
t.string "provider", default: "email", null: false
|
||||
t.string "uid", default: "", null: false
|
||||
t.string "encrypted_password", default: "", null: false
|
||||
t.string "reset_password_token"
|
||||
t.datetime "reset_password_sent_at", precision: nil
|
||||
t.boolean "allow_password_change", default: false
|
||||
t.datetime "remember_created_at", precision: nil
|
||||
t.integer "sign_in_count", default: 0, null: false
|
||||
t.datetime "current_sign_in_at", precision: nil
|
||||
t.datetime "last_sign_in_at", precision: nil
|
||||
t.string "current_sign_in_ip"
|
||||
t.string "last_sign_in_ip"
|
||||
t.string "confirmation_token"
|
||||
t.datetime "confirmed_at", precision: nil
|
||||
t.datetime "confirmation_sent_at", precision: nil
|
||||
t.string "unconfirmed_email"
|
||||
t.string "username"
|
||||
t.string "email"
|
||||
t.text "tokens"
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
t.datetime "updated_at", precision: nil, null: false
|
||||
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
|
||||
t.index ["email"], name: "index_users_on_email", unique: true
|
||||
t.index ["provider"], name: "index_users_on_provider"
|
||||
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
||||
t.index ["uid"], name: "index_users_on_uid", unique: true
|
||||
t.index ["username"], name: "index_users_on_username", unique: true
|
||||
end
|
||||
|
||||
add_foreign_key "beamers", "tournaments", on_delete: :cascade
|
||||
add_foreign_key "bets", "matches", on_delete: :cascade
|
||||
add_foreign_key "bets", "teams", on_delete: :cascade
|
||||
add_foreign_key "bets", "users", on_delete: :cascade
|
||||
add_foreign_key "group_scores", "groups", on_delete: :cascade
|
||||
add_foreign_key "group_scores", "teams", on_delete: :cascade
|
||||
add_foreign_key "groups", "stages", on_delete: :cascade
|
||||
add_foreign_key "match_scores", "matches", on_delete: :cascade
|
||||
add_foreign_key "match_scores", "teams", on_delete: :cascade
|
||||
add_foreign_key "matches", "groups", on_delete: :cascade
|
||||
add_foreign_key "matches", "stages", on_delete: :cascade
|
||||
add_foreign_key "stages", "tournaments", on_delete: :cascade
|
||||
add_foreign_key "team_action_items", "team_action_lists", on_delete: :cascade
|
||||
add_foreign_key "team_action_items", "teams", on_delete: :cascade
|
||||
add_foreign_key "team_action_lists", "tournaments", on_delete: :cascade
|
||||
add_foreign_key "teams", "tournaments", on_delete: :cascade
|
||||
add_foreign_key "tournament_sync_queue_entries", "tournaments", on_delete: :cascade
|
||||
add_foreign_key "tournaments", "users", on_delete: :cascade
|
||||
end
|
||||
|
|
@ -222,13 +222,13 @@ RSpec.describe TournamentsController, type: :controller do
|
|||
|
||||
describe 'GET #timer' do
|
||||
it 'returns timer state in ISO 8601 format' do
|
||||
timer_end = Time.utc(2026, 4, 13, 18, 0, 0)
|
||||
@tournament.update!(timer_end: timer_end, timer_mode: 'countdown')
|
||||
timestamp = Time.utc(2026, 4, 13, 18, 0, 0)
|
||||
@tournament.update!(timestamp: timestamp, timer_mode: 'countdown')
|
||||
|
||||
get :timer, params: { id: @tournament.to_param }
|
||||
|
||||
expect(response).to be_successful
|
||||
expect(deserialize_response(response)[:timestamp]).to eq(timer_end.iso8601)
|
||||
expect(deserialize_response(response)[:timestamp]).to eq(timestamp.iso8601)
|
||||
expect(deserialize_response(response)[:timer_mode]).to eq('countdown')
|
||||
end
|
||||
end
|
||||
|
|
@ -244,8 +244,8 @@ RSpec.describe TournamentsController, type: :controller do
|
|||
patch :set_timer, params: { id: @tournament.to_param, timestamp: timestamp }
|
||||
|
||||
expect(response).to be_successful
|
||||
expect(@tournament.reload.timer_end.iso8601).to eq(Time.iso8601(timestamp).utc.iso8601)
|
||||
expect(deserialize_response(response)[:timestamp]).to eq(@tournament.timer_end.iso8601)
|
||||
expect(@tournament.reload.timestamp.iso8601).to eq(Time.iso8601(timestamp).utc.iso8601)
|
||||
expect(deserialize_response(response)[:timestamp]).to eq(@tournament.timestamp.iso8601)
|
||||
expect(deserialize_response(response)[:timer_mode]).to eq('countdown')
|
||||
end
|
||||
|
||||
|
|
@ -256,17 +256,17 @@ RSpec.describe TournamentsController, type: :controller do
|
|||
|
||||
expect(response).to be_successful
|
||||
expect(@tournament.reload.timer_mode).to eq('countup')
|
||||
expect(@tournament.timer_end).to be_between(before_request - 1.second, Time.zone.now + 1.second)
|
||||
expect(@tournament.timestamp).to be_between(before_request - 1.second, Time.zone.now + 1.second)
|
||||
expect(deserialize_response(response)[:timer_mode]).to eq('countup')
|
||||
end
|
||||
|
||||
it 'clears timer state when clear_timer=true' do
|
||||
@tournament.update!(timer_end: Time.utc(2030, 4, 13, 18, 0, 0), timer_mode: 'countdown')
|
||||
@tournament.update!(timestamp: Time.utc(2030, 4, 13, 18, 0, 0), timer_mode: 'countdown')
|
||||
|
||||
patch :set_timer, params: { id: @tournament.to_param, clear_timer: true }
|
||||
|
||||
expect(response).to be_successful
|
||||
expect(@tournament.reload.timer_end).to be_nil
|
||||
expect(@tournament.reload.timestamp).to be_nil
|
||||
expect(@tournament.timer_mode).to be_nil
|
||||
expect(deserialize_response(response)[:timestamp]).to be_nil
|
||||
expect(deserialize_response(response)[:timer_mode]).to be_nil
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ RSpec.describe TournamentSnapshotImporter do
|
|||
playoff_teams_amount: tournament.playoff_teams_amount,
|
||||
instant_finalists_amount: tournament.instant_finalists_amount,
|
||||
intermediate_round_participants_amount: tournament.intermediate_round_participants_amount,
|
||||
timestamp: tournament.timer_end&.iso8601,
|
||||
timestamp: tournament.timestamp&.iso8601,
|
||||
timer_mode: tournament.timer_mode,
|
||||
teams: tournament.teams.order(:name).map { |team| team.name },
|
||||
team_action_lists: tournament.team_action_lists.order(:key).map do |list|
|
||||
|
|
|
|||
Loading…
Reference in New Issue