refactor: remove authentication module and integrate Better Auth
- Deleted the `autenticacao.ts` file to streamline the authentication process. - Updated the `auth.ts` file to include new functions for user management and password updates. - Modified the schema to enforce the presence of `authId` for users, ensuring integration with Better Auth. - Refactored the seed process to create users with Better Auth integration, enhancing user management capabilities. - Cleaned up the `usuarios.ts` file to utilize the new authentication functions and improve code clarity.
This commit is contained in:
@@ -1,8 +1,15 @@
|
||||
import { internalMutation, mutation, query } from "./_generated/server";
|
||||
import {
|
||||
action,
|
||||
internalAction,
|
||||
internalMutation,
|
||||
mutation,
|
||||
query,
|
||||
} from "./_generated/server";
|
||||
import { internal } from "./_generated/api";
|
||||
import { v } from "convex/values";
|
||||
import { hashPassword } from "./auth/utils";
|
||||
import { Id } from "./_generated/dataModel";
|
||||
import { createAuthUser } from "./auth";
|
||||
|
||||
// Dados exportados do Convex Cloud
|
||||
const simbolosData = [
|
||||
@@ -187,83 +194,63 @@ const solicitacoesAcessoData = [
|
||||
/**
|
||||
* Seed inicial do banco de dados com os dados exportados do Convex Cloud
|
||||
*/
|
||||
export const seedDatabase = internalMutation({
|
||||
export const seedCreateRoles = internalMutation({
|
||||
args: {},
|
||||
returns: v.null(),
|
||||
handler: async (ctx) => {
|
||||
console.log("🌱 Iniciando seed do banco de dados...");
|
||||
|
||||
// 1. Criar Roles (Perfis de Acesso)
|
||||
console.log("🔐 Criando roles...");
|
||||
// TI_MASTER - Nível 0 - Acesso total irrestrito
|
||||
const roleTIMaster = await ctx.db.insert("roles", {
|
||||
nome: "ti_master",
|
||||
descricao: "TI Master",
|
||||
nivel: 0,
|
||||
setor: "ti",
|
||||
customizado: false,
|
||||
editavel: false,
|
||||
});
|
||||
console.log(" ✅ Role criada: ti_master (Nível 0 - Acesso Total)");
|
||||
const ensureRole = async (
|
||||
nome: string,
|
||||
descricao: string,
|
||||
nivel: number,
|
||||
setor?: string,
|
||||
editavel?: boolean
|
||||
) => {
|
||||
const existing = await ctx.db
|
||||
.query("roles")
|
||||
.withIndex("by_nome", (q) => q.eq("nome", nome))
|
||||
.first();
|
||||
if (existing) {
|
||||
console.log(` ℹ️ Role já existe: ${nome}`);
|
||||
return existing._id;
|
||||
}
|
||||
const id = await ctx.db.insert("roles", {
|
||||
nome,
|
||||
descricao,
|
||||
nivel,
|
||||
setor,
|
||||
customizado: false,
|
||||
editavel,
|
||||
});
|
||||
console.log(` ✅ Role criada: ${nome}`);
|
||||
return id;
|
||||
};
|
||||
|
||||
// ADMIN - Nível 2 - Permissões configuráveis
|
||||
const roleAdmin = await ctx.db.insert("roles", {
|
||||
nome: "admin",
|
||||
descricao: "Administrador Geral",
|
||||
nivel: 2,
|
||||
setor: "administrativo",
|
||||
customizado: false,
|
||||
editavel: true, // Permissões configuráveis
|
||||
});
|
||||
console.log(" ✅ Role criada: admin (Nível 2 - Configurável)");
|
||||
await ensureRole("ti_master", "TI Master", 0, "ti", false);
|
||||
await ensureRole("admin", "Administrador Geral", 2, "administrativo", true);
|
||||
await ensureRole("ti_usuario", "TI Usuário", 2, "ti", true);
|
||||
await ensureRole("rh", "Recursos Humanos", 2, "recursos_humanos", false);
|
||||
await ensureRole("financeiro", "Financeiro", 2, "financeiro", false);
|
||||
await ensureRole("usuario", "Usuário Padrão", 3, undefined, false);
|
||||
// Encadeia próxima etapa
|
||||
await ctx.scheduler.runAfter(0, internal.seed.seedCreateSimbolos, {});
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
// TI_USUARIO - Nível 2 - Suporte técnico
|
||||
const roleTIUsuario = await ctx.db.insert("roles", {
|
||||
nome: "ti_usuario",
|
||||
descricao: "TI Usuário",
|
||||
nivel: 2,
|
||||
setor: "ti",
|
||||
customizado: false,
|
||||
editavel: true,
|
||||
});
|
||||
console.log(" ✅ Role criada: ti_usuario (Nível 2 - Suporte)");
|
||||
|
||||
const roleRH = await ctx.db.insert("roles", {
|
||||
nome: "rh",
|
||||
descricao: "Recursos Humanos",
|
||||
nivel: 2,
|
||||
setor: "recursos_humanos",
|
||||
customizado: false,
|
||||
editavel: false,
|
||||
});
|
||||
console.log(" ✅ Role criada: rh");
|
||||
|
||||
const roleFinanceiro = await ctx.db.insert("roles", {
|
||||
nome: "financeiro",
|
||||
descricao: "Financeiro",
|
||||
nivel: 2,
|
||||
setor: "financeiro",
|
||||
customizado: false,
|
||||
editavel: false,
|
||||
});
|
||||
console.log(" ✅ Role criada: financeiro");
|
||||
|
||||
const roleUsuario = await ctx.db.insert("roles", {
|
||||
nome: "usuario",
|
||||
descricao: "Usuário Padrão",
|
||||
nivel: 3,
|
||||
setor: undefined,
|
||||
customizado: false,
|
||||
editavel: false,
|
||||
});
|
||||
console.log(" ✅ Role criada: usuario (Nível 3 - Padrão)");
|
||||
|
||||
// 2. Criar Símbolos (Cargos)
|
||||
export const seedCreateSimbolos = internalMutation({
|
||||
args: {},
|
||||
returns: v.null(),
|
||||
handler: async (ctx) => {
|
||||
console.log("💰 Criando símbolos...");
|
||||
const simbolosMap = new Map<string, Id<"simbolos">>();
|
||||
|
||||
const existentes = await ctx.db.query("simbolos").collect();
|
||||
const nomesExistentes = new Set(existentes.map((s) => s.nome));
|
||||
for (const simbolo of simbolosData) {
|
||||
const simboloId = await ctx.db.insert("simbolos", {
|
||||
if (nomesExistentes.has(simbolo.nome)) {
|
||||
console.log(` ℹ️ Símbolo já existe: ${simbolo.nome}`);
|
||||
continue;
|
||||
}
|
||||
await ctx.db.insert("simbolos", {
|
||||
nome: simbolo.nome,
|
||||
descricao: simbolo.descricao,
|
||||
tipo: simbolo.tipo,
|
||||
@@ -271,24 +258,43 @@ export const seedDatabase = internalMutation({
|
||||
repValor: simbolo.repValor || "",
|
||||
vencValor: simbolo.vencValor || "",
|
||||
});
|
||||
simbolosMap.set(simbolo.nome, simboloId);
|
||||
console.log(` ✅ Símbolo criado: ${simbolo.nome}`);
|
||||
}
|
||||
// Encadeia próxima etapa
|
||||
await ctx.scheduler.runAfter(0, internal.seed.seedCreateFuncionarios, {});
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
// 3. Criar Funcionários
|
||||
export const seedCreateFuncionarios = internalMutation({
|
||||
args: {},
|
||||
returns: v.null(),
|
||||
handler: async (ctx) => {
|
||||
console.log("👥 Criando funcionários...");
|
||||
const funcionariosMap = new Map<string, Id<"funcionarios">>();
|
||||
const simbolos = await ctx.db.query("simbolos").collect();
|
||||
const simbolosMap = new Map<string, Id<"simbolos">>();
|
||||
for (const s of simbolos) {
|
||||
simbolosMap.set(s.nome, s._id as Id<"simbolos">);
|
||||
}
|
||||
|
||||
for (const funcionario of funcionariosData) {
|
||||
const simboloId = simbolosMap.get(funcionario.simboloNome);
|
||||
if (!simboloId) {
|
||||
// Evitar duplicar por CPF
|
||||
const existente = await ctx.db
|
||||
.query("funcionarios")
|
||||
.withIndex("by_cpf", (q) => q.eq("cpf", funcionario.cpf))
|
||||
.first();
|
||||
if (existente) {
|
||||
console.log(
|
||||
` ❌ Símbolo não encontrado: ${funcionario.simboloNome}`
|
||||
` ℹ️ Funcionário já existe (CPF ${funcionario.cpf}): ${existente.nome}`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
const funcId = await ctx.db.insert("funcionarios", {
|
||||
const simboloId = simbolosMap.get(funcionario.simboloNome);
|
||||
if (!simboloId) {
|
||||
console.log(` ❌ Símbolo não encontrado: ${funcionario.simboloNome}`);
|
||||
continue;
|
||||
}
|
||||
await ctx.db.insert("funcionarios", {
|
||||
admissaoData: funcionario.admissaoData,
|
||||
cep: funcionario.cep,
|
||||
cidade: funcionario.cidade,
|
||||
@@ -304,36 +310,126 @@ export const seedDatabase = internalMutation({
|
||||
telefone: funcionario.telefone,
|
||||
uf: funcionario.uf,
|
||||
});
|
||||
funcionariosMap.set(funcionario.matricula, funcId);
|
||||
console.log(` ✅ Funcionário criado: ${funcionario.nome}`);
|
||||
}
|
||||
// Encadeia próxima etapa
|
||||
await ctx.scheduler.runAfter(
|
||||
0,
|
||||
internal.seed.seedCreateUsuariosParaFuncionarios,
|
||||
{}
|
||||
);
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
// 5. Criar usuários para os funcionários
|
||||
export const seedCreateUsuariosParaFuncionarios = internalMutation({
|
||||
args: {},
|
||||
returns: v.null(),
|
||||
handler: async (ctx) => {
|
||||
console.log("👤 Criando usuários para funcionários...");
|
||||
// Agenda criação por funcionário para evitar timeout
|
||||
let delay = 0;
|
||||
for (const funcionario of funcionariosData) {
|
||||
const funcId = funcionariosMap.get(funcionario.matricula);
|
||||
if (!funcId) continue;
|
||||
|
||||
const senhaInicial = await hashPassword("Mudar@123");
|
||||
await ctx.db.insert("usuarios", {
|
||||
senhaHash: senhaInicial,
|
||||
nome: funcionario.nome,
|
||||
email: funcionario.email,
|
||||
funcionarioId: funcId as Id<"funcionarios">,
|
||||
roleId: roleUsuario,
|
||||
ativo: true,
|
||||
primeiroAcesso: true,
|
||||
criadoEm: Date.now(),
|
||||
atualizadoEm: Date.now(),
|
||||
});
|
||||
console.log(
|
||||
` ✅ Usuário criado: ${funcionario.nome} (senha: Mudar@123)`
|
||||
await ctx.scheduler.runAfter(
|
||||
delay,
|
||||
internal.seed.seedCreateUsuarioParaFuncionario,
|
||||
{
|
||||
matricula: funcionario.matricula,
|
||||
nome: funcionario.nome,
|
||||
email: funcionario.email,
|
||||
}
|
||||
);
|
||||
delay += 50;
|
||||
}
|
||||
// Agenda próxima etapa após as criações individuais
|
||||
await ctx.scheduler.runAfter(
|
||||
delay + 300,
|
||||
internal.seed.seedInserirSolicitacoesAcesso,
|
||||
{}
|
||||
);
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
export const seedCreateUsuarioParaFuncionario = internalMutation({
|
||||
args: {
|
||||
matricula: v.string(),
|
||||
nome: v.string(),
|
||||
email: v.string(),
|
||||
},
|
||||
returns: v.null(),
|
||||
handler: async (ctx, args) => {
|
||||
// Role "usuario"
|
||||
const roleUsuario = await ctx.db
|
||||
.query("roles")
|
||||
.withIndex("by_nome", (q) => q.eq("nome", "usuario"))
|
||||
.first();
|
||||
if (!roleUsuario) {
|
||||
console.log(' ❌ Role "usuario" não encontrada');
|
||||
return null;
|
||||
}
|
||||
|
||||
// 6. Inserir solicitações de acesso
|
||||
const funcionarioDoc = await ctx.db
|
||||
.query("funcionarios")
|
||||
.withIndex("by_matricula", (q) => q.eq("matricula", args.matricula))
|
||||
.first();
|
||||
if (!funcionarioDoc) {
|
||||
console.log(
|
||||
` ❌ Funcionário não encontrado pela matrícula: ${args.matricula}`
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
const usuarioExistente = await ctx.db
|
||||
.query("usuarios")
|
||||
.withIndex("by_email", (q) => q.eq("email", args.email))
|
||||
.first();
|
||||
if (usuarioExistente) {
|
||||
console.log(` ℹ️ Usuário já existe para ${args.email}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const authUserId = await createAuthUser(ctx, {
|
||||
nome: args.nome,
|
||||
email: args.email,
|
||||
password: "Mudar@123",
|
||||
});
|
||||
|
||||
await ctx.db.insert("usuarios", {
|
||||
authId: authUserId,
|
||||
nome: args.nome,
|
||||
email: args.email,
|
||||
funcionarioId: funcionarioDoc._id as Id<"funcionarios">,
|
||||
roleId: roleUsuario._id,
|
||||
ativo: true,
|
||||
primeiroAcesso: true,
|
||||
criadoEm: Date.now(),
|
||||
atualizadoEm: Date.now(),
|
||||
});
|
||||
console.log(` ✅ Usuário criado: ${args.nome} (senha: Mudar@123)`);
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
export const seedInserirSolicitacoesAcesso = internalMutation({
|
||||
args: {},
|
||||
returns: v.null(),
|
||||
handler: async (ctx) => {
|
||||
console.log("📋 Inserindo solicitações de acesso...");
|
||||
for (const solicitacao of solicitacoesAcessoData) {
|
||||
// Evitar duplicidade por matrícula
|
||||
const existente = await ctx.db
|
||||
.query("solicitacoesAcesso")
|
||||
.withIndex("by_matricula", (q) =>
|
||||
q.eq("matricula", solicitacao.matricula)
|
||||
)
|
||||
.first();
|
||||
if (existente) {
|
||||
console.log(
|
||||
` ℹ️ Solicitação já existe p/ matrícula ${solicitacao.matricula}`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
const dadosSolicitacao: {
|
||||
nome: string;
|
||||
matricula: string;
|
||||
@@ -365,10 +461,24 @@ export const seedDatabase = internalMutation({
|
||||
` ✅ Solicitação criada: ${solicitacao.nome} (${solicitacao.status})`
|
||||
);
|
||||
}
|
||||
|
||||
console.log("✨ Seed do banco de dados concluído com sucesso!");
|
||||
console.log("✨ Seed concluído!");
|
||||
return null;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const seedDatabase = internalAction({
|
||||
args: {},
|
||||
returns: v.null(),
|
||||
handler: async (ctx) => {
|
||||
console.log("🌱 Iniciando seed do banco de dados (action)...");
|
||||
await ctx.runMutation(internal.seed.seedCreateRoles, {});
|
||||
await ctx.runMutation(internal.seed.seedCreateSimbolos, {});
|
||||
await ctx.runMutation(internal.seed.seedCreateFuncionarios, {});
|
||||
await ctx.runMutation(internal.seed.seedCreateUsuariosParaFuncionarios, {});
|
||||
await ctx.runMutation(internal.seed.seedInserirSolicitacoesAcesso, {});
|
||||
console.log("✨ Seed do banco de dados concluído com sucesso pela action!");
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -379,10 +489,12 @@ export const popularBanco = mutation({
|
||||
args: {},
|
||||
returns: v.null(),
|
||||
handler: async (ctx) => {
|
||||
console.log("🌱 Executando popularBanco (wrapper público para seedDatabase)...");
|
||||
// Chama a internalMutation para reaproveitar a lógica de seed
|
||||
await ctx.runMutation(internal.seed.seedDatabase, {});
|
||||
console.log("✅ Seed concluído pelo wrapper público");
|
||||
console.log(
|
||||
"🌱 Executando popularBanco (wrapper público para seedDatabase)..."
|
||||
);
|
||||
// Agenda apenas a primeira etapa; as demais serão encadeadas internamente
|
||||
await ctx.scheduler.runAfter(0, internal.seed.seedCreateRoles, {});
|
||||
console.log("✅ Seed iniciado (etapa 1 agendada)");
|
||||
return null;
|
||||
},
|
||||
});
|
||||
@@ -525,7 +637,7 @@ export const clearDatabase = internalMutation({
|
||||
);
|
||||
|
||||
// 9. Perfis customizados
|
||||
|
||||
|
||||
// 10. Templates de mensagens
|
||||
const templatesMensagens = await ctx.db
|
||||
.query("templatesMensagens")
|
||||
@@ -587,9 +699,9 @@ export const clearDatabase = internalMutation({
|
||||
console.log(` ✅ ${sessoes.length} sessões removidas`);
|
||||
|
||||
// 14. Menu-permissões personalizadas
|
||||
|
||||
|
||||
// 15. Menu-permissões
|
||||
|
||||
|
||||
// 16. Role-permissões
|
||||
const rolePermissoes = await ctx.db.query("rolePermissoes").collect();
|
||||
for (const rp of rolePermissoes) {
|
||||
@@ -795,7 +907,7 @@ export const limparBanco = mutation({
|
||||
);
|
||||
|
||||
// 9. Perfis customizados (já está no código da internalMutation mas vazio)
|
||||
|
||||
|
||||
// 10. Templates de mensagens
|
||||
const templatesMensagens = await ctx.db
|
||||
.query("templatesMensagens")
|
||||
@@ -857,9 +969,9 @@ export const limparBanco = mutation({
|
||||
console.log(` ✅ ${sessoes.length} sessões removidas`);
|
||||
|
||||
// 14. Menu-permissões personalizadas (já está no código da internalMutation mas vazio)
|
||||
|
||||
|
||||
// 15. Menu-permissões (já está no código da internalMutation mas vazio)
|
||||
|
||||
|
||||
// 16. Role-permissões
|
||||
const rolePermissoes = await ctx.db.query("rolePermissoes").collect();
|
||||
for (const rp of rolePermissoes) {
|
||||
@@ -942,13 +1054,14 @@ export const verificarBanco = query({
|
||||
const funcionarios = await ctx.db.query("funcionarios").collect();
|
||||
const roles = await ctx.db.query("roles").collect();
|
||||
const simbolos = await ctx.db.query("simbolos").collect();
|
||||
|
||||
|
||||
return {
|
||||
usuarios: usuarios.length,
|
||||
funcionarios: funcionarios.length,
|
||||
roles: roles.length,
|
||||
simbolos: simbolos.length,
|
||||
total: usuarios.length + funcionarios.length + roles.length + simbolos.length,
|
||||
total:
|
||||
usuarios.length + funcionarios.length + roles.length + simbolos.length,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user