From d16367582c46e026101bbc228f9343cd348f97b9 Mon Sep 17 00:00:00 2001 From: adlee-was-taken Date: Fri, 10 Apr 2026 23:48:35 -0400 Subject: [PATCH] feat(server): add is_test_account + marks_as_test schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New columns support separating soak-harness test traffic from real user traffic in stats queries. Rebuilds leaderboard_overall matview to include is_test_account so the fast path stays filterable. Migration is idempotent via DO $$ / IF NOT EXISTS blocks inside SCHEMA_SQL, which runs on every server startup — same mechanism every existing post-v1 column migration uses. Co-Authored-By: Claude Opus 4.6 (1M context) --- server/stores/user_store.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/server/stores/user_store.py b/server/stores/user_store.py index 33e996b..febf639 100644 --- a/server/stores/user_store.py +++ b/server/stores/user_store.py @@ -95,6 +95,19 @@ BEGIN WHERE table_name = 'users_v2' AND column_name = 'last_seen_at') THEN ALTER TABLE users_v2 ADD COLUMN last_seen_at TIMESTAMPTZ; END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns + WHERE table_name = 'users_v2' AND column_name = 'is_test_account') THEN + ALTER TABLE users_v2 ADD COLUMN is_test_account BOOLEAN DEFAULT FALSE; + END IF; +END $$; + +-- Add marks_as_test to invite_codes if not exists +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM information_schema.columns + WHERE table_name = 'invite_codes' AND column_name = 'marks_as_test') THEN + ALTER TABLE invite_codes ADD COLUMN marks_as_test BOOLEAN DEFAULT FALSE; + END IF; END $$; -- Admin audit log table @@ -296,14 +309,14 @@ CREATE TABLE IF NOT EXISTS system_metrics ( ); -- Leaderboard materialized view (refreshed periodically) --- Drop and recreate if missing rating column (v3.1.0 migration) +-- Drop and recreate if missing is_test_account column (soak harness migration) DO $$ BEGIN IF EXISTS (SELECT 1 FROM pg_matviews WHERE matviewname = 'leaderboard_overall') THEN - -- Check if rating column exists in the view + -- Check if is_test_account column exists in the view IF NOT EXISTS ( SELECT 1 FROM information_schema.columns - WHERE table_name = 'leaderboard_overall' AND column_name = 'rating' + WHERE table_name = 'leaderboard_overall' AND column_name = 'is_test_account' ) THEN DROP MATERIALIZED VIEW leaderboard_overall; END IF; @@ -315,6 +328,7 @@ BEGIN SELECT u.id as user_id, u.username, + COALESCE(u.is_test_account, FALSE) as is_test_account, s.games_played, s.games_won, ROUND(s.games_won::numeric / NULLIF(s.games_played, 0) * 100, 1) as win_rate, @@ -342,6 +356,8 @@ CREATE INDEX IF NOT EXISTS idx_users_reset ON users_v2(reset_token) WHERE reset_ CREATE INDEX IF NOT EXISTS idx_users_guest ON users_v2(guest_id) WHERE guest_id IS NOT NULL; CREATE INDEX IF NOT EXISTS idx_users_active ON users_v2(is_active) WHERE deleted_at IS NULL; CREATE INDEX IF NOT EXISTS idx_users_banned ON users_v2(is_banned) WHERE is_banned = TRUE; +CREATE INDEX IF NOT EXISTS idx_users_test_account ON users_v2(is_test_account) + WHERE is_test_account = TRUE; CREATE INDEX IF NOT EXISTS idx_sessions_user ON user_sessions(user_id); CREATE INDEX IF NOT EXISTS idx_sessions_token ON user_sessions(token_hash);