# Cria os perfis pré-prontos e atribui a cada usuário existente o perfil do papel # que ele já tinha. Sem isso, o dia seguinte ao deploy seria "todo mundo no # fallback" — funciona, mas a tela de perfis nasceria vazia e o ADM não teria de # onde partir para montar o dele. # # ⚠️ A lista de chaves está DUPLICADA aqui e em Permissao::PADRAO_POR_ROLE, de # propósito: migration não pode depender de model. Se o catálogo mudar daqui a # seis meses, o histórico do banco não pode mudar junto — quem já rodou esta # migration continua com o perfil que foi criado naquele dia. # # Idempotente (o teste e a produção migram em momentos diferentes, e a migration # pode encontrar um banco onde o ADM já criou perfis à mão). class SemearPerfisAcesso < ActiveRecord::Migration[7.1] TODAS = %w[ dashboard.ver dashboard.financeiro dashboard.operacoes dashboard.exportar dashboard.metricas consolidacao.ver consolidacao.criar consolidacao.editar consolidacao.editar_finalizada consolidacao.finalizar consolidacao.arquivar consolidacao.excluir consolidacao.registrar_pagamento consolidacao.cancelar_pagamento consolidacao.gerir_motoristas consolidacao.exportar_pdf notificacao.contatos notificacao.contatos_gerenciar notificacao.contatos_excluir notificacao.eventos notificacao.eventos_gerenciar notificacao.disparar_manual notificacao.variaveis notificacao.envios notificacao.credenciais notificacao.whatsapp_sessao admin.usuarios admin.usuarios_gerenciar admin.perfis admin.configuracoes admin.configuracoes_editar admin.auditoria admin.edicao_lancamento admin.planilha_simpli_route ].freeze GERENTE = %w[ dashboard.ver dashboard.financeiro dashboard.operacoes dashboard.exportar dashboard.metricas consolidacao.ver consolidacao.criar consolidacao.editar consolidacao.editar_finalizada consolidacao.finalizar consolidacao.arquivar consolidacao.excluir consolidacao.registrar_pagamento consolidacao.cancelar_pagamento consolidacao.gerir_motoristas consolidacao.exportar_pdf notificacao.contatos notificacao.contatos_gerenciar notificacao.envios admin.usuarios admin.configuracoes admin.auditoria admin.planilha_simpli_route ].freeze OPERADOR = %w[ dashboard.ver dashboard.financeiro dashboard.operacoes dashboard.exportar dashboard.metricas consolidacao.ver consolidacao.criar consolidacao.editar consolidacao.finalizar consolidacao.gerir_motoristas consolidacao.exportar_pdf ].freeze EXTERNO = %w[dashboard.ver dashboard.operacoes].freeze # nome, descrição, permissões, role legada que recebe este perfil PERFIS = [ ['Administrador', 'Acesso total ao sistema.', :todas, 0], ['Gerente', 'Opera e paga; administra usuários, preços e destinatários.', GERENTE, 1], ['Operador', 'Monta e finaliza consolidações; não paga nem administra.', OPERADOR, 2], ['Externo', 'Somente leitura dos indicadores de operação.', EXTERNO, 4] ].freeze def up PERFIS.each do |nome, descricao, permissoes, role| lista = (permissoes == :todas ? TODAS : permissoes) id = select_value("SELECT id FROM perfis_acesso WHERE LOWER(nome) = #{quote(nome.downcase)}") if id.nil? execute(<<~SQL.squish) INSERT INTO perfis_acesso (nome, descricao, permissoes, sistema, ativo, created_at, updated_at) VALUES (#{quote(nome)}, #{quote(descricao)}, #{quote(lista.to_json)}::jsonb, true, true, NOW(), NOW()) SQL id = select_value("SELECT id FROM perfis_acesso WHERE LOWER(nome) = #{quote(nome.downcase)}") end # Só quem ainda não tem perfil: se o ADM já ajustou alguém à mão entre o # deploy e a migration, a escolha dele vence. execute("UPDATE users SET perfil_acesso_id = #{id}, updated_at = NOW() " \ "WHERE role = #{role} AND perfil_acesso_id IS NULL") end end def down execute('UPDATE users SET perfil_acesso_id = NULL') execute('DELETE FROM perfis_acesso WHERE sistema = true') end end