feat(server): add is_test_account + marks_as_test schema
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) <noreply@anthropic.com>
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user