""" Seed database with sample data for local development. Run: python -m app.scripts.seed """ import asyncio import uuid from datetime import datetime, timedelta, timezone from sqlalchemy import select from app.core.database import async_session_factory from app.core.security import hash_password # Import all ORM modules so SQLAlchemy string relationships resolve on Windows/local runs. import app.models.application # noqa: F401 import app.models.resume # noqa: F401 import app.models.alerts # noqa: F401 import app.models.llm # noqa: F401 import app.api.routes.bookmarks # noqa: F401 import app.api.routes.cover_letters # noqa: F401 import app.api.routes.reminders # noqa: F401 import app.api.routes.qa_bank # noqa: F401 import app.api.routes.webhooks # noqa: F401 import app.services.analytics # noqa: F401 from app.models.job import Company, Job from app.models.scraper import JobSource from app.models.user import Profile, User SAMPLE_COMPANIES = [ {"name": "Google", "slug": "google", "domain": "google.com", "industry": "Technology", "size_range": "10000+", "headquarters": "Mountain View, CA", "company_type": "public", "tech_stack": ["C++", "Python", "Go", "Kubernetes", "TensorFlow"]}, {"name": "Stripe", "slug": "stripe", "domain": "stripe.com", "industry": "Fintech", "size_range": "5001-10000", "headquarters": "San Francisco, CA", "company_type": "private", "tech_stack": ["Ruby", "Java", "Scala", "PostgreSQL"]}, {"name": "Vercel", "slug": "vercel", "domain": "vercel.com", "industry": "Developer Tools", "size_range": "201-500", "headquarters": "San Francisco, CA", "company_type": "startup", "tech_stack": ["TypeScript", "Next.js", "React", "Rust"]}, {"name": "Anthropic", "slug": "anthropic", "domain": "anthropic.com", "industry": "AI/ML", "size_range": "501-1000", "headquarters": "San Francisco, CA", "company_type": "startup", "tech_stack": ["Python", "PyTorch", "Kubernetes", "Rust"]}, {"name": "Linear", "slug": "linear", "domain": "linear.app", "industry": "Developer Tools", "size_range": "51-200", "headquarters": "San Francisco, CA", "company_type": "startup", "tech_stack": ["TypeScript", "React", "GraphQL", "PostgreSQL"]}, {"name": "Figma", "slug": "figma", "domain": "figma.com", "industry": "Design", "size_range": "1001-5000", "headquarters": "San Francisco, CA", "company_type": "private", "tech_stack": ["TypeScript", "React", "WebGL", "Rust"]}, {"name": "Datadog", "slug": "datadog", "domain": "datadoghq.com", "industry": "DevOps", "size_range": "5001-10000", "headquarters": "New York, NY", "company_type": "public", "tech_stack": ["Go", "Python", "Kubernetes", "Kafka"]}, {"name": "Notion", "slug": "notion", "domain": "notion.so", "industry": "Productivity", "size_range": "501-1000", "headquarters": "San Francisco, CA", "company_type": "private", "tech_stack": ["TypeScript", "React", "Node.js", "PostgreSQL"]}, ] SAMPLE_JOBS = [ {"title": "Senior Frontend Engineer", "company": "Vercel", "remote_type": "remote", "employment_type": "full_time", "seniority_level": "senior", "salary_min": 180000, "salary_max": 250000, "skills_required": ["React", "Next.js", "TypeScript", "CSS"], "description_text": "Join our frontend team to build the future of web development. You'll work on Next.js, Turbopack, and our deployment platform used by millions of developers."}, {"title": "Staff Software Engineer - AI Infrastructure", "company": "Anthropic", "remote_type": "hybrid", "employment_type": "full_time", "seniority_level": "senior", "salary_min": 300000, "salary_max": 450000, "skills_required": ["Python", "Distributed Systems", "ML Infrastructure", "Kubernetes"], "description_text": "Build the infrastructure powering Claude. Work on training pipelines, inference systems, and developer APIs at scale."}, {"title": "Product Engineer", "company": "Linear", "remote_type": "remote", "employment_type": "full_time", "seniority_level": "mid", "salary_min": 150000, "salary_max": 200000, "skills_required": ["React", "TypeScript", "Node.js", "PostgreSQL"], "description_text": "Build features end-to-end for our project management tool used by the best product teams. Own features from conception to deployment."}, {"title": "Backend Engineer - Payments", "company": "Stripe", "remote_type": "hybrid", "employment_type": "full_time", "seniority_level": "mid", "salary_min": 175000, "salary_max": 250000, "skills_required": ["Ruby", "Java", "Distributed Systems", "SQL"], "description_text": "Build the economic infrastructure for the internet. Work on payment processing, fraud detection, and financial services APIs."}, {"title": "Senior Software Engineer - Search", "company": "Google", "remote_type": "onsite", "employment_type": "full_time", "seniority_level": "senior", "salary_min": 200000, "salary_max": 350000, "skills_required": ["C++", "Python", "Distributed Systems", "Information Retrieval"], "description_text": "Improve search quality for billions of users. Work on ranking algorithms, knowledge graphs, and AI-powered features."}, {"title": "Full Stack Engineer", "company": "Notion", "remote_type": "hybrid", "employment_type": "full_time", "seniority_level": "mid", "salary_min": 160000, "salary_max": 220000, "skills_required": ["React", "TypeScript", "Node.js", "PostgreSQL"], "description_text": "Build collaborative features for Notion's workspace platform. Work across the stack from real-time sync to UI components."}, {"title": "Design Engineer", "company": "Figma", "remote_type": "hybrid", "employment_type": "full_time", "seniority_level": "mid", "salary_min": 170000, "salary_max": 240000, "skills_required": ["React", "TypeScript", "WebGL", "Design Systems"], "description_text": "Bridge design and engineering at Figma. Build interactive UI components, design system primitives, and creative tools."}, {"title": "Senior Site Reliability Engineer", "company": "Datadog", "remote_type": "remote", "employment_type": "full_time", "seniority_level": "senior", "salary_min": 190000, "salary_max": 280000, "skills_required": ["Kubernetes", "Terraform", "Go", "Observability"], "description_text": "Keep Datadog running at scale. Own service reliability, incident response, and infrastructure automation for our monitoring platform."}, {"title": "Machine Learning Engineer - NLP", "company": "Google", "remote_type": "onsite", "employment_type": "full_time", "seniority_level": "senior", "salary_min": 220000, "salary_max": 380000, "skills_required": ["Python", "PyTorch", "Transformers", "NLP"], "description_text": "Work on large language models and NLP systems. Apply cutting-edge research to production systems serving billions of queries."}, {"title": "Software Engineering Intern", "company": "Stripe", "remote_type": "hybrid", "employment_type": "internship", "seniority_level": "intern", "salary_min": 80000, "salary_max": 100000, "skills_required": ["Python", "JavaScript", "SQL"], "description_text": "12-week summer internship. Work on real projects alongside experienced engineers. Past interns have shipped features used by millions."}, ] SAMPLE_SOURCES = [ {"name": "Greenhouse - Vercel", "source_type": "ats_api", "domain": "vercel.com", "base_url": "https://boards-api.greenhouse.io/v1/boards/vercel/jobs", "ats_vendor": "greenhouse", "ats_config": {"board_token": "vercel"}}, {"name": "Greenhouse - Anthropic", "source_type": "ats_api", "domain": "anthropic.com", "base_url": "https://boards-api.greenhouse.io/v1/boards/anthropic/jobs", "ats_vendor": "greenhouse", "ats_config": {"board_token": "anthropic"}}, {"name": "Lever - Linear", "source_type": "ats_api", "domain": "linear.app", "base_url": "https://api.lever.co/v0/postings/linear", "ats_vendor": "lever", "ats_config": {"company_slug": "linear"}}, {"name": "Ashby - Notion", "source_type": "ats_api", "domain": "notion.so", "base_url": "https://api.ashbyhq.com/posting-api/job-board", "ats_vendor": "ashby", "ats_config": {"board_slug": "notion"}}, ] async def seed(): """Seed the database with sample data.""" async with async_session_factory() as db: print("🌱 Seeding database...") # Avoid duplicate seed runs. existing = await db.scalar(select(User).where(User.email == "demo@jobportal.dev")) if existing: print("✅ Seed data already exists. Skipping.") return # 1. Create admin user admin = User( email="admin@jobportal.dev", hashed_password=hash_password("admin123"), full_name="Admin User", role="admin", is_active=True, is_verified=True, is_superuser=True, ) db.add(admin) # 2. Create demo user demo = User( email="demo@jobportal.dev", hashed_password=hash_password("demo123"), full_name="Demo User", role="candidate", is_active=True, is_verified=True, ) db.add(demo) await db.flush() # 3. Create demo profile profile = Profile( user_id=demo.id, headline="Full Stack Engineer", location="San Francisco, CA", summary="Passionate full-stack engineer with 5 years of experience building web applications.", skills=[ {"name": "React", "category": "Frameworks", "level": 5}, {"name": "TypeScript", "category": "Languages", "level": 5}, {"name": "Python", "category": "Languages", "level": 4}, {"name": "Node.js", "category": "Frameworks", "level": 4}, {"name": "PostgreSQL", "category": "Databases", "level": 4}, {"name": "AWS", "category": "Cloud", "level": 3}, {"name": "Docker", "category": "Tools", "level": 4}, {"name": "Next.js", "category": "Frameworks", "level": 5}, ], experience=[ { "company": "TechCorp", "title": "Senior Software Engineer", "location": "San Francisco, CA", "start_date": "2022-01", "end_date": "", "is_current": True, "bullets": [ "Led development of real-time collaboration features serving 100K+ daily active users", "Reduced page load time by 40% through code splitting and performance optimization", "Mentored 3 junior engineers and led weekly architecture reviews", ], }, ], remote_preference="remote", salary_min=180000, salary_max=250000, salary_currency="USD", open_to_work=True, ) db.add(profile) # 4. Create companies company_map = {} for c in SAMPLE_COMPANIES: company = Company(**c) db.add(company) company_map[c["name"]] = company await db.flush() # 5. Create jobs now = datetime.now(timezone.utc) for i, j in enumerate(SAMPLE_JOBS): company = company_map.get(j["company"]) job = Job( title=j["title"], company_id=company.id if company else None, company_name=j["company"], source_url=f"https://{company.domain}/careers/{uuid.uuid4().hex[:8]}" if company else "https://example.com/jobs/1", source_domain=company.domain if company else "example.com", source_type="seed", remote_type=j.get("remote_type"), employment_type=j.get("employment_type"), seniority_level=j.get("seniority_level"), salary_min=j.get("salary_min"), salary_max=j.get("salary_max"), salary_currency="USD", salary_interval="yearly", skills_required=j.get("skills_required"), description_text=j.get("description_text"), status="active", date_posted=now - timedelta(days=i * 2), locations=[{"raw": "San Francisco, CA", "city": "San Francisco", "state": "CA", "country": "US"}], ) db.add(job) # 6. Create sources for s in SAMPLE_SOURCES: source = JobSource(**s) db.add(source) await db.commit() print("✅ Database seeded successfully!") print(" Admin: admin@jobportal.dev / admin123") print(" Demo: demo@jobportal.dev / demo123") print(f" Companies: {len(SAMPLE_COMPANIES)}") print(f" Jobs: {len(SAMPLE_JOBS)}") print(f" Sources: {len(SAMPLE_SOURCES)}") if __name__ == "__main__": asyncio.run(seed())