""" Comprehensive Demo Data Seeder for Elmeg Creates 12 diverse user personas and populates with Goose data """ import sys from datetime import datetime, timedelta from sqlmodel import Session, select from passlib.context import CryptContext from database import engine from models import ( User, Vertical, Venue, Tour, Show, Song, Performance, Artist, Attendance, Comment, Rating, Review, Group, GroupMember, GroupPost, PerformanceNickname, UserPreferences, Badge, UserBadge, Tag, EntityTag ) pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") # User Personas USERS = [ {"email": "archivist@demo.com", "username": "TheArchivist", "role": "user", "wiki_mode": True, "bio": "Pure data, no noise"}, {"email": "statnerd@demo.com", "username": "StatNerd420", "role": "user", "wiki_mode": False, "bio": "Gap charts are life"}, {"email": "reviewer@demo.com", "username": "CriticalListener", "role": "user", "wiki_mode": False, "bio": "Every show deserves analysis"}, {"email": "casual@demo.com", "username": "CasualFan", "role": "user", "wiki_mode": False, "bio": "Just here for the vibes"}, {"email": "groupleader@demo.com", "username": "NortheastHonkers", "role": "user", "wiki_mode": False, "bio": "NYC/Boston crew organizer"}, {"email": "mod@demo.com", "username": "ModGoose", "role": "moderator", "wiki_mode": False, "bio": "Keeping it clean"}, {"email": "admin@demo.com", "username": "AdminBird", "role": "admin", "wiki_mode": False, "bio": "Platform steward"}, {"email": "newbie@demo.com", "username": "NewToGoose", "role": "user", "wiki_mode": False, "bio": "Just discovered them!"}, {"email": "taper@demo.com", "username": "TaperTom", "role": "user", "wiki_mode": False, "bio": "Recording quality matters"}, {"email": "tourfollower@demo.com", "username": "RoadWarrior", "role": "user", "wiki_mode": False, "bio": "50+ shows and counting"}, {"email": "lurker@demo.com", "username": "SilentHonker", "role": "user", "wiki_mode": True, "bio": "Observer mode"}, {"email": "hype@demo.com", "username": "HypeGoose", "role": "user", "wiki_mode": False, "bio": "EVERYTHING IS FIRE 🔥"}, ] def create_users(session: Session): """Create 12 diverse user personas""" print("Creating users...") users = [] for user_data in USERS: user = User( email=user_data["email"], hashed_password=pwd_context.hash("demo123"), is_active=True, is_superuser=(user_data["role"] == "admin"), role=user_data["role"] ) session.add(user) session.commit() session.refresh(user) # Set preferences prefs = UserPreferences( user_id=user.id, wiki_mode=user_data["wiki_mode"], show_ratings=not user_data["wiki_mode"], show_comments=not user_data["wiki_mode"] ) session.add(prefs) users.append(user) session.commit() print(f"✓ Created {len(users)} users") return users def create_vertical(session: Session): """Create Goose vertical""" print("Creating Goose vertical...") vertical = Vertical( name="Goose", slug="goose", description="Goose is a jam band from Connecticut" ) session.add(vertical) session.commit() session.refresh(vertical) print("✓ Created Goose vertical") return vertical def create_sample_data(session: Session, vertical: Vertical, users: list): """Create comprehensive sample data""" print("Creating sample venues, tours, and shows...") # Venues venues = [ Venue(name="Red Rocks Amphitheatre", city="Morrison", state="CO", country="USA", capacity=9525), Venue(name="The Capitol Theatre", city="Port Chester", state="NY", country="USA", capacity=1800), Venue(name="Radio City Music Hall", city="New York", state="NY", country="USA", capacity=6015), Venue(name="The Gorge Amphitheatre", city="George", state="WA", country="USA", capacity=27500), Venue(name="Brooklyn Bowl", city="Brooklyn", state="NY", country="USA", capacity=600), ] for v in venues: session.add(v) session.commit() # Tours tours = [ Tour(name="Fall 2023 Tour", start_date=datetime(2023, 10, 1), end_date=datetime(2023, 11, 15)), Tour(name="Summer 2024 Tour", start_date=datetime(2024, 6, 1), end_date=datetime(2024, 8, 31)), ] for t in tours: session.add(t) session.commit() # Songs songs = [ Song(title="Hungersite", vertical_id=vertical.id, original_artist=None), Song(title="Arcadia", vertical_id=vertical.id, original_artist=None), Song(title="Hot Tea", vertical_id=vertical.id, original_artist=None), Song(title="Tumble", vertical_id=vertical.id, original_artist=None), Song(title="Seekers on the Ridge", vertical_id=vertical.id, original_artist=None), Song(title="Arrow", vertical_id=vertical.id, original_artist=None), Song(title="Empress of Organos", vertical_id=vertical.id, original_artist=None), Song(title="Rockdale", vertical_id=vertical.id, original_artist=None), ] for s in songs: session.add(s) session.commit() # Shows shows = [] for i in range(10): show = Show( date=datetime(2024, 1, 1) + timedelta(days=i*30), vertical_id=vertical.id, venue_id=venues[i % len(venues)].id, tour_id=tours[i % len(tours)].id if i < 8 else None, notes=f"Night {i+1} of tour" if i < 5 else None ) session.add(show) shows.append(show) session.commit() # Performances (setlists) for show in shows: for pos, song in enumerate(songs[:5], 1): perf = Performance( show_id=show.id, song_id=song.id, position=pos, set_name="Set 1" if pos <= 3 else "Set 2", segue=(pos % 2 == 0), notes="Extended jam" if pos == 3 else None ) session.add(perf) session.commit() print(f"✓ Created {len(venues)} venues, {len(tours)} tours, {len(songs)} songs, {len(shows)} shows") return venues, tours, songs, shows def seed_user_activity(session: Session, users: list, shows: list, songs: list): """Seed diverse user activity based on personas""" print("Seeding user activity...") # Archivist - No social activity # StatNerd - Attendance tracking stat_nerd = users[1] for show in shows[:8]: att = Attendance(user_id=stat_nerd.id, show_id=show.id, notes="Stats logged") session.add(att) # Reviewer - Detailed reviews reviewer = users[2] for show in shows[:3]: review = Review( user_id=reviewer.id, show_id=show.id, blurb="A masterclass in improvisation", content="The Hungersite opener set the tone perfectly. The segue into Arcadia was seamless...", score=9, created_at=show.date + timedelta(days=1) ) session.add(review) # Casual Fan - Occasional comments casual = users[3] perfs = session.exec(select(Performance).limit(5)).all() for perf in perfs[:2]: comment = Comment( user_id=casual.id, show_id=perf.show_id, content="This was so good live!", created_at=datetime.utcnow() - timedelta(days=10) ) session.add(comment) # Group Leader - Creates group leader = users[4] group = Group( name="Northeast Honkers", description="Goose fans from NYC and Boston area", privacy="public", created_by=leader.id ) session.add(group) session.commit() # Add members for user in users[:6]: member = GroupMember(group_id=group.id, user_id=user.id, role="admin" if user.id == leader.id else "member") session.add(member) # Group posts post = GroupPost( group_id=group.id, user_id=leader.id, content="Who's going to the Capitol show next month?" ) session.add(post) # Taper - Notes on recording quality taper = users[8] for show in shows[:4]: comment = Comment( user_id=taper.id, show_id=show.id, content="AUD recording available - great soundboard quality", created_at=show.date + timedelta(hours=12) ) session.add(comment) # Road Warrior - Massive attendance warrior = users[9] for show in shows: att = Attendance(user_id=warrior.id, show_id=show.id, notes="On the road!") session.add(att) # Hype Person - Rates everything 10/10 hype = users[11] for show in shows[:5]: rating = Rating(user_id=hype.id, show_id=show.id, score=10) review = Review( user_id=hype.id, show_id=show.id, blurb="ABSOLUTE HEATER 🔥🔥🔥", content="This show SLAPPED. Every song was FIRE. Best show ever!!!", score=10, created_at=show.date + timedelta(hours=6) ) session.add(rating) session.add(review) # Performance Nicknames mod = users[5] perfs = session.exec(select(Performance).limit(3)).all() for perf in perfs: nick = PerformanceNickname( performance_id=perf.id, nickname="Red Rocks Hungersite" if perf.position == 1 else "Epic Jam", description="Legendary version", status="approved", suggested_by=mod.id ) session.add(nick) session.commit() print("✓ Seeded comprehensive user activity") def main(): print("=" * 60) print("ELMEG DEMO DATA SEEDER") print("=" * 60) with Session(engine) as session: # Check if already seeded existing = session.exec(select(User)).first() if existing: print("⚠ Database already contains data!") response = input("Clear and reseed? (yes/no): ") if response.lower() != "yes": print("Aborted.") return # Clear all data (in reverse dependency order) from sqlalchemy import text for model in [GroupPost, GroupMember, Group, UserBadge, Badge, PerformanceNickname, EntityTag, Tag, Attendance, Comment, Rating, Review, Performance, Show, Tour, Song, Venue, Artist, UserPreferences, User, Vertical]: session.exec(text(f"DELETE FROM {model.__tablename__}")) session.commit() print("✓ Cleared existing data") # Seed users = create_users(session) vertical = create_vertical(session) venues, tours, songs, shows = create_sample_data(session, vertical, users) seed_user_activity(session, users, shows, songs) print("=" * 60) print("✓ DEMO DATA SEEDED SUCCESSFULLY!") print("=" * 60) print("\nLogin credentials (all passwords: demo123):") for user_data in USERS: print(f" {user_data['email']:30} ({user_data['username']})") print("\nStart the demo server:") print(" cd /Users/ten/ANTIGRAVITY/elmeg-demo/backend") print(" DATABASE_URL='sqlite:///./elmeg-demo.db' uvicorn main:app --reload --port 8001") if __name__ == "__main__": main()