revamping frontend logging system and reorganising documentation
This commit is contained in:
319
scripts/seed_database.py
Normal file
319
scripts/seed_database.py
Normal file
@@ -0,0 +1,319 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Seed the database with initial development data.
|
||||
|
||||
Creates:
|
||||
- Admin user (admin/admin123)
|
||||
- Test vendors (TESTVENDOR, WIZAMART)
|
||||
|
||||
Usage:
|
||||
python scripts/seed_database.py
|
||||
|
||||
This script is idempotent - safe to run multiple times.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add project root to path
|
||||
project_root = Path(__file__).parent.parent
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import select
|
||||
|
||||
from app.core.database import SessionLocal, engine
|
||||
from models.database.user import User
|
||||
from models.database.vendor import Vendor
|
||||
from middleware.auth import AuthManager
|
||||
from datetime import datetime, timezone
|
||||
|
||||
# Default credentials
|
||||
DEFAULT_ADMIN_EMAIL = "admin@letzshop.com"
|
||||
DEFAULT_ADMIN_USERNAME = "admin"
|
||||
DEFAULT_ADMIN_PASSWORD = "admin123" # Change in production!
|
||||
|
||||
|
||||
def verify_database_ready() -> bool:
|
||||
"""
|
||||
Verify that database tables exist.
|
||||
|
||||
Returns:
|
||||
bool: True if database is ready, False otherwise
|
||||
"""
|
||||
try:
|
||||
with engine.connect() as conn:
|
||||
from sqlalchemy import text
|
||||
# Check for users table
|
||||
result = conn.execute(
|
||||
text("SELECT name FROM sqlite_master WHERE type='table' AND name='users'")
|
||||
)
|
||||
users_table = result.fetchall()
|
||||
|
||||
# Check for vendors table
|
||||
result = conn.execute(
|
||||
text("SELECT name FROM sqlite_master WHERE type='table' AND name='vendors'")
|
||||
)
|
||||
vendors_table = result.fetchall()
|
||||
|
||||
return len(users_table) > 0 and len(vendors_table) > 0
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error checking database: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def create_admin_user(db: Session, auth_manager: AuthManager) -> tuple[User, bool]:
|
||||
"""
|
||||
Create admin user if it doesn't exist.
|
||||
|
||||
Args:
|
||||
db: Database session
|
||||
auth_manager: AuthManager instance for password hashing
|
||||
|
||||
Returns:
|
||||
tuple: (User object, was_created boolean)
|
||||
"""
|
||||
# Check if admin already exists
|
||||
existing_admin = db.execute(
|
||||
select(User).where(User.username == DEFAULT_ADMIN_USERNAME)
|
||||
).scalar_one_or_none()
|
||||
|
||||
if existing_admin:
|
||||
return existing_admin, False
|
||||
|
||||
# Create new admin user
|
||||
admin = User(
|
||||
email=DEFAULT_ADMIN_EMAIL,
|
||||
username=DEFAULT_ADMIN_USERNAME,
|
||||
hashed_password=auth_manager.hash_password(DEFAULT_ADMIN_PASSWORD),
|
||||
role="admin",
|
||||
is_active=True,
|
||||
created_at=datetime.now(timezone.utc),
|
||||
updated_at=datetime.now(timezone.utc)
|
||||
)
|
||||
|
||||
db.add(admin)
|
||||
db.flush() # Get the ID
|
||||
|
||||
return admin, True
|
||||
|
||||
|
||||
def create_vendor(
|
||||
db: Session,
|
||||
vendor_code: str,
|
||||
name: str,
|
||||
subdomain: str,
|
||||
owner_user_id: int,
|
||||
description: str = None
|
||||
) -> tuple[Vendor, bool]:
|
||||
"""
|
||||
Create vendor if it doesn't exist.
|
||||
|
||||
Args:
|
||||
db: Database session
|
||||
vendor_code: Unique vendor code
|
||||
name: Vendor name
|
||||
subdomain: Subdomain for the vendor
|
||||
owner_user_id: ID of the owner user
|
||||
description: Optional description
|
||||
|
||||
Returns:
|
||||
tuple: (Vendor object, was_created boolean)
|
||||
"""
|
||||
# Check if vendor already exists
|
||||
existing_vendor = db.execute(
|
||||
select(Vendor).where(Vendor.vendor_code == vendor_code)
|
||||
).scalar_one_or_none()
|
||||
|
||||
if existing_vendor:
|
||||
return existing_vendor, False
|
||||
|
||||
# Create new vendor
|
||||
vendor = Vendor(
|
||||
vendor_code=vendor_code,
|
||||
subdomain=subdomain,
|
||||
name=name,
|
||||
description=description or f"{name} - Development vendor",
|
||||
owner_user_id=owner_user_id,
|
||||
contact_email=f"contact@{subdomain}.com",
|
||||
contact_phone="+352 123 456 789",
|
||||
website=f"https://{subdomain}.com",
|
||||
is_active=True,
|
||||
is_verified=True,
|
||||
created_at=datetime.now(timezone.utc),
|
||||
updated_at=datetime.now(timezone.utc)
|
||||
)
|
||||
|
||||
db.add(vendor)
|
||||
db.flush()
|
||||
|
||||
return vendor, True
|
||||
|
||||
|
||||
def seed_database():
|
||||
"""Main seeding function."""
|
||||
|
||||
print("\n" + "╔" + "═" * 68 + "╗")
|
||||
print("║" + " " * 18 + "DATABASE SEEDING SCRIPT" + " " * 27 + "║")
|
||||
print("╚" + "═" * 68 + "╝\n")
|
||||
|
||||
# ========================================================================
|
||||
# STEP 1: VERIFY DATABASE
|
||||
# ========================================================================
|
||||
|
||||
print("STEP 1: Verifying database...")
|
||||
|
||||
if not verify_database_ready():
|
||||
print("\n❌ ERROR: Database not ready!")
|
||||
print("\n Required tables don't exist yet.")
|
||||
print(" Please run database migrations first:\n")
|
||||
print(" alembic upgrade head\n")
|
||||
sys.exit(1)
|
||||
|
||||
print(" ✓ Database tables verified\n")
|
||||
|
||||
# ========================================================================
|
||||
# STEP 2: CREATE ADMIN USER
|
||||
# ========================================================================
|
||||
|
||||
db = SessionLocal()
|
||||
auth_manager = AuthManager()
|
||||
|
||||
try:
|
||||
print("STEP 2: Creating admin user...")
|
||||
|
||||
admin, admin_created = create_admin_user(db, auth_manager)
|
||||
|
||||
if admin_created:
|
||||
print(f" ✓ Admin user created (ID: {admin.id})")
|
||||
print(f" Username: {admin.username}")
|
||||
print(f" Email: {admin.email}")
|
||||
else:
|
||||
print(f" ℹ️ Admin user already exists (ID: {admin.id})")
|
||||
print(f" Username: {admin.username}")
|
||||
print(f" Email: {admin.email}")
|
||||
|
||||
# ====================================================================
|
||||
# STEP 3: CREATE VENDORS
|
||||
# ====================================================================
|
||||
|
||||
print("\nSTEP 3: Creating vendors...")
|
||||
|
||||
# Create TESTVENDOR
|
||||
test_vendor, test_created = create_vendor(
|
||||
db,
|
||||
vendor_code="TESTVENDOR",
|
||||
name="Test Vendor",
|
||||
subdomain="testvendor",
|
||||
owner_user_id=admin.id,
|
||||
description="Development test vendor for general testing"
|
||||
)
|
||||
|
||||
if test_created:
|
||||
print(f" ✓ TESTVENDOR created (ID: {test_vendor.id})")
|
||||
else:
|
||||
print(f" ℹ️ TESTVENDOR already exists (ID: {test_vendor.id})")
|
||||
|
||||
# Create WIZAMART
|
||||
wizamart, wizamart_created = create_vendor(
|
||||
db,
|
||||
vendor_code="WIZAMART",
|
||||
name="WizaMart",
|
||||
subdomain="wizamart",
|
||||
owner_user_id=admin.id,
|
||||
description="Primary development vendor for theme customization"
|
||||
)
|
||||
|
||||
if wizamart_created:
|
||||
print(f" ✓ WIZAMART created (ID: {wizamart.id})")
|
||||
else:
|
||||
print(f" ℹ️ WIZAMART already exists (ID: {wizamart.id})")
|
||||
|
||||
# Commit all changes
|
||||
db.commit()
|
||||
|
||||
# ====================================================================
|
||||
# SUMMARY
|
||||
# ====================================================================
|
||||
|
||||
print("\n" + "╔" + "═" * 68 + "╗")
|
||||
print("║" + " " * 22 + "SEEDING COMPLETE!" + " " * 28 + "║")
|
||||
print("╚" + "═" * 68 + "╝\n")
|
||||
|
||||
if admin_created or test_created or wizamart_created:
|
||||
print("✅ New items created:")
|
||||
if admin_created:
|
||||
print(" • Admin user")
|
||||
if test_created:
|
||||
print(" • TESTVENDOR")
|
||||
if wizamart_created:
|
||||
print(" • WIZAMART")
|
||||
else:
|
||||
print("ℹ️ All items already existed - no changes made")
|
||||
|
||||
print("\n" + "─" * 70)
|
||||
print("📝 ADMIN LOGIN CREDENTIALS")
|
||||
print("─" * 70)
|
||||
print(f" URL: http://localhost:8000/admin/login")
|
||||
print(f" Username: {DEFAULT_ADMIN_USERNAME}")
|
||||
print(f" Password: {DEFAULT_ADMIN_PASSWORD}")
|
||||
print("─" * 70)
|
||||
|
||||
print("\n" + "─" * 70)
|
||||
print("🏪 VENDORS")
|
||||
print("─" * 70)
|
||||
|
||||
vendors = db.execute(select(Vendor)).scalars().all()
|
||||
for v in vendors:
|
||||
print(f"\n {v.vendor_code}")
|
||||
print(f" Name: {v.name}")
|
||||
print(f" Subdomain: {v.subdomain}.letzshop.com")
|
||||
print(f" Theme URL: http://localhost:8000/admin/vendors/{v.vendor_code}/theme")
|
||||
print(f" Verified: {'✓' if v.is_verified else '✗'}")
|
||||
print(f" Active: {'✓' if v.is_active else '✗'}")
|
||||
|
||||
print("\n" + "─" * 70)
|
||||
print("🚀 NEXT STEPS")
|
||||
print("─" * 70)
|
||||
print(" 1. Start the server:")
|
||||
print(" python -m uvicorn app.main:app --reload\n")
|
||||
print(" 2. Login to admin panel:")
|
||||
print(" http://localhost:8000/admin/login\n")
|
||||
print(" 3. Test theme editor:")
|
||||
print(" http://localhost:8000/admin/vendors/WIZAMART/theme\n")
|
||||
|
||||
if admin_created:
|
||||
print("⚠️ SECURITY: Change the default admin password after first login!")
|
||||
|
||||
print()
|
||||
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
print("\n" + "╔" + "═" * 68 + "╗")
|
||||
print("║" + " " * 28 + "ERROR" + " " * 35 + "║")
|
||||
print("╚" + "═" * 68 + "╝\n")
|
||||
print(f"❌ Failed to seed database: {e}")
|
||||
print(f"\nError type: {type(e).__name__}")
|
||||
print("\nCommon issues:")
|
||||
print(" - Database migrations not run (run: alembic upgrade head)")
|
||||
print(" - Database connection issues")
|
||||
print(" - Foreign key constraint violations")
|
||||
print()
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
seed_database()
|
||||
except KeyboardInterrupt:
|
||||
print("\n\n⚠️ Seeding interrupted by user")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f"\n❌ Fatal error: {e}")
|
||||
sys.exit(1)
|
||||
Reference in New Issue
Block a user