Files
sgse-app/packages/backend/convex/tables/lgpdTables.ts

99 lines
3.8 KiB
TypeScript

import { defineTable } from 'convex/server';
import { v } from 'convex/values';
export const lgpdTables = {
// ========== LGPD - Lei Geral de Proteção de Dados ==========
// Solicitações de direitos LGPD
solicitacoesLGPD: defineTable({
tipo: v.union(
v.literal('acesso'),
v.literal('correcao'),
v.literal('exclusao'),
v.literal('portabilidade'),
v.literal('revogacao_consentimento'),
v.literal('informacao_compartilhamento')
),
usuarioId: v.id('usuarios'),
funcionarioId: v.optional(v.id('funcionarios')),
status: v.union(
v.literal('pendente'),
v.literal('em_analise'),
v.literal('concluida'),
v.literal('rejeitada'),
v.literal('cancelada')
),
dadosSolicitados: v.optional(v.string()), // JSON com detalhes da solicitação
resposta: v.optional(v.string()), // Resposta da solicitação
arquivoResposta: v.optional(v.id('_storage')), // Arquivo gerado (ex: exportação de dados)
respondidoPor: v.optional(v.id('usuarios')),
respondidoEm: v.optional(v.number()),
criadoEm: v.number(),
prazoResposta: v.number(), // Prazo legal (15 dias) - timestamp
observacoes: v.optional(v.string())
})
.index('by_usuario', ['usuarioId'])
.index('by_status', ['status'])
.index('by_tipo', ['tipo'])
.index('by_prazo', ['prazoResposta'])
.index('by_funcionario', ['funcionarioId']),
// Consentimentos dos usuários
consentimentos: defineTable({
usuarioId: v.id('usuarios'),
tipo: v.union(
v.literal('termo_uso'),
v.literal('politica_privacidade'),
v.literal('comunicacoes'),
v.literal('compartilhamento_dados')
),
aceito: v.boolean(),
versao: v.string(), // Versão do documento aceito (ex: "1.0")
ipAddress: v.optional(v.string()),
userAgent: v.optional(v.string()),
aceitoEm: v.number(),
revogadoEm: v.optional(v.number()),
revogadoPor: v.optional(v.id('usuarios')) // Se revogado pelo próprio usuário ou por TI
})
.index('by_usuario', ['usuarioId'])
.index('by_tipo', ['tipo'])
.index('by_usuario_tipo', ['usuarioId', 'tipo'])
.index('by_versao', ['versao']),
// Registro de Operações de Tratamento (ROT)
registrosTratamento: defineTable({
finalidade: v.string(), // Finalidade do tratamento
baseLegal: v.string(), // Base legal (ex: "Art. 7º, II - Execução de políticas públicas")
categoriasDados: v.array(v.string()), // ["dados_identificacao", "dados_contato", "dados_profissionais"]
categoriasTitulares: v.array(v.string()), // ["funcionarios", "servidores", "colaboradores"]
medidasSeguranca: v.array(v.string()), // ["criptografia", "controle_acesso", "logs_auditoria"]
prazoRetencao: v.number(), // em dias
compartilhamentoTerceiros: v.boolean(),
terceiros: v.optional(v.array(v.string())), // Lista de terceiros com quem compartilha
responsavel: v.id('usuarios'), // Responsável pelo tratamento
criadoEm: v.number(),
atualizadoEm: v.number(),
ativo: v.boolean(),
descricao: v.optional(v.string()) // Descrição detalhada
})
.index('by_finalidade', ['finalidade'])
.index('by_ativo', ['ativo'])
.index('by_responsavel', ['responsavel']),
// Configurações LGPD
configuracaoLGPD: defineTable({
encarregadoNome: v.optional(v.string()),
encarregadoEmail: v.optional(v.string()),
encarregadoTelefone: v.optional(v.string()),
encarregadoHorarioAtendimento: v.optional(v.string()), // Ex: "Segunda a Sexta, das 8h às 17h"
prazoRespostaPadrao: v.number(), // em dias (padrão: 15)
diasAlertaVencimento: v.number(), // dias antes do prazo para alertar (padrão: 3)
termoObrigatorio: v.boolean(), // Se o termo de consentimento é obrigatório
versaoTermoAtual: v.string(), // Versão atual do termo (ex: "1.0")
politicaRetencao: v.optional(v.string()), // JSON com política de retenção por tipo de dado
ativo: v.boolean(),
atualizadoPor: v.id('usuarios'),
atualizadoEm: v.number()
}).index('by_ativo', ['ativo'])
};