""" Data migration que: 1. Crea el catálogo global de permisos (RolePermission). 2. Para cada Organizacion existente, crea los 5 roles por defecto con sus permisos. 3. Para cada CustomUser existente, mapea sus auth.Group actuales al UserRole equivalente. Usa get_or_create en todos los pasos — segura de ejecutar múltiples veces. """ from django.db import migrations # Importamos solo constantes (no modelos ni funciones con imports de Django) # para que la migration sea estable ante futuros refactors del código de la app. from api.rbac.roles import PERMISSIONS_CATALOG, DEFAULT_ROLES def _crear_permisos(RolePermission): perms_map = {} for codename, descripcion, modulo in PERMISSIONS_CATALOG: perm, _ = RolePermission.objects.get_or_create( codename=codename, defaults={'descripcion': descripcion, 'modulo': modulo}, ) perms_map[codename] = perm return perms_map def _crear_roles_org(OrganizationRole, org, perms_map): for nombre, config in DEFAULT_ROLES.items(): role, created = OrganizationRole.objects.get_or_create( organizacion=org, nombre=nombre, defaults={ 'descripcion': config['descripcion'], 'is_admin_role': config.get('is_admin_role', False), }, ) if created: role_perms = [perms_map[c] for c in config['permissions'] if c in perms_map] role.permissions.set(role_perms) def seed_rbac_data(apps, schema_editor): RolePermission = apps.get_model('rbac', 'RolePermission') OrganizationRole = apps.get_model('rbac', 'OrganizationRole') UserRole = apps.get_model('rbac', 'UserRole') Organizacion = apps.get_model('organization', 'Organizacion') CustomUser = apps.get_model('cuser', 'CustomUser') # Paso 1 — Catálogo de permisos perms_map = _crear_permisos(RolePermission) # Paso 2 — Roles por defecto para cada organización existente for org in Organizacion.objects.all(): _crear_roles_org(OrganizationRole, org, perms_map) # Paso 3 — Mapeo de usuarios: auth.Group → UserRole # Solo usuarios que tengan organización asignada y grupos asignados for user in CustomUser.objects.filter(organizacion__isnull=False).prefetch_related('groups'): for group in user.groups.all(): try: role = OrganizationRole.objects.get( organizacion=user.organizacion, nombre=group.name, ) UserRole.objects.get_or_create(user=user, role=role) except OrganizationRole.DoesNotExist: # El grupo no tiene equivalente en los roles por defecto — se ignora pass def reverse_seed(apps, schema_editor): # Revertir borra todos los datos RBAC. Los auth.Group originales no se tocan. apps.get_model('rbac', 'UserRole').objects.all().delete() apps.get_model('rbac', 'OrganizationRole').objects.all().delete() apps.get_model('rbac', 'RolePermission').objects.all().delete() class Migration(migrations.Migration): dependencies = [ ('rbac', '0001_initial'), ('cuser', '0005_customuser_rfc_fk_to_m2m'), ('organization', '0003_organizacion_apply_auto_download'), ] operations = [ migrations.RunPython(seed_rbac_data, reverse_code=reverse_seed), ]