"""Remove CLIENT_MANAGER, CLIENT_AGENT, CLIENT_AUDITOR from user_role_enum Revision ID: d2e3f4a5b6c7 Revises: c1d2e3f4a5b6 Create Date: 2026-03-03 14:00:00.000000 Consolida 9 roles → 6 roles migrando datos primero y luego recreando el tipo enum de PostgreSQL (única forma de eliminar valores en PG). Mapeo de datos: CLIENT_MANAGER → CLIENT_ADMIN (conserva nivel de gestión) CLIENT_AGENT → CLIENT_USER (acceso básico de cliente) CLIENT_AUDITOR → CLIENT_USER (acceso básico de cliente) ADVERTENCIA DOWNGRADE: La migración inversa restaura los valores del enum pero NO puede recuperar la distinción original entre CLIENT_AGENT y CLIENT_AUDITOR (ambos quedaron como CLIENT_USER). El downgrade es seguro a nivel de integridad de datos, pero irreversible en semántica. """ from alembic import op # revision identifiers, used by Alembic. revision = 'd2e3f4a5b6c7' down_revision = 'c1d2e3f4a5b6' branch_labels = None depends_on = None def upgrade() -> None: # ── Paso 1: Migrar datos ANTES de modificar el tipo ──────────────────── # CLIENT_MANAGER → CLIENT_ADMIN (conserva acceso de gestión) op.execute("UPDATE users SET role = 'CLIENT_ADMIN' WHERE role = 'CLIENT_MANAGER'") # CLIENT_AGENT → CLIENT_USER (acceso básico de cliente) op.execute("UPDATE users SET role = 'CLIENT_USER' WHERE role = 'CLIENT_AGENT'") # CLIENT_AUDITOR → CLIENT_USER (acceso básico de cliente) op.execute("UPDATE users SET role = 'CLIENT_USER' WHERE role = 'CLIENT_AUDITOR'") # ── Paso 2: Soltar la restricción de tipo para poder recrear el enum ─── # PostgreSQL no permite DROP VALUE en un enum; hay que recrear el tipo. op.execute("ALTER TABLE users ALTER COLUMN role TYPE TEXT") # ── Paso 3: Eliminar tipo actual y recrearlo solo con los 6 roles ────── op.execute("DROP TYPE user_role_enum") op.execute(""" CREATE TYPE user_role_enum AS ENUM ( 'ADMIN', 'SUPPORT_MANAGER', 'AGENT', 'AUDITOR', 'CLIENT_ADMIN', 'CLIENT_USER' ) """) # ── Paso 4: Restaurar columna al tipo enum ────────────────────────────── op.execute( "ALTER TABLE users ALTER COLUMN role TYPE user_role_enum " "USING role::user_role_enum" ) def downgrade() -> None: # ── Paso 1: Soltar la restricción de tipo para recrear el enum ───────── op.execute("ALTER TABLE users ALTER COLUMN role TYPE TEXT") # ── Paso 2: Recrear enum con los 9 valores originales ────────────────── op.execute("DROP TYPE user_role_enum") op.execute(""" CREATE TYPE user_role_enum AS ENUM ( 'ADMIN', 'SUPPORT_MANAGER', 'AGENT', 'AUDITOR', 'CLIENT_ADMIN', 'CLIENT_MANAGER', 'CLIENT_AGENT', 'CLIENT_AUDITOR', 'CLIENT_USER' ) """) # ── Paso 3: Restaurar columna al tipo enum ────────────────────────────── op.execute( "ALTER TABLE users ALTER COLUMN role TYPE user_role_enum " "USING role::user_role_enum" ) # ── Nota sobre pérdida de datos ───────────────────────────────────────── # Los usuarios que eran CLIENT_MANAGER ahora son CLIENT_ADMIN. # Los usuarios que eran CLIENT_AGENT o CLIENT_AUDITOR ahora son CLIENT_USER. # No es posible restaurar la distinción original automáticamente.