320 lines
No EOL
13 KiB
Python
320 lines
No EOL
13 KiB
Python
from bson import ObjectId
|
|
from app.db import get_db
|
|
from datetime import datetime
|
|
|
|
|
|
class Folder:
|
|
@staticmethod
|
|
def create(folder_data, user_id):
|
|
"""Create a new folder."""
|
|
db = get_db()
|
|
|
|
# Add metadata
|
|
folder_data["created_at"] = datetime.utcnow()
|
|
folder_data["created_by"] = user_id
|
|
|
|
# Note: No longer storing persona_ids in folders - using persona-centric storage
|
|
|
|
result = db.folders.insert_one(folder_data)
|
|
return str(result.inserted_id)
|
|
|
|
@staticmethod
|
|
def find_by_id(folder_id):
|
|
"""Find a folder by its ID."""
|
|
db = get_db()
|
|
try:
|
|
folder = db.folders.find_one({"_id": ObjectId(folder_id)})
|
|
if folder:
|
|
folder["_id"] = str(folder["_id"])
|
|
return folder
|
|
except Exception as e:
|
|
print(f"Error in find_by_id: {e}")
|
|
return None
|
|
|
|
@staticmethod
|
|
def find_by_user(user_id, limit=100):
|
|
"""Find all folders created by a specific user."""
|
|
db = get_db()
|
|
folders = db.folders.find({"created_by": user_id}).sort("created_at", -1).limit(limit)
|
|
result = []
|
|
|
|
for folder in folders:
|
|
folder["_id"] = str(folder["_id"])
|
|
result.append(folder)
|
|
|
|
return result
|
|
|
|
@staticmethod
|
|
def get_all(limit=100):
|
|
"""Get all folders (for debugging/admin purposes)."""
|
|
try:
|
|
db = get_db()
|
|
folders = list(db.folders.find().sort("created_at", -1).limit(limit))
|
|
result = []
|
|
|
|
for folder in folders:
|
|
folder["_id"] = str(folder["_id"])
|
|
result.append(folder)
|
|
|
|
return result
|
|
except Exception as e:
|
|
print(f"Error in Folder.get_all: {e}")
|
|
return []
|
|
|
|
@staticmethod
|
|
def update(folder_id, data):
|
|
"""Update a folder."""
|
|
db = get_db()
|
|
|
|
# Create a copy of the data to avoid modifying the original
|
|
filtered_data = data.copy()
|
|
|
|
# Remove fields that shouldn't be updated
|
|
if '_id' in filtered_data:
|
|
del filtered_data['_id']
|
|
if 'id' in filtered_data:
|
|
del filtered_data['id']
|
|
if 'created_at' in filtered_data:
|
|
del filtered_data['created_at']
|
|
if 'created_by' in filtered_data:
|
|
del filtered_data['created_by']
|
|
|
|
# Set the updated timestamp
|
|
filtered_data["updated_at"] = datetime.utcnow()
|
|
|
|
result = db.folders.update_one(
|
|
{"_id": ObjectId(folder_id)},
|
|
{"$set": filtered_data}
|
|
)
|
|
|
|
return result.modified_count > 0
|
|
|
|
@staticmethod
|
|
def delete(folder_id):
|
|
"""Delete a folder."""
|
|
db = get_db()
|
|
try:
|
|
result = db.folders.delete_one({"_id": ObjectId(folder_id)})
|
|
return result.deleted_count > 0
|
|
except Exception as e:
|
|
print(f"Error in delete: {e}")
|
|
return False
|
|
|
|
@staticmethod
|
|
def add_persona(folder_id, persona_id):
|
|
"""Add a persona to a folder (persona-centric storage)."""
|
|
db = get_db()
|
|
|
|
try:
|
|
print(f"🔧 FOLDER ADD_PERSONA: folder_id={folder_id}, persona_id={persona_id}")
|
|
|
|
# Check if persona exists
|
|
persona = db.personas.find_one({"_id": ObjectId(persona_id)})
|
|
if not persona:
|
|
print(f"❌ FOLDER ADD_PERSONA: Persona {persona_id} not found")
|
|
return False
|
|
|
|
print(f"✅ FOLDER ADD_PERSONA: Found persona {persona.get('name', 'Unknown')} ({persona_id})")
|
|
print(f"📋 FOLDER ADD_PERSONA: Current folder_ids: {persona.get('folder_ids', 'None')}")
|
|
|
|
# Only update the persona's folder_ids - single source of truth
|
|
persona_result = db.personas.update_one(
|
|
{"_id": ObjectId(persona_id)},
|
|
{"$addToSet": {"folder_ids": folder_id}, "$set": {"updated_at": datetime.utcnow()}}
|
|
)
|
|
|
|
print(f"📝 FOLDER ADD_PERSONA: Update result - modified_count: {persona_result.modified_count}, matched_count: {persona_result.matched_count}")
|
|
|
|
# Verify the update
|
|
updated_persona = db.personas.find_one({"_id": ObjectId(persona_id)})
|
|
print(f"✅ FOLDER ADD_PERSONA: Updated folder_ids: {updated_persona.get('folder_ids', 'None')}")
|
|
|
|
# Update folder's updated_at timestamp
|
|
db.folders.update_one(
|
|
{"_id": ObjectId(folder_id)},
|
|
{"$set": {"updated_at": datetime.utcnow()}}
|
|
)
|
|
|
|
return persona_result.modified_count > 0
|
|
except Exception as e:
|
|
print(f"❌ FOLDER ADD_PERSONA ERROR: {e}")
|
|
import traceback
|
|
print(f"❌ FOLDER ADD_PERSONA TRACEBACK: {traceback.format_exc()}")
|
|
return False
|
|
|
|
@staticmethod
|
|
def remove_persona(folder_id, persona_id):
|
|
"""Remove a persona from a folder (persona-centric storage)."""
|
|
db = get_db()
|
|
|
|
try:
|
|
print(f"🔧 FOLDER REMOVE_PERSONA: folder_id={folder_id}, persona_id={persona_id}")
|
|
|
|
# Check if persona exists
|
|
persona = db.personas.find_one({"_id": ObjectId(persona_id)})
|
|
if not persona:
|
|
print(f"❌ FOLDER REMOVE_PERSONA: Persona {persona_id} not found")
|
|
return False
|
|
|
|
print(f"✅ FOLDER REMOVE_PERSONA: Found persona {persona.get('name', 'Unknown')} ({persona_id})")
|
|
print(f"📋 FOLDER REMOVE_PERSONA: Current folder_ids: {persona.get('folder_ids', 'None')}")
|
|
|
|
# Only update the persona's folder_ids - single source of truth
|
|
persona_result = db.personas.update_one(
|
|
{"_id": ObjectId(persona_id)},
|
|
{"$pull": {"folder_ids": folder_id}, "$set": {"updated_at": datetime.utcnow()}}
|
|
)
|
|
|
|
print(f"📝 FOLDER REMOVE_PERSONA: Update result - modified_count: {persona_result.modified_count}, matched_count: {persona_result.matched_count}")
|
|
|
|
# Verify the update
|
|
updated_persona = db.personas.find_one({"_id": ObjectId(persona_id)})
|
|
print(f"✅ FOLDER REMOVE_PERSONA: Updated folder_ids: {updated_persona.get('folder_ids', 'None')}")
|
|
|
|
# Update folder's updated_at timestamp
|
|
db.folders.update_one(
|
|
{"_id": ObjectId(folder_id)},
|
|
{"$set": {"updated_at": datetime.utcnow()}}
|
|
)
|
|
|
|
return persona_result.modified_count > 0
|
|
except Exception as e:
|
|
print(f"❌ FOLDER REMOVE_PERSONA ERROR: {e}")
|
|
import traceback
|
|
print(f"❌ FOLDER REMOVE_PERSONA TRACEBACK: {traceback.format_exc()}")
|
|
return False
|
|
|
|
@staticmethod
|
|
def add_personas_batch(folder_id, persona_ids):
|
|
"""Add multiple personas to a folder (persona-centric storage)."""
|
|
db = get_db()
|
|
|
|
try:
|
|
print(f"🔧 FOLDER ADD_PERSONAS_BATCH: folder_id={folder_id}, persona_ids={persona_ids}")
|
|
|
|
# Add folder to each persona's folder_ids - single source of truth
|
|
persona_results = []
|
|
for persona_id in persona_ids:
|
|
try:
|
|
print(f"🔧 FOLDER BATCH: Processing persona {persona_id}")
|
|
|
|
# Check if persona exists
|
|
persona = db.personas.find_one({"_id": ObjectId(persona_id)})
|
|
if not persona:
|
|
print(f"❌ FOLDER BATCH: Persona {persona_id} not found")
|
|
persona_results.append(False)
|
|
continue
|
|
|
|
print(f"✅ FOLDER BATCH: Found persona {persona.get('name', 'Unknown')}")
|
|
print(f"📋 FOLDER BATCH: Current folder_ids: {persona.get('folder_ids', 'None')}")
|
|
|
|
result = db.personas.update_one(
|
|
{"_id": ObjectId(persona_id)},
|
|
{"$addToSet": {"folder_ids": folder_id}, "$set": {"updated_at": datetime.utcnow()}}
|
|
)
|
|
|
|
print(f"📝 FOLDER BATCH: Update result for {persona_id} - modified: {result.modified_count}")
|
|
persona_results.append(result.modified_count > 0)
|
|
|
|
except Exception as e:
|
|
print(f"❌ FOLDER BATCH ERROR for persona {persona_id}: {e}")
|
|
persona_results.append(False)
|
|
|
|
# Update folder's updated_at timestamp
|
|
db.folders.update_one(
|
|
{"_id": ObjectId(folder_id)},
|
|
{"$set": {"updated_at": datetime.utcnow()}}
|
|
)
|
|
|
|
success_count = sum(1 for r in persona_results if r)
|
|
print(f"✅ FOLDER ADD_PERSONAS_BATCH: {success_count}/{len(persona_ids)} personas updated successfully")
|
|
|
|
return any(persona_results)
|
|
except Exception as e:
|
|
print(f"❌ FOLDER ADD_PERSONAS_BATCH ERROR: {e}")
|
|
import traceback
|
|
print(f"❌ FOLDER ADD_PERSONAS_BATCH TRACEBACK: {traceback.format_exc()}")
|
|
return False
|
|
|
|
@staticmethod
|
|
def remove_personas_batch(folder_id, persona_ids):
|
|
"""Remove multiple personas from a folder (persona-centric storage)."""
|
|
db = get_db()
|
|
|
|
try:
|
|
print(f"🔧 FOLDER REMOVE_PERSONAS_BATCH: folder_id={folder_id}, persona_ids={persona_ids}")
|
|
|
|
# Remove folder from each persona's folder_ids - single source of truth
|
|
persona_results = []
|
|
for persona_id in persona_ids:
|
|
try:
|
|
print(f"🔧 FOLDER REMOVE_BATCH: Processing persona {persona_id}")
|
|
|
|
# Check if persona exists
|
|
persona = db.personas.find_one({"_id": ObjectId(persona_id)})
|
|
if not persona:
|
|
print(f"❌ FOLDER REMOVE_BATCH: Persona {persona_id} not found")
|
|
persona_results.append(False)
|
|
continue
|
|
|
|
print(f"✅ FOLDER REMOVE_BATCH: Found persona {persona.get('name', 'Unknown')}")
|
|
print(f"📋 FOLDER REMOVE_BATCH: Current folder_ids: {persona.get('folder_ids', 'None')}")
|
|
|
|
result = db.personas.update_one(
|
|
{"_id": ObjectId(persona_id)},
|
|
{"$pull": {"folder_ids": folder_id}, "$set": {"updated_at": datetime.utcnow()}}
|
|
)
|
|
|
|
print(f"📝 FOLDER REMOVE_BATCH: Update result for {persona_id} - modified: {result.modified_count}")
|
|
persona_results.append(result.modified_count > 0)
|
|
|
|
except Exception as e:
|
|
print(f"❌ FOLDER REMOVE_BATCH ERROR for persona {persona_id}: {e}")
|
|
persona_results.append(False)
|
|
|
|
# Update folder's updated_at timestamp
|
|
db.folders.update_one(
|
|
{"_id": ObjectId(folder_id)},
|
|
{"$set": {"updated_at": datetime.utcnow()}}
|
|
)
|
|
|
|
success_count = sum(1 for r in persona_results if r)
|
|
print(f"✅ FOLDER REMOVE_PERSONAS_BATCH: {success_count}/{len(persona_ids)} personas updated successfully")
|
|
|
|
return any(persona_results)
|
|
except Exception as e:
|
|
print(f"❌ FOLDER REMOVE_PERSONAS_BATCH ERROR: {e}")
|
|
import traceback
|
|
print(f"❌ FOLDER REMOVE_PERSONAS_BATCH TRACEBACK: {traceback.format_exc()}")
|
|
return False
|
|
|
|
@staticmethod
|
|
def get_folders_containing_persona(persona_id, user_id=None):
|
|
"""Find all folders that contain a specific persona (persona-centric storage)."""
|
|
db = get_db()
|
|
|
|
try:
|
|
# Get the persona to see which folders it belongs to
|
|
persona = db.personas.find_one({"_id": ObjectId(persona_id)})
|
|
if not persona or not persona.get("folder_ids"):
|
|
return []
|
|
|
|
# Get folders by their IDs
|
|
folder_ids = [ObjectId(fid) for fid in persona["folder_ids"]]
|
|
query = {"_id": {"$in": folder_ids}}
|
|
|
|
# Optionally filter by user
|
|
if user_id:
|
|
query["created_by"] = user_id
|
|
|
|
folders = list(db.folders.find(query))
|
|
result = []
|
|
|
|
for folder in folders:
|
|
folder["_id"] = str(folder["_id"])
|
|
result.append(folder)
|
|
|
|
return result
|
|
except Exception as e:
|
|
print(f"Error getting folders for persona {persona_id}: {e}")
|
|
return [] |