""" Migration seed: create the 'admin' role and assign it to existing is_admin=True users. Run once after deploying the updated schema. Idempotent — safe to run multiple times. Usage: KMTN_DATABASE_URL=... python migrate_roles.py (run from the backend/ directory) """ import asyncio from sqlalchemy import select, text from app.database import async_session from app.user_models import User, Role, user_roles async def migrate() -> None: """Ensure 'admin' role exists and assign to existing is_admin=True users.""" async with async_session() as session: # 1) Create 'admin' role if it doesn't exist result = await session.execute(select(Role).where(Role.name == "admin")) admin_role = result.scalar_one_or_none() if admin_role is None: admin_role = Role(name="admin", description="Full administrative access") session.add(admin_role) await session.commit() await session.refresh(admin_role) print(f" ✓ Created 'admin' role (id={admin_role.id})") else: print(f" ✓ 'admin' role already exists (id={admin_role.id})") # 2) Assign 'admin' role to all existing is_admin=True users result = await session.execute( select(User).where(User.is_admin == True) # noqa: E712 ) admin_users = result.scalars().all() migrated = 0 for user in admin_users: if admin_role not in user.roles: user.roles.append(admin_role) migrated += 1 if migrated: await session.commit() print(f" ✓ Assigned 'admin' role to {migrated} existing admin user(s)") else: print(" ✓ No new role assignments needed") # 3) Summary result = await session.execute( select(User).where(user_roles.c.role_id == admin_role.id) ) role_admins = result.scalars().all() print(f" → {len(role_admins)} user(s) now have the 'admin' role") if __name__ == "__main__": print("Running role migration...") asyncio.run(migrate()) print("Done.")