Commit fcc74b9f authored by Mahmoud Aglan's avatar Mahmoud Aglan

fix: creating a tournament without a start time failed against production

el3ab_tournaments.starts_at is NOT NULL in the live schema. tournament-admin.php
allowed it to be null, so every create call that did not supply one was rejected
by Postgres. The local test schema had the column nullable, so the suite passed
and the defect only appeared when the rehearsal ran against production.

starts_at now defaults to now() — which also gives auto_start something to act on —
and tests/schema.sql marks the column NOT NULL so the next one is caught locally.

Adds tests/rehearsal.mjs, the script that found it: four throwaway accounts driven
through matchmaking, a 33-move game to checkmate and a full Swiss round against the
live deployment, with teardown in a finally block. Run it after any deploy.
Co-Authored-By: 's avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
parent 760f2e96
...@@ -80,7 +80,9 @@ function adminCreate($db, string $userId, array $input): void { ...@@ -80,7 +80,9 @@ function adminCreate($db, string $userId, array $input): void {
'rounds_total' => $rounds, 'rounds_total' => $rounds,
'min_players' => max(2, (int)($input['min_players'] ?? 4)), 'min_players' => max(2, (int)($input['min_players'] ?? 4)),
'max_players' => max(2, (int)($input['max_players'] ?? 64)), 'max_players' => max(2, (int)($input['max_players'] ?? 64)),
'starts_at' => $input['starts_at'] ?? null, // starts_at is NOT NULL in production. Defaulting it to now keeps the
// create call usable without one, and auto_start then has a time to act on.
'starts_at' => $input['starts_at'] ?: gmdate('c'),
'status' => TOURNAMENT_STATUS_REGISTRATION, 'status' => TOURNAMENT_STATUS_REGISTRATION,
'current_round' => 0, 'current_round' => 0,
'auto_start' => (bool)($input['auto_start'] ?? true), 'auto_start' => (bool)($input['auto_start'] ?? true),
......
This diff is collapsed.
...@@ -27,7 +27,7 @@ CREATE TABLE el3ab_tournaments ( ...@@ -27,7 +27,7 @@ CREATE TABLE el3ab_tournaments (
rounds_total int, swiss_rounds int, rounds_total int, swiss_rounds int,
min_players int DEFAULT 4, max_players int DEFAULT 64, min_players int DEFAULT 4, max_players int DEFAULT 64,
bye_value numeric DEFAULT 1.0, bye_value numeric DEFAULT 1.0,
registration_closes_at timestamptz, starts_at timestamptz, registration_closes_at timestamptz, starts_at timestamptz NOT NULL,
status text DEFAULT 'draft', current_round int DEFAULT 0, status text DEFAULT 'draft', current_round int DEFAULT 0,
is_rated bool DEFAULT true, auto_start bool DEFAULT true, is_rated bool DEFAULT true, auto_start bool DEFAULT true,
created_by uuid, tiebreak_rules jsonb DEFAULT '[]'::jsonb, created_by uuid, tiebreak_rules jsonb DEFAULT '[]'::jsonb,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment