from sqlalchemy import or_, select from sqlalchemy.orm import Session from app.core.config import settings from app.core.security import get_password_hash, verify_password from app.db.session import sync_engine from app.models.user import User def ensure_default_admin() -> None: if not settings.DEFAULT_ADMIN_ENABLED: return phone = settings.DEFAULT_ADMIN_PHONE.strip() or None email = settings.DEFAULT_ADMIN_EMAIL.strip() or None if not phone and not email: raise RuntimeError("DEFAULT_ADMIN_PHONE or DEFAULT_ADMIN_EMAIL is required") filters = [] if phone: filters.append(User.phone == phone) if email: filters.append(User.email == email) with Session(sync_engine) as session: user = session.execute(select(User).where(or_(*filters))).scalar_one_or_none() if user is None: user = User( phone=phone, email=email, password_hash=get_password_hash(settings.DEFAULT_ADMIN_PASSWORD), nickname=settings.DEFAULT_ADMIN_NICKNAME, identity="both", role="admin", is_active=True, ) session.add(user) session.commit() return changed = False expected = { "phone": phone, "email": email, "nickname": settings.DEFAULT_ADMIN_NICKNAME, "identity": "both", "role": "admin", "is_active": True, } for field, value in expected.items(): if value is not None and getattr(user, field) != value: setattr(user, field, value) changed = True if settings.DEFAULT_ADMIN_SYNC_PASSWORD and not verify_password( settings.DEFAULT_ADMIN_PASSWORD, user.password_hash, ): user.password_hash = get_password_hash(settings.DEFAULT_ADMIN_PASSWORD) changed = True if changed: session.add(user) session.commit()