#!/usr/bin/env python3 """ Cleanup script to fix corrupted conversation participants Finds conversations where participants is a string instead of an array and fixes them """ import asyncio import sys from pathlib import Path # Add parent directory to path sys.path.insert(0, str(Path(__file__).parent.parent)) from app.database import connect_db, disconnect_db, get_db import logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) async def fix_corrupted_conversations(): """Fix conversations with participants as string instead of array""" try: # Connect to database await connect_db() db = await get_db() # Find conversations where participants is a string (corrupted) corrupted = await db.conversations.find({ "participants": {"$type": "string"} # MongoDB type check }).to_list(length=None) logger.info(f"Found {len(corrupted)} corrupted conversations") if not corrupted: logger.info("No corrupted conversations found. Database is clean!") return # Fix each corrupted conversation fixed_count = 0 for conv in corrupted: conv_id = conv["_id"] old_participants = conv["participants"] logger.info(f"Fixing conversation {conv_id}: participants = '{old_participants}'") # Delete the corrupted conversation # (We'll let the system recreate it properly when needed) result = await db.conversations.delete_one({"_id": conv_id}) if result.deleted_count > 0: fixed_count += 1 logger.info(f" ✅ Deleted corrupted conversation {conv_id}") else: logger.error(f" ❌ Failed to delete conversation {conv_id}") logger.info(f"\n{'='*60}") logger.info(f"Cleanup complete!") logger.info(f"Fixed {fixed_count} corrupted conversations") logger.info(f"They will be recreated correctly when alerts are sent") logger.info(f"{'='*60}\n") except Exception as e: logger.error(f"Cleanup failed: {e}") raise finally: await disconnect_db() if __name__ == "__main__": logger.info("Starting conversation cleanup...") asyncio.run(fix_corrupted_conversations())