-- Track when the last WebSocket session ended (last tab closed). ALTER TABLE heroes ADD COLUMN IF NOT EXISTS ws_disconnected_at TIMESTAMPTZ NULL; -- Accumulated offline session stats (after grace period); cleared when player opens init. CREATE TABLE IF NOT EXISTS hero_offline_digest ( hero_id BIGINT PRIMARY KEY REFERENCES heroes(id) ON DELETE CASCADE, monsters_killed INT NOT NULL DEFAULT 0, xp_gained BIGINT NOT NULL DEFAULT 0, gold_gained BIGINT NOT NULL DEFAULT 0, levels_gained INT NOT NULL DEFAULT 0, deaths INT NOT NULL DEFAULT 0, revives INT NOT NULL DEFAULT 0, loot JSONB NOT NULL DEFAULT '[]'::jsonb, updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_hero_offline_digest_updated ON hero_offline_digest (updated_at);