openvibers/openvibe.live Commits

N-1 fixtures re-recorded from efab014, the release now in production (npm run n-1:record).

OP OpenVibers committed 27 Sept 2026 · 29d68089d0 · 2 files, +160 −15


Changes

ddiff --git a/test/fixtures/n-1/client.json b/test/fixtures/n-1/client.json
iindex 35d30ae8..4cfcd514 100644
---- a/test/fixtures/n-1/client.json
++++ b/test/fixtures/n-1/client.json
@@@ -1,14 +1,14 @@
{
"service": "live",
-- "release": "f0edbc0384fc9a3cf9c5c6e295863cf3391c7411",
-- "recorded_at": "2026-09-27T20:20:38.345Z",
++ "release": "efab01493b4d5d790e96d141f3fe8aa37766a9bd",
++ "recorded_at": "2026-09-27T22:05:12.539Z",
"note": "N-1 fixture: written by `npm run n-1:record`, replayed by test/n-1.test.js",
"manifest": {
"service": "live",
-- "release": "f0edbc0384fc",
-- "released_at": "2026-09-27T19:52:56.000Z",
-- "booted_at": "2026-09-27T20:20:34.950Z",
-- "contracts_version": "0.68.0",
++ "release": "efab01493b4d",
++ "released_at": "2026-09-27T22:04:32.000Z",
++ "booted_at": "2026-09-27T22:05:09.738Z",
++ "contracts_version": "0.70.0",
"packages": {
"openvibe-shared": "1.23.0",
"openvibe-sdk": "0.11.0"
@@@ -16,16 +16,146 @@
"min_client_release": null,
"mixed_version_window_hours": 24,
"components": {
++ "styles": {
++ "kind": "style",
++ "version": "a8f6301f7132"
++ },
"shell": {
"kind": "script",
-- "version": "f0edbc0384fc"
++ "version": "bc104c195d93"
},
"server": {
"kind": "server",
-- "version": "f0edbc0384fc"
++ "version": "19ad7fdc4038"
++ }
++ },
++ "assets": {
++ "/css/broadcast.css": {
++ "url": "/css/broadcast.css?v=942804f7c8a1",
++ "component": "styles",
++ "integrity": "sha384-LfnTU+h1Yti04NHlUWnNOawAsOl4TvBKTFbUFGqac4eCIWWGXUgwTgsy37HULiWf"
++ },
++ "/css/chat-shared.css": {
++ "url": "/css/chat-shared.css?v=558d74cf2e6a",
++ "component": "styles",
++ "integrity": "sha384-+UNgBYuMRLHmTl0hBPmZI+91u+ud0yHLElwmd/4UrYgHoLHIYVElOwsOQ4G8UdWB"
++ },
++ "/css/context-cards.css": {
++ "url": "/css/context-cards.css?v=60ad33ae3e48",
++ "component": "styles",
++ "integrity": "sha384-QafukgfMwvBUHfswsJWBwg8bmN1uOmnZxkxgcTcmRSWKV+PIQMCJp8gDNA+KZf4h"
++ },
++ "/css/cosmetics.css": {
++ "url": "/css/cosmetics.css?v=193dbe9046fb",
++ "component": "styles",
++ "integrity": "sha384-5dCgICmYIqP2d8mqEj/16RJhNUgahGNEAiyb/E4gnUWSvxQWrGssylbv92PUdIhq"
++ },
++ "/css/features/arena.css": {
++ "url": "/css/features/arena.css?v=6993aaa22df5",
++ "component": "styles",
++ "integrity": "sha384-EVAZL6dcfj1jLiFB5BWHcV+Iv0dTz8V5oDaJDoQROVMAV2EGMKS+tfK7Sh+rQDq/"
++ },
++ "/css/features/broadcast.css": {
++ "url": "/css/features/broadcast.css?v=aedd632a73c3",
++ "component": "styles",
++ "integrity": "sha384-soU+Q4G+XY0bwjBFTyF4Q2YSOGKmH6joFz+2JFXRg9Fg4J17LYo9DYyoDR/ekWCj"
++ },
++ "/css/features/channel.css": {
++ "url": "/css/features/channel.css?v=dfe3fa1b9949",
++ "component": "styles",
++ "integrity": "sha384-YALxSITW32gKIdeBKV2ohJL2eQnhJFXoVFhKQyNanfa1IarVcdlIYuB50FMI8V04"
++ },
++ "/css/features/chatpage.css": {
++ "url": "/css/features/chatpage.css?v=c5c63e94503f",
++ "component": "styles",
++ "integrity": "sha384-2CnY63wmfX6sJ3AgpNab5FRmu8HOKt2HZs3T2SLP+ghsZzmKLbtL0vsu6HgegwSQ"
++ },
++ "/css/features/content.css": {
++ "url": "/css/features/content.css?v=95d237faf73a",
++ "component": "styles",
++ "integrity": "sha384-iAF+LsoCNaMS6BM2YUZu95mDl8+jgtko6D++4d70Hs0d8xH8UceNDPINIfISe3uT"
++ },
++ "/css/features/dashboard.css": {
++ "url": "/css/features/dashboard.css?v=90998f175a26",
++ "component": "styles",
++ "integrity": "sha384-t9R2mNl4dR/1OSCUsCcjYmnlhg2EgJy3gbUjJFUa3QtzTN3j+mmi+VjCqHcI+LDL"
++ },
++ "/css/features/docs.css": {
++ "url": "/css/features/docs.css?v=3e586537c2ed",
++ "component": "styles",
++ "integrity": "sha384-ScMgltMdpbu/xxJE+0X3at8vA0aoMluHTa79n/Kj19npf8Ob07YedPxUZBbGBh2v"
++ },
++ "/css/features/featured.css": {
++ "url": "/css/features/featured.css?v=06b2cfdc2603",
++ "component": "styles",
++ "integrity": "sha384-qxjHx5W7yoUfDcK9M8DcVBKQX2YcR+sHHeGwpKNYrg6zM9tjKFsrcXfB4FvHcuUC"
++ },
++ "/css/features/home.css": {
++ "url": "/css/features/home.css?v=52249fa8d30a",
++ "component": "styles",
++ "integrity": "sha384-a5G7379pPDZ/TQCvTf/MlHZJJeaY7fFs/MCdRfHPrHlqSPZjSmvPWk3C29+WttOB"
++ },
++ "/css/features/media.css": {
++ "url": "/css/features/media.css?v=dea567ff26e8",
++ "component": "styles",
++ "integrity": "sha384-5fg7EMKpaBjMyM4mYM/iM+HPpZnUUaCd1FmVEcauKoN9QWfbFWVhNIhrb2oA5RiK"
++ },
++ "/css/features/search.css": {
++ "url": "/css/features/search.css?v=59f2f133271c",
++ "component": "styles",
++ "integrity": "sha384-RJYUmnxzvBcKyiQ5i2JiaKeDt7n04ZxD5fi5T1PT66PR0Yawvd0FsvFuTdBY8djz"
++ },
++ "/css/features/stats.css": {
++ "url": "/css/features/stats.css?v=7676bfc9ec0d",
++ "component": "styles",
++ "integrity": "sha384-BO+i8mr3s9siQE0a/XSNd+MvZfi8GDyhIjQFf+9zC5CUXx5DvmoY71wRT0jUr42X"
++ },
++ "/css/home-fx.css": {
++ "url": "/css/home-fx.css?v=8f135af68e76",
++ "component": "styles",
++ "integrity": "sha384-nQYM/f49re/MHydZjlV6hNxCLoyuxQzovB+ui4pxQVAho58GRcwfrsC8ruxcmq4Y"
++ },
++ "/css/home-tour.css": {
++ "url": "/css/home-tour.css?v=3f1293159aff",
++ "component": "styles",
++ "integrity": "sha384-amhdltUcvPHMlKbKgAysH1oVa5LXmXYvie7lrfnBB7+hnqpcSiFHfLUDcwnSznho"
++ },
++ "/css/i18n-star.css": {
++ "url": "/css/i18n-star.css?v=3a854948d72f",
++ "component": "styles",
++ "integrity": "sha384-/t8NyMvWUsTmPjLVxYRBh7GlOKSe9o07vFfclZa/bO1AXE/yxM0t4yCExEl8NRxk"
++ },
++ "/css/media-player.css": {
++ "url": "/css/media-player.css?v=7b7fdf4b15e5",
++ "component": "styles",
++ "integrity": "sha384-OsZjCMedAayAH/g66rIZS8/cND69xI8/Qx1ci04sfY8gbrncRjXT0WCDg/d+BYg9"
++ },
++ "/css/messenger.css": {
++ "url": "/css/messenger.css?v=8d3312c1f857",
++ "component": "styles",
++ "integrity": "sha384-2+sE2r3ITTgGbYnYQ2TD5atavSwm9i2LyvxGPkKYYRn07kizleHqQYAYrrZVW5cr"
++ },
++ "/css/ov-guide.css": {
++ "url": "/css/ov-guide.css?v=5eb601c01a03",
++ "component": "styles",
++ "integrity": "sha384-06D5yA90IAi0imrONhtPHVkzAe00RqUQM0w96tT5EUXx1lwLjn6P2f0UTruHZCss"
++ },
++ "/css/recap.css": {
++ "url": "/css/recap.css?v=3da2cd3feae6",
++ "component": "styles",
++ "integrity": "sha384-iVDuJckwXLQPfhSFXjJKmyIIXM+XbRccOWefcHh1vChYrlfwFWAgWXinI4iihWor"
++ },
++ "/css/style.css": {
++ "url": "/css/style.css?v=a3843ec6bdd6",
++ "component": "styles",
++ "integrity": "sha384-TTgsUgnTu8mZ4WLNGRY2cT3qxM34lqxhC/uSH7I3lV3UnZq5fIaR38aoFRZ6xjM3"
++ },
++ "/css/vendor/fontawesome-6.5.1.min.css": {
++ "url": "/css/vendor/fontawesome-6.5.1.min.css?v=d6c948f648fd",
++ "component": "styles",
++ "integrity": "sha384-9ddrCrHYijelWEPj5YYYDDZX0rQI1lOUDIXD2CPZegU6il/rymCFoydiMC8HMCa8"
}
},
-- "assets": {},
"schema_generation": null,
"schema_compatible_from": null,
"contract_ranges": {},
ddiff --git a/test/fixtures/n-1/worker.json b/test/fixtures/n-1/worker.json
iindex db27af1e..2cdc4700 100644
---- a/test/fixtures/n-1/worker.json
++++ b/test/fixtures/n-1/worker.json
@@@ -1,7 +1,7 @@
{
"service": "live",
-- "release": "f0edbc0384fc9a3cf9c5c6e295863cf3391c7411",
-- "recorded_at": "2026-09-27T20:20:38.345Z",
++ "release": "efab01493b4d5d790e96d141f3fe8aa37766a9bd",
++ "recorded_at": "2026-09-27T22:05:12.539Z",
"note": "N-1 fixture: written by `npm run n-1:record`, replayed by test/n-1.test.js",
"user_version": 0,
"schema": [
@@@ -257,19 +257,19 @@
"schema_migrations": [
{
"id": "001_vibes_decimal_to_bits",
-- "applied_at": "2026-09-27 20:20:33",
++ "applied_at": "2026-09-27 22:05:08",
"mode": "adopted",
-- "duration_ms": 0
++ "duration_ms": 1
},
{
"id": "002_pastes_ai_columns",
-- "applied_at": "2026-09-27 20:20:33",
++ "applied_at": "2026-09-27 22:05:08",
"mode": "applied",
"duration_ms": 5
},
{
"id": "004_hot_path_indexes",
-- "applied_at": "2026-09-27 20:20:33",
++ "applied_at": "2026-09-27 22:05:08",
"mode": "applied",
"duration_ms": 0
}
@@@ -278,6 +278,7 @@
"lazy": [
"CREATE TABLE IF NOT EXISTS module_summary_pushes ( user_id INTEGER NOT NULL, namespace TEXT NOT NULL, hash TEXT NOT NULL, pushed_at DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (user_id, namespace) )",
"CREATE TABLE IF NOT EXISTS token_revocations ( subject_id TEXT PRIMARY KEY, valid_after_ms INTEGER NOT NULL, reason TEXT, updated_at INTEGER NOT NULL )",
++ "CREATE TABLE IF NOT EXISTS subject_merges ( merge_id TEXT PRIMARY KEY, from_subject TEXT NOT NULL, into_subject TEXT NOT NULL, from_user_id INTEGER, into_user_id INTEGER, outcome TEXT NOT NULL, applied_at DATETIME DEFAULT CURRENT_TIMESTAMP )",
"CREATE TABLE IF NOT EXISTS subject_projection ( subject_id TEXT PRIMARY KEY, network_user_id INTEGER, revision INTEGER NOT NULL, username TEXT NOT NULL, display_name TEXT, avatar_url TEXT, profile_color TEXT, role TEXT NOT NULL, banned INTEGER NOT NULL DEFAULT 0, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP )",
"CREATE TABLE IF NOT EXISTS username_history ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL, old_username TEXT NOT NULL, new_username TEXT NOT NULL, changed_at DATETIME DEFAULT CURRENT_TIMESTAMP )",
"CREATE TABLE IF NOT EXISTS chat_bridge_outbox ( id INTEGER PRIMARY KEY AUTOINCREMENT, boot TEXT NOT NULL, ref INTEGER, op TEXT NOT NULL, args TEXT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP )",
@@@ -291,6 +292,7 @@
"CREATE TABLE IF NOT EXISTS opencoin_admin_grants ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_key TEXT UNIQUE, admin_id INTEGER, user_id INTEGER NOT NULL, amount INTEGER NOT NULL, reason TEXT, balance INTEGER, created_at DATETIME DEFAULT CURRENT_TIMESTAMP )",
"CREATE TABLE IF NOT EXISTS follow_projection_revisions ( follower_subject TEXT NOT NULL, target_subject TEXT NOT NULL, revision INTEGER NOT NULL, PRIMARY KEY (follower_subject, target_subject) )",
"CREATE TABLE IF NOT EXISTS tips_deliveries ( idempotency_key TEXT PRIMARY KEY, effect TEXT, state TEXT NOT NULL DEFAULT 'pending', response_json TEXT, claimed_at INTEGER NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP )",
++ "ALTER TABLE users ADD COLUMN merged_into INTEGER",
"ALTER TABLE users ADD COLUMN theme_id INTEGER",
"ALTER TABLE streams ADD COLUMN call_mode TEXT DEFAULT NULL"
],
@@@ -308,6 +310,7 @@
"DELETE FROM camera_profiles WHERE id = ?",
"DELETE FROM channel_ai_bots WHERE id = ?",
"DELETE FROM channel_moderators WHERE channel_id = ? AND user_id = ?",
++ "DELETE FROM channel_points WHERE user_id = ? AND streamer_id = ?",
"DELETE FROM channel_sounds WHERE id = ?",
"DELETE FROM chat_bridge_outbox",
"DELETE FROM chat_bridge_outbox WHERE id = ?",
@@@ -325,6 +328,7 @@
"DELETE FROM donation_goals WHERE id = ? AND user_id = ?",
"DELETE FROM emotes WHERE id = ?",
"DELETE FROM follows WHERE follower_id = ? AND streamer_id = ?",
++ "DELETE FROM follows WHERE id = ?",
"DELETE FROM hidden_relay_users WHERE id = ?",
"DELETE FROM hidden_relay_users WHERE platform = ? AND external_username = ? AND channel_id IS ?",
"DELETE FROM lineage_unresolved WHERE last_at < ?",
@@@ -385,6 +389,7 @@
"INSERT INTO channel_ai_config (user_id, enabled, num_ambient_bots, pacing_seconds, persona, transcribe_enabled, vision_enabled, use_shared_key, daily_budget_cents, byo_key, byo_base_url, byo_model) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
"INSERT INTO channel_moderation_settings ( channel_id, slow_mode_seconds, followers_only, emote_only, allow_anonymous, links_allowed, gifs_enabled, account_age_gate_hours, caps_percentage_limit, aggressive_filter, max_message_length, slur_filter_enabled, slur_filter_use_builtin, slur_filter_terms, slur_filter_regexes, slur_filter_nudge_message, slur_filter_disabled_categories, ip_approval_mode, soundboard_enabled, soundboard_allow_pitch, soundboard_allow_speed, soundboard_banned_ids, viewer_auto_delete_enabled, viewer_delete_all_enabled, custom_emotes_enabled, custom_sounds_enabled, max_sound_seconds, uploads_mods_only, emote_scale, emote_size_min, emote_size_max, sounds_mods_only, mods_can_edit_about ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
"INSERT INTO channel_moderation_settings (channel_id) VALUES (?)",
++ "INSERT INTO channel_points (user_id, streamer_id, balance) VALUES (?, ?, ?)",
"INSERT INTO channel_points (user_id, streamer_id, balance, updated_at) VALUES (?, ?, ?, CURRENT_TIMESTAMP) ON CONFLICT(user_id, streamer_id) DO UPDATE SET balance = balance + excluded.balance, updated_at = CURRENT_TIMESTAMP",
"INSERT INTO channel_points_log (idempotency_key, user_id, streamer_id, delta, reason) VALUES (?, ?, ?, ?, ?)",
"INSERT INTO channel_sounds (channel_owner_id, command, url, mime, duration_seconds, created_by, created_by_name, emote_code) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
@@@ -455,6 +460,7 @@
"INSERT OR IGNORE INTO billing_actions (action, idempotency_key, live_user_id, live_ref, method, path, request_json) VALUES (?, ?, ?, ?, ?, ?, ?)",
"INSERT OR IGNORE INTO channel_ai_config (user_id, enabled, num_ambient_bots, pacing_seconds, persona, transcribe_enabled, vision_enabled, use_shared_key, daily_budget_cents, byo_key, byo_base_url, byo_model) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
"INSERT OR IGNORE INTO channel_moderators (channel_id, user_id, added_by) VALUES (?, ?, ?)",
++ "INSERT OR IGNORE INTO channel_points_log (idempotency_key, user_id, streamer_id, delta, reason) VALUES (?, ?, ?, ?, ?)",
"INSERT OR IGNORE INTO channels (user_id, title, description, category, protocol) VALUES (?, ?, ?, ?, ?)",
"INSERT OR IGNORE INTO chat_timeline_events (scope, subject_id, ts, label, detail) VALUES (?, ?, ?, ?, ?)",
"INSERT OR IGNORE INTO clip_ai_state (clip_id) VALUES (?)",
@@@ -472,6 +478,7 @@
"INSERT OR IGNORE INTO site_settings (key, value, description, type) VALUES (?, ?, ?, ?)",
"INSERT OR IGNORE INTO stream_first_chats (chatter_key, channel_user_id) VALUES (?, ?)",
"INSERT OR IGNORE INTO stream_memories (stream_id, user_id, offset_seconds, description, tags, thumbnail_url, transcript_json) VALUES (?, ?, ?, ?, ?, ?, ?)",
++ "INSERT OR IGNORE INTO subject_merges (merge_id, from_subject, into_subject, from_user_id, into_user_id, outcome) VALUES (?, ?, ?, ?, ?, ?)",
"INSERT OR IGNORE INTO tips_deliveries (idempotency_key, effect, state, claimed_at) VALUES (?, ?, 'pending', ?)",
"INSERT OR IGNORE INTO user_cosmetics (user_id, item_id, category) VALUES (?, ?, ?)",
"INSERT OR IGNORE INTO users (username, password_hash, display_name, role) VALUES (?, ?, ?, 'user')",
@@@ -633,6 +640,7 @@
"SELECT 1 FROM channel_moderation_settings WHERE channel_id = ?",
"SELECT 1 FROM channel_moderation_settings WHERE channel_id = ? LIMIT 1",
"SELECT 1 FROM channel_moderators WHERE user_id = ? AND channel_id = ?",
++ "SELECT 1 FROM channel_points WHERE user_id = ? AND streamer_id = ?",
"SELECT 1 FROM chat_messages cm JOIN streams s ON cm.stream_id = s.id WHERE s.channel_id = ? AND cm.is_deleted = 0 AND (cm.user_id = ? OR cm.anon_id = ?) LIMIT 1",
"SELECT 1 FROM control_whitelist WHERE channel_id = ? AND user_id = ?",
"SELECT 1 FROM dm_blocks WHERE (blocker_id = ? AND blocked_id = ?) OR (blocker_id = ? AND blocked_id = ?)",
@@@ -654,6 +662,7 @@
"SELECT 1 FROM stream_timeline_events WHERE stream_id = ? AND kind = 'speech' AND created_at >= datetime('now', '-30 minutes') LIMIT 1",
"SELECT 1 FROM streams WHERE user_id = ? AND is_live = 1 LIMIT 1",
"SELECT 1 FROM streams WHERE user_id = ? LIMIT 1",
++ "SELECT 1 FROM subject_merges WHERE merge_id = ?",
"SELECT 1 FROM user_cosmetics WHERE user_id = ? AND item_id = ?",
"SELECT AVG(CASE WHEN sampled_at >= datetime('now','-1 day') AND viewers > 0 THEN viewers END) AS vAvg24, MAX(CASE WHEN sampled_at >= datetime('now','-1 day') THEN viewers END) AS vPeak24, AVG(CASE WHEN viewers > 0 THEN viewers END) AS vAvg7, AVG(CASE WHEN sampled_at >= datetime('now','-1 day') AND live_streams > 0 THEN live_streams END) AS lAvg24, MAX(CASE WHEN sampled_at >= datetime('now','-1 day') THEN live_streams END) AS lPeak24, AVG(CASE WHEN live_streams > 0 THEN live_streams END) AS lAvg7, COUNT(*) AS samples FROM viewer_samples WHERE sampled_at >= datetime('now','-7 days')",
"SELECT AVG(viewer_count) as avg_vc FROM viewer_snapshots WHERE stream_id = ?",
@@@ -1046,6 +1055,7 @@
"SELECT status, COUNT(*) AS n FROM billing_actions GROUP BY status",
"SELECT stream_id, json, ai, created_at FROM stream_recaps WHERE user_id = ? ORDER BY created_at DESC LIMIT ?",
"SELECT stream_id, new_followers, clips_created, coins_earned FROM stream_analytics WHERE stream_id = ?",
++ "SELECT streamer_id AS s, balance FROM channel_points WHERE user_id = ?",
"SELECT streamer_id FROM follows WHERE follower_id = ?",
"SELECT strftime('%s', sampled_at) AS t, viewers, live_streams FROM viewer_samples WHERE sampled_at >= datetime('now', ?) ORDER BY sampled_at ASC",
"SELECT subject_id FROM linked_accounts WHERE service = 'network' AND user_id = ?",
@@@ -1096,6 +1106,7 @@
"SELECT u.username, u.display_name, u.avatar_url, SUM(t.amount) AS total FROM transactions t JOIN users u ON u.id = t.from_user_id WHERE t.type = 'donation' AND t.created_at >= datetime('now', '-7 days') GROUP BY t.from_user_id ORDER BY total DESC LIMIT 3",
"SELECT user_id AS id FROM streams WHERE (started_at >= @from AND started_at < @to) OR (ended_at >= @from AND ended_at < @to) UNION SELECT streamer_id FROM follows WHERE created_at >= @from AND created_at < @to UNION SELECT id FROM users WHERE updated_at >= @from AND updated_at < @to UNION SELECT user_id FROM channels WHERE updated_at >= @from AND updated_at < @to",
"SELECT user_id AS k, overview AS v FROM streamer_overviews WHERE overview LIKE '{%\"description\"%'",
++ "SELECT user_id AS u, balance FROM channel_points WHERE streamer_id = ?",
"SELECT user_id FROM channel_moderators WHERE channel_id = ?",
"SELECT user_id FROM linked_accounts WHERE service = 'network' AND (subject_id = ? OR service_user_id = ?) ORDER BY subject_id = ? DESC LIMIT 1",
"SELECT user_id FROM linked_accounts WHERE service = 'network' AND service_user_id = ?",
@@@ -1142,6 +1153,7 @@
"UPDATE channel_ai_bots SET msg_count = msg_count + 1, last_active_at = CURRENT_TIMESTAMP WHERE id = ?",
"UPDATE channel_moderation_settings SET sub_only = ? WHERE channel_id = ?",
"UPDATE channel_moderation_settings SET tts_max_length = ? WHERE channel_id = ?",
++ "UPDATE channel_points SET balance = balance + ?, updated_at = CURRENT_TIMESTAMP WHERE user_id = ? AND streamer_id = ?",
"UPDATE channel_points SET balance = balance + ?, updated_at = CURRENT_TIMESTAMP WHERE user_id = ? AND streamer_id = ? AND balance >= ?",
"UPDATE channel_sounds SET command = ? WHERE channel_owner_id = ? AND command = ?",
"UPDATE channel_sounds SET emote_code = ? WHERE channel_owner_id = ? AND command = ?",
@@@ -1177,6 +1189,7 @@
"UPDATE linked_accounts SET service = 'network' WHERE service = 'hobotools' AND user_id NOT IN (SELECT user_id FROM linked_accounts WHERE service = 'network')",
"UPDATE linked_accounts SET subject_id = ? WHERE service = 'network' AND user_id = ? AND service_user_id = ? AND (subject_id IS NULL OR subject_id != ?)",
"UPDATE linked_accounts SET subject_id = ? WHERE service = 'network' AND user_id = ? AND service_user_id = ? AND subject_id IS NULL",
++ "UPDATE linked_accounts SET subject_id = ?, service_user_id = COALESCE(?, service_user_id) WHERE service = 'network' AND user_id = ?",
"UPDATE managed_streams SET broadcast_settings = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ? AND user_id = ?",
"UPDATE managed_streams SET ingest_authority = 'live', updated_at = CURRENT_TIMESTAMP WHERE id = ?",
"UPDATE managed_streams SET ingest_authority = 'openre', openre_stream_id = ?, stream_key = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?",
@@@ -1228,6 +1241,7 @@
"UPDATE streams SET started_at = CURRENT_TIMESTAMP, last_heartbeat = CURRENT_TIMESTAMP WHERE id = ?",
"UPDATE streams SET tags = ? WHERE id = ?",
"UPDATE streams SET thumbnail_url = ? WHERE id = ?",
++ "UPDATE streams SET user_id = ? WHERE user_id = ?",
"UPDATE streams SET viewer_count = ?, peak_viewers = MAX(peak_viewers, ?) WHERE id = ?",
"UPDATE subscriptions SET status=?, is_active=?, cancel_at_period_end=?, current_period_end=COALESCE(?, current_period_end), updated_at=CURRENT_TIMESTAMP WHERE id=?",
"UPDATE subscriptions SET tier=?, provider=?, provider_ref=COALESCE(?, provider_ref), price_cents=?, currency=?, status=?, is_active=?, current_period_end=?, auto_renew=COALESCE(?, auto_renew), cancel_at_period_end=0, updated_at=CURRENT_TIMESTAMP WHERE id=?",
@@@ -1246,6 +1260,7 @@
"UPDATE users SET is_banned = 1, ban_reason = ? WHERE id = ?",
"UPDATE users SET is_banned = 1, ban_reason = ? WHERE id = ? AND is_banned = 0",
"UPDATE users SET is_owner = 1, role = 'admin' WHERE LOWER(username) = ? AND is_owner != 1",
++ "UPDATE users SET merged_into = ? WHERE id = ?",
"UPDATE users SET openvibe_bucks_balance = openvibe_bucks_balance + ? WHERE id = ?",
"UPDATE users SET openvibe_bucks_balance = openvibe_bucks_balance - ? WHERE id = ?",
"UPDATE users SET openvibe_bucks_cashout_balance = openvibe_bucks_cashout_balance + ? WHERE id = ?",