File size: 3,421 Bytes
6687173
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/usr/bin/env python3
"""
NUCLEAR CLEANUP: Delete corrupted conversations and fix the index
"""

import asyncio
import sys
from pathlib import 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 nuclear_cleanup():
    """Aggressively fix all conversation issues"""
    
    try:
        await connect_db()
        db = await get_db()
        
        logger.info("Step 1: Finding ALL conversations...")
        all_convs = await db.conversations.find({}).to_list(length=None)
        logger.info(f"Total conversations in DB: {len(all_convs)}")
        
        # Check each conversation
        corrupted_ids = []
        for conv in all_convs:
            participants = conv.get("participants")
            conv_id = conv["_id"]
            
            # Check if corrupted (not a proper list of 2 strings)
            is_corrupted = False
            
            if isinstance(participants, str):
                logger.info(f"  ❌ CORRUPTED (string): {conv_id} -> '{participants}'")
                is_corrupted = True
            elif not isinstance(participants, list):
                logger.info(f"  ❌ CORRUPTED (not list): {conv_id} -> {type(participants)}")
                is_corrupted = True
            elif len(participants) != 2:
                logger.info(f"  ❌ CORRUPTED (wrong length): {conv_id} -> {participants}")
                is_corrupted = True
            else:
                # Verify each participant is a string
                for p in participants:
                    if not isinstance(p, str):
                        logger.info(f"  ❌ CORRUPTED (bad participant type): {conv_id}")
                        is_corrupted = True
                        break
            
            if is_corrupted:
                corrupted_ids.append(conv_id)
        
        logger.info(f"\nFound {len(corrupted_ids)} corrupted conversations")
        
        # Delete corrupted conversations and their messages
        for conv_id in corrupted_ids:
            await db.messages.delete_many({"conversation_id": str(conv_id)})
            await db.conversations.delete_one({"_id": conv_id})
            logger.info(f"  βœ… Deleted: {conv_id}")
        
        # Step 2: Drop and recreate the index
        logger.info("\nStep 2: Fixing participants index...")
        try:
            await db.conversations.drop_index("participants_1")
            logger.info("  Dropped old participants_1 index")
        except Exception as e:
            logger.info(f"  No existing index to drop: {e}")
        
        # Recreate with proper unique index
        await db.conversations.create_index("participants", unique=True)
        logger.info("  βœ… Created new unique index on participants")
        
        logger.info(f"\n{'='*60}")
        logger.info(f"βœ… NUCLEAR CLEANUP COMPLETE!")
        logger.info(f"Deleted {len(corrupted_ids)} corrupted conversations")
        logger.info(f"Index recreated")
        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("πŸ”₯ NUCLEAR CLEANUP - Fixing all conversation issues...")
    asyncio.run(nuclear_cleanup())