feat(rgpd): pedido de acesso/apagamento de dados + processo escrito (item 9.5)

- migration_20260925_rgpd_requests.sql: tabela rgpd_requests (email, tipo,
  estado, consentimento).
- config/functions_rgpd.php: rgpd_find() (acesso, art.º 15) e rgpd_erase()
  (apagamento por anonimização, art.º 17) sobre membership_leads/trial_leads/
  event_leads, + CRUD dos pedidos.
- Política de Privacidade: formulário público (POST + CSRF + anti-spam) para
  pedir acesso ou apagamento, e o processo escrito (resposta em 30 dias).
- Backoffice: página "Pedidos RGPD" (nav + index) para exportar os dados de um
  email (CSV, audit) ou anonimizá-los (POST + CSRF, audit).

O email está desligado, por isso os pedidos ficam guardados (como as leads),
não dependem de SMTP. Texto legal com placeholders — rever com jurista antes
do go-live (como já constava na Política).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
andreandClaude Fable 5 committed 2026-09-25 23:48:18 +01:00
1 parent 116817e2de
commit 3f2c505c17
6 files changed
+248 -1

No files matched your search

+4
View File
@@ -173,6 +173,10 @@ $app_name = defined('APP_NAME') ? APP_NAME : 'FitMe 3070';
<a class="nav-link<?= (strpos($_SERVER['SCRIPT_NAME'] ?? '', '/views/admin/trash/') !== false) ? ' active' : '' ?>"
href="<?= base_url('views/admin/trash/index.php') ?>"><i class="bi bi-trash3-fill"></i>Lixeira</a>
</li>
<li class="nav-item">
<a class="nav-link<?= (strpos($_SERVER['SCRIPT_NAME'] ?? '', '/views/admin/rgpd/') !== false) ? ' active' : '' ?>"
href="<?= base_url('views/admin/rgpd/index.php') ?>"><i class="bi bi-shield-lock-fill"></i>Pedidos RGPD</a>
</li>
</ul>
<?php endif; ?>