#!/usr/bin/env python3 """ WaveSpeed Migration Script for Per-User SQLite Databases This script finds user databases and adds WaveSpeed columns to usage_summaries table """ import os import sqlite3 import sys from pathlib import Path def get_user_db_path(user_id: str) -> str: """Get the database path for a specific user.""" # Sanitize user_id to be safe for filesystem safe_user_id = "".join(c for c in user_id if c.isalnum() or c in ('-', '_')) # Get workspace directory (assuming we're in backend folder) root_dir = Path(__file__).parent.parent workspace_dir = root_dir / 'workspace' user_workspace = workspace_dir / f"workspace_{safe_user_id}" # Check for legacy naming convention first legacy_db_path = user_workspace / 'db' / 'alwrity.db' specific_db_path = user_workspace / 'db' / f'alwrity_{safe_user_id}.db' # If the specific one exists, use it (preferred) if specific_db_path.exists(): return str(specific_db_path) # If legacy exists and specific doesn't, use legacy if legacy_db_path.exists(): return str(legacy_db_path) # Default to specific for new databases return str(specific_db_path) def migrate_user_database(user_id: str, db_path: str) -> bool: """Migrate a single user database""" print(f"\nšŸ”§ Migrating database for user: {user_id}") print(f"šŸ“ Database path: {db_path}") if not os.path.exists(db_path): print(f"āŒ Database file not found: {db_path}") return False try: conn = sqlite3.connect(db_path) cursor = conn.cursor() # Check if usage_summaries table exists cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='usage_summaries'") table_exists = cursor.fetchone() if not table_exists: print("āš ļø usage_summaries table not found, skipping this database") return True # Check if columns already exist cursor.execute('PRAGMA table_info(usage_summaries)') columns = [col[1] for col in cursor.fetchall()] wavespeed_cols = [col for col in columns if 'wavespeed' in col] if wavespeed_cols: print(f"āœ… WaveSpeed columns already exist: {wavespeed_cols}") return True print("āž• Adding WaveSpeed columns...") # Add the columns try: cursor.execute('ALTER TABLE usage_summaries ADD COLUMN wavespeed_calls INTEGER DEFAULT 0') print(" āœ… Added wavespeed_calls") except sqlite3.OperationalError as e: if "duplicate column name" in str(e): print(" āš ļø wavespeed_calls already exists") else: raise e try: cursor.execute('ALTER TABLE usage_summaries ADD COLUMN wavespeed_tokens INTEGER DEFAULT 0') print(" āœ… Added wavespeed_tokens") except sqlite3.OperationalError as e: if "duplicate column name" in str(e): print(" āš ļø wavespeed_tokens already exists") else: raise e try: cursor.execute('ALTER TABLE usage_summaries ADD COLUMN wavespeed_cost REAL DEFAULT 0.0') print(" āœ… Added wavespeed_cost") except sqlite3.OperationalError as e: if "duplicate column name" in str(e): print(" āš ļø wavespeed_cost already exists") else: raise e conn.commit() # Verify the changes cursor.execute('PRAGMA table_info(usage_summaries)') updated_columns = [col[1] for col in cursor.fetchall()] added_wavespeed_cols = [col for col in updated_columns if 'wavespeed' in col] print(f"āœ… WaveSpeed columns successfully added: {added_wavespeed_cols}") return True except Exception as e: print(f"āŒ Error migrating database: {e}") return False finally: if 'conn' in locals(): conn.close() def migrate_all_user_databases(): """Find and migrate all user databases""" print("šŸš€ Starting WaveSpeed migration for all user databases...") # Get workspace directory root_dir = Path(__file__).parent.parent workspace_dir = root_dir / 'workspace' if not workspace_dir.exists(): print(f"āŒ Workspace directory not found: {workspace_dir}") return False # Find all user workspace directories user_workspaces = [d for d in workspace_dir.iterdir() if d.is_dir() and d.name.startswith('workspace_')] if not user_workspaces: print("āŒ No user workspace directories found") return False print(f"šŸ“ Found {len(user_workspaces)} user workspace directories") success_count = 0 for workspace_dir in user_workspaces: # Extract user_id from directory name user_id = workspace_dir.name.replace('workspace_', '') # Get database path db_path = get_user_db_path(user_id) # Migrate this user's database if migrate_user_database(user_id, db_path): success_count += 1 print(f"\nšŸŽ‰ Migration completed!") print(f"āœ… Successfully migrated: {success_count}/{len(user_workspaces)} databases") return success_count > 0 def migrate_specific_user(user_id: str): """Migrate a specific user's database""" print(f"šŸŽÆ Migrating specific user: {user_id}") db_path = get_user_db_path(user_id) return migrate_user_database(user_id, db_path) if __name__ == "__main__": if len(sys.argv) > 1: # Migrate specific user user_id = sys.argv[1] success = migrate_specific_user(user_id) else: # Migrate all users success = migrate_all_user_databases() if success: print("\nāœ… WaveSpeed migration completed successfully!") print("The system can now track WaveSpeed LLM usage and costs.") else: print("\nāŒ Migration failed. Please check the error messages above.") sys.exit(1)