""" Migration Script: Separate Databases for Admin & Commerce ========================================================= Migrates collections from 'sahihislam' into: - 'sahihislam_admin' (Control Plane & Telemetry) - 'sahihislam_commerce' (Ads, Wallets & Financial Ledger) Leaves intact in 'sahihislam': - 'hadiths' (with vector search index) - 'quran' - 'quran_verses' (with vector search index) - 'vector_memory' (with vector search index) - 'users', 'chats', 'masjids', 'daily_progress', 'qaza_tracker', 'tasbeeh_records' """ import asyncio import os import sys sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) from dotenv import load_dotenv load_dotenv(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".env"))) from motor.motor_asyncio import AsyncIOMotorClient MONGO_URI = os.getenv("MONGO_URI") if not MONGO_URI: print("❌ MONGO_URI missing!") sys.exit(1) ADMIN_COLLECTIONS = [ "system_settings", "platform_settings", "sendads", "audit_logs", "client_errors", "pending_approvals", "mufti_requests", "masjid_reports", "email_change_requests", "email_change_logs", ] COMMERCE_COLLECTIONS = [ "ads", "ad_analytics", "products", "orders", "wallets", "transactions", "payouts", "shop_settings", "subscriptions", ] async def migrate_collection(src_db, dest_db, col_name): src_col = src_db[col_name] dest_col = dest_db[col_name] count = await src_col.count_documents({}) if count == 0: print(f" • {col_name}: 0 docs (initialized empty)") return True docs = await src_col.find({}).to_list(length=None) # Clear any previous migration attempts in target await dest_col.delete_many({}) await dest_col.insert_many(docs) target_count = await dest_col.count_documents({}) assert target_count == count, f"Count mismatch for {col_name}: {count} vs {target_count}" print(f" • {col_name}: successfully migrated {target_count}/{count} docs") return True async def main(): print("=" * 60) print("🚀 MIGRATING TO SEPARATE DATABASES: ADMIN & COMMERCE") print("=" * 60) client = AsyncIOMotorClient(MONGO_URI) src_db = client["sahihislam"] admin_db = client["sahihislam_admin"] commerce_db = client["sahihislam_commerce"] # 1. Migrate Admin Collections print("\n1. Migrating to 'sahihislam_admin':") for col in ADMIN_COLLECTIONS: await migrate_collection(src_db, admin_db, col) # 2. Migrate Commerce Collections print("\n2. Migrating to 'sahihislam_commerce':") for col in COMMERCE_COLLECTIONS: await migrate_collection(src_db, commerce_db, col) # 3. Clean up migrated collections from source database print("\n3. Cleaning up old collections from 'sahihislam':") all_migrated = ADMIN_COLLECTIONS + COMMERCE_COLLECTIONS for col in all_migrated: await src_db[col].drop() print(f" • Dropped {col} from sahihislam") # 4. Verification of final database state print("\n4. Final Database Breakdown:") dbs = await client.list_database_names() print(" Active Databases:", dbs) for db_name in ["sahihislam", "sahihislam_admin", "sahihislam_commerce"]: db_ref = client[db_name] colls = await db_ref.list_collection_names() print(f"\n 📁 [{db_name}] ({len(colls)} collections):") for c in sorted(colls): cnt = await db_ref[c].count_documents({}) print(f" - {c}: {cnt} docs") print("\n" + "=" * 60) print("🎉 DATABASE MIGRATION COMPLETED SUCCESSFULLY WITH 100% INTEGRITY!") print("=" * 60) if __name__ == "__main__": asyncio.run(main())