✅ EXECUÇÃO — 15/08/2026
Implementado e validado em produção (homolog). Commits: 2062f6c (fundação: 21 tabelas), 080c857 (features), bbfa277 (lint). Deploy CI verde.
Validação ao vivo: página(s) da feature respondendo 200 com a role correta + procedures tRPC testadas via HTTP (respostas JSON corretas). Ver relatório da sessão.
Detalhes de implementação e decisões: conforme o design acima deste documento (schema, procedures e páginas seguidos conforme especificado; ajustes menores documentados no commit).
📄 Card 48 [M8] — LGPD Editor de Termos Versionado
📚 Referência SULTS: https://www.sults.com.br/produtos/lgpd Editor de termos de uso com versionamento imutável, aceite obrigatório com bloqueio de tela e registro (nome, data, hora, versão) para auditorias da ANPD.
🎯 Objetivo
Expandir o ConsentRecord existente (Card 2) em um módulo completo de gestão de termos LGPD:
- Editor rico de Termos de Uso (seções numeradas, links, formatação jurídica)
- Versionamento imutável (toda alteração registra data/hora/autor)
- Documentos por perfil: Política de Dados, Termo de Confidencialidade, DPA
- Aceite com bloqueio de tela + assinatura obrigatória
- Registro imutável (nome completo + data/hora + versão aceita)
- Exportação de relatórios de aderência (ANPD)
📚 Documentação de Referência
docs/SEGURANCA_LGPD.md§2.3 (Consentimento)prisma/schema.prisma—ConsentRecordjá existe (expandir)
🛠️ Especificação Técnica
Schema Prisma (novo + expandir)
model LgpdTerm {
id String @id @default(cuid())
type LgpdTermType // PRIVACY_POLICY, CONFIDENTIALITY, DPA, TERMS_OF_USE
title String
version Int // auto-incremento por tipo
content String @db.Text // markdown jurídico
isActive Boolean @default(true)
publishedAt DateTime?
publishedById String
publishedBy User @relation(fields: [publishedById], references: [id])
targetRoles String[] // roles que precisam aceitar
acceptances LgpdAcceptance[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([type, version])
}
model LgpdAcceptance {
id String @id @default(cuid())
termId String
term LgpdTerm @relation(fields: [termId], references: [id])
userId String
user User @relation(fields: [userId], references: [id])
termVersion Int // snapshot da versão aceita
acceptedAt DateTime @default(now())
ipAddress String?
userAgent String?
@@unique([termId, userId])
}
enum LgpdTermType { PRIVACY_POLICY CONFIDENTIALITY DPA TERMS_OF_USE IMAGE_AUTHORIZATION }
⚠️ Manter
ConsentRecord(Card 2) para consentimentos granulares (LGPD opt-in por feature).LgpdTermé para termos formais versionados.
Rotas (page.tsx)
/master/lgpd— painel admin (editor + versionamento + relatório aderência)/master/lgpd/[termId]/editor— editor rico (markdown)- Componente
<LgpdGate />— wrapper que bloqueia navegação se há termo pendente
Procedures tRPC (master.lgpd)
terms.list(todos os tipos + versões)terms.create(rascunho de nova versão)terms.publish(publica nova versão — exige re-aceite de todos)terms.archivependingForUser(termos que o usuário ainda não aceitou na versão vigente)accept(registra LgpdAcceptance com IP + userAgent)report(aderência por termo: % aceitos, pendentes, export CSV)
Editor rico
- Usar componente
<MarkdownEditor />(pode serreact-markdown+@uiw/react-md-editor) - Preview side-by-side
- Auto-save rascunho (não versiona até publish)
Lógica de trava (Gate)
- Hook
useLgpdGate(): ao montar AppShell, chamapendingForUser - Se houver pendente → renderiza
<LgpdGate />em tela cheia com termo + checkbox "Li e aceito" + botão confirmar - Não dá pra navegar sem aceitar
✅ Critérios de Aceite
- MASTER cria/edita/publica termos com editor rico markdown
- Nova versão publicada → todos precisam re-aceitar
- Trava de tela no login se há termo pendente
- Registro imutável: userId + versão + timestamp + IP + userAgent
- Relatório de aderência exportável CSV (ANPD)
- Imutabilidade: versões antigas não editáveis (apenas archived)
- Build passa + lint OK
🔌 Handoff
- Hook
useLgpdGate()plugado no AppShell (similaruseSurveyGate) - Bucket
lgpd-termspara anexos (se necessário) - Procedimento de auditoria futura: query em
LgpdAcceptancepor usuário/versão
🎯 Próximo
Card 49: NPS (Pesquisa de Satisfação 0-10) — M9