import { defineSchema, defineTable } from "convex/server"; import { Infer, v } from "convex/values"; import { tables } from "./betterAuth/schema"; import { cidrv4 } from "better-auth"; export const simboloTipo = v.union( v.literal("cargo_comissionado"), v.literal("funcao_gratificada") ); export type SimboloTipo = Infer; export default defineSchema({ ...tables, todos: defineTable({ text: v.string(), completed: v.boolean(), }), funcionarios: defineTable({ nome: v.string(), nascimento: v.string(), rg: v.string(), cpf: v.string(), endereco: v.string(), cep: v.string(), cidade: v.string(), uf: v.string(), telefone: v.string(), email: v.string(), matricula: v.string(), admissaoData: v.optional(v.string()), desligamentoData: v.optional(v.string()), simboloId: v.id("simbolos"), simboloTipo: simboloTipo, }) .index("by_matricula", ["matricula"]) .index("by_nome", ["nome"]) .index("by_simboloId", ["simboloId"]) .index("by_simboloTipo", ["simboloTipo"]) .index("by_cpf", ["cpf"]) .index("by_rg", ["rg"]), atestados: defineTable({ funcionarioId: v.id("funcionarios"), dataInicio: v.string(), dataFim: v.string(), cid: v.string(), descricao: v.string(), }), ferias: defineTable({ funcionarioId: v.id("funcionarios"), dataInicio: v.string(), dataFim: v.string(), }), simbolos: defineTable({ nome: v.string(), tipo: simboloTipo, descricao: v.string(), vencValor: v.string(), repValor: v.string(), valor: v.string(), }), solicitacoesAcesso: defineTable({ nome: v.string(), matricula: v.string(), email: v.string(), telefone: v.string(), status: v.union( v.literal("pendente"), v.literal("aprovado"), v.literal("rejeitado") ), dataSolicitacao: v.number(), dataResposta: v.optional(v.number()), observacoes: v.optional(v.string()), }) .index("by_status", ["status"]) .index("by_matricula", ["matricula"]) .index("by_email", ["email"]), // Sistema de Autenticação e Controle de Acesso usuarios: defineTable({ matricula: v.string(), senhaHash: v.string(), // Senha criptografada com bcrypt nome: v.string(), email: v.string(), funcionarioId: v.optional(v.id("funcionarios")), roleId: v.id("roles"), ativo: v.boolean(), primeiroAcesso: v.boolean(), ultimoAcesso: v.optional(v.number()), criadoEm: v.number(), atualizadoEm: v.number(), }) .index("by_matricula", ["matricula"]) .index("by_email", ["email"]) .index("by_role", ["roleId"]) .index("by_ativo", ["ativo"]), roles: defineTable({ nome: v.string(), // "admin", "ti", "usuario_avancado", "usuario" descricao: v.string(), nivel: v.number(), // 0 = admin, 1 = ti, 2 = usuario_avancado, 3 = usuario setor: v.optional(v.string()), // "ti", "rh", "financeiro", etc. }) .index("by_nome", ["nome"]) .index("by_nivel", ["nivel"]) .index("by_setor", ["setor"]), permissoes: defineTable({ nome: v.string(), // "funcionarios.criar", "simbolos.editar", etc. descricao: v.string(), recurso: v.string(), // "funcionarios", "simbolos", "usuarios", etc. acao: v.string(), // "criar", "ler", "editar", "excluir" }) .index("by_recurso", ["recurso"]) .index("by_nome", ["nome"]), rolePermissoes: defineTable({ roleId: v.id("roles"), permissaoId: v.id("permissoes"), }) .index("by_role", ["roleId"]) .index("by_permissao", ["permissaoId"]), // Permissões de Menu (granulares por role) menuPermissoes: defineTable({ roleId: v.id("roles"), menuPath: v.string(), // "/recursos-humanos", "/financeiro", etc. podeAcessar: v.boolean(), podeConsultar: v.boolean(), // Pode apenas visualizar podeGravar: v.boolean(), // Pode criar/editar/excluir }) .index("by_role", ["roleId"]) .index("by_menu", ["menuPath"]) .index("by_role_and_menu", ["roleId", "menuPath"]), // Permissões de Menu Personalizadas (por matrícula) menuPermissoesPersonalizadas: defineTable({ usuarioId: v.id("usuarios"), matricula: v.string(), // Para facilitar busca menuPath: v.string(), podeAcessar: v.boolean(), podeConsultar: v.boolean(), podeGravar: v.boolean(), }) .index("by_usuario", ["usuarioId"]) .index("by_matricula", ["matricula"]) .index("by_usuario_and_menu", ["usuarioId", "menuPath"]) .index("by_matricula_and_menu", ["matricula", "menuPath"]), sessoes: defineTable({ usuarioId: v.id("usuarios"), token: v.string(), ipAddress: v.optional(v.string()), userAgent: v.optional(v.string()), criadoEm: v.number(), expiraEm: v.number(), ativo: v.boolean(), }) .index("by_usuario", ["usuarioId"]) .index("by_token", ["token"]) .index("by_ativo", ["ativo"]) .index("by_expiracao", ["expiraEm"]), logsAcesso: defineTable({ usuarioId: v.id("usuarios"), tipo: v.union( v.literal("login"), v.literal("logout"), v.literal("acesso_negado"), v.literal("senha_alterada"), v.literal("sessao_expirada") ), ipAddress: v.optional(v.string()), userAgent: v.optional(v.string()), detalhes: v.optional(v.string()), timestamp: v.number(), }) .index("by_usuario", ["usuarioId"]) .index("by_tipo", ["tipo"]) .index("by_timestamp", ["timestamp"]), configuracaoAcesso: defineTable({ chave: v.string(), // "sessao_duracao", "max_tentativas_login", etc. valor: v.string(), descricao: v.string(), }) .index("by_chave", ["chave"]), });