openvibers/openvibe.tips Commits
Import: read Live's chat_messages time from its timestamp column (created_at on older snapshots); the fixture now mirrors Live's schema — the production dry run failed on it
Changes
@@@ -92,8 +92,10 @@ async function importLive(domain, { live, billingSource = null, resolveLiveUsers// ── Read the snapshot ────────────────────────────────────const txns = tableExists(live, 'transactions') ? live.prepare("SELECT * FROM transactions WHERE type IN ('donation', 'refund') ORDER BY id").all() : [];const chatCols = columns(live, 'chat_messages');++ // Live's chat_messages carries its time in `timestamp` (older snapshots: created_at).++ const chatTs = chatCols.includes('created_at') ? 'created_at' : (chatCols.includes('timestamp') ? 'timestamp' : 'NULL');const chatDonations = chatCols.includes('metadata')-- ? live.prepare("SELECT id, channel_user_id, username, message, metadata, created_at FROM chat_messages WHERE message_type = 'donation' AND metadata LIKE '%powerchat%' ORDER BY id").all()++ ? live.prepare(`SELECT id, channel_user_id, username, message, metadata, ${chatTs} AS created_at FROM chat_messages WHERE message_type = 'donation' AND metadata LIKE '%powerchat%' ORDER BY id`).all(): [];const goalRows = tableExists(live, 'donation_goals') ? live.prepare('SELECT * FROM donation_goals ORDER BY id').all() : [];const users = new Map((tableExists(live, 'users') ? live.prepare('SELECT id, username, display_name FROM users').all() : []).map((u) => [String(u.id), u]));@@@ -13,7 +13,7 @@ function liveFixture(file) {CREATE TABLE transactions (id INTEGER PRIMARY KEY, from_user_id INTEGER, to_user_id INTEGER, stream_id INTEGER, amount INTEGER NOT NULL,type TEXT NOT NULL, status TEXT DEFAULT 'completed', message TEXT, paypal_transaction_id TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);CREATE TABLE chat_messages (id INTEGER PRIMARY KEY, stream_id INTEGER, channel_user_id INTEGER, user_id INTEGER, username TEXT, message TEXT,-- message_type TEXT DEFAULT 'chat', metadata TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);++ message_type TEXT DEFAULT 'chat', metadata TEXT, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP); -- Live's column nameCREATE TABLE donation_goals (id INTEGER PRIMARY KEY, user_id INTEGER, title TEXT, target_amount INTEGER, current_amount INTEGER DEFAULT 0,is_active INTEGER DEFAULT 1, image_url TEXT, media_type TEXT, reached_at DATETIME, sort_order INTEGER DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);CREATE TABLE site_settings (key TEXT PRIMARY KEY, value TEXT);@@@ -31,7 +31,7 @@ function liveFixture(file) {t.run(7, 1, 2, null, 250, 'refund', 'completed', 'Refund: Song', '2026-02-04 10:00:00');t.run(8, null, 5, null, 1000, 'donation', 'completed', 'PowerChat tip via site account ($10.00)', '2026-02-05 12:00:00');t.run(9, null, 2, null, 1000, 'purchase', 'completed', null, '2026-01-20 12:00:00');-- const c = db.prepare("INSERT INTO chat_messages (id, channel_user_id, username, message, message_type, metadata, created_at) VALUES (?, ?, ?, ?, 'donation', ?, ?)");++ const c = db.prepare("INSERT INTO chat_messages (id, channel_user_id, username, message, message_type, metadata, timestamp) VALUES (?, ?, ?, ?, 'donation', ?, ?)");c.run(1, 5, 'Fan', 'Fan tipped 1000 Vibes (PowerChat)', JSON.stringify({ kind: 'donation', amount: 1000, message: '', username: 'Fan', source: 'powerchat' }), '2026-02-05 12:00:30');c.run(2, 1, 'Direct', 'Direct tipped 700 Vibes (PowerChat)', JSON.stringify({ kind: 'donation', amount: 700, message: 'love it', username: 'Direct', source: 'powerchat' }), '2026-02-06 09:00:00');c.run(3, 1, 'Viewer', 'Viewer donated 500 Vibes: nice', JSON.stringify({ kind: 'donation', amount: 500, username: 'Viewer' }), '2026-02-01 10:00:01');
@@ -92,8 +92,10 @@ async function importLive(domain, { live, billingSource = null, resolveLiveUsers
@@ -92,8 +92,10 @@ async function importLive(domain, { live, billingSource = null, resolveLiveUsers
// ── Read the snapshot ────────────────────────────────────
// ── Read the snapshot ────────────────────────────────────
const txns = tableExists(live, 'transactions') ? live.prepare("SELECT * FROM transactions WHERE type IN ('donation', 'refund') ORDER BY id").all() : [];
const txns = tableExists(live, 'transactions') ? live.prepare("SELECT * FROM transactions WHERE type IN ('donation', 'refund') ORDER BY id").all() : [];
const chatCols = columns(live, 'chat_messages');
const chatCols = columns(live, 'chat_messages');
+ // Live's chat_messages carries its time in `timestamp` (older snapshots: created_at).
+ const chatTs = chatCols.includes('created_at') ? 'created_at' : (chatCols.includes('timestamp') ? 'timestamp' : 'NULL');
const chatDonations = chatCols.includes('metadata')
const chatDonations = chatCols.includes('metadata')
- ? live.prepare("SELECT id, channel_user_id, username, message, metadata, created_at FROM chat_messages WHERE message_type = 'donation' AND metadata LIKE '%powerchat%' ORDER BY id").all()
+ ? live.prepare(`SELECT id, channel_user_id, username, message, metadata, ${chatTs} AS created_at FROM chat_messages WHERE message_type = 'donation' AND metadata LIKE '%powerchat%' ORDER BY id`).all()
: [];
: [];
const goalRows = tableExists(live, 'donation_goals') ? live.prepare('SELECT * FROM donation_goals ORDER BY id').all() : [];
const goalRows = tableExists(live, 'donation_goals') ? live.prepare('SELECT * FROM donation_goals ORDER BY id').all() : [];
const users = new Map((tableExists(live, 'users') ? live.prepare('SELECT id, username, display_name FROM users').all() : []).map((u) => [String(u.id), u]));
const users = new Map((tableExists(live, 'users') ? live.prepare('SELECT id, username, display_name FROM users').all() : []).map((u) => [String(u.id), u]));
@@ -13,7 +13,7 @@ function liveFixture(file) {
@@ -13,7 +13,7 @@ function liveFixture(file) {
CREATE TABLE transactions (id INTEGER PRIMARY KEY, from_user_id INTEGER, to_user_id INTEGER, stream_id INTEGER, amount INTEGER NOT NULL,
CREATE TABLE transactions (id INTEGER PRIMARY KEY, from_user_id INTEGER, to_user_id INTEGER, stream_id INTEGER, amount INTEGER NOT NULL,
type TEXT NOT NULL, status TEXT DEFAULT 'completed', message TEXT, paypal_transaction_id TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);
type TEXT NOT NULL, status TEXT DEFAULT 'completed', message TEXT, paypal_transaction_id TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);
CREATE TABLE chat_messages (id INTEGER PRIMARY KEY, stream_id INTEGER, channel_user_id INTEGER, user_id INTEGER, username TEXT, message TEXT,
CREATE TABLE chat_messages (id INTEGER PRIMARY KEY, stream_id INTEGER, channel_user_id INTEGER, user_id INTEGER, username TEXT, message TEXT,
- message_type TEXT DEFAULT 'chat', metadata TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);
+ message_type TEXT DEFAULT 'chat', metadata TEXT, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP); -- Live's column name
CREATE TABLE donation_goals (id INTEGER PRIMARY KEY, user_id INTEGER, title TEXT, target_amount INTEGER, current_amount INTEGER DEFAULT 0,
CREATE TABLE donation_goals (id INTEGER PRIMARY KEY, user_id INTEGER, title TEXT, target_amount INTEGER, current_amount INTEGER DEFAULT 0,
is_active INTEGER DEFAULT 1, image_url TEXT, media_type TEXT, reached_at DATETIME, sort_order INTEGER DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);
is_active INTEGER DEFAULT 1, image_url TEXT, media_type TEXT, reached_at DATETIME, sort_order INTEGER DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP);
CREATE TABLE site_settings (key TEXT PRIMARY KEY, value TEXT);
CREATE TABLE site_settings (key TEXT PRIMARY KEY, value TEXT);
@@ -31,7 +31,7 @@ function liveFixture(file) {
@@ -31,7 +31,7 @@ function liveFixture(file) {
t.run(7, 1, 2, null, 250, 'refund', 'completed', 'Refund: Song', '2026-02-04 10:00:00');
t.run(7, 1, 2, null, 250, 'refund', 'completed', 'Refund: Song', '2026-02-04 10:00:00');
t.run(8, null, 5, null, 1000, 'donation', 'completed', 'PowerChat tip via site account ($10.00)', '2026-02-05 12:00:00');
t.run(8, null, 5, null, 1000, 'donation', 'completed', 'PowerChat tip via site account ($10.00)', '2026-02-05 12:00:00');
t.run(9, null, 2, null, 1000, 'purchase', 'completed', null, '2026-01-20 12:00:00');
t.run(9, null, 2, null, 1000, 'purchase', 'completed', null, '2026-01-20 12:00:00');
- const c = db.prepare("INSERT INTO chat_messages (id, channel_user_id, username, message, message_type, metadata, created_at) VALUES (?, ?, ?, ?, 'donation', ?, ?)");
+ const c = db.prepare("INSERT INTO chat_messages (id, channel_user_id, username, message, message_type, metadata, timestamp) VALUES (?, ?, ?, ?, 'donation', ?, ?)");
c.run(1, 5, 'Fan', 'Fan tipped 1000 Vibes (PowerChat)', JSON.stringify({ kind: 'donation', amount: 1000, message: '', username: 'Fan', source: 'powerchat' }), '2026-02-05 12:00:30');
c.run(1, 5, 'Fan', 'Fan tipped 1000 Vibes (PowerChat)', JSON.stringify({ kind: 'donation', amount: 1000, message: '', username: 'Fan', source: 'powerchat' }), '2026-02-05 12:00:30');
c.run(2, 1, 'Direct', 'Direct tipped 700 Vibes (PowerChat)', JSON.stringify({ kind: 'donation', amount: 700, message: 'love it', username: 'Direct', source: 'powerchat' }), '2026-02-06 09:00:00');
c.run(2, 1, 'Direct', 'Direct tipped 700 Vibes (PowerChat)', JSON.stringify({ kind: 'donation', amount: 700, message: 'love it', username: 'Direct', source: 'powerchat' }), '2026-02-06 09:00:00');
c.run(3, 1, 'Viewer', 'Viewer donated 500 Vibes: nice', JSON.stringify({ kind: 'donation', amount: 500, username: 'Viewer' }), '2026-02-01 10:00:01');
c.run(3, 1, 'Viewer', 'Viewer donated 500 Vibes: nice', JSON.stringify({ kind: 'donation', amount: 500, username: 'Viewer' }), '2026-02-01 10:00:01');