import sqlite3 from datetime import datetime, timedelta def backfill_snapshots(): conn = sqlite3.connect('data/hiffi_catalog.db') cur = conn.cursor() # 1. Create the rolling snapshots table cur.execute(''' CREATE TABLE IF NOT EXISTS artist_metrics_snapshots ( snapshot_id INTEGER PRIMARY KEY AUTOINCREMENT, artist_id TEXT NOT NULL, platform TEXT NOT NULL, metric_type TEXT NOT NULL, metric_value REAL NOT NULL, recorded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (artist_id) REFERENCES artists(artist_id) ) ''') # Clear existing to prevent duplicate stacking if run multiple times cur.execute('DELETE FROM artist_metrics_snapshots') # 2. Fetch baseline telemetry using the exact column names you provided cur.execute(''' WITH latest AS ( SELECT t.*, ROW_NUMBER() OVER (PARTITION BY t.artist_id ORDER BY t.last_synced_at DESC, t.telemetry_id DESC) as rn FROM telemetry_metrics t ) SELECT a.artist_id, l.subscribers_count, l.total_views, l.spotify_monthly_listeners, l.instagram_followers, l.growth_velocity_7d, l.growth_velocity_30d FROM artists a JOIN latest l ON a.artist_id = l.artist_id WHERE a.image_verified_flag = 1 AND l.rn = 1 ''') records = cur.fetchall() now = datetime.utcnow() t_7d = (now - timedelta(days=7)).strftime('%Y-%m-%d %H:%M:%S') t_30d = (now - timedelta(days=30)).strftime('%Y-%m-%d %H:%M:%S') t_now = now.strftime('%Y-%m-%d %H:%M:%S') insert_data = [] for row in records: artist_id, yt_subs, yt_views, spt_listeners, ig_followers, v_7d, v_30d = row # Reverse-calculate historic metrics from the current percentages def calc_historic(current, velocity_pct): if current is None or velocity_pct is None: return current try: return max(0, current / (1.0 + (velocity_pct / 100.0))) except ZeroDivisionError: return current platforms = [ ('youtube', 'subscribers', yt_subs), ('youtube', 'views', yt_views), ('spotify', 'listeners', spt_listeners), ('instagram', 'followers', ig_followers) ] for plat, m_type, current_val in platforms: if current_val is None: continue val_7d = calc_historic(current_val, v_7d) val_30d = calc_historic(current_val, v_30d) # Stage insertions for T-30, T-7, and T-0 insert_data.append((artist_id, plat, m_type, val_30d, t_30d)) insert_data.append((artist_id, plat, m_type, val_7d, t_7d)) insert_data.append((artist_id, plat, m_type, current_val, t_now)) # 3. Batch insert and commit cur.executemany(''' INSERT INTO artist_metrics_snapshots (artist_id, platform, metric_type, metric_value, recorded_at) VALUES (?, ?, ?, ?, ?) ''', insert_data) conn.commit() print(f"✅ Successfully generated {len(insert_data)} snapshot rows for {len(records)} artists.") print("UI growth badges will now render correctly using historical timestamps.") conn.close() if __name__ == "__main__": backfill_snapshots()