298 lines
9.4 KiB
TypeScript
298 lines
9.4 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({
|
|
// Campos obrigatórios existentes
|
|
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,
|
|
|
|
// Dados Pessoais Adicionais (opcionais)
|
|
nomePai: v.optional(v.string()),
|
|
nomeMae: v.optional(v.string()),
|
|
naturalidade: v.optional(v.string()),
|
|
naturalidadeUF: v.optional(v.string()),
|
|
sexo: v.optional(v.union(
|
|
v.literal("masculino"),
|
|
v.literal("feminino"),
|
|
v.literal("outro")
|
|
)),
|
|
estadoCivil: v.optional(v.union(
|
|
v.literal("solteiro"),
|
|
v.literal("casado"),
|
|
v.literal("divorciado"),
|
|
v.literal("viuvo"),
|
|
v.literal("uniao_estavel")
|
|
)),
|
|
nacionalidade: v.optional(v.string()),
|
|
|
|
// Documentos Pessoais
|
|
rgOrgaoExpedidor: v.optional(v.string()),
|
|
rgDataEmissao: v.optional(v.string()),
|
|
carteiraProfissionalNumero: v.optional(v.string()),
|
|
carteiraProfissionalSerie: v.optional(v.string()),
|
|
carteiraProfissionalDataEmissao: v.optional(v.string()),
|
|
reservistaNumero: v.optional(v.string()),
|
|
reservistaSerie: v.optional(v.string()),
|
|
tituloEleitorNumero: v.optional(v.string()),
|
|
tituloEleitorZona: v.optional(v.string()),
|
|
tituloEleitorSecao: v.optional(v.string()),
|
|
pisNumero: v.optional(v.string()),
|
|
|
|
// Formação e Saúde
|
|
grauInstrucao: v.optional(v.union(
|
|
v.literal("fundamental"),
|
|
v.literal("medio"),
|
|
v.literal("superior"),
|
|
v.literal("pos_graduacao"),
|
|
v.literal("mestrado"),
|
|
v.literal("doutorado")
|
|
)),
|
|
formacao: v.optional(v.string()),
|
|
formacaoRegistro: v.optional(v.string()),
|
|
grupoSanguineo: v.optional(v.union(
|
|
v.literal("A"),
|
|
v.literal("B"),
|
|
v.literal("AB"),
|
|
v.literal("O")
|
|
)),
|
|
fatorRH: v.optional(v.union(
|
|
v.literal("positivo"),
|
|
v.literal("negativo")
|
|
)),
|
|
|
|
// Cargo e Vínculo
|
|
descricaoCargo: v.optional(v.string()),
|
|
nomeacaoPortaria: v.optional(v.string()),
|
|
nomeacaoData: v.optional(v.string()),
|
|
nomeacaoDOE: v.optional(v.string()),
|
|
pertenceOrgaoPublico: v.optional(v.boolean()),
|
|
orgaoOrigem: v.optional(v.string()),
|
|
aposentado: v.optional(v.union(
|
|
v.literal("nao"),
|
|
v.literal("funape_ipsep"),
|
|
v.literal("inss")
|
|
)),
|
|
|
|
// Dados Bancários
|
|
contaBradescoNumero: v.optional(v.string()),
|
|
contaBradescoDV: v.optional(v.string()),
|
|
contaBradescoAgencia: v.optional(v.string()),
|
|
|
|
// Documentos Anexos (Storage IDs)
|
|
certidaoAntecedentesPF: v.optional(v.id("_storage")),
|
|
certidaoAntecedentesJFPE: v.optional(v.id("_storage")),
|
|
certidaoAntecedentesSDS: v.optional(v.id("_storage")),
|
|
certidaoAntecedentesTJPE: v.optional(v.id("_storage")),
|
|
certidaoImprobidade: v.optional(v.id("_storage")),
|
|
rgFrente: v.optional(v.id("_storage")),
|
|
rgVerso: v.optional(v.id("_storage")),
|
|
cpfFrente: v.optional(v.id("_storage")),
|
|
cpfVerso: v.optional(v.id("_storage")),
|
|
situacaoCadastralCPF: v.optional(v.id("_storage")),
|
|
tituloEleitorFrente: v.optional(v.id("_storage")),
|
|
tituloEleitorVerso: v.optional(v.id("_storage")),
|
|
comprovanteVotacao: v.optional(v.id("_storage")),
|
|
carteiraProfissionalFrente: v.optional(v.id("_storage")),
|
|
carteiraProfissionalVerso: v.optional(v.id("_storage")),
|
|
comprovantePIS: v.optional(v.id("_storage")),
|
|
certidaoRegistroCivil: v.optional(v.id("_storage")),
|
|
certidaoNascimentoDependentes: v.optional(v.id("_storage")),
|
|
cpfDependentes: v.optional(v.id("_storage")),
|
|
reservistaDoc: v.optional(v.id("_storage")),
|
|
comprovanteEscolaridade: v.optional(v.id("_storage")),
|
|
comprovanteResidencia: v.optional(v.id("_storage")),
|
|
comprovanteContaBradesco: v.optional(v.id("_storage")),
|
|
|
|
// Declarações (Storage IDs)
|
|
declaracaoAcumulacaoCargo: v.optional(v.id("_storage")),
|
|
declaracaoDependentesIR: v.optional(v.id("_storage")),
|
|
declaracaoIdoneidade: v.optional(v.id("_storage")),
|
|
termoNepotismo: v.optional(v.id("_storage")),
|
|
termoOpcaoRemuneracao: v.optional(v.id("_storage")),
|
|
})
|
|
.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"]),
|
|
});
|