A LGPD chega no time de engenharia geralmente na forma errada: um pedido pra colocar banner de cookie e um link de política de privacidade no rodapé.
Isso é a camada mais fina. O que a lei realmente exige toca modelagem de dado, retenção e capacidade de resposta, e nada disso se resolve no frontend.
Vale o aviso: isto é leitura de engenheiro sobre implicações técnicas, não orientação jurídica. As decisões sobre base legal e escopo são do jurídico.
As perguntas que o seu sistema precisa responder
Antes de qualquer implementação, tente responder estas quatro com uma consulta:
Onde exatamente está o dado pessoal de uma pessoa específica, em todos os sistemas?
Por que a gente guarda cada um desses campos?
Há quanto tempo, e até quando deveria guardar?
Quem acessou nos últimos meses?
Se alguma delas exigir uma reunião pra responder, esse é o trabalho de verdade, e nenhum banner ajuda.
O inventário é o primeiro entregável
Não um documento na wiki: um mapeamento que fica junto do código e envelhece junto com ele.
// user.entity.ts
@Entity("users")
export class User {
@Column()
@PersonalData({ category: "identificação", basis: "contrato", retention: "5 anos após encerramento" })
cpf: string;
@Column()
@PersonalData({ category: "contato", basis: "contrato", retention: "5 anos após encerramento" })
email: string;
@Column()
@PersonalData({ category: "comportamental", basis: "legítimo interesse", retention: "18 meses" })
lastSeenAt: Date;
}
Um decorador que só carrega metadado. O ganho é que ele vive ao lado da definição da coluna, então quem adiciona um campo é obrigado a pensar na classificação, e dá pra gerar o inventário automaticamente a partir do código.
Documento separado do código desatualiza em três meses. Sempre.
Os lugares esquecidos
O inventário quase sempre cobre o banco principal e esquece o resto.
Log de aplicação, que é onde o vazamento silencioso acontece com mais frequência. Escrevi um cenário completo sobre isso em o log que vazou CPF.
Backup, que guarda tudo por meses e não sabe apagar seletivamente.
Data warehouse, planilha de análise, ferramenta de suporte, provedor de e-mail, ferramenta de sessão gravada.
Ambiente de homologação com cópia da produção. Esse é o mais comum e o mais indefensável: dado real de cliente, com controle de acesso frouxo, disponível pra estagiário.
Exclusão que funciona de verdade
O direito à eliminação bate de frente com duas coisas que a engenharia gosta: imutabilidade e backup.
O padrão que resolve na prática é separar identidade de fato.
-- tabela mutável, apagável
create table person (
id uuid primary key,
name text,
cpf text,
email text,
deleted_at timestamptz
);
-- registro imutável, referencia a pessoa por id
create table ledger_entry (
id bigserial primary key,
person_id uuid not null, -- referência, nunca cópia dos dados
amount_minor bigint not null
);
O histórico financeiro continua íntegro e o dado pessoal some quando precisa sumir. Sistema que copia nome e CPF pra dentro de cada evento imutável cria um problema sem solução barata.
Para o que precisa sobreviver anonimizado, criptografia por titular é a técnica que funciona: cada pessoa tem sua chave, o dado sensível é guardado cifrado, e apagar a chave torna o conteúdo irrecuperável sem tocar em nenhuma linha imutável.
Backup: a saída aceita costuma ser não restaurar dado de quem pediu exclusão, com procedimento escrito. Backup não é reescrito, e isso precisa estar documentado antes de alguém perguntar.
Retenção que acontece sozinha
Retenção definida em política e não implementada em código é retenção que não existe.
-- job que roda diariamente
delete from user_session where created_at < now() - interval '18 months';
update person
set name = null, cpf = null, email = null, anonymized_at = now()
where deleted_at < now() - interval '30 days' and anonymized_at is null;
O trabalho difícil não é escrever isso, é decidir os prazos. E a decisão é do jurídico junto com o negócio, com a engenharia apontando o custo técnico de cada opção.
Log de acesso
O direito de saber com quem o dado foi compartilhado exige registro de acesso, não só de alteração.
A maioria dos sistemas registra UPDATE e não registra SELECT. Consulta de dado pessoal por operador de suporte precisa gerar evento, com quem, quando, qual titular e a que propósito. Isso é o mesmo mecanismo do audit trail, aplicado à leitura.
De quebra, é o que permite detectar acesso indevido, que é uma categoria de incidente que passa completamente despercebida sem esse registro.
Minimização é decisão de arquitetura
O princípio mais útil e o mais ignorado: não colete o que você não usa.
Todo formulário acumula campo que alguém pediu um dia e ninguém mais consulta. Cada um deles é risco, é obrigação e é custo.
Uma revisão anual perguntando “quem usa esse campo?” costuma permitir remover um terço. Menos dado é menos superfície, menos trabalho de conformidade e menos consequência num vazamento.
O que eu faria primeiro
Se o sistema não tem nada, a ordem por retorno:
Redação de campo sensível no log, que fecha o vazamento mais provável e leva um dia.
Inventário junto do código, que é o que torna todo o resto possível.
Retenção implementada em job, começando pelos dados de menor valor e maior volume.
Ambiente de homologação com dado sintético ou mascarado, que elimina uma categoria inteira de exposição.
E registro de acesso, que é o mais trabalhoso e o que mais protege quando algo acontece.