#!/usr/bin/env python3 """ dev_wipe.py — Test data cleanup script for Lojiz dev/staging. Wipes all test data for a given user ID: • scout_mandates • search_alerts • bookings (pending/confirmed only — leaves completed history) • viewings • notifications • aida DM messages + conversation clear-marker Usage: python dev_wipe.py # wipes default USER_ID below python dev_wipe.py # wipes specific user python dev_wipe.py --all-mandates # wipes ALL scout mandates (all users) """ import asyncio import sys from motor.motor_asyncio import AsyncIOMotorClient from dotenv import load_dotenv import os load_dotenv() # ── Config ──────────────────────────────────────────────────────────────────── MONGO_URL = os.getenv("MONGODB_URL", "mongodb://localhost:27017") DB_NAME = os.getenv("MONGODB_DATABASE", "lojiz") # Default user to wipe — override via CLI arg DEFAULT_USER_ID = "69065321eec337ffa2084300" # Booking statuses considered "pending" (safe to delete during testing) PENDING_BOOKING_STATUSES = ["Pending", "Confirmed", "ActiveStay"] # ── Wipe logic ──────────────────────────────────────────────────────────────── async def wipe_user(user_id: str, db) -> None: print(f"\n🧹 Wiping test data for user: {user_id}") print("─" * 60) # 1. Scout mandates r = await db["scout_mandates"].delete_many({"user_id": user_id}) print(f" ✅ scout_mandates deleted: {r.deleted_count}") # 2. Search alerts (legacy + active) r = await db["search_alerts"].delete_many({"user_id": user_id}) print(f" ✅ search_alerts deleted: {r.deleted_count}") # 3. Bookings — only pending/active, keep completed history r = await db["bookings"].delete_many({ "$or": [ {"user_id": user_id}, {"landlord_id": user_id}, ], "status": {"$in": PENDING_BOOKING_STATUSES}, }) print(f" ✅ bookings (pending) deleted: {r.deleted_count}") # 4. Viewings (pre + post reminders live here) r = await db["viewings"].delete_many({ "$or": [ {"visitor_id": user_id}, {"landlord_id": user_id}, ] }) print(f" ✅ viewings deleted: {r.deleted_count}") # 5. Notifications r = await db["notifications"].delete_many({"user_id": user_id}) print(f" ✅ notifications deleted: {r.deleted_count}") # 6. AIDA DM messages — clear the AIDA conversation messages # (keeps the conversation doc itself so the DM thread still appears) aida_conv = await db["conversations"].find_one({ "participants": {"$all": ["AIDA_BOT", user_id]} }) if aida_conv: conv_id = str(aida_conv["_id"]) r = await db["messages"].delete_many({"conversation_id": conv_id}) # Reset last_message on the conversation await db["conversations"].update_one( {"_id": aida_conv["_id"]}, {"$set": {"last_message": None, "last_message_at": None}}, ) print(f" ✅ AIDA DM messages deleted: {r.deleted_count} (conv: {conv_id})") else: print(f" ℹ️ AIDA DM messages no conversation found — skipped") print("─" * 60) print(f"✅ Done. User {user_id} is clean for fresh testing.\n") async def wipe_all_mandates(db) -> None: print("\n⚠️ Wiping ALL scout mandates across all users…") r = await db["scout_mandates"].delete_many({}) print(f" ✅ scout_mandates (all users) deleted: {r.deleted_count}\n") async def main(): all_mandates = "--all-mandates" in sys.argv args = [a for a in sys.argv[1:] if not a.startswith("--")] user_id = args[0] if args else DEFAULT_USER_ID client = AsyncIOMotorClient(MONGO_URL) db = client[DB_NAME] try: # Verify connection await db.command("ping") print(f"✅ Connected to MongoDB: {DB_NAME}") if all_mandates: await wipe_all_mandates(db) await wipe_user(user_id, db) except Exception as e: print(f"\n❌ Error: {e}") sys.exit(1) finally: client.close() if __name__ == "__main__": asyncio.run(main())