semblance-dev/backend/scripts/populate_db_direct.py
2025-08-04 09:07:59 -05:00

549 lines
No EOL
23 KiB
Python
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
Standalone script to populate MongoDB with sample data for the Semblance Synthetic Society app.
This script doesn't rely on the backend modules and connects directly to MongoDB.
"""
import sys
import os
import json
import datetime
from pymongo import MongoClient
from getpass import getpass
from bson.objectid import ObjectId
import random
import string
# Sample persona data from the frontend
sample_personas = [
{
"id": "0",
"name": "Oliver Reynolds",
"age": "42",
"gender": "Male",
"occupation": "Senior Investment Manager",
"education": "Master's degree (Business and Finance)",
"location": "Kensington, London, UK",
"techSavviness": 85,
"personality": "Discerning, sophisticated, detail-oriented, values heritage and craftsmanship",
"interests": "Classic automobiles, high-end timepieces, luxury real estate, fine dining, art exhibitions",
"brandLoyalty": 90,
"priceConsciousness": 30,
"environmentalConcern": 60,
"hasPurchasingPower": True,
"hasChildren": True,
"thinkFeelDo": {
"thinks": [
"How does this reflect my personal standards and values?",
"Is this truly the pinnacle of craftsmanship and quality?",
"Will this purchase stand the test of time as a lasting investment?",
"How can this be further personalized to my exact preferences?"
],
"feels": [
"Proud to associate with heritage brands that reflect my achievements",
"Gratified by bespoke experiences that acknowledge my unique tastes",
"Frustrated by standardized approaches that fail to recognize individual preferences",
"Reassured by transparent, detailed information about craftsmanship and materials"
],
"does": [
"Conducts thorough research before making significant purchasing decisions",
"Seeks personalized consultations with dedicated specialists",
"Expects seamless integration between digital and in-person experiences",
"Values and maintains long-term relationships with trusted luxury brands",
"Regularly attends exclusive events and private showings"
]
},
"oceanTraits": {
"openness": 85,
"conscientiousness": 90,
"extraversion": 60,
"agreeableness": 65,
"neuroticism": 25
}
},
{
"id": "1",
"name": "Fiona Caldwell",
"age": "38",
"gender": "Female",
"occupation": "Founder and Creative Director of a luxury lifestyle brand",
"education": "First-Class Honours degree from a prestigious university",
"location": "Chelsea, London, UK",
"ethnicity": "White British",
"socialGrade": "A/B",
"householdIncome": "Approximately £195,000 per annum",
"householdComposition": "Single professional with established network",
"livingSituation": "Stylish, modern flat in exclusive London district",
"techSavviness": 90,
"personality": "Innovative, discerning, detail-oriented, values quality and distinctiveness",
"interests": "Bespoke fashion, high-end design, contemporary art, exclusive dining experiences",
"mediaConsumption": "Premium publications (The Spectator, Tatler, Vogue) and digital influencers",
"deviceUsage": "High-performance smartphone, tablet, and ultrabook; active on luxury-focused social platforms",
"shoppingHabits": "Prefers bespoke shopping with personalized digital interfaces and in-person exclusivity",
"brandPreferences": "Brands combining heritage with innovation; appreciates tailored craftsmanship",
"brandLoyalty": 85,
"priceConsciousness": 25,
"environmentalConcern": 70,
"hasPurchasingPower": True,
"hasChildren": False,
"communicationPreferences": "Clear, direct, personalized communication through premium channels",
"thinkFeelDo": {
"thinks": [
"How does this complement my personal brand and creative vision?",
"Is this innovative yet timeless enough for my lifestyle?",
"Will this experience or product truly stand out from the mainstream?",
"How can this be tailored to reflect my unique aesthetic sensibilities?"
],
"feels": [
"Excited by innovative designs that push creative boundaries",
"Valued when brands recognize her accomplishments and creative influence",
"Frustrated by cookie-cutter luxury experiences that lack personality",
"Inspired by perfect execution of bespoke experiences that reflect attention to detail"
],
"does": [
"Engages with immersive digital platforms and virtual showrooms",
"Attends exclusive industry events and creative collaborations",
"Seeks one-to-one consultancy sessions for significant purchases",
"Shares refined experiences within her select network of peers",
"Collaborates with luxury brands that align with her creative vision"
]
},
"oceanTraits": {
"openness": 95,
"conscientiousness": 85,
"extraversion": 70,
"agreeableness": 65,
"neuroticism": 30
}
},
{
"id": "2",
"name": "Michael Chen",
"age": "37",
"gender": "Male",
"occupation": "Software Engineer",
"location": "San Francisco, USA",
"techSavviness": 95,
"personality": "Analytical, detail-oriented, values efficiency",
"thinkFeelDo": {
"thinks": ["I need to understand how things work", "Efficiency is key"],
"feels": ["Annoyed by bugs or performance issues", "Satisfied by clean, logical interfaces"],
"does": ["Tests edge cases", "Reads documentation thoroughly"]
},
"oceanTraits": {
"openness": 70,
"conscientiousness": 90,
"extraversion": 40,
"agreeableness": 55,
"neuroticism": 30
}
},
{
"id": "4",
"name": "David Kim",
"age": "22",
"gender": "Male",
"occupation": "Student",
"location": "Austin, USA",
"techSavviness": 90,
"personality": "Curious, experimental, price-conscious",
"thinkFeelDo": {
"thinks": ["How can I customize this?", "Is this worth my time?"],
"feels": ["Bored by traditional interfaces", "Excited by customization options"],
"does": ["Tries all settings and features", "Abandons apps that don't engage quickly"]
},
"oceanTraits": {
"openness": 90,
"conscientiousness": 50,
"extraversion": 65,
"agreeableness": 70,
"neuroticism": 40
}
},
{
"id": "5",
"name": "Lisa Patel",
"age": "41",
"gender": "Female",
"occupation": "Product Manager",
"location": "Seattle, USA",
"techSavviness": 80,
"personality": "Strategic thinker, detail-oriented, collaborative",
"thinkFeelDo": {
"thinks": ["How does this fit into the ecosystem?", "What problems does this solve?"],
"feels": ["Concerned about integration issues", "Satisfied by cohesive user journeys"],
"does": ["Evaluates the full user journey", "Compares with competing products"]
},
"oceanTraits": {
"openness": 75,
"conscientiousness": 85,
"extraversion": 60,
"agreeableness": 75,
"neuroticism": 35
}
},
{
"id": "7",
"name": "Olivia Brown",
"age": "31",
"gender": "Female",
"occupation": "UX Designer",
"location": "Portland, USA",
"techSavviness": 90,
"personality": "Creative, empathetic, user-centered",
"thinkFeelDo": {
"thinks": ["How does this make users feel?", "Is this accessible to everyone?"],
"feels": ["Frustrated by poor accessibility", "Inspired by elegant solutions"],
"does": ["Analyzes micro-interactions", "Considers edge cases and accessibility"]
},
"oceanTraits": {
"openness": 85,
"conscientiousness": 75,
"extraversion": 60,
"agreeableness": 80,
"neuroticism": 40
}
},
{
"id": "8",
"name": "Arash Montazeri",
"age": "46",
"gender": "Male",
"occupation": "Senior Executive at a leading technology firm",
"education": "Bachelor's degree in Engineering from a prestigious UK university",
"location": "Ascot, Berkshire, UK",
"ethnicity": "Iranian-British",
"householdIncome": "Approximately £240,000 per annum",
"socialGrade": "A",
"householdComposition": "Married with two grown-up children",
"livingSituation": "Elegant country estate near Ascot blending British comfort and Persian design",
"techSavviness": 94,
"personality": "Integrates heritage and innovation; values bespoke, culturally nuanced service and excellence",
"interests": "Classic cars, bespoke tailoring, fine wines, Persian and contemporary art, luxury travel, golfing at country clubs",
"brandLoyalty": 95,
"priceConsciousness": 40,
"environmentalConcern": 75,
"hasPurchasingPower": True,
"hasChildren": True,
"deviceUsage": "Uses latest smartphones, tablets, smart home tech; prefers personalized luxury interfaces",
"shoppingHabits": "Relationship-driven, high-touch purchasing process with bespoke consultations; expects seamless online-offline integration",
"brandPreferences": "Heritage-driven, premium brands merging traditional craftsmanship with innovation (e.g., RollsRoyce)",
"paymentMethods": "Secure digital banking, premium credit, bespoke financing for high-value purchases",
"mediaConsumption": "Reads Financial Times, The Economist, and select cultural journals reflecting Iranian heritage and global outlook",
"coreValues": "Strong emphasis on heritage and innovation; bespoke service honoring tradition and Iranian culture",
"lifestyleChoices": "Golfing, fine dining at gourmet restaurants, immersive luxury travel, and revisiting Iranian roots",
"socialActivities": "Active in elite clubs, attends high-profile charity/cultural events, celebrates diversity and craftsmanship",
"categoryKnowledge": "Well-versed in luxury automotive engineering and bespoke options; values modern and traditional artistry",
"purchaseBehaviour": "Balances rational analysis and emotional attachment; major purchases are investments in legacy and taste",
"decisionInfluences": "Brand heritage, craftsmanship events, peer endorsements, transparency, and personalized narratives",
"painPoints": "Frustrated by fragmented, impersonal journeys and digital/in-person integration gaps",
"journeyContext": "Engages via invitation-only showrooms, virtual tours, and bespoke digital experiences with seamless support",
"keyTouchpoints": "One-to-one consultations, private previews of new bespoke options, post-purchase concierge support",
"communicationPreferences": "Prefers direct, timely engagement via a relationship manager, comfortable in-person and with premium digital",
"oceanTraits": {
"openness": 93,
"conscientiousness": 97,
"extraversion": 68,
"agreeableness": 64,
"neuroticism": 18
},
"selfDeterminationNeeds": {
"autonomy": "Seeks independence and offerings reflecting multifaceted identity",
"competence": "Desires recognition for refined taste and expects flawless service mirroring achievements",
"relatedness": "Wants personalized, respectful brand relationships honoring Iranian and British sophistication"
},
"motivations": [
"Pursuit of excellence in every aspect",
"Preserve cultural legacy through selective luxury experiences",
"Leave a lasting impact via refined, innovative purchases",
"Deep connections with heritage brands",
"Integrity and authenticity in every luxury engagement",
"Opportunities to express identity through bespoke, meaningful customization"
],
"fears": [
"Receiving subpar, impersonal service",
"Excessive digitization eroding tailored luxury experience"
],
"scenarioType": "Scenarios Across Life, Luxury, Technology, and Heritage",
"scenarios": [
"Arash attends a private RollsRoyce preview showcasing a bespoke vehicle that artfully blends British engineering with Persian design, collaborating one-on-one with brand artisans.",
"Invited to a virtual configurator experience, Arash works directly with a relationship manager to design a tailored vehicle from the comfort of his study, later completing the process with an in-person consultation.",
"At a high-profile cultural gala, Arash discusses his curated automotive and art collections, valuing brands that recognize and celebrate his unique heritage and refined taste.",
"Arash grows frustrated when a luxury brand's digital appointment system does not seamlessly coordinate with in-person experience, prompting him to seek out brands with superior omnichannel integration.",
"When considering a new bespoke vehicle, Arash weighs heritage, innovation, and family legacy, seeking a process that honors his background in every detail—from material selection to narrative storytelling.",
"Post-purchase, Arash values ongoing, dedicated aftercare provided by a trusted relationship manager, ensuring every aspect of ownership exceeds expectations and reflects his status."
],
"narrative": "Arash Montazeri exemplifies the modern luxury consumer who seamlessly integrates his Iranian heritage with contemporary British sophistication."
}
]
# Sample focus group data from the frontend
sample_focus_groups = [
{
"id": "1",
"name": "Mobile App UX Evaluation",
"status": "in-progress",
"participants": [
"1", "2", "4", "5", "7"
],
"date": "2023-06-12T15:30:00Z",
"duration": 60,
"topic": "user-experience",
"discussionGuide": """
# Discussion Guide: Mobile App UX Evaluation
## Introduction (5 minutes)
Welcome to our focus group discussion. Today we'll be exploring your experiences and opinions on our mobile app interface. There are no right or wrong answers, we're just interested in your honest thoughts.
## Warm-up Questions (10 minutes)
Let's start by introducing ourselves and sharing a bit about your daily smartphone usage.
## Navigation Experience Exploration (15 minutes)
Now, let's dive deeper into your experiences with the app navigation. What features do you find most intuitive? What frustrations have you encountered?
## Creative Testing (20 minutes)
We'll now show you some design concepts and get your feedback.
## Conclusion (10 minutes)
To wrap up, I'd like to hear your final thoughts on what we've discussed today and any additional insights you'd like to share.
"""
},
{
"id": "2",
"name": "Product Feature Feedback",
"status": "in-progress",
"participants": [
"1", "4", "5", "7"
],
"date": "2023-06-15T10:00:00Z",
"duration": 90,
"topic": "product-feedback",
"discussionGuide": """
# Discussion Guide: Product Feature Feedback
## Introduction (5 minutes)
Welcome to our focus group discussion. Today we'll be exploring your thoughts on our upcoming product features.
## Warm-up Questions (10 minutes)
Let's start by discussing your current experience with similar products.
## Feature Exploration (30 minutes)
We'll present several feature concepts and gather your feedback on each.
## Prioritization Exercise (15 minutes)
Help us understand which features would be most valuable to you.
## Conclusion (10 minutes)
Final thoughts and summary of the discussion.
"""
},
{
"id": "3",
"name": "Marketing Campaign Testing",
"status": "in-progress",
"participants": [
"2", "4", "7"
],
"date": "2023-06-12T15:30:00Z",
"duration": 45,
"topic": "creative-testing",
"discussionGuide": """
# Discussion Guide: Marketing Campaign Testing
## Introduction (5 minutes)
Welcome everyone. Today we're evaluating some marketing campaign concepts.
## Warm-up (5 minutes)
Brief discussion about marketing campaigns that have caught your attention recently.
## Campaign Concept Review (25 minutes)
We'll review several campaign directions and gather your impressions.
## Message Effectiveness (10 minutes)
Discussion about which messages resonate most strongly and why.
## Conclusion (5 minutes)
Final impressions and recommendations.
"""
}
]
def connect_to_mongodb():
"""Connect to MongoDB with or without authentication"""
print("Connecting to MongoDB...")
# Try with MongoDB default credentials first (widely used standard defaults)
standard_credentials = [
{"user": "admin", "pass": "admin", "db": "admin"},
{"user": "mongodb", "pass": "mongodb", "db": "admin"},
{"user": "root", "pass": "root", "db": "admin"},
{"user": "user", "pass": "pass", "db": "admin"}
]
# Try each set of standard credentials
for creds in standard_credentials:
try:
uri = f"mongodb://{creds['user']}:{creds['pass']}@localhost:27017/semblance_db?authSource={creds['db']}"
client = MongoClient(uri, serverSelectionTimeoutMS=2000)
db = client.semblance_db
# Test the connection with a simple command
db.command('ping')
print(f"Successfully connected to MongoDB with standard credentials ({creds['user']})")
return client, db
except Exception as e:
# Continue trying other credentials
pass
print("Could not connect with standard credentials")
# Try connecting without auth (in case auth is not required)
try:
client = MongoClient('mongodb://localhost:27017', serverSelectionTimeoutMS=2000)
db = client.semblance_db
# Try to perform an operation that requires auth to verify
# we actually have write access (ping might succeed without auth)
result = db.command('buildInfo')
if result:
# Try to create a test document to verify write access
test_result = db.test_collection.insert_one({"test": "auth"})
db.test_collection.delete_one({"_id": test_result.inserted_id})
print("Successfully connected to MongoDB without authentication")
return client, db
except Exception as e:
print(f"Could not connect without auth: {e}")
# Try with environment variables
mongo_user = os.environ.get('MONGO_USER')
mongo_pass = os.environ.get('MONGO_PASS')
if mongo_user and mongo_pass:
try:
uri = f"mongodb://{mongo_user}:{mongo_pass}@localhost:27017/semblance_db?authSource=admin"
client = MongoClient(uri, serverSelectionTimeoutMS=2000)
db = client.semblance_db
# Test the connection with an operation
db.command('ping')
print(f"Successfully connected to MongoDB with environment credentials")
return client, db
except Exception as e:
print(f"Could not connect with environment credentials: {e}")
# Ask for credentials interactively
print("\nMongoDB requires authentication.")
print("Please enter your MongoDB credentials:")
username = input("MongoDB username: ")
password = getpass("MongoDB password: ")
try:
uri = f"mongodb://{username}:{password}@localhost:27017/semblance_db?authSource=admin"
client = MongoClient(uri, serverSelectionTimeoutMS=2000)
db = client.semblance_db
db.command('ping')
print("Successfully connected to MongoDB with provided credentials")
return client, db
except Exception as e:
print(f"Error connecting with provided credentials: {e}")
print("Could not connect to MongoDB. Please check your credentials.")
sys.exit(1)
def create_default_user(db):
"""Create a default admin user if it doesn't exist"""
try:
# Check if user exists
existing_user = db.users.find_one({"username": "admin"})
if existing_user:
print("Default admin user already exists")
return existing_user["_id"]
# Create a simple password hash (in a real app, use proper password hashing)
# For this script, using a simple md5 hash (not secure for production!)
import hashlib
password_hash = hashlib.md5("admin".encode()).hexdigest()
# Create user
user = {
"username": "admin",
"email": "admin@example.com",
"password": password_hash,
"created_at": datetime.datetime.now().isoformat()
}
result = db.users.insert_one(user)
print("Created default admin user")
return result.inserted_id
except Exception as e:
print(f"Error creating default user: {e}")
# Return a temporary ObjectId
return ObjectId()
def main():
# Connect to MongoDB
client, db = connect_to_mongodb()
# Create default user
user_id = create_default_user(db)
# Clear existing data
try:
db.personas.delete_many({})
db.focus_groups.delete_many({})
print("Cleared existing personas and focus groups")
except Exception as e:
print(f"Warning: Could not clear collections: {e}")
# Map from frontend IDs to MongoDB IDs
id_mapping = {}
# Import personas
print("\nAdding personas...")
for persona_data in sample_personas:
try:
# Remove frontend ID
frontend_id = persona_data.pop("id")
# Add metadata
persona_data["created_by"] = str(user_id)
persona_data["created_at"] = datetime.datetime.now()
# Insert into MongoDB
result = db.personas.insert_one(persona_data)
mongo_id = result.inserted_id
# Store mapping
id_mapping[frontend_id] = mongo_id
print(f"Imported persona: {persona_data.get('name')} (frontend ID: {frontend_id} → MongoDB ID: {mongo_id})")
except Exception as e:
print(f"Error importing persona: {e}")
# Import focus groups
print("\nAdding focus groups...")
for focus_group_data in sample_focus_groups:
try:
# Remove frontend ID
frontend_id = focus_group_data.pop("id")
# Map participants
frontend_participants = focus_group_data.pop("participants", [])
participants = []
for p_id in frontend_participants:
if p_id in id_mapping:
participants.append(id_mapping[p_id])
focus_group_data["participants"] = participants
# Add metadata
focus_group_data["created_by"] = str(user_id)
focus_group_data["created_at"] = datetime.datetime.now()
# Insert into MongoDB
result = db.focus_groups.insert_one(focus_group_data)
mongo_id = result.inserted_id
print(f"Imported focus group: {focus_group_data.get('name')} (frontend ID: {frontend_id} → MongoDB ID: {mongo_id})")
print(f" - Participants: {len(participants)}")
except Exception as e:
print(f"Error importing focus group: {e}")
print("\nData import complete!")
client.close()
if __name__ == "__main__":
main()