#!/usr/bin/env python3 """ Script to delete ALL corrupted conversations where participants is a string """ 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_all_corrupted_conversations(): """Delete ALL conversations where participants is stored as a string""" try: await connect_db() db = await get_db() # Method 1: Find by type (string instead of array) corrupted = await db.conversations.find({ "participants": {"$type": "string"} }).to_list(length=None) logger.info(f"Found {len(corrupted)} corrupted by type check") # Method 2: Delete directly by the known problematic user ID known_corrupted = await db.conversations.find({ "participants": "6901d49e03321114aa21e246" # String, not in array }).to_list(length=None) logger.info(f"Found {len(known_corrupted)} with known corrupted participant") # Combine and dedupe all_ids = set() for conv in corrupted + known_corrupted: all_ids.add(conv["_id"]) logger.info(f"Total unique corrupted: {len(all_ids)}") # Delete them deleted = 0 for conv_id in all_ids: # Delete messages first await db.messages.delete_many({"conversation_id": str(conv_id)}) # Delete conversation result = await db.conversations.delete_one({"_id": conv_id}) if result.deleted_count > 0: deleted += 1 logger.info(f" ✅ Deleted corrupted conversation: {conv_id}") # Also check if there are any AIDA_BOT conversations with wrong structure aida_convs = await db.conversations.find({ "$or": [ {"participants": "AIDA_BOT"}, {"participants": {"$elemMatch": {"$eq": "AIDA_BOT"}}} ] }).to_list(length=None) logger.info(f"Found {len(aida_convs)} AIDA conversations to verify") for conv in aida_convs: participants = conv.get("participants") # Check if it's not properly an array of 2 strings if not isinstance(participants, list) or len(participants) != 2: await db.messages.delete_many({"conversation_id": str(conv["_id"])}) await db.conversations.delete_one({"_id": conv["_id"]}) deleted += 1 logger.info(f" ✅ Deleted malformed AIDA conversation: {conv['_id']}") logger.info(f"\n{'='*60}") logger.info(f"✅ Cleanup Complete!") logger.info(f"Deleted {deleted} corrupted conversations") 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("Fixing ALL corrupted conversations...") asyncio.run(fix_all_corrupted_conversations())