""" Script de migración para implementar sistema de roles Crea tabla roles y migra usuarios existentes """ from sqlalchemy import create_engine, text from app.core.config import settings def migrate(): engine = create_engine(settings.DATABASE_URL) with engine.connect() as conn: print("🔄 Iniciando migración de roles...") # 1. Crear tabla roles print("📋 Creando tabla roles...") conn.execute(text(""" CREATE TABLE IF NOT EXISTS roles ( id SERIAL PRIMARY KEY, name VARCHAR(50) UNIQUE NOT NULL, display_name VARCHAR(100) NOT NULL, description VARCHAR(255), can_manage_users BOOLEAN DEFAULT FALSE, can_manage_roles BOOLEAN DEFAULT FALSE, can_manage_checklists BOOLEAN DEFAULT FALSE, can_create_inspections BOOLEAN DEFAULT FALSE, can_view_all_inspections BOOLEAN DEFAULT FALSE, can_view_reports BOOLEAN DEFAULT FALSE, can_deactivate_inspections BOOLEAN DEFAULT FALSE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ) """)) conn.commit() # 2. Insertar roles predefinidos print("👥 Insertando roles predefinidos...") conn.execute(text(""" INSERT INTO roles (name, display_name, description, can_manage_users, can_manage_roles, can_manage_checklists, can_create_inspections, can_view_all_inspections, can_view_reports, can_deactivate_inspections) VALUES ('administrador', 'Administrador', 'Acceso completo al sistema', TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE), ('asesor', 'Asesor', 'Acceso a reportes e informes', FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE), ('mecanico', 'Mecánico', 'Realizar inspecciones', FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE) ON CONFLICT (name) DO NOTHING """)) conn.commit() # 3. Agregar columna role_id a users (temporal) print("🔧 Agregando columna role_id a usuarios...") conn.execute(text(""" ALTER TABLE users ADD COLUMN IF NOT EXISTS role_id INTEGER """)) conn.commit() # 4. Migrar datos: admin -> administrador (id=1) print("🔄 Migrando usuarios admin -> administrador...") conn.execute(text(""" UPDATE users SET role_id = (SELECT id FROM roles WHERE name = 'administrador') WHERE role = 'admin' AND role_id IS NULL """)) conn.commit() # 5. Migrar datos: mechanic -> mecanico (id=3) print("🔄 Migrando usuarios mechanic -> mecanico...") conn.execute(text(""" UPDATE users SET role_id = (SELECT id FROM roles WHERE name = 'mecanico') WHERE role IN ('mechanic', 'mecanico') AND role_id IS NULL """)) conn.commit() # 6. Verificar que todos tienen role_id result = conn.execute(text("SELECT COUNT(*) FROM users WHERE role_id IS NULL")) null_count = result.scalar() if null_count > 0: print(f"⚠️ Advertencia: {null_count} usuarios sin role_id asignado") print(" Asignando rol de mecánico por defecto...") conn.execute(text(""" UPDATE users SET role_id = (SELECT id FROM roles WHERE name = 'mecanico') WHERE role_id IS NULL """)) conn.commit() # 7. Hacer role_id NOT NULL y crear foreign key print("🔒 Aplicando restricciones...") conn.execute(text(""" ALTER TABLE users ALTER COLUMN role_id SET NOT NULL """)) conn.execute(text(""" ALTER TABLE users ADD CONSTRAINT fk_users_role_id FOREIGN KEY (role_id) REFERENCES roles(id) """)) conn.commit() # 8. Eliminar columna role antigua print("🗑️ Eliminando columna role antigua...") conn.execute(text(""" ALTER TABLE users DROP COLUMN IF EXISTS role """)) conn.commit() # 9. Mostrar resumen print("\n✅ Migración completada!") print("\n📊 Resumen de roles:") result = conn.execute(text(""" SELECT r.name, r.display_name, COUNT(u.id) as user_count FROM roles r LEFT JOIN users u ON u.role_id = r.id GROUP BY r.id, r.name, r.display_name ORDER BY r.id """)) for row in result: print(f" {row[1]}: {row[2]} usuario(s)") print("\n🎉 Sistema de roles implementado correctamente!") if __name__ == "__main__": migrate()