from __future__ import annotations import argparse import json from sqlalchemy import delete, select from sqlalchemy.orm import Session from .auth import hash_password from .content import HERO_SLIDES, VEHICLE_OPTIONS from .database import Base, SessionLocal, engine from .models import ( AdminUser, HeroSlide, MediaAsset, VehicleOption, ) def create_media(db: Session, url: str | None, group: str, name: str | None = None) -> None: if not url: return media = db.scalar(select(MediaAsset).where(MediaAsset.url == url)) if media is None: media = next((item for item in db.new if isinstance(item, MediaAsset) and item.url == url), None) if media: media.group = group media.name = name else: db.add(MediaAsset(url=url, group=group, name=name)) def seed_initial_content(db: Session) -> dict: for model in [VehicleOption, HeroSlide, MediaAsset]: db.execute(delete(model)) db.flush() for index, slide in enumerate(HERO_SLIDES): create_media(db, slide["image"], "hero", slide["title"]) db.add( HeroSlide( title=slide["title"], kicker=slide["kicker"], actionLabel=slide["action"], image=slide["image"], sortOrder=index, ) ) for index, option in enumerate(VEHICLE_OPTIONS): create_media(db, option["image"], "vehicle-option", option["title"]) db.add( VehicleOption( title=option["title"], description=option.get("description"), image=option.get("image"), sortOrder=index, ) ) return { "heroSlides": len(HERO_SLIDES), "vehicleOptions": len(VEHICLE_OPTIONS), } def seed_database(reset: bool) -> dict: Base.metadata.create_all(bind=engine) with SessionLocal() as db: user = db.scalar(select(AdminUser).where(AdminUser.email == "admin@example.com")) if user: user.passwordHash = hash_password("ChangeMe123!") user.isActive = True user.name = "后台管理员" user.role = "super_admin" else: db.add( AdminUser( email="admin@example.com", name="后台管理员", passwordHash=hash_password("ChangeMe123!"), role="super_admin", ) ) result = seed_initial_content(db) if reset else {"seeded": False} db.commit() return result def main() -> None: parser = argparse.ArgumentParser(description="Seed WonderQ Admin database") parser.add_argument("--no-reset", action="store_true", help="Only ensure admin user exists") args = parser.parse_args() result = seed_database(reset=not args.no_reset) print(f"Seed complete. Admin login: admin@example.com / ChangeMe123!") print(json.dumps(result, ensure_ascii=False)) if __name__ == "__main__": main()