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']) };