Files
sgse-app/packages/backend/convex/schema.ts

193 lines
5.5 KiB
TypeScript

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<typeof simboloTipo>;
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"]),
});