Contexto: porque LGPD pesa mais em EAD
Plataformas EAD coletam mais dados sensiveis que e-commerce ou redes sociais:
- Dados educacionais (LGPD Art. 11 — dado pessoal sensivel quando revela condicao de saude/bem-estar)
- Dados comportamentais ricos — tempo em cada aula, padroes de estudo, dificuldades, ansiedade pre-prova
- Dados de menores — fundamental I/II + medio = ~80% do mercado K-12 brasileiro
- Dados de pais/responsaveis (vinculacao GuardianLink)
- Dados biometricos quando ha proctoring com webcam (Studeia nao tem nativo, mas LTI a Examity/ProctorU sim)
ANPD ja fez fiscalizacoes em edtechs brasileiras em 2024-2025. Multas de R$50 milhoes (2% faturamento bruto, ate R$50M cap) sao reais.
8 frentes obrigatorias
1. DPO (Data Protection Officer) — Art. 41
Empresa precisa indicar pessoa fisica como encarregado pelo tratamento de dados. Responsabilidades:
- Aceitar reclamacoes e comunicacoes dos titulares
- Receber comunicacoes da ANPD
- Orientar funcionarios sobre LGPD
- Executar planos de adequacao
Opcoes:
| Modelo | Custo | Adequado pra |
|---|---|---|
| DPO interno (CLT) | R$8-20k/mes salario | Empresas >100 funcionarios |
| DPO externo (consultoria especializada) | R$2-8k/mes | Empresas 10-100 funcionarios |
| DPO virtual (escritorio de advocacia) | R$1-3k/mes | Microempresas |
Indicar publicamente: nome + email do DPO na politica de privacidade.
2. Consentimento parental real para menores — Art. 14
LGPD Art. 14 §1: "O tratamento de dados pessoais de criancas devera ser realizado com o consentimento especifico e em destaque dado por pelo menos um dos pais ou pelo responsavel legal."
Plataformas que ignoram = caro:
- ❌ Anti-padrao: checkbox "Tenho mais de 13 anos" sem verificacao
- ❌ Anti-padrao: campo "Email do pai" sem verificar se eh real
- ✅ Padrao Studeia: aluno cadastra → status
pending_parental_consent→ email/SMS para pai → pai clica link + responde verificacao SMS (anti-fraude) → statusactive
Plus: pai escolhe nivel de acesso por filho via ProgressSharingConfig. Aluno menor de 13: pai tem acesso TOTAL por padrao. 13-17: pai configura.
Implementacao concreta:
// Aluno se cadastra
if (user.age < 18) {
user.isMinor = true;
user.status = "pending_parental_consent";
// GuardianLink criado mas inativo
await prisma.guardianLink.create({
data: {
childId: user.id,
parentEmail: parentEmail,
parentPhone: parentPhone,
verified: false,
verificationToken: generateSecureToken(),
}
});
// Email + SMS pro pai com link de verificacao
await sendVerification({ ... });
}
Aluno NAO consegue acessar conteudo enquanto status != "active". Sem brecha.
3. Data export — Art. 18 IV
Titular pode solicitar copia de TODOS os dados pessoais que voce processa sobre ele. Em formato estruturado e legivel.
Studeia: GET /api/user/data-export retorna JSON com:
{
"user": { id, email, name, role, ... },
"enrollments": [ ... ],
"lessonCompletions": [ ... ],
"quizAttempts": [ ... ],
"chatSessions": [ ... ], // historico chat com tutor IA
"messages": [ ... ], // mensagens diretas + forum
"badges": [ ... ],
"gamificationProfile": { ... },
"aiSupervisorIncidents": [ ... ], // se houver
"consentRecords": [ ... ]
}
Rate limit: 1 export por 24h por usuario (anti-abuso). Redis key data-export-cooldown:{userId} TTL 86400.
Disponibilizado em ate 15 dias da solicitacao (LGPD nao define prazo exato, mas 15 dias e padrao ANPD).
4. Account deletion — Art. 18 VI
Titular pode solicitar elimina dos dados pessoais. Mas tem nuance:
- PII (dados pessoais identificaveis) — DEVE ser eliminado/anonimizado
- Dados academicos historicos — pode ser RETIDO por finalidade legitima (retencao fiscal, prova de formacao do aluno, defesa em eventual litigio)
Studeia faz:
// DELETE /api/user/account
await prisma.$transaction(async (tx) => {
// 1. Anonimiza PII
await tx.user.update({
where: { id: userId },
data: {
email: `deleted-${userId}@anonymous.studeia.com`,
name: "Usuario deletado",
phone: null,
address: null,
avatarUrl: null,
cpf: null, // CPF tambem
status: "deleted",
deletedAt: new Date(),
}
});
// 2. Deleta dados conversacionais
await tx.chatSession.deleteMany({ where: { userId } });
await tx.directMessage.deleteMany({ where: { senderId: userId } });
await tx.directMessage.updateMany({ where: { recipientId: userId }, data: { recipientId: ANONYMIZED } });
// 3. Anonimiza dados academicos (mantem historico mas sem PII)
// LessonCompletion, QuizAttempt, Grade ja referenciam por User.id (mantido)
// Como User.email e User.name foram anonimizados, dados academicos ficam "anonimos"
// 4. Anonimiza incidents de safety (mantem severity + categoria pra compliance)
await tx.aiSupervisorIncident.updateMany({
where: { userId },
data: {
messagesSnapshot: [],
supervisorReasoning: null,
appealText: null,
}
});
// 5. Cron purga dados academicos > 5 anos automaticamente
});
5 anos = retencao fiscal LGPD-friendly (Lei 10.406/2002 + nossa CR Art. 7º XXIX).
5. DPA com terceiros — disclosure obrigatoria
Tenant DEVE listar em politica de privacidade TODOS os processadores de dados terceirizados.
Studeia repassa pra cada tenant uma lista:
- Anthropic (Claude) — processa prompts + respostas. DPA GDPR/LGPD. Sede USA. Data retention: 30 dias.
- OpenAI (GPT fallback) — idem. Sede USA. Data retention: 30 dias.
- Voyage AI (embeddings primary) — processa texto pra embedding. Sede USA. Data retention: 30 dias.
- Stripe (pagamentos USD) — PCI-DSS Level 1. Sede USA. Retention: 7 anos (fiscal).
- Asaas (pagamentos BR PIX/boleto) — sede BR. Retention: 7 anos.
- Supabase (banco + auth + storage) — sede USA. Region: us-east-1 (default) ou sa-east-1 opcional.
- Sentry (observability) — Session replay com maskAllText:true + blockAllMedia:true (LGPD-compliant).
- PostHog (analytics) — IP anonymization on. No PII tracking.
- Resend / SendGrid (email) — sede USA. Retention: 30 dias.
Tenant copia essa lista pra sua politica de privacidade. Cobre disclosure.
6. Tenant isolation real — RLS + filter mandatory
LGPD Art. 6 V: dados pessoais devem ser tratados com seguranca apropriada.
Multi-tenant LMS = dados de Escola A NUNCA podem aparecer em consulta de Escola B. Studeia implementa em 3 camadas:
- Filter mandatory em queries Prisma: toda chamada
prisma.X.findMany()em codigo de aplicacao DEVE incluirwhere: { tenantId }. Critical rule #6 do projeto. - RLS Supabase: policy automatica em todas tabelas relevantes:
CREATE POLICY tenant_isolation_courses ON courses FOR SELECT USING (tenant_id = current_setting('app.current_tenant_id')::uuid); - RAG tenantOnlyMode: retrieve nunca cita material de outra instituicao.
7. Audit log imutavel
LGPD Art. 37 + ANPD Resolucao CD/ANPD nº 4/2023: registro de operacoes de tratamento.
Studeia: AdminAuditLog model com:
model AdminAuditLog {
id String @id @default(uuid())
actorId String // quem fez a acao
action AdminAuditAction
targetType String // "user", "tenant", "course", etc
targetId String?
metadata Json?
ip String?
userAgent String?
createdAt DateTime @default(now())
}
Acoes auditadas (15+ tipos):
- impersonate.start / stop
- tenant.create / plan.change / config.update / delete
- user.role.change / tenant.link
- ai_supervisor.* (incident transitions, prompt updates, etc)
- subscription.admin_update
- payment.manual.record
Imutavel: append-only. Nao ha endpoint pra deletar (proposital).
8. Plano de resposta a incidente
LGPD Art. 48: incidente de seguranca que possa acarretar risco/dano relevante = comunicacao a ANPD em prazo razoavel (interpretacao: 24h).
Studeia: runbook em docs/runbooks/incident-response.md com SEV table:
| SEV | Trigger | Acao primaria | SLA notif |
|---|---|---|---|
| SEV1 | Vazamento PII > 100 users | ANPD reporting + clientes + status page | <2h |
| SEV2 | Outage > 30min OR PII < 100 users | Clientes + status page | <4h |
| SEV3 | Performance degradacao | Status page | <12h |
| SEV4 | Bug funcional sem PII | Backlog priorizado | NA |
Plus: postmortem publico (sanitizado) em docs/incidents/ para SEV1/SEV2.
Adicoes especificas para Studeia
Logging de prompts LLM
Antes de enviar prompt pra Anthropic/OpenAI:
// Redact PII conhecida
function redactPIIBeforeLLM(prompt: string, user: User): string {
return prompt
.replace(new RegExp(user.email, 'gi'), '[EMAIL_REDACTED]')
.replace(new RegExp(user.cpf ?? '', 'g'), '[CPF_REDACTED]')
.replace(new RegExp(user.phone ?? '', 'g'), '[PHONE_REDACTED]');
}
Antes de logar prompt em AiUsageLog:
function redactPIIBeforeLog(prompt: string): string {
// Generic patterns
return prompt
.replace(/\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g, '[CPF]')
.replace(/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g, '[EMAIL]')
.replace(/\b\d{4,5}-?\d{4}\b/g, '[PHONE]');
}
AiUsageLog.prompt armazena versao redacted. Custos + analytics funcionam sem expor PII.
Tutor IA + chat history
Aluno acessa "Minhas conversas" e ve historico. Pais com permissao tambem (depending on ProgressSharingConfig.viewChatHistory).
Mas: ANPD pode requisitar via judicial. Resposta:
- Studeia mantem chat history por 1 ano (retention default, configurable per-tenant)
- Apos 1 ano: cron
/api/cron/chat-cleanupanonimiza (mantem turno count para analytics, deleta texto) - Em requisicao judicial: exporta JSON com seo conteudo solicitado
- Logging do acesso em AdminAuditLog (action:
data.judicial_request)
O que NUNCA fazer
❌ Coletar mais dados que o necessario (princpio minimizacao Art. 6 III) ❌ Compartilhar dados de alunos para fins de marketing (mesmo "internamente") ❌ Treinar modelo de IA com dados de alunos sem consentimento explicito ❌ Vender dados de comportamento de estudo para terceiros ❌ Usar dados de menor para publicidade direcionada (proibido por lei) ❌ Reter dados sem finalidade clara (Art. 16) ❌ Usar IA tutor sem informar que e IA (transparencia, Art. 6 VI)
E o avatar IA real-time (futuro)?
Quando Studeia adicionar avatar com video/voz (roadmap HeyGen/D-ID):
- Consentimento adicional explicito (uso de "imagem virtual de tutor")
- Disclosure que e IA (rodape "Tutor virtual gerado por IA")
- Nao usar voz real de pessoa publica sem licenciamento (deepfake risk)